highcharts-more.src.js 502 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568756975707571757275737574757575767577757875797580758175827583758475857586758775887589759075917592759375947595759675977598759976007601760276037604760576067607760876097610761176127613761476157616761776187619762076217622762376247625762676277628762976307631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700770177027703770477057706770777087709771077117712771377147715771677177718771977207721772277237724772577267727772877297730773177327733773477357736773777387739774077417742774377447745774677477748774977507751775277537754775577567757775877597760776177627763776477657766776777687769777077717772777377747775777677777778777977807781778277837784778577867787778877897790779177927793779477957796779777987799780078017802780378047805780678077808780978107811781278137814781578167817781878197820782178227823782478257826782778287829783078317832783378347835783678377838783978407841784278437844784578467847784878497850785178527853785478557856785778587859786078617862786378647865786678677868786978707871787278737874787578767877787878797880788178827883788478857886788778887889789078917892789378947895789678977898789979007901790279037904790579067907790879097910791179127913791479157916791779187919792079217922792379247925792679277928792979307931793279337934793579367937793879397940794179427943794479457946794779487949795079517952795379547955795679577958795979607961796279637964796579667967796879697970797179727973797479757976797779787979798079817982798379847985798679877988798979907991799279937994799579967997799879998000800180028003800480058006800780088009801080118012801380148015801680178018801980208021802280238024802580268027802880298030803180328033803480358036803780388039804080418042804380448045804680478048804980508051805280538054805580568057805880598060806180628063806480658066806780688069807080718072807380748075807680778078807980808081808280838084808580868087808880898090809180928093809480958096809780988099810081018102810381048105810681078108810981108111811281138114811581168117811881198120812181228123812481258126812781288129813081318132813381348135813681378138813981408141814281438144814581468147814881498150815181528153815481558156815781588159816081618162816381648165816681678168816981708171817281738174817581768177817881798180818181828183818481858186818781888189819081918192819381948195819681978198819982008201820282038204820582068207820882098210821182128213821482158216821782188219822082218222822382248225822682278228822982308231823282338234823582368237823882398240824182428243824482458246824782488249825082518252825382548255825682578258825982608261826282638264826582668267826882698270827182728273827482758276827782788279828082818282828382848285828682878288828982908291829282938294829582968297829882998300830183028303830483058306830783088309831083118312831383148315831683178318831983208321832283238324832583268327832883298330833183328333833483358336833783388339834083418342834383448345834683478348834983508351835283538354835583568357835883598360836183628363836483658366836783688369837083718372837383748375837683778378837983808381838283838384838583868387838883898390839183928393839483958396839783988399840084018402840384048405840684078408840984108411841284138414841584168417841884198420842184228423842484258426842784288429843084318432843384348435843684378438843984408441844284438444844584468447844884498450845184528453845484558456845784588459846084618462846384648465846684678468846984708471847284738474847584768477847884798480848184828483848484858486848784888489849084918492849384948495849684978498849985008501850285038504850585068507850885098510851185128513851485158516851785188519852085218522852385248525852685278528852985308531853285338534853585368537853885398540854185428543854485458546854785488549855085518552855385548555855685578558855985608561856285638564856585668567856885698570857185728573857485758576857785788579858085818582858385848585858685878588858985908591859285938594859585968597859885998600860186028603860486058606860786088609861086118612861386148615861686178618861986208621862286238624862586268627862886298630863186328633863486358636863786388639864086418642864386448645864686478648864986508651865286538654865586568657865886598660866186628663866486658666866786688669867086718672867386748675867686778678867986808681868286838684868586868687868886898690869186928693869486958696869786988699870087018702870387048705870687078708870987108711871287138714871587168717871887198720872187228723872487258726872787288729873087318732873387348735873687378738873987408741874287438744874587468747874887498750875187528753875487558756875787588759876087618762876387648765876687678768876987708771877287738774877587768777877887798780878187828783878487858786878787888789879087918792879387948795879687978798879988008801880288038804880588068807880888098810881188128813881488158816881788188819882088218822882388248825882688278828882988308831883288338834883588368837883888398840884188428843884488458846884788488849885088518852885388548855885688578858885988608861886288638864886588668867886888698870887188728873887488758876887788788879888088818882888388848885888688878888888988908891889288938894889588968897889888998900890189028903890489058906890789088909891089118912891389148915891689178918891989208921892289238924892589268927892889298930893189328933893489358936893789388939894089418942894389448945894689478948894989508951895289538954895589568957895889598960896189628963896489658966896789688969897089718972897389748975897689778978897989808981898289838984898589868987898889898990899189928993899489958996899789988999900090019002900390049005900690079008900990109011901290139014901590169017901890199020902190229023902490259026902790289029903090319032903390349035903690379038903990409041904290439044904590469047904890499050905190529053905490559056905790589059906090619062906390649065906690679068906990709071907290739074907590769077907890799080908190829083908490859086908790889089909090919092909390949095909690979098909991009101910291039104910591069107910891099110911191129113911491159116911791189119912091219122912391249125912691279128912991309131913291339134913591369137913891399140914191429143914491459146914791489149915091519152915391549155915691579158915991609161916291639164916591669167916891699170917191729173917491759176917791789179918091819182918391849185918691879188918991909191919291939194919591969197919891999200920192029203920492059206920792089209921092119212921392149215921692179218921992209221922292239224922592269227922892299230923192329233923492359236923792389239924092419242924392449245924692479248924992509251925292539254925592569257925892599260926192629263926492659266926792689269927092719272927392749275927692779278927992809281928292839284928592869287928892899290929192929293929492959296929792989299930093019302930393049305930693079308930993109311931293139314931593169317931893199320932193229323932493259326932793289329933093319332933393349335933693379338933993409341934293439344934593469347934893499350935193529353935493559356935793589359936093619362936393649365936693679368936993709371937293739374937593769377937893799380938193829383938493859386938793889389939093919392939393949395939693979398939994009401940294039404940594069407940894099410941194129413941494159416941794189419942094219422942394249425942694279428942994309431943294339434943594369437943894399440944194429443944494459446944794489449945094519452945394549455945694579458945994609461946294639464946594669467946894699470947194729473947494759476947794789479948094819482948394849485948694879488948994909491949294939494949594969497949894999500950195029503950495059506950795089509951095119512951395149515951695179518951995209521952295239524952595269527952895299530953195329533953495359536953795389539954095419542954395449545954695479548954995509551955295539554955595569557955895599560956195629563956495659566956795689569957095719572957395749575957695779578957995809581958295839584958595869587958895899590959195929593959495959596959795989599960096019602960396049605960696079608960996109611961296139614961596169617961896199620962196229623962496259626962796289629963096319632963396349635963696379638963996409641964296439644964596469647964896499650965196529653965496559656965796589659966096619662966396649665966696679668966996709671967296739674967596769677967896799680968196829683968496859686968796889689969096919692969396949695969696979698969997009701970297039704970597069707970897099710971197129713971497159716971797189719972097219722972397249725972697279728972997309731973297339734973597369737973897399740974197429743974497459746974797489749975097519752975397549755975697579758975997609761976297639764976597669767976897699770977197729773977497759776977797789779978097819782978397849785978697879788978997909791979297939794979597969797979897999800980198029803980498059806980798089809981098119812981398149815981698179818981998209821982298239824982598269827982898299830983198329833983498359836983798389839984098419842984398449845984698479848984998509851985298539854985598569857985898599860986198629863986498659866986798689869987098719872987398749875987698779878987998809881988298839884988598869887988898899890989198929893989498959896989798989899990099019902990399049905990699079908990999109911991299139914991599169917991899199920992199229923992499259926992799289929993099319932993399349935993699379938993999409941994299439944994599469947994899499950995199529953995499559956995799589959996099619962996399649965996699679968996999709971997299739974997599769977997899799980998199829983998499859986998799889989999099919992999399949995999699979998999910000100011000210003100041000510006100071000810009100101001110012100131001410015100161001710018100191002010021100221002310024100251002610027100281002910030100311003210033100341003510036100371003810039100401004110042100431004410045100461004710048100491005010051100521005310054100551005610057100581005910060100611006210063100641006510066100671006810069100701007110072100731007410075100761007710078100791008010081100821008310084100851008610087100881008910090100911009210093100941009510096100971009810099101001010110102101031010410105101061010710108101091011010111101121011310114101151011610117101181011910120101211012210123101241012510126101271012810129101301013110132101331013410135101361013710138101391014010141101421014310144101451014610147101481014910150101511015210153101541015510156101571015810159101601016110162101631016410165101661016710168101691017010171101721017310174101751017610177101781017910180101811018210183101841018510186101871018810189101901019110192101931019410195101961019710198101991020010201102021020310204102051020610207102081020910210102111021210213102141021510216102171021810219102201022110222102231022410225102261022710228102291023010231102321023310234102351023610237102381023910240102411024210243102441024510246102471024810249102501025110252102531025410255102561025710258102591026010261102621026310264102651026610267102681026910270102711027210273102741027510276102771027810279102801028110282102831028410285102861028710288102891029010291102921029310294102951029610297102981029910300103011030210303103041030510306103071030810309103101031110312103131031410315103161031710318103191032010321103221032310324103251032610327103281032910330103311033210333103341033510336103371033810339103401034110342103431034410345103461034710348103491035010351103521035310354103551035610357103581035910360103611036210363103641036510366103671036810369103701037110372103731037410375103761037710378103791038010381103821038310384103851038610387103881038910390103911039210393103941039510396103971039810399104001040110402104031040410405104061040710408104091041010411104121041310414104151041610417104181041910420104211042210423104241042510426104271042810429104301043110432104331043410435104361043710438104391044010441104421044310444104451044610447104481044910450104511045210453104541045510456104571045810459104601046110462104631046410465104661046710468104691047010471104721047310474104751047610477104781047910480104811048210483104841048510486104871048810489104901049110492104931049410495104961049710498104991050010501105021050310504105051050610507105081050910510105111051210513105141051510516105171051810519105201052110522105231052410525105261052710528105291053010531105321053310534105351053610537105381053910540105411054210543105441054510546105471054810549105501055110552105531055410555105561055710558105591056010561105621056310564105651056610567105681056910570105711057210573105741057510576105771057810579105801058110582105831058410585105861058710588105891059010591105921059310594105951059610597105981059910600106011060210603106041060510606106071060810609106101061110612106131061410615106161061710618106191062010621106221062310624106251062610627106281062910630106311063210633106341063510636106371063810639106401064110642106431064410645106461064710648106491065010651106521065310654106551065610657106581065910660106611066210663106641066510666106671066810669106701067110672106731067410675106761067710678106791068010681106821068310684106851068610687106881068910690106911069210693106941069510696106971069810699107001070110702107031070410705107061070710708107091071010711107121071310714107151071610717107181071910720107211072210723107241072510726107271072810729107301073110732107331073410735107361073710738107391074010741107421074310744107451074610747107481074910750107511075210753107541075510756107571075810759107601076110762107631076410765107661076710768107691077010771107721077310774107751077610777107781077910780107811078210783107841078510786107871078810789107901079110792107931079410795107961079710798107991080010801108021080310804108051080610807108081080910810108111081210813108141081510816108171081810819108201082110822108231082410825108261082710828108291083010831108321083310834108351083610837108381083910840108411084210843108441084510846108471084810849108501085110852108531085410855108561085710858108591086010861108621086310864108651086610867108681086910870108711087210873108741087510876108771087810879108801088110882108831088410885108861088710888108891089010891108921089310894108951089610897108981089910900109011090210903109041090510906109071090810909109101091110912109131091410915109161091710918109191092010921109221092310924109251092610927109281092910930109311093210933109341093510936109371093810939109401094110942109431094410945109461094710948109491095010951109521095310954109551095610957109581095910960109611096210963109641096510966109671096810969109701097110972109731097410975109761097710978109791098010981109821098310984109851098610987109881098910990109911099210993109941099510996109971099810999110001100111002110031100411005110061100711008110091101011011110121101311014110151101611017110181101911020110211102211023110241102511026110271102811029110301103111032110331103411035110361103711038110391104011041110421104311044110451104611047110481104911050110511105211053110541105511056110571105811059110601106111062110631106411065110661106711068110691107011071110721107311074110751107611077110781107911080110811108211083110841108511086110871108811089110901109111092110931109411095110961109711098110991110011101111021110311104111051110611107111081110911110111111111211113111141111511116111171111811119111201112111122111231112411125111261112711128111291113011131111321113311134111351113611137111381113911140111411114211143111441114511146111471114811149111501115111152111531115411155111561115711158111591116011161111621116311164111651116611167111681116911170111711117211173111741117511176111771117811179111801118111182111831118411185111861118711188111891119011191111921119311194111951119611197111981119911200112011120211203112041120511206112071120811209112101121111212112131121411215112161121711218112191122011221112221122311224112251122611227112281122911230112311123211233112341123511236112371123811239112401124111242112431124411245112461124711248112491125011251112521125311254112551125611257112581125911260112611126211263112641126511266112671126811269112701127111272112731127411275112761127711278112791128011281112821128311284112851128611287112881128911290112911129211293112941129511296112971129811299113001130111302113031130411305113061130711308113091131011311113121131311314113151131611317113181131911320113211132211323113241132511326113271132811329113301133111332113331133411335113361133711338113391134011341113421134311344113451134611347113481134911350113511135211353113541135511356113571135811359113601136111362113631136411365113661136711368113691137011371113721137311374113751137611377113781137911380113811138211383113841138511386113871138811389113901139111392113931139411395113961139711398113991140011401114021140311404114051140611407114081140911410114111141211413114141141511416114171141811419114201142111422114231142411425114261142711428114291143011431114321143311434114351143611437114381143911440114411144211443114441144511446114471144811449114501145111452114531145411455114561145711458114591146011461114621146311464114651146611467114681146911470114711147211473114741147511476114771147811479114801148111482114831148411485114861148711488114891149011491114921149311494114951149611497114981149911500115011150211503115041150511506115071150811509115101151111512115131151411515115161151711518115191152011521115221152311524115251152611527115281152911530115311153211533115341153511536115371153811539115401154111542115431154411545115461154711548115491155011551115521155311554115551155611557115581155911560115611156211563115641156511566115671156811569115701157111572115731157411575115761157711578115791158011581115821158311584115851158611587115881158911590115911159211593115941159511596115971159811599116001160111602116031160411605116061160711608116091161011611116121161311614116151161611617116181161911620116211162211623116241162511626116271162811629116301163111632116331163411635116361163711638116391164011641116421164311644116451164611647116481164911650116511165211653116541165511656116571165811659116601166111662116631166411665116661166711668116691167011671116721167311674116751167611677116781167911680116811168211683116841168511686116871168811689116901169111692116931169411695116961169711698116991170011701117021170311704117051170611707117081170911710117111171211713117141171511716117171171811719117201172111722117231172411725117261172711728117291173011731117321173311734117351173611737117381173911740117411174211743
  1. /**
  2. * @license Highcharts JS v9.1.0 (2021-05-04)
  3. *
  4. * (c) 2009-2021 Torstein Honsi
  5. *
  6. * License: www.highcharts.com/license
  7. */
  8. 'use strict';
  9. (function (factory) {
  10. if (typeof module === 'object' && module.exports) {
  11. factory['default'] = factory;
  12. module.exports = factory;
  13. } else if (typeof define === 'function' && define.amd) {
  14. define('highcharts/highcharts-more', ['highcharts'], function (Highcharts) {
  15. factory(Highcharts);
  16. factory.Highcharts = Highcharts;
  17. return factory;
  18. });
  19. } else {
  20. factory(typeof Highcharts !== 'undefined' ? Highcharts : undefined);
  21. }
  22. }(function (Highcharts) {
  23. var _modules = Highcharts ? Highcharts._modules : {};
  24. function _registerModule(obj, path, args, fn) {
  25. if (!obj.hasOwnProperty(path)) {
  26. obj[path] = fn.apply(null, args);
  27. }
  28. }
  29. _registerModule(_modules, 'Extensions/Pane.js', [_modules['Core/Chart/Chart.js'], _modules['Core/Globals.js'], _modules['Core/Color/Palette.js'], _modules['Core/Pointer.js'], _modules['Core/Utilities.js'], _modules['Mixins/CenteredSeries.js']], function (Chart, H, palette, Pointer, U, centeredSeriesMixin) {
  30. /* *
  31. *
  32. * (c) 2010-2021 Torstein Honsi
  33. *
  34. * License: www.highcharts.com/license
  35. *
  36. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  37. *
  38. * */
  39. var addEvent = U.addEvent,
  40. extend = U.extend,
  41. merge = U.merge,
  42. pick = U.pick,
  43. splat = U.splat;
  44. /**
  45. * @typedef {"arc"|"circle"|"solid"} Highcharts.PaneBackgroundShapeValue
  46. */
  47. /* eslint-disable no-invalid-this, valid-jsdoc */
  48. Chart.prototype.collectionsWithUpdate.push('pane');
  49. /**
  50. * The Pane object allows options that are common to a set of X and Y axes.
  51. *
  52. * In the future, this can be extended to basic Highcharts and Highcharts Stock.
  53. *
  54. * @private
  55. * @class
  56. * @name Highcharts.Pane
  57. * @param {Highcharts.PaneOptions} options
  58. * @param {Highcharts.Chart} chart
  59. */
  60. var Pane = /** @class */ (function () {
  61. function Pane(options, chart) {
  62. this.background = void 0;
  63. this.center = void 0;
  64. this.chart = void 0;
  65. this.options = void 0;
  66. this.coll = 'pane'; // Member of chart.pane
  67. /**
  68. * The pane serves as a container for axes and backgrounds for circular
  69. * gauges and polar charts.
  70. *
  71. * @since 2.3.0
  72. * @product highcharts
  73. * @requires highcharts-more
  74. * @optionparent pane
  75. */
  76. this.defaultOptions = {
  77. /**
  78. * The end angle of the polar X axis or gauge value axis, given in
  79. * degrees where 0 is north. Defaults to [startAngle](#pane.startAngle)
  80. * + 360.
  81. *
  82. * @sample {highcharts} highcharts/demo/gauge-vu-meter/
  83. * VU-meter with custom start and end angle
  84. *
  85. * @type {number}
  86. * @since 2.3.0
  87. * @product highcharts
  88. * @apioption pane.endAngle
  89. */
  90. /**
  91. * The center of a polar chart or angular gauge, given as an array
  92. * of [x, y] positions. Positions can be given as integers that
  93. * transform to pixels, or as percentages of the plot area size.
  94. *
  95. * @sample {highcharts} highcharts/demo/gauge-vu-meter/
  96. * Two gauges with different center
  97. *
  98. * @type {Array<string|number>}
  99. * @default ["50%", "50%"]
  100. * @since 2.3.0
  101. * @product highcharts
  102. */
  103. center: ['50%', '50%'],
  104. /**
  105. * The size of the pane, either as a number defining pixels, or a
  106. * percentage defining a percentage of the available plot area (the
  107. * smallest of the plot height or plot width).
  108. *
  109. * @sample {highcharts} highcharts/demo/gauge-vu-meter/
  110. * Smaller size
  111. *
  112. * @type {number|string}
  113. * @product highcharts
  114. */
  115. size: '85%',
  116. /**
  117. * The inner size of the pane, either as a number defining pixels, or a
  118. * percentage defining a percentage of the pane's size.
  119. *
  120. * @sample {highcharts} highcharts/series-polar/column-inverted-inner
  121. * The inner size set to 20%
  122. *
  123. * @type {number|string}
  124. * @product highcharts
  125. */
  126. innerSize: '0%',
  127. /**
  128. * The start angle of the polar X axis or gauge axis, given in degrees
  129. * where 0 is north. Defaults to 0.
  130. *
  131. * @sample {highcharts} highcharts/demo/gauge-vu-meter/
  132. * VU-meter with custom start and end angle
  133. *
  134. * @since 2.3.0
  135. * @product highcharts
  136. */
  137. startAngle: 0
  138. };
  139. /**
  140. * An array of background items for the pane.
  141. *
  142. * @sample {highcharts} highcharts/demo/gauge-speedometer/
  143. * Speedometer gauge with multiple backgrounds
  144. *
  145. * @type {Array<*>}
  146. * @optionparent pane.background
  147. */
  148. this.defaultBackgroundOptions = {
  149. /**
  150. * The class name for this background.
  151. *
  152. * @sample {highcharts} highcharts/css/pane/
  153. * Panes styled by CSS
  154. * @sample {highstock} highcharts/css/pane/
  155. * Panes styled by CSS
  156. * @sample {highmaps} highcharts/css/pane/
  157. * Panes styled by CSS
  158. *
  159. * @type {string}
  160. * @default highcharts-pane
  161. * @since 5.0.0
  162. * @apioption pane.background.className
  163. */
  164. /**
  165. * The shape of the pane background. When `solid`, the background
  166. * is circular. When `arc`, the background extends only from the min
  167. * to the max of the value axis.
  168. *
  169. * @type {Highcharts.PaneBackgroundShapeValue}
  170. * @since 2.3.0
  171. * @product highcharts
  172. */
  173. shape: 'circle',
  174. /**
  175. * The pixel border width of the pane background.
  176. *
  177. * @since 2.3.0
  178. * @product highcharts
  179. */
  180. borderWidth: 1,
  181. /**
  182. * The pane background border color.
  183. *
  184. * @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
  185. * @since 2.3.0
  186. * @product highcharts
  187. */
  188. borderColor: palette.neutralColor20,
  189. /**
  190. * The background color or gradient for the pane.
  191. *
  192. * @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
  193. * @default { linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 }, stops: [[0, #ffffff], [1, #e6e6e6]] }
  194. * @since 2.3.0
  195. * @product highcharts
  196. */
  197. backgroundColor: {
  198. /** @ignore-option */
  199. linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 },
  200. /** @ignore-option */
  201. stops: [
  202. [0, palette.backgroundColor],
  203. [1, palette.neutralColor10]
  204. ]
  205. },
  206. /** @ignore-option */
  207. from: -Number.MAX_VALUE,
  208. /**
  209. * The inner radius of the pane background. Can be either numeric
  210. * (pixels) or a percentage string.
  211. *
  212. * @type {number|string}
  213. * @since 2.3.0
  214. * @product highcharts
  215. */
  216. innerRadius: 0,
  217. /** @ignore-option */
  218. to: Number.MAX_VALUE,
  219. /**
  220. * The outer radius of the circular pane background. Can be either
  221. * numeric (pixels) or a percentage string.
  222. *
  223. * @type {number|string}
  224. * @since 2.3.0
  225. * @product highcharts
  226. */
  227. outerRadius: '105%'
  228. };
  229. this.init(options, chart);
  230. }
  231. /**
  232. * Initialize the Pane object
  233. *
  234. * @private
  235. * @function Highcharts.Pane#init
  236. *
  237. * @param {Highcharts.PaneOptions} options
  238. *
  239. * @param {Highcharts.Chart} chart
  240. */
  241. Pane.prototype.init = function (options, chart) {
  242. this.chart = chart;
  243. this.background = [];
  244. chart.pane.push(this);
  245. this.setOptions(options);
  246. };
  247. /**
  248. * @private
  249. * @function Highcharts.Pane#setOptions
  250. *
  251. * @param {Highcharts.PaneOptions} options
  252. */
  253. Pane.prototype.setOptions = function (options) {
  254. // Set options. Angular charts have a default background (#3318)
  255. this.options = options = merge(this.defaultOptions, this.chart.angular ? { background: {} } : void 0, options);
  256. };
  257. /**
  258. * Render the pane with its backgrounds.
  259. *
  260. * @private
  261. * @function Highcharts.Pane#render
  262. */
  263. Pane.prototype.render = function () {
  264. var options = this.options,
  265. backgroundOption = this.options.background,
  266. renderer = this.chart.renderer,
  267. len,
  268. i;
  269. if (!this.group) {
  270. this.group = renderer.g('pane-group')
  271. .attr({ zIndex: options.zIndex || 0 })
  272. .add();
  273. }
  274. this.updateCenter();
  275. // Render the backgrounds
  276. if (backgroundOption) {
  277. backgroundOption = splat(backgroundOption);
  278. len = Math.max(backgroundOption.length, this.background.length || 0);
  279. for (i = 0; i < len; i++) {
  280. // #6641 - if axis exists, chart is circular and apply
  281. // background
  282. if (backgroundOption[i] && this.axis) {
  283. this.renderBackground(merge(this.defaultBackgroundOptions, backgroundOption[i]), i);
  284. }
  285. else if (this.background[i]) {
  286. this.background[i] = this.background[i].destroy();
  287. this.background.splice(i, 1);
  288. }
  289. }
  290. }
  291. };
  292. /**
  293. * Render an individual pane background.
  294. *
  295. * @private
  296. * @function Highcharts.Pane#renderBackground
  297. *
  298. * @param {Highcharts.PaneBackgroundOptions} backgroundOptions
  299. * Background options
  300. *
  301. * @param {number} i
  302. * The index of the background in this.backgrounds
  303. */
  304. Pane.prototype.renderBackground = function (backgroundOptions, i) {
  305. var method = 'animate',
  306. attribs = {
  307. 'class': 'highcharts-pane ' + (backgroundOptions.className || '')
  308. };
  309. if (!this.chart.styledMode) {
  310. extend(attribs, {
  311. 'fill': backgroundOptions.backgroundColor,
  312. 'stroke': backgroundOptions.borderColor,
  313. 'stroke-width': backgroundOptions.borderWidth
  314. });
  315. }
  316. if (!this.background[i]) {
  317. this.background[i] = this.chart.renderer
  318. .path()
  319. .add(this.group);
  320. method = 'attr';
  321. }
  322. this.background[i][method]({
  323. 'd': this.axis.getPlotBandPath(backgroundOptions.from, backgroundOptions.to, backgroundOptions)
  324. }).attr(attribs);
  325. };
  326. /**
  327. * Gets the center for the pane and its axis.
  328. *
  329. * @private
  330. * @function Highcharts.Pane#updateCenter
  331. * @param {Highcharts.Axis} [axis]
  332. * @return {void}
  333. */
  334. Pane.prototype.updateCenter = function (axis) {
  335. this.center = (axis ||
  336. this.axis ||
  337. {}).center = centeredSeriesMixin.getCenter.call(this);
  338. };
  339. /**
  340. * Destroy the pane item
  341. *
  342. * @ignore
  343. * @private
  344. * @function Highcharts.Pane#destroy
  345. * /
  346. destroy: function () {
  347. erase(this.chart.pane, this);
  348. this.background.forEach(function (background) {
  349. background.destroy();
  350. });
  351. this.background.length = 0;
  352. this.group = this.group.destroy();
  353. },
  354. */
  355. /**
  356. * Update the pane item with new options
  357. *
  358. * @private
  359. * @function Highcharts.Pane#update
  360. * @param {Highcharts.PaneOptions} options
  361. * New pane options
  362. * @param {boolean} [redraw]
  363. * @return {void}
  364. */
  365. Pane.prototype.update = function (options, redraw) {
  366. merge(true, this.options, options);
  367. merge(true, this.chart.options.pane, options); // #9917
  368. this.setOptions(this.options);
  369. this.render();
  370. this.chart.axes.forEach(function (axis) {
  371. if (axis.pane === this) {
  372. axis.pane = null;
  373. axis.update({}, redraw);
  374. }
  375. }, this);
  376. };
  377. return Pane;
  378. }());
  379. /**
  380. * Check whether element is inside or outside pane.
  381. * @private
  382. * @param {number} x Element's x coordinate
  383. * @param {number} y Element's y coordinate
  384. * @param {Array<number>} center Pane's center (x, y) and diameter
  385. * @return {boolean}
  386. */
  387. function isInsidePane(x, y, center) {
  388. return Math.sqrt(Math.pow(x - center[0], 2) + Math.pow(y - center[1], 2)) <= center[2] / 2;
  389. }
  390. Chart.prototype.getHoverPane = function (eventArgs) {
  391. var chart = this;
  392. var hoverPane;
  393. if (eventArgs) {
  394. chart.pane.forEach(function (pane) {
  395. var plotX = eventArgs.chartX - chart.plotLeft,
  396. plotY = eventArgs.chartY - chart.plotTop,
  397. x = chart.inverted ? plotY : plotX,
  398. y = chart.inverted ? plotX : plotY;
  399. if (isInsidePane(x, y, pane.center)) {
  400. hoverPane = pane;
  401. }
  402. });
  403. }
  404. return hoverPane;
  405. };
  406. addEvent(Chart, 'afterIsInsidePlot', function (e) {
  407. var chart = this;
  408. if (chart.polar) {
  409. e.isInsidePlot = chart.pane.some(function (pane) { return isInsidePane(e.x, e.y, pane.center); });
  410. }
  411. });
  412. addEvent(Pointer, 'beforeGetHoverData', function (eventArgs) {
  413. var chart = this.chart;
  414. if (chart.polar) {
  415. // Find pane we are currently hovering over.
  416. chart.hoverPane = chart.getHoverPane(eventArgs);
  417. // Edit filter method to handle polar
  418. eventArgs.filter = function (s) {
  419. return (s.visible &&
  420. !(!eventArgs.shared && s.directTouch) && // #3821
  421. pick(s.options.enableMouseTracking, true) &&
  422. (!chart.hoverPane || s.xAxis.pane === chart.hoverPane));
  423. };
  424. }
  425. else {
  426. chart.hoverPane = void 0;
  427. }
  428. });
  429. addEvent(Pointer, 'afterGetHoverData', function (eventArgs) {
  430. var chart = this.chart;
  431. if (eventArgs.hoverPoint &&
  432. eventArgs.hoverPoint.plotX &&
  433. eventArgs.hoverPoint.plotY &&
  434. chart.hoverPane &&
  435. !isInsidePane(eventArgs.hoverPoint.plotX, eventArgs.hoverPoint.plotY, chart.hoverPane.center)) {
  436. eventArgs.hoverPoint = void 0;
  437. }
  438. });
  439. H.Pane = Pane;
  440. return H.Pane;
  441. });
  442. _registerModule(_modules, 'Core/Axis/HiddenAxis.js', [], function () {
  443. /* *
  444. *
  445. * (c) 2010-2021 Torstein Honsi
  446. *
  447. * License: www.highcharts.com/license
  448. *
  449. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  450. *
  451. * */
  452. /**
  453. * @private
  454. * @class
  455. */
  456. var HiddenAxis = /** @class */ (function () {
  457. function HiddenAxis() {
  458. }
  459. /**
  460. * Augments methods for the x axis in order to hide it completely. Used for
  461. * the X axis in gauges
  462. *
  463. * @private
  464. *
  465. * @param {Highcharts.Axis} axis
  466. * Radial axis to augment.
  467. */
  468. HiddenAxis.init = function (axis) {
  469. axis.getOffset = function () { };
  470. axis.redraw = function () {
  471. this.isDirty = false; // prevent setting Y axis dirty
  472. };
  473. axis.render = function () {
  474. this.isDirty = false; // prevent setting Y axis dirty
  475. };
  476. axis.createLabelCollector = function () {
  477. return function () {
  478. return;
  479. };
  480. };
  481. axis.setScale = function () { };
  482. axis.setCategories = function () { };
  483. axis.setTitle = function () { };
  484. axis.isHidden = true;
  485. };
  486. return HiddenAxis;
  487. }());
  488. return HiddenAxis;
  489. });
  490. _registerModule(_modules, 'Core/Axis/RadialAxis.js', [_modules['Core/Axis/Axis.js'], _modules['Core/Axis/Tick.js'], _modules['Core/Axis/HiddenAxis.js'], _modules['Core/Utilities.js']], function (Axis, Tick, HiddenAxis, U) {
  491. /* *
  492. *
  493. * (c) 2010-2021 Torstein Honsi
  494. *
  495. * License: www.highcharts.com/license
  496. *
  497. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  498. *
  499. * */
  500. var addEvent = U.addEvent,
  501. correctFloat = U.correctFloat,
  502. defined = U.defined,
  503. extend = U.extend,
  504. fireEvent = U.fireEvent,
  505. isNumber = U.isNumber,
  506. merge = U.merge,
  507. pick = U.pick,
  508. pInt = U.pInt,
  509. relativeLength = U.relativeLength,
  510. wrap = U.wrap;
  511. /**
  512. * @private
  513. * @class
  514. */
  515. var RadialAxis = /** @class */ (function () {
  516. function RadialAxis() {
  517. }
  518. /* *
  519. *
  520. * Static Functions
  521. *
  522. * */
  523. RadialAxis.init = function (axis) {
  524. var axisProto = Axis.prototype;
  525. // Merge and set options.
  526. axis.setOptions = function (userOptions) {
  527. var options = this.options = merge(axis.constructor.defaultOptions,
  528. this.defaultPolarOptions,
  529. userOptions);
  530. // Make sure the plotBands array is instanciated for each Axis
  531. // (#2649)
  532. if (!options.plotBands) {
  533. options.plotBands = [];
  534. }
  535. fireEvent(this, 'afterSetOptions');
  536. };
  537. // Wrap the getOffset method to return zero offset for title or labels
  538. // in a radial axis.
  539. axis.getOffset = function () {
  540. // Call the Axis prototype method (the method we're in now is on the
  541. // instance)
  542. axisProto.getOffset.call(this);
  543. // Title or label offsets are not counted
  544. this.chart.axisOffset[this.side] = 0;
  545. };
  546. /**
  547. * Get the path for the axis line. This method is also referenced in the
  548. * getPlotLinePath method.
  549. *
  550. * @private
  551. *
  552. * @param {number} _lineWidth
  553. * Line width is not used.
  554. *
  555. * @param {number} [radius]
  556. * Radius of radial path.
  557. *
  558. * @param {number} [innerRadius]
  559. * Inner radius of radial path.
  560. *
  561. * @return {RadialAxisPath}
  562. */
  563. axis.getLinePath = function (_lineWidth, radius, innerRadius) {
  564. var center = this.pane.center,
  565. end,
  566. chart = this.chart,
  567. r = pick(radius,
  568. center[2] / 2 - this.offset),
  569. left = this.left || 0,
  570. top = this.top || 0,
  571. path;
  572. if (typeof innerRadius === 'undefined') {
  573. innerRadius = this.horiz ? 0 : this.center && -this.center[3] / 2;
  574. }
  575. // In case when innerSize of pane is set, it must be included
  576. if (innerRadius) {
  577. r += innerRadius;
  578. }
  579. if (this.isCircular || typeof radius !== 'undefined') {
  580. path = this.chart.renderer.symbols.arc(left + center[0], top + center[1], r, r, {
  581. start: this.startAngleRad,
  582. end: this.endAngleRad,
  583. open: true,
  584. innerR: 0
  585. });
  586. // Bounds used to position the plotLine label next to the line
  587. // (#7117)
  588. path.xBounds = [left + center[0]];
  589. path.yBounds = [top + center[1] - r];
  590. }
  591. else {
  592. end = this.postTranslate(this.angleRad, r);
  593. path = [
  594. ['M', this.center[0] + chart.plotLeft, this.center[1] + chart.plotTop],
  595. ['L', end.x, end.y]
  596. ];
  597. }
  598. return path;
  599. };
  600. /**
  601. * Override setAxisTranslation by setting the translation to the
  602. * difference in rotation. This allows the translate method to return
  603. * angle for any given value.
  604. *
  605. * @private
  606. */
  607. axis.setAxisTranslation = function () {
  608. // Call uber method
  609. axisProto.setAxisTranslation.call(this);
  610. // Set transA and minPixelPadding
  611. if (this.center) { // it's not defined the first time
  612. if (this.isCircular) {
  613. this.transA = (this.endAngleRad - this.startAngleRad) /
  614. ((this.max - this.min) || 1);
  615. }
  616. else {
  617. // The transA here is the length of the axis, so in case
  618. // of inner radius, the length must be decreased by it
  619. this.transA = ((this.center[2] - this.center[3]) / 2) /
  620. ((this.max - this.min) || 1);
  621. }
  622. if (this.isXAxis) {
  623. this.minPixelPadding = this.transA * this.minPointOffset;
  624. }
  625. else {
  626. // This is a workaround for regression #2593, but categories
  627. // still don't position correctly.
  628. this.minPixelPadding = 0;
  629. }
  630. }
  631. };
  632. /**
  633. * In case of auto connect, add one closestPointRange to the max value
  634. * right before tickPositions are computed, so that ticks will extend
  635. * passed the real max.
  636. * @private
  637. */
  638. axis.beforeSetTickPositions = function () {
  639. // If autoConnect is true, polygonal grid lines are connected, and
  640. // one closestPointRange is added to the X axis to prevent the last
  641. // point from overlapping the first.
  642. this.autoConnect = (this.isCircular &&
  643. typeof pick(this.userMax, this.options.max) === 'undefined' &&
  644. correctFloat(this.endAngleRad - this.startAngleRad) ===
  645. correctFloat(2 * Math.PI));
  646. // This will lead to add an extra tick to xAxis in order to display
  647. // a correct range on inverted polar
  648. if (!this.isCircular && this.chart.inverted) {
  649. this.max++;
  650. }
  651. if (this.autoConnect) {
  652. this.max += ((this.categories && 1) ||
  653. this.pointRange ||
  654. this.closestPointRange ||
  655. 0); // #1197, #2260
  656. }
  657. };
  658. /**
  659. * Override the setAxisSize method to use the arc's circumference as
  660. * length. This allows tickPixelInterval to apply to pixel lengths along
  661. * the perimeter.
  662. * @private
  663. */
  664. axis.setAxisSize = function () {
  665. var center,
  666. start;
  667. axisProto.setAxisSize.call(this);
  668. if (this.isRadial) {
  669. // Set the center array
  670. this.pane.updateCenter(this);
  671. // In case when the innerSize is set in a polar chart, the axis'
  672. // center cannot be a reference to pane's center
  673. center = this.center = this.pane.center.slice();
  674. // The sector is used in Axis.translate to compute the
  675. // translation of reversed axis points (#2570)
  676. if (this.isCircular) {
  677. this.sector = this.endAngleRad - this.startAngleRad;
  678. }
  679. else {
  680. // When the pane's startAngle or the axis' angle is set then
  681. // new x and y values for vertical axis' center must be
  682. // calulated
  683. start = this.postTranslate(this.angleRad, center[3] / 2);
  684. center[0] = start.x - this.chart.plotLeft;
  685. center[1] = start.y - this.chart.plotTop;
  686. }
  687. // Axis len is used to lay out the ticks
  688. this.len = this.width = this.height =
  689. (center[2] - center[3]) * pick(this.sector, 1) / 2;
  690. }
  691. };
  692. /**
  693. * Returns the x, y coordinate of a point given by a value and a pixel
  694. * distance from center.
  695. *
  696. * @private
  697. *
  698. * @param {number} value
  699. * Point value.
  700. *
  701. * @param {number} [length]
  702. * Distance from center.
  703. *
  704. * @return {Highcharts.PositionObject}
  705. */
  706. axis.getPosition = function (value, length) {
  707. var translatedVal = this.translate(value);
  708. return this.postTranslate(this.isCircular ? translatedVal : this.angleRad, // #2848
  709. // In case when translatedVal is negative, the 0 value must be
  710. // used instead, in order to deal with lines and labels that
  711. // fall out of the visible range near the center of a pane
  712. pick(this.isCircular ?
  713. length :
  714. (translatedVal < 0 ? 0 : translatedVal), this.center[2] / 2) - this.offset);
  715. };
  716. /**
  717. * Translate from intermediate plotX (angle), plotY (axis.len - radius)
  718. * to final chart coordinates.
  719. *
  720. * @private
  721. *
  722. * @param {number} angle
  723. * Translation angle.
  724. *
  725. * @param {number} radius
  726. * Translation radius.
  727. *
  728. * @return {Highcharts.PositionObject}
  729. */
  730. axis.postTranslate = function (angle, radius) {
  731. var chart = this.chart,
  732. center = this.center;
  733. angle = this.startAngleRad + angle;
  734. return {
  735. x: chart.plotLeft + center[0] + Math.cos(angle) * radius,
  736. y: chart.plotTop + center[1] + Math.sin(angle) * radius
  737. };
  738. };
  739. /**
  740. * Find the path for plot bands along the radial axis.
  741. *
  742. * @private
  743. *
  744. * @param {number} from
  745. * From value.
  746. *
  747. * @param {number} to
  748. * To value.
  749. *
  750. * @param {Highcharts.AxisPlotBandsOptions} options
  751. * Band options.
  752. *
  753. * @return {RadialAxisPath}
  754. */
  755. axis.getPlotBandPath = function (from, to, options) {
  756. var radiusToPixels = function (radius) {
  757. if (typeof radius === 'string') {
  758. var r = parseInt(radius, 10);
  759. if (percentRegex.test(radius)) {
  760. r = (r * fullRadius) / 100;
  761. }
  762. return r;
  763. }
  764. return radius;
  765. };
  766. var center = this.center,
  767. startAngleRad = this.startAngleRad,
  768. fullRadius = center[2] / 2,
  769. offset = Math.min(this.offset, 0),
  770. left = this.left || 0,
  771. top = this.top || 0,
  772. percentRegex = /%$/,
  773. start,
  774. end,
  775. angle,
  776. xOnPerimeter,
  777. open,
  778. isCircular = this.isCircular, // X axis in a polar chart
  779. path,
  780. outerRadius = pick(radiusToPixels(options.outerRadius),
  781. fullRadius),
  782. innerRadius = radiusToPixels(options.innerRadius),
  783. thickness = pick(radiusToPixels(options.thickness), 10);
  784. // Polygonal plot bands
  785. if (this.options.gridLineInterpolation === 'polygon') {
  786. path = this.getPlotLinePath({ value: from }).concat(this.getPlotLinePath({ value: to, reverse: true }));
  787. // Circular grid bands
  788. }
  789. else {
  790. // Keep within bounds
  791. from = Math.max(from, this.min);
  792. to = Math.min(to, this.max);
  793. var transFrom = this.translate(from);
  794. var transTo = this.translate(to);
  795. // Plot bands on Y axis (radial axis) - inner and outer
  796. // radius depend on to and from
  797. if (!isCircular) {
  798. outerRadius = transFrom || 0;
  799. innerRadius = transTo || 0;
  800. }
  801. // Handle full circle
  802. if (options.shape === 'circle' || !isCircular) {
  803. start = -Math.PI / 2;
  804. end = Math.PI * 1.5;
  805. open = true;
  806. }
  807. else {
  808. start = startAngleRad + (transFrom || 0);
  809. end = startAngleRad + (transTo || 0);
  810. }
  811. outerRadius -= offset; // #5283
  812. thickness -= offset; // #5283
  813. path = this.chart.renderer.symbols.arc(left + center[0], top + center[1], outerRadius, outerRadius, {
  814. // Math is for reversed yAxis (#3606)
  815. start: Math.min(start, end),
  816. end: Math.max(start, end),
  817. innerR: pick(innerRadius, outerRadius - thickness),
  818. open: open
  819. });
  820. // Provide positioning boxes for the label (#6406)
  821. if (isCircular) {
  822. angle = (end + start) / 2;
  823. xOnPerimeter = (left +
  824. center[0] +
  825. (center[2] / 2) * Math.cos(angle));
  826. path.xBounds = angle > -Math.PI / 2 && angle < Math.PI / 2 ?
  827. // Right hemisphere
  828. [xOnPerimeter, this.chart.plotWidth] :
  829. // Left hemisphere
  830. [0, xOnPerimeter];
  831. path.yBounds = [
  832. top + center[1] + (center[2] / 2) * Math.sin(angle)
  833. ];
  834. // Shift up or down to get the label clear of the perimeter
  835. path.yBounds[0] += ((angle > -Math.PI && angle < 0) ||
  836. (angle > Math.PI)) ? -10 : 10;
  837. }
  838. }
  839. return path;
  840. };
  841. // Find the correct end values of crosshair in polar.
  842. axis.getCrosshairPosition = function (options, x1, y1) {
  843. var axis = this,
  844. value = options.value,
  845. center = axis.pane.center,
  846. shapeArgs,
  847. end,
  848. x2,
  849. y2;
  850. if (axis.isCircular) {
  851. if (!defined(value)) {
  852. // When the snap is set to false
  853. x2 = options.chartX || 0;
  854. y2 = options.chartY || 0;
  855. value = axis.translate(Math.atan2(y2 - y1, x2 - x1) - axis.startAngleRad, true);
  856. }
  857. else if (options.point) {
  858. // When the snap is set to true
  859. shapeArgs = options.point.shapeArgs || {};
  860. if (shapeArgs.start) {
  861. // Find a true value of the point based on the
  862. // angle
  863. value = axis.chart.inverted ?
  864. axis.translate(options.point.rectPlotY, true) :
  865. options.point.x;
  866. }
  867. }
  868. end = axis.getPosition(value);
  869. x2 = end.x;
  870. y2 = end.y;
  871. }
  872. else {
  873. if (!defined(value)) {
  874. x2 = options.chartX;
  875. y2 = options.chartY;
  876. }
  877. if (defined(x2) && defined(y2)) {
  878. // Calculate radius of non-circular axis' crosshair
  879. y1 = center[1] + axis.chart.plotTop;
  880. value = axis.translate(Math.min(Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2)), center[2] / 2) - center[3] / 2, true);
  881. }
  882. }
  883. return [value, x2 || 0, y2 || 0];
  884. };
  885. // Find the path for plot lines perpendicular to the radial axis.
  886. axis.getPlotLinePath = function (options) {
  887. var axis = this, center = axis.pane.center, chart = axis.chart, inverted = chart.inverted, value = options.value, reverse = options.reverse, end = axis.getPosition(value), background = axis.pane.options.background ?
  888. (axis.pane.options.background[0] ||
  889. axis.pane.options.background) :
  890. {}, innerRadius = background.innerRadius || '0%', outerRadius = background.outerRadius || '100%', x1 = center[0] + chart.plotLeft, y1 = center[1] + chart.plotTop, x2 = end.x, y2 = end.y, height = axis.height, isCrosshair = options.isCrosshair, paneInnerR = center[3] / 2, innerRatio, distance, a, b, otherAxis, xy, tickPositions, crossPos, path;
  891. // Crosshair logic
  892. if (isCrosshair) {
  893. // Find crosshair's position and perform destructuring
  894. // assignment
  895. crossPos = this.getCrosshairPosition(options, x1, y1);
  896. value = crossPos[0];
  897. x2 = crossPos[1];
  898. y2 = crossPos[2];
  899. }
  900. // Spokes
  901. if (axis.isCircular) {
  902. distance =
  903. Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2));
  904. a = (typeof innerRadius === 'string') ?
  905. relativeLength(innerRadius, 1) : (innerRadius / distance);
  906. b = (typeof outerRadius === 'string') ?
  907. relativeLength(outerRadius, 1) : (outerRadius / distance);
  908. // To ensure that gridlines won't be displayed in area
  909. // defined by innerSize in case of custom radiuses of pane's
  910. // background
  911. if (center && paneInnerR) {
  912. innerRatio = paneInnerR / distance;
  913. if (a < innerRatio) {
  914. a = innerRatio;
  915. }
  916. if (b < innerRatio) {
  917. b = innerRatio;
  918. }
  919. }
  920. path = [
  921. ['M', x1 + a * (x2 - x1), y1 - a * (y1 - y2)],
  922. ['L', x2 - (1 - b) * (x2 - x1), y2 + (1 - b) * (y1 - y2)]
  923. ];
  924. // Concentric circles
  925. }
  926. else {
  927. // Pick the right values depending if it is grid line or
  928. // crosshair
  929. value = axis.translate(value);
  930. // This is required in case when xAxis is non-circular to
  931. // prevent grid lines (or crosshairs, if enabled) from
  932. // rendering above the center after they supposed to be
  933. // displayed below the center point
  934. if (value) {
  935. if (value < 0 || value > height) {
  936. value = 0;
  937. }
  938. }
  939. if (axis.options.gridLineInterpolation === 'circle') {
  940. // A value of 0 is in the center, so it won't be
  941. // visible, but draw it anyway for update and animation
  942. // (#2366)
  943. path = axis.getLinePath(0, value, paneInnerR);
  944. // Concentric polygons
  945. }
  946. else {
  947. path = [];
  948. // Find the other axis (a circular one) in the same pane
  949. chart[inverted ? 'yAxis' : 'xAxis'].forEach(function (a) {
  950. if (a.pane === axis.pane) {
  951. otherAxis = a;
  952. }
  953. });
  954. if (otherAxis) {
  955. tickPositions = otherAxis.tickPositions;
  956. if (otherAxis.autoConnect) {
  957. tickPositions =
  958. tickPositions.concat([tickPositions[0]]);
  959. }
  960. // Reverse the positions for concatenation of polygonal
  961. // plot bands
  962. if (reverse) {
  963. tickPositions = tickPositions.slice().reverse();
  964. }
  965. if (value) {
  966. value += paneInnerR;
  967. }
  968. for (var i = 0; i < tickPositions.length; i++) {
  969. xy = otherAxis.getPosition(tickPositions[i], value);
  970. path.push(i ? ['L', xy.x, xy.y] : ['M', xy.x, xy.y]);
  971. }
  972. }
  973. }
  974. }
  975. return path;
  976. };
  977. // Find the position for the axis title, by default inside the gauge.
  978. axis.getTitlePosition = function () {
  979. var center = this.center,
  980. chart = this.chart,
  981. titleOptions = this.options.title;
  982. return {
  983. x: chart.plotLeft + center[0] + (titleOptions.x || 0),
  984. y: (chart.plotTop +
  985. center[1] -
  986. ({
  987. high: 0.5,
  988. middle: 0.25,
  989. low: 0
  990. }[titleOptions.align] *
  991. center[2]) +
  992. (titleOptions.y || 0))
  993. };
  994. };
  995. /**
  996. * Attach and return collecting function for labels in radial axis for
  997. * anti-collision.
  998. *
  999. * @private
  1000. *
  1001. * @return {Highcharts.ChartLabelCollectorFunction}
  1002. */
  1003. axis.createLabelCollector = function () {
  1004. var axis = this;
  1005. return function () {
  1006. if (axis.isRadial &&
  1007. axis.tickPositions &&
  1008. // undocumented option for now, but working
  1009. axis.options.labels.allowOverlap !== true) {
  1010. return axis.tickPositions
  1011. .map(function (pos) {
  1012. return axis.ticks[pos] && axis.ticks[pos].label;
  1013. })
  1014. .filter(function (label) {
  1015. return Boolean(label);
  1016. });
  1017. }
  1018. };
  1019. };
  1020. };
  1021. /**
  1022. * Augments methods for the value axis.
  1023. *
  1024. * @private
  1025. *
  1026. * @param {Highcharts.Axis} AxisClass
  1027. * Axis class to extend.
  1028. *
  1029. * @param {Highcharts.Tick} TickClass
  1030. * Tick class to use.
  1031. */
  1032. RadialAxis.compose = function (AxisClass, TickClass) {
  1033. /* eslint-disable no-invalid-this */
  1034. // Actions before axis init.
  1035. addEvent(AxisClass, 'init', function (e) {
  1036. var axis = this;
  1037. var chart = axis.chart;
  1038. var inverted = chart.inverted,
  1039. angular = chart.angular,
  1040. polar = chart.polar,
  1041. isX = axis.isXAxis,
  1042. coll = axis.coll,
  1043. isHidden = angular && isX,
  1044. isCircular,
  1045. chartOptions = chart.options,
  1046. paneIndex = e.userOptions.pane || 0,
  1047. pane = this.pane =
  1048. chart.pane && chart.pane[paneIndex];
  1049. // Prevent changes for colorAxis
  1050. if (coll === 'colorAxis') {
  1051. this.isRadial = false;
  1052. return;
  1053. }
  1054. // Before prototype.init
  1055. if (angular) {
  1056. if (isHidden) {
  1057. HiddenAxis.init(axis);
  1058. }
  1059. else {
  1060. RadialAxis.init(axis);
  1061. }
  1062. isCircular = !isX;
  1063. if (isCircular) {
  1064. axis.defaultPolarOptions = RadialAxis.defaultRadialGaugeOptions;
  1065. }
  1066. }
  1067. else if (polar) {
  1068. RadialAxis.init(axis);
  1069. // Check which axis is circular
  1070. isCircular = axis.horiz;
  1071. axis.defaultPolarOptions = isCircular ?
  1072. RadialAxis.defaultCircularOptions :
  1073. merge(coll === 'xAxis' ?
  1074. AxisClass.defaultOptions :
  1075. AxisClass.defaultYAxisOptions, RadialAxis.defaultRadialOptions);
  1076. // Apply the stack labels for yAxis in case of inverted chart
  1077. if (inverted && coll === 'yAxis') {
  1078. axis.defaultPolarOptions.stackLabels = AxisClass.defaultYAxisOptions.stackLabels;
  1079. axis.defaultPolarOptions.reversedStacks = true;
  1080. }
  1081. }
  1082. // Disable certain features on angular and polar axes
  1083. if (angular || polar) {
  1084. axis.isRadial = true;
  1085. chartOptions.chart.zoomType = null;
  1086. if (!axis.labelCollector) {
  1087. axis.labelCollector = axis.createLabelCollector();
  1088. }
  1089. if (axis.labelCollector) {
  1090. // Prevent overlapping axis labels (#9761)
  1091. chart.labelCollectors.push(axis.labelCollector);
  1092. }
  1093. }
  1094. else {
  1095. this.isRadial = false;
  1096. }
  1097. // A pointer back to this axis to borrow geometry
  1098. if (pane && isCircular) {
  1099. pane.axis = axis;
  1100. }
  1101. axis.isCircular = isCircular;
  1102. });
  1103. addEvent(AxisClass, 'afterInit', function () {
  1104. var axis = this;
  1105. var chart = axis.chart,
  1106. options = axis.options,
  1107. isHidden = chart.angular && axis.isXAxis,
  1108. pane = axis.pane,
  1109. paneOptions = pane && pane.options;
  1110. if (!isHidden && pane && (chart.angular || chart.polar)) {
  1111. // Start and end angle options are given in degrees relative to
  1112. // top, while internal computations are in radians relative to
  1113. // right (like SVG).
  1114. // Y axis in polar charts
  1115. axis.angleRad = (options.angle || 0) * Math.PI / 180;
  1116. // Gauges
  1117. axis.startAngleRad =
  1118. (paneOptions.startAngle - 90) * Math.PI / 180;
  1119. axis.endAngleRad = (pick(paneOptions.endAngle, paneOptions.startAngle + 360) - 90) * Math.PI / 180; // Gauges
  1120. axis.offset = options.offset || 0;
  1121. }
  1122. });
  1123. // Wrap auto label align to avoid setting axis-wide rotation on radial
  1124. // axes. (#4920)
  1125. addEvent(AxisClass, 'autoLabelAlign', function (e) {
  1126. if (this.isRadial) {
  1127. e.align = void 0;
  1128. e.preventDefault();
  1129. }
  1130. });
  1131. // Remove label collector function on axis remove/update
  1132. addEvent(AxisClass, 'destroy', function () {
  1133. var axis = this;
  1134. if (axis.chart &&
  1135. axis.chart.labelCollectors) {
  1136. var index = (axis.labelCollector ?
  1137. axis.chart.labelCollectors.indexOf(axis.labelCollector) :
  1138. -1);
  1139. if (index >= 0) {
  1140. axis.chart.labelCollectors.splice(index, 1);
  1141. }
  1142. }
  1143. });
  1144. addEvent(AxisClass, 'initialAxisTranslation', function () {
  1145. var axis = this;
  1146. if (axis.isRadial) {
  1147. axis.beforeSetTickPositions();
  1148. }
  1149. });
  1150. // Add special cases within the Tick class' methods for radial axes.
  1151. addEvent(TickClass, 'afterGetPosition', function (e) {
  1152. var tick = this;
  1153. if (tick.axis.getPosition) {
  1154. extend(e.pos, tick.axis.getPosition(this.pos));
  1155. }
  1156. });
  1157. // Find the center position of the label based on the distance option.
  1158. addEvent(TickClass, 'afterGetLabelPosition', function (e) {
  1159. var tick = this;
  1160. var axis = tick.axis;
  1161. var label = tick.label;
  1162. if (!label) {
  1163. return;
  1164. }
  1165. var labelBBox = label.getBBox(), labelOptions = axis.options.labels, optionsY = labelOptions.y, ret, centerSlot = 20, // 20 degrees to each side at the top and bottom
  1166. align = labelOptions.align, angle = ((axis.translate(this.pos) + axis.startAngleRad +
  1167. Math.PI / 2) / Math.PI * 180) % 360, correctAngle = Math.round(angle), labelDir = 'end', // Direction of the label 'start' or 'end'
  1168. reducedAngle1 = correctAngle < 0 ?
  1169. correctAngle + 360 : correctAngle, reducedAngle2 = reducedAngle1, translateY = 0, translateX = 0, labelYPosCorrection = !defined(optionsY) ? -labelBBox.height * 0.3 : 0;
  1170. if (axis.isRadial) { // Both X and Y axes in a polar chart
  1171. ret = axis.getPosition(this.pos, (axis.center[2] / 2) +
  1172. relativeLength(pick(labelOptions.distance, -25), axis.center[2] / 2, -axis.center[2] / 2));
  1173. // Automatically rotated
  1174. if (labelOptions.rotation === 'auto') {
  1175. label.attr({
  1176. rotation: angle
  1177. });
  1178. // Vertically centered
  1179. }
  1180. else if (!defined(optionsY)) {
  1181. optionsY = (axis.chart.renderer
  1182. .fontMetrics(label.styles && label.styles.fontSize).b -
  1183. labelBBox.height / 2);
  1184. }
  1185. // Automatic alignment
  1186. if (!defined(align)) {
  1187. if (axis.isCircular) { // Y axis
  1188. if (labelBBox.width >
  1189. axis.len * axis.tickInterval / (axis.max - axis.min)) { // #3506
  1190. centerSlot = 0;
  1191. }
  1192. if (angle > centerSlot && angle < 180 - centerSlot) {
  1193. align = 'left'; // right hemisphere
  1194. }
  1195. else if (angle > 180 + centerSlot &&
  1196. angle < 360 - centerSlot) {
  1197. align = 'right'; // left hemisphere
  1198. }
  1199. else {
  1200. align = 'center'; // top or bottom
  1201. }
  1202. }
  1203. else {
  1204. align = 'center';
  1205. }
  1206. label.attr({
  1207. align: align
  1208. });
  1209. }
  1210. // Auto alignment for solid-gauges with two labels (#10635)
  1211. if (align === 'auto' &&
  1212. axis.tickPositions.length === 2 &&
  1213. axis.isCircular) {
  1214. // Angles reduced to 0 - 90 or 180 - 270
  1215. if (reducedAngle1 > 90 && reducedAngle1 < 180) {
  1216. reducedAngle1 = 180 - reducedAngle1;
  1217. }
  1218. else if (reducedAngle1 > 270 && reducedAngle1 <= 360) {
  1219. reducedAngle1 = 540 - reducedAngle1;
  1220. }
  1221. // Angles reduced to 0 - 180
  1222. if (reducedAngle2 > 180 && reducedAngle2 <= 360) {
  1223. reducedAngle2 = 360 - reducedAngle2;
  1224. }
  1225. if ((axis.pane.options.startAngle === correctAngle) ||
  1226. (axis.pane.options.startAngle === correctAngle + 360) ||
  1227. (axis.pane.options.startAngle === correctAngle - 360)) {
  1228. labelDir = 'start';
  1229. }
  1230. if ((correctAngle >= -90 && correctAngle <= 90) ||
  1231. (correctAngle >= -360 && correctAngle <= -270) ||
  1232. (correctAngle >= 270 && correctAngle <= 360)) {
  1233. align = (labelDir === 'start') ? 'right' : 'left';
  1234. }
  1235. else {
  1236. align = (labelDir === 'start') ? 'left' : 'right';
  1237. }
  1238. // For angles beetwen (90 + n * 180) +- 20
  1239. if (reducedAngle2 > 70 && reducedAngle2 < 110) {
  1240. align = 'center';
  1241. }
  1242. // auto Y translation
  1243. if (reducedAngle1 < 15 ||
  1244. (reducedAngle1 >= 180 && reducedAngle1 < 195)) {
  1245. translateY = labelBBox.height * 0.3;
  1246. }
  1247. else if (reducedAngle1 >= 15 && reducedAngle1 <= 35) {
  1248. translateY = labelDir === 'start' ?
  1249. 0 : labelBBox.height * 0.75;
  1250. }
  1251. else if (reducedAngle1 >= 195 && reducedAngle1 <= 215) {
  1252. translateY = labelDir === 'start' ?
  1253. labelBBox.height * 0.75 : 0;
  1254. }
  1255. else if (reducedAngle1 > 35 && reducedAngle1 <= 90) {
  1256. translateY = labelDir === 'start' ?
  1257. -labelBBox.height * 0.25 : labelBBox.height;
  1258. }
  1259. else if (reducedAngle1 > 215 && reducedAngle1 <= 270) {
  1260. translateY = labelDir === 'start' ?
  1261. labelBBox.height : -labelBBox.height * 0.25;
  1262. }
  1263. // auto X translation
  1264. if (reducedAngle2 < 15) {
  1265. translateX = labelDir === 'start' ?
  1266. -labelBBox.height * 0.15 : labelBBox.height * 0.15;
  1267. }
  1268. else if (reducedAngle2 > 165 && reducedAngle2 <= 180) {
  1269. translateX = labelDir === 'start' ?
  1270. labelBBox.height * 0.15 : -labelBBox.height * 0.15;
  1271. }
  1272. label.attr({ align: align });
  1273. label.translate(translateX, translateY + labelYPosCorrection);
  1274. }
  1275. e.pos.x = ret.x + (labelOptions.x || 0);
  1276. e.pos.y = ret.y + (optionsY || 0);
  1277. }
  1278. });
  1279. // Wrap the getMarkPath function to return the path of the radial marker
  1280. wrap(TickClass.prototype, 'getMarkPath', function (proceed, x, y, tickLength, tickWidth, horiz, renderer) {
  1281. var tick = this;
  1282. var axis = tick.axis;
  1283. var endPoint,
  1284. ret;
  1285. if (axis.isRadial) {
  1286. endPoint = axis.getPosition(this.pos, axis.center[2] / 2 + tickLength);
  1287. ret = [
  1288. 'M',
  1289. x,
  1290. y,
  1291. 'L',
  1292. endPoint.x,
  1293. endPoint.y
  1294. ];
  1295. }
  1296. else {
  1297. ret = proceed.call(this, x, y, tickLength, tickWidth, horiz, renderer);
  1298. }
  1299. return ret;
  1300. });
  1301. };
  1302. /* *
  1303. *
  1304. * Static Properties
  1305. *
  1306. * */
  1307. /**
  1308. * Circular axis around the perimeter of a polar chart.
  1309. * @private
  1310. */
  1311. RadialAxis.defaultCircularOptions = {
  1312. gridLineWidth: 1,
  1313. labels: {
  1314. align: void 0,
  1315. distance: 15,
  1316. x: 0,
  1317. y: void 0,
  1318. style: {
  1319. textOverflow: 'none' // wrap lines by default (#7248)
  1320. }
  1321. },
  1322. maxPadding: 0,
  1323. minPadding: 0,
  1324. showLastLabel: false,
  1325. tickLength: 0
  1326. };
  1327. /**
  1328. * The default options extend defaultYAxisOptions.
  1329. * @private
  1330. */
  1331. RadialAxis.defaultRadialGaugeOptions = {
  1332. labels: {
  1333. align: 'center',
  1334. x: 0,
  1335. y: void 0 // auto
  1336. },
  1337. minorGridLineWidth: 0,
  1338. minorTickInterval: 'auto',
  1339. minorTickLength: 10,
  1340. minorTickPosition: 'inside',
  1341. minorTickWidth: 1,
  1342. tickLength: 10,
  1343. tickPosition: 'inside',
  1344. tickWidth: 2,
  1345. title: {
  1346. rotation: 0
  1347. },
  1348. zIndex: 2 // behind dials, points in the series group
  1349. };
  1350. /**
  1351. * Radial axis, like a spoke in a polar chart.
  1352. * @private
  1353. */
  1354. RadialAxis.defaultRadialOptions = {
  1355. /**
  1356. * In a polar chart, this is the angle of the Y axis in degrees, where
  1357. * 0 is up and 90 is right. The angle determines the position of the
  1358. * axis line and the labels, though the coordinate system is unaffected.
  1359. * Since v8.0.0 this option is also applicable for X axis (inverted
  1360. * polar).
  1361. *
  1362. * @sample {highcharts} highcharts/xaxis/angle/
  1363. * Custom X axis' angle on inverted polar chart
  1364. * @sample {highcharts} highcharts/yaxis/angle/
  1365. * Dual axis polar chart
  1366. *
  1367. * @type {number}
  1368. * @default 0
  1369. * @since 4.2.7
  1370. * @product highcharts
  1371. * @apioption xAxis.angle
  1372. */
  1373. /**
  1374. * Polar charts only. Whether the grid lines should draw as a polygon
  1375. * with straight lines between categories, or as circles. Can be either
  1376. * `circle` or `polygon`. Since v8.0.0 this option is also applicable
  1377. * for X axis (inverted polar).
  1378. *
  1379. * @sample {highcharts} highcharts/demo/polar-spider/
  1380. * Polygon grid lines
  1381. * @sample {highcharts} highcharts/xaxis/gridlineinterpolation/
  1382. * Circle and polygon on inverted polar
  1383. * @sample {highcharts} highcharts/yaxis/gridlineinterpolation/
  1384. * Circle and polygon
  1385. *
  1386. * @type {string}
  1387. * @product highcharts
  1388. * @validvalue ["circle", "polygon"]
  1389. * @apioption xAxis.gridLineInterpolation
  1390. */
  1391. gridLineInterpolation: 'circle',
  1392. gridLineWidth: 1,
  1393. labels: {
  1394. align: 'right',
  1395. x: -3,
  1396. y: -2
  1397. },
  1398. showLastLabel: false,
  1399. title: {
  1400. x: 4,
  1401. text: null,
  1402. rotation: 90
  1403. }
  1404. };
  1405. return RadialAxis;
  1406. }());
  1407. RadialAxis.compose(Axis, Tick); // @todo move outside
  1408. return RadialAxis;
  1409. });
  1410. _registerModule(_modules, 'Series/AreaRange/AreaRangePoint.js', [_modules['Series/Area/AreaSeries.js'], _modules['Core/Series/Point.js'], _modules['Core/Utilities.js']], function (AreaSeries, Point, U) {
  1411. /* *
  1412. *
  1413. * (c) 2010-2021 Torstein Honsi
  1414. *
  1415. * License: www.highcharts.com/license
  1416. *
  1417. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  1418. *
  1419. * */
  1420. var __extends = (this && this.__extends) || (function () {
  1421. var extendStatics = function (d,
  1422. b) {
  1423. extendStatics = Object.setPrototypeOf ||
  1424. ({ __proto__: [] } instanceof Array && function (d,
  1425. b) { d.__proto__ = b; }) ||
  1426. function (d,
  1427. b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  1428. return extendStatics(d, b);
  1429. };
  1430. return function (d, b) {
  1431. extendStatics(d, b);
  1432. function __() { this.constructor = d; }
  1433. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  1434. };
  1435. })();
  1436. var pointProto = Point.prototype;
  1437. var defined = U.defined,
  1438. isNumber = U.isNumber;
  1439. /* *
  1440. *
  1441. * Class
  1442. *
  1443. * */
  1444. var AreaRangePoint = /** @class */ (function (_super) {
  1445. __extends(AreaRangePoint, _super);
  1446. function AreaRangePoint() {
  1447. /* *
  1448. *
  1449. * Properties
  1450. *
  1451. * */
  1452. var _this = _super !== null && _super.apply(this,
  1453. arguments) || this;
  1454. _this.high = void 0;
  1455. _this.low = void 0;
  1456. _this.options = void 0;
  1457. _this.plotHigh = void 0;
  1458. _this.plotLow = void 0;
  1459. _this.plotHighX = void 0;
  1460. _this.plotLowX = void 0;
  1461. _this.plotX = void 0;
  1462. _this.series = void 0;
  1463. return _this;
  1464. }
  1465. /* *
  1466. *
  1467. * Functions
  1468. *
  1469. * */
  1470. /**
  1471. * @private
  1472. */
  1473. AreaRangePoint.prototype.setState = function () {
  1474. var prevState = this.state,
  1475. series = this.series,
  1476. isPolar = series.chart.polar;
  1477. if (!defined(this.plotHigh)) {
  1478. // Boost doesn't calculate plotHigh
  1479. this.plotHigh = series.yAxis.toPixels(this.high, true);
  1480. }
  1481. if (!defined(this.plotLow)) {
  1482. // Boost doesn't calculate plotLow
  1483. this.plotLow = this.plotY = series.yAxis.toPixels(this.low, true);
  1484. }
  1485. if (series.stateMarkerGraphic) {
  1486. series.lowerStateMarkerGraphic = series.stateMarkerGraphic;
  1487. series.stateMarkerGraphic = series.upperStateMarkerGraphic;
  1488. }
  1489. // Change state also for the top marker
  1490. this.graphic = this.upperGraphic;
  1491. this.plotY = this.plotHigh;
  1492. if (isPolar) {
  1493. this.plotX = this.plotHighX;
  1494. }
  1495. // Top state:
  1496. pointProto.setState.apply(this, arguments);
  1497. this.state = prevState;
  1498. // Now restore defaults
  1499. this.plotY = this.plotLow;
  1500. this.graphic = this.lowerGraphic;
  1501. if (isPolar) {
  1502. this.plotX = this.plotLowX;
  1503. }
  1504. if (series.stateMarkerGraphic) {
  1505. series.upperStateMarkerGraphic = series.stateMarkerGraphic;
  1506. series.stateMarkerGraphic = series.lowerStateMarkerGraphic;
  1507. // Lower marker is stored at stateMarkerGraphic
  1508. // to avoid reference duplication (#7021)
  1509. series.lowerStateMarkerGraphic = void 0;
  1510. }
  1511. pointProto.setState.apply(this, arguments);
  1512. };
  1513. AreaRangePoint.prototype.haloPath = function () {
  1514. var isPolar = this.series.chart.polar,
  1515. path = [];
  1516. // Bottom halo
  1517. this.plotY = this.plotLow;
  1518. if (isPolar) {
  1519. this.plotX = this.plotLowX;
  1520. }
  1521. if (this.isInside) {
  1522. path = pointProto.haloPath.apply(this, arguments);
  1523. }
  1524. // Top halo
  1525. this.plotY = this.plotHigh;
  1526. if (isPolar) {
  1527. this.plotX = this.plotHighX;
  1528. }
  1529. if (this.isTopInside) {
  1530. path = path.concat(pointProto.haloPath.apply(this, arguments));
  1531. }
  1532. return path;
  1533. };
  1534. AreaRangePoint.prototype.isValid = function () {
  1535. return isNumber(this.low) && isNumber(this.high);
  1536. };
  1537. return AreaRangePoint;
  1538. }(AreaSeries.prototype.pointClass));
  1539. /* *
  1540. *
  1541. * Default export
  1542. *
  1543. * */
  1544. return AreaRangePoint;
  1545. });
  1546. _registerModule(_modules, 'Series/AreaRange/AreaRangeSeries.js', [_modules['Series/AreaRange/AreaRangePoint.js'], _modules['Series/Area/AreaSeries.js'], _modules['Series/Column/ColumnSeries.js'], _modules['Core/Globals.js'], _modules['Core/Series/Series.js'], _modules['Core/Series/SeriesRegistry.js'], _modules['Core/Utilities.js']], function (AreaRangePoint, AreaSeries, ColumnSeries, H, Series, SeriesRegistry, U) {
  1547. /* *
  1548. *
  1549. * (c) 2010-2021 Torstein Honsi
  1550. *
  1551. * License: www.highcharts.com/license
  1552. *
  1553. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  1554. *
  1555. * */
  1556. var __extends = (this && this.__extends) || (function () {
  1557. var extendStatics = function (d,
  1558. b) {
  1559. extendStatics = Object.setPrototypeOf ||
  1560. ({ __proto__: [] } instanceof Array && function (d,
  1561. b) { d.__proto__ = b; }) ||
  1562. function (d,
  1563. b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  1564. return extendStatics(d, b);
  1565. };
  1566. return function (d, b) {
  1567. extendStatics(d, b);
  1568. function __() { this.constructor = d; }
  1569. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  1570. };
  1571. })();
  1572. var areaProto = AreaSeries.prototype;
  1573. var columnProto = ColumnSeries.prototype;
  1574. var noop = H.noop;
  1575. var seriesProto = Series.prototype;
  1576. var defined = U.defined,
  1577. extend = U.extend,
  1578. isArray = U.isArray,
  1579. pick = U.pick,
  1580. merge = U.merge;
  1581. /* *
  1582. *
  1583. * Class
  1584. *
  1585. * */
  1586. /**
  1587. * The AreaRange series type.
  1588. *
  1589. * @private
  1590. * @class
  1591. * @name Highcharts.seriesTypes.arearange
  1592. *
  1593. * @augments Highcharts.Series
  1594. */
  1595. var AreaRangeSeries = /** @class */ (function (_super) {
  1596. __extends(AreaRangeSeries, _super);
  1597. function AreaRangeSeries() {
  1598. /**
  1599. *
  1600. * Static properties
  1601. *
  1602. */
  1603. var _this = _super !== null && _super.apply(this,
  1604. arguments) || this;
  1605. /* *
  1606. *
  1607. * Properties
  1608. *
  1609. * */
  1610. _this.data = void 0;
  1611. _this.options = void 0;
  1612. _this.points = void 0;
  1613. _this.lowerStateMarkerGraphic = void 0;
  1614. _this.xAxis = void 0;
  1615. return _this;
  1616. /* eslint-enable valid-jsdoc */
  1617. }
  1618. /* *
  1619. *
  1620. * Functions
  1621. *
  1622. * */
  1623. /* eslint-disable valid-jsdoc */
  1624. AreaRangeSeries.prototype.toYData = function (point) {
  1625. return [point.low, point.high];
  1626. };
  1627. /**
  1628. * Translate a point's plotHigh from the internal angle and radius measures
  1629. * to true plotHigh coordinates. This is an addition of the toXY method
  1630. * found in Polar.js, because it runs too early for arearanges to be
  1631. * considered (#3419).
  1632. * @private
  1633. */
  1634. AreaRangeSeries.prototype.highToXY = function (point) {
  1635. // Find the polar plotX and plotY
  1636. var chart = this.chart,
  1637. xy = this.xAxis.postTranslate(point.rectPlotX || 0,
  1638. this.yAxis.len - point.plotHigh);
  1639. point.plotHighX = xy.x - chart.plotLeft;
  1640. point.plotHigh = xy.y - chart.plotTop;
  1641. point.plotLowX = point.plotX;
  1642. };
  1643. /**
  1644. * Translate data points from raw values x and y to plotX and plotY.
  1645. * @private
  1646. */
  1647. AreaRangeSeries.prototype.translate = function () {
  1648. var series = this,
  1649. yAxis = series.yAxis,
  1650. hasModifyValue = !!series.modifyValue;
  1651. areaProto.translate.apply(series);
  1652. // Set plotLow and plotHigh
  1653. series.points.forEach(function (point) {
  1654. var high = point.high,
  1655. plotY = point.plotY;
  1656. if (point.isNull) {
  1657. point.plotY = null;
  1658. }
  1659. else {
  1660. point.plotLow = plotY;
  1661. point.plotHigh = yAxis.translate(hasModifyValue ?
  1662. series.modifyValue(high, point) :
  1663. high, 0, 1, 0, 1);
  1664. if (hasModifyValue) {
  1665. point.yBottom = point.plotHigh;
  1666. }
  1667. }
  1668. });
  1669. // Postprocess plotHigh
  1670. if (this.chart.polar) {
  1671. this.points.forEach(function (point) {
  1672. series.highToXY(point);
  1673. point.tooltipPos = [
  1674. (point.plotHighX + point.plotLowX) / 2,
  1675. (point.plotHigh + point.plotLow) / 2
  1676. ];
  1677. });
  1678. }
  1679. };
  1680. /**
  1681. * Extend the line series' getSegmentPath method by applying the segment
  1682. * path to both lower and higher values of the range.
  1683. * @private
  1684. */
  1685. AreaRangeSeries.prototype.getGraphPath = function (points) {
  1686. var highPoints = [],
  1687. highAreaPoints = [],
  1688. i,
  1689. getGraphPath = areaProto.getGraphPath,
  1690. point,
  1691. pointShim,
  1692. linePath,
  1693. lowerPath,
  1694. options = this.options,
  1695. polar = this.chart.polar,
  1696. connectEnds = polar && options.connectEnds !== false,
  1697. connectNulls = options.connectNulls,
  1698. step = options.step,
  1699. higherPath,
  1700. higherAreaPath;
  1701. points = points || this.points;
  1702. // Create the top line and the top part of the area fill. The area fill
  1703. // compensates for null points by drawing down to the lower graph,
  1704. // moving across the null gap and starting again at the lower graph.
  1705. i = points.length;
  1706. while (i--) {
  1707. point = points[i];
  1708. // Support for polar
  1709. var highAreaPoint = polar ? {
  1710. plotX: point.rectPlotX,
  1711. plotY: point.yBottom,
  1712. doCurve: false // #5186, gaps in areasplinerange fill
  1713. } : {
  1714. plotX: point.plotX,
  1715. plotY: point.plotY,
  1716. doCurve: false // #5186, gaps in areasplinerange fill
  1717. };
  1718. if (!point.isNull &&
  1719. !connectEnds &&
  1720. !connectNulls &&
  1721. (!points[i + 1] || points[i + 1].isNull)) {
  1722. highAreaPoints.push(highAreaPoint);
  1723. }
  1724. pointShim = {
  1725. polarPlotY: point.polarPlotY,
  1726. rectPlotX: point.rectPlotX,
  1727. yBottom: point.yBottom,
  1728. // plotHighX is for polar charts
  1729. plotX: pick(point.plotHighX, point.plotX),
  1730. plotY: point.plotHigh,
  1731. isNull: point.isNull
  1732. };
  1733. highAreaPoints.push(pointShim);
  1734. highPoints.push(pointShim);
  1735. if (!point.isNull &&
  1736. !connectEnds &&
  1737. !connectNulls &&
  1738. (!points[i - 1] || points[i - 1].isNull)) {
  1739. highAreaPoints.push(highAreaPoint);
  1740. }
  1741. }
  1742. // Get the paths
  1743. lowerPath = getGraphPath.call(this, points);
  1744. if (step) {
  1745. if (step === true) {
  1746. step = 'left';
  1747. }
  1748. options.step = {
  1749. left: 'right',
  1750. center: 'center',
  1751. right: 'left'
  1752. }[step]; // swap for reading in getGraphPath
  1753. }
  1754. higherPath = getGraphPath.call(this, highPoints);
  1755. higherAreaPath = getGraphPath.call(this, highAreaPoints);
  1756. options.step = step;
  1757. // Create a line on both top and bottom of the range
  1758. linePath = []
  1759. .concat(lowerPath, higherPath);
  1760. // For the area path, we need to change the 'move' statement
  1761. // into 'lineTo'
  1762. if (!this.chart.polar && higherAreaPath[0] && higherAreaPath[0][0] === 'M') {
  1763. // This probably doesn't work for spline
  1764. higherAreaPath[0] = ['L', higherAreaPath[0][1], higherAreaPath[0][2]];
  1765. }
  1766. this.graphPath = linePath;
  1767. this.areaPath = lowerPath.concat(higherAreaPath);
  1768. // Prepare for sideways animation
  1769. linePath.isArea = true;
  1770. linePath.xMap = lowerPath.xMap;
  1771. this.areaPath.xMap = lowerPath.xMap;
  1772. return linePath;
  1773. };
  1774. /**
  1775. * Extend the basic drawDataLabels method by running it for both lower and
  1776. * higher values.
  1777. * @private
  1778. */
  1779. AreaRangeSeries.prototype.drawDataLabels = function () {
  1780. var data = this.points,
  1781. length = data.length,
  1782. i,
  1783. originalDataLabels = [],
  1784. dataLabelOptions = this.options.dataLabels,
  1785. point,
  1786. up,
  1787. inverted = this.chart.inverted,
  1788. upperDataLabelOptions,
  1789. lowerDataLabelOptions;
  1790. if (dataLabelOptions) {
  1791. // Split into upper and lower options. If data labels is an array,
  1792. // the first element is the upper label, the second is the lower.
  1793. //
  1794. // TODO: We want to change this and allow multiple labels for both
  1795. // upper and lower values in the future - introducing some options
  1796. // for which point value to use as Y for the dataLabel, so that
  1797. // this could be handled in Series.drawDataLabels. This would also
  1798. // improve performance since we now have to loop over all the
  1799. // points multiple times to work around the data label logic.
  1800. if (isArray(dataLabelOptions)) {
  1801. upperDataLabelOptions = dataLabelOptions[0] || { enabled: false };
  1802. lowerDataLabelOptions = dataLabelOptions[1] || { enabled: false };
  1803. }
  1804. else {
  1805. // Make copies
  1806. upperDataLabelOptions = extend({}, dataLabelOptions);
  1807. upperDataLabelOptions.x = dataLabelOptions.xHigh;
  1808. upperDataLabelOptions.y = dataLabelOptions.yHigh;
  1809. lowerDataLabelOptions = extend({}, dataLabelOptions);
  1810. lowerDataLabelOptions.x = dataLabelOptions.xLow;
  1811. lowerDataLabelOptions.y = dataLabelOptions.yLow;
  1812. }
  1813. // Draw upper labels
  1814. if (upperDataLabelOptions.enabled || this._hasPointLabels) {
  1815. // Set preliminary values for plotY and dataLabel
  1816. // and draw the upper labels
  1817. i = length;
  1818. while (i--) {
  1819. point = data[i];
  1820. if (point) {
  1821. up = upperDataLabelOptions.inside ?
  1822. point.plotHigh < point.plotLow :
  1823. point.plotHigh > point.plotLow;
  1824. point.y = point.high;
  1825. point._plotY = point.plotY;
  1826. point.plotY = point.plotHigh;
  1827. // Store original data labels and set preliminary label
  1828. // objects to be picked up in the uber method
  1829. originalDataLabels[i] = point.dataLabel;
  1830. point.dataLabel = point.dataLabelUpper;
  1831. // Set the default offset
  1832. point.below = up;
  1833. if (inverted) {
  1834. if (!upperDataLabelOptions.align) {
  1835. upperDataLabelOptions.align = up ? 'right' : 'left';
  1836. }
  1837. }
  1838. else {
  1839. if (!upperDataLabelOptions.verticalAlign) {
  1840. upperDataLabelOptions.verticalAlign = up ?
  1841. 'top' :
  1842. 'bottom';
  1843. }
  1844. }
  1845. }
  1846. }
  1847. this.options.dataLabels = upperDataLabelOptions;
  1848. if (seriesProto.drawDataLabels) {
  1849. // #1209:
  1850. seriesProto.drawDataLabels.apply(this, arguments);
  1851. }
  1852. // Reset state after the upper labels were created. Move
  1853. // it to point.dataLabelUpper and reassign the originals.
  1854. // We do this here to support not drawing a lower label.
  1855. i = length;
  1856. while (i--) {
  1857. point = data[i];
  1858. if (point) {
  1859. point.dataLabelUpper = point.dataLabel;
  1860. point.dataLabel = originalDataLabels[i];
  1861. delete point.dataLabels;
  1862. point.y = point.low;
  1863. point.plotY = point._plotY;
  1864. }
  1865. }
  1866. }
  1867. // Draw lower labels
  1868. if (lowerDataLabelOptions.enabled || this._hasPointLabels) {
  1869. i = length;
  1870. while (i--) {
  1871. point = data[i];
  1872. if (point) {
  1873. up = lowerDataLabelOptions.inside ?
  1874. point.plotHigh < point.plotLow :
  1875. point.plotHigh > point.plotLow;
  1876. // Set the default offset
  1877. point.below = !up;
  1878. if (inverted) {
  1879. if (!lowerDataLabelOptions.align) {
  1880. lowerDataLabelOptions.align = up ? 'left' : 'right';
  1881. }
  1882. }
  1883. else {
  1884. if (!lowerDataLabelOptions.verticalAlign) {
  1885. lowerDataLabelOptions.verticalAlign = up ?
  1886. 'bottom' :
  1887. 'top';
  1888. }
  1889. }
  1890. }
  1891. }
  1892. this.options.dataLabels = lowerDataLabelOptions;
  1893. if (seriesProto.drawDataLabels) {
  1894. seriesProto.drawDataLabels.apply(this, arguments);
  1895. }
  1896. }
  1897. // Merge upper and lower into point.dataLabels for later destroying
  1898. if (upperDataLabelOptions.enabled) {
  1899. i = length;
  1900. while (i--) {
  1901. point = data[i];
  1902. if (point) {
  1903. point.dataLabels = [
  1904. point.dataLabelUpper,
  1905. point.dataLabel
  1906. ].filter(function (label) {
  1907. return !!label;
  1908. });
  1909. }
  1910. }
  1911. }
  1912. // Reset options
  1913. this.options.dataLabels = dataLabelOptions;
  1914. }
  1915. };
  1916. AreaRangeSeries.prototype.alignDataLabel = function () {
  1917. columnProto.alignDataLabel.apply(this, arguments);
  1918. };
  1919. AreaRangeSeries.prototype.drawPoints = function () {
  1920. var series = this,
  1921. pointLength = series.points.length,
  1922. point,
  1923. i;
  1924. // Draw bottom points
  1925. seriesProto.drawPoints.apply(series, arguments);
  1926. // Prepare drawing top points
  1927. i = 0;
  1928. while (i < pointLength) {
  1929. point = series.points[i];
  1930. // Save original props to be overridden by temporary props for top
  1931. // points
  1932. point.origProps = {
  1933. plotY: point.plotY,
  1934. plotX: point.plotX,
  1935. isInside: point.isInside,
  1936. negative: point.negative,
  1937. zone: point.zone,
  1938. y: point.y
  1939. };
  1940. point.lowerGraphic = point.graphic;
  1941. point.graphic = point.upperGraphic;
  1942. point.plotY = point.plotHigh;
  1943. if (defined(point.plotHighX)) {
  1944. point.plotX = point.plotHighX;
  1945. }
  1946. point.y = pick(point.high, point.origProps.y); // #15523
  1947. point.negative = point.y < (series.options.threshold || 0);
  1948. if (series.zones.length) {
  1949. point.zone = point.getZone();
  1950. }
  1951. if (!series.chart.polar) {
  1952. point.isInside = point.isTopInside = (typeof point.plotY !== 'undefined' &&
  1953. point.plotY >= 0 &&
  1954. point.plotY <= series.yAxis.len && // #3519
  1955. point.plotX >= 0 &&
  1956. point.plotX <= series.xAxis.len);
  1957. }
  1958. i++;
  1959. }
  1960. // Draw top points
  1961. seriesProto.drawPoints.apply(series, arguments);
  1962. // Reset top points preliminary modifications
  1963. i = 0;
  1964. while (i < pointLength) {
  1965. point = series.points[i];
  1966. point.upperGraphic = point.graphic;
  1967. point.graphic = point.lowerGraphic;
  1968. if (point.origProps) {
  1969. extend(point, point.origProps);
  1970. delete point.origProps;
  1971. }
  1972. i++;
  1973. }
  1974. };
  1975. /**
  1976. * The area range series is a carteseian series with higher and lower
  1977. * values for each point along an X axis, where the area between the
  1978. * values is shaded.
  1979. *
  1980. * @sample {highcharts} highcharts/demo/arearange/
  1981. * Area range chart
  1982. * @sample {highstock} stock/demo/arearange/
  1983. * Area range chart
  1984. *
  1985. * @extends plotOptions.area
  1986. * @product highcharts highstock
  1987. * @excluding stack, stacking
  1988. * @requires highcharts-more
  1989. * @optionparent plotOptions.arearange
  1990. */
  1991. AreaRangeSeries.defaultOptions = merge(AreaSeries.defaultOptions, {
  1992. /**
  1993. * @see [fillColor](#plotOptions.arearange.fillColor)
  1994. * @see [fillOpacity](#plotOptions.arearange.fillOpacity)
  1995. *
  1996. * @apioption plotOptions.arearange.color
  1997. */
  1998. /**
  1999. * @default low
  2000. * @apioption plotOptions.arearange.colorKey
  2001. */
  2002. /**
  2003. * @see [color](#plotOptions.arearange.color)
  2004. * @see [fillOpacity](#plotOptions.arearange.fillOpacity)
  2005. *
  2006. * @apioption plotOptions.arearange.fillColor
  2007. */
  2008. /**
  2009. * @see [color](#plotOptions.arearange.color)
  2010. * @see [fillColor](#plotOptions.arearange.fillColor)
  2011. *
  2012. * @default {highcharts} 0.75
  2013. * @default {highstock} 0.75
  2014. * @apioption plotOptions.arearange.fillOpacity
  2015. */
  2016. /**
  2017. * Whether to apply a drop shadow to the graph line. Since 2.3 the
  2018. * shadow can be an object configuration containing `color`, `offsetX`,
  2019. * `offsetY`, `opacity` and `width`.
  2020. *
  2021. * @type {boolean|Highcharts.ShadowOptionsObject}
  2022. * @product highcharts
  2023. * @apioption plotOptions.arearange.shadow
  2024. */
  2025. /**
  2026. * Pixel width of the arearange graph line.
  2027. *
  2028. * @since 2.3.0
  2029. *
  2030. * @private
  2031. */
  2032. lineWidth: 1,
  2033. threshold: null,
  2034. tooltip: {
  2035. pointFormat: '<span style="color:{series.color}">\u25CF</span> ' +
  2036. '{series.name}: <b>{point.low}</b> - <b>{point.high}</b><br/>'
  2037. },
  2038. /**
  2039. * Whether the whole area or just the line should respond to mouseover
  2040. * tooltips and other mouse or touch events.
  2041. *
  2042. * @since 2.3.0
  2043. *
  2044. * @private
  2045. */
  2046. trackByArea: true,
  2047. /**
  2048. * Extended data labels for range series types. Range series data
  2049. * labels use no `x` and `y` options. Instead, they have `xLow`,
  2050. * `xHigh`, `yLow` and `yHigh` options to allow the higher and lower
  2051. * data label sets individually.
  2052. *
  2053. * @declare Highcharts.SeriesAreaRangeDataLabelsOptionsObject
  2054. * @exclude x, y
  2055. * @since 2.3.0
  2056. * @product highcharts highstock
  2057. *
  2058. * @private
  2059. */
  2060. dataLabels: {
  2061. align: void 0,
  2062. verticalAlign: void 0,
  2063. /**
  2064. * X offset of the lower data labels relative to the point value.
  2065. *
  2066. * @sample highcharts/plotoptions/arearange-datalabels/
  2067. * Data labels on range series
  2068. * @sample highcharts/plotoptions/arearange-datalabels/
  2069. * Data labels on range series
  2070. */
  2071. xLow: 0,
  2072. /**
  2073. * X offset of the higher data labels relative to the point value.
  2074. *
  2075. * @sample highcharts/plotoptions/arearange-datalabels/
  2076. * Data labels on range series
  2077. */
  2078. xHigh: 0,
  2079. /**
  2080. * Y offset of the lower data labels relative to the point value.
  2081. *
  2082. * @sample highcharts/plotoptions/arearange-datalabels/
  2083. * Data labels on range series
  2084. */
  2085. yLow: 0,
  2086. /**
  2087. * Y offset of the higher data labels relative to the point value.
  2088. *
  2089. * @sample highcharts/plotoptions/arearange-datalabels/
  2090. * Data labels on range series
  2091. */
  2092. yHigh: 0
  2093. }
  2094. });
  2095. return AreaRangeSeries;
  2096. }(AreaSeries));
  2097. extend(AreaRangeSeries.prototype, {
  2098. pointArrayMap: ['low', 'high'],
  2099. pointValKey: 'low',
  2100. deferTranslatePolar: true,
  2101. pointClass: AreaRangePoint,
  2102. setStackedPoints: noop
  2103. });
  2104. SeriesRegistry.registerSeriesType('arearange', AreaRangeSeries);
  2105. /* *
  2106. *
  2107. * Default export
  2108. *
  2109. * */
  2110. /**
  2111. * A `arearange` series. If the [type](#series.arearange.type) option is not
  2112. * specified, it is inherited from [chart.type](#chart.type).
  2113. *
  2114. *
  2115. * @extends series,plotOptions.arearange
  2116. * @excluding dataParser, dataURL, stack, stacking
  2117. * @product highcharts highstock
  2118. * @requires highcharts-more
  2119. * @apioption series.arearange
  2120. */
  2121. /**
  2122. * @see [fillColor](#series.arearange.fillColor)
  2123. * @see [fillOpacity](#series.arearange.fillOpacity)
  2124. *
  2125. * @apioption series.arearange.color
  2126. */
  2127. /**
  2128. * An array of data points for the series. For the `arearange` series type,
  2129. * points can be given in the following ways:
  2130. *
  2131. * 1. An array of arrays with 3 or 2 values. In this case, the values
  2132. * correspond to `x,low,high`. If the first value is a string, it is
  2133. * applied as the name of the point, and the `x` value is inferred.
  2134. * The `x` value can also be omitted, in which case the inner arrays
  2135. * should be of length 2\. Then the `x` value is automatically calculated,
  2136. * either starting at 0 and incremented by 1, or from `pointStart`
  2137. * and `pointInterval` given in the series options.
  2138. * ```js
  2139. * data: [
  2140. * [0, 8, 3],
  2141. * [1, 1, 1],
  2142. * [2, 6, 8]
  2143. * ]
  2144. * ```
  2145. *
  2146. * 2. An array of objects with named values. The following snippet shows only a
  2147. * few settings, see the complete options set below. If the total number of
  2148. * data points exceeds the series'
  2149. * [turboThreshold](#series.arearange.turboThreshold),
  2150. * this option is not available.
  2151. * ```js
  2152. * data: [{
  2153. * x: 1,
  2154. * low: 9,
  2155. * high: 0,
  2156. * name: "Point2",
  2157. * color: "#00FF00"
  2158. * }, {
  2159. * x: 1,
  2160. * low: 3,
  2161. * high: 4,
  2162. * name: "Point1",
  2163. * color: "#FF00FF"
  2164. * }]
  2165. * ```
  2166. *
  2167. * @sample {highcharts} highcharts/series/data-array-of-arrays/
  2168. * Arrays of numeric x and y
  2169. * @sample {highcharts} highcharts/series/data-array-of-arrays-datetime/
  2170. * Arrays of datetime x and y
  2171. * @sample {highcharts} highcharts/series/data-array-of-name-value/
  2172. * Arrays of point.name and y
  2173. * @sample {highcharts} highcharts/series/data-array-of-objects/
  2174. * Config objects
  2175. *
  2176. * @type {Array<Array<(number|string),number>|Array<(number|string),number,number>|*>}
  2177. * @extends series.line.data
  2178. * @excluding marker, y
  2179. * @product highcharts highstock
  2180. * @apioption series.arearange.data
  2181. */
  2182. /**
  2183. * @extends series.arearange.dataLabels
  2184. * @product highcharts highstock
  2185. * @apioption series.arearange.data.dataLabels
  2186. */
  2187. /**
  2188. * @see [color](#series.arearange.color)
  2189. * @see [fillOpacity](#series.arearange.fillOpacity)
  2190. *
  2191. * @apioption series.arearange.fillColor
  2192. */
  2193. /**
  2194. * @see [color](#series.arearange.color)
  2195. * @see [fillColor](#series.arearange.fillColor)
  2196. *
  2197. * @default {highcharts} 0.75
  2198. * @default {highstock} 0.75
  2199. * @apioption series.arearange.fillOpacity
  2200. */
  2201. /**
  2202. * The high or maximum value for each data point.
  2203. *
  2204. * @type {number}
  2205. * @product highcharts highstock
  2206. * @apioption series.arearange.data.high
  2207. */
  2208. /**
  2209. * The low or minimum value for each data point.
  2210. *
  2211. * @type {number}
  2212. * @product highcharts highstock
  2213. * @apioption series.arearange.data.low
  2214. */
  2215. ''; // adds doclets above to tranpiled file
  2216. return AreaRangeSeries;
  2217. });
  2218. _registerModule(_modules, 'Series/AreaSplineRange/AreaSplineRangeSeries.js', [_modules['Series/AreaRange/AreaRangeSeries.js'], _modules['Core/Series/SeriesRegistry.js'], _modules['Core/Utilities.js']], function (AreaRangeSeries, SeriesRegistry, U) {
  2219. /* *
  2220. *
  2221. * (c) 2010-2021 Torstein Honsi
  2222. *
  2223. * License: www.highcharts.com/license
  2224. *
  2225. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  2226. *
  2227. * */
  2228. var __extends = (this && this.__extends) || (function () {
  2229. var extendStatics = function (d,
  2230. b) {
  2231. extendStatics = Object.setPrototypeOf ||
  2232. ({ __proto__: [] } instanceof Array && function (d,
  2233. b) { d.__proto__ = b; }) ||
  2234. function (d,
  2235. b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  2236. return extendStatics(d, b);
  2237. };
  2238. return function (d, b) {
  2239. extendStatics(d, b);
  2240. function __() { this.constructor = d; }
  2241. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  2242. };
  2243. })();
  2244. var SplineSeries = SeriesRegistry.seriesTypes.spline;
  2245. var merge = U.merge,
  2246. extend = U.extend;
  2247. /* *
  2248. *
  2249. * Class
  2250. *
  2251. * */
  2252. /**
  2253. * The areasplinerange series type.
  2254. *
  2255. * @private
  2256. * @class
  2257. * @name Highcharts.seriesTypes.areasplinerange
  2258. *
  2259. * @augments Highcharts.Series
  2260. */
  2261. var AreaSplineRangeSeries = /** @class */ (function (_super) {
  2262. __extends(AreaSplineRangeSeries, _super);
  2263. function AreaSplineRangeSeries() {
  2264. /* *
  2265. *
  2266. * Static properties
  2267. *
  2268. * */
  2269. var _this = _super !== null && _super.apply(this,
  2270. arguments) || this;
  2271. /* *
  2272. *
  2273. * Properties
  2274. *
  2275. * */
  2276. _this.options = void 0;
  2277. _this.data = void 0;
  2278. _this.points = void 0;
  2279. return _this;
  2280. }
  2281. /**
  2282. * The area spline range is a cartesian series type with higher and
  2283. * lower Y values along an X axis. The area inside the range is colored, and
  2284. * the graph outlining the area is a smoothed spline.
  2285. *
  2286. * @sample {highstock|highstock} stock/demo/areasplinerange/
  2287. * Area spline range
  2288. *
  2289. * @extends plotOptions.arearange
  2290. * @since 2.3.0
  2291. * @excluding step, boostThreshold, boostBlending
  2292. * @product highcharts highstock
  2293. * @requires highcharts-more
  2294. * @apioption plotOptions.areasplinerange
  2295. */
  2296. /**
  2297. * @see [fillColor](#plotOptions.areasplinerange.fillColor)
  2298. * @see [fillOpacity](#plotOptions.areasplinerange.fillOpacity)
  2299. *
  2300. * @apioption plotOptions.areasplinerange.color
  2301. */
  2302. /**
  2303. * @see [color](#plotOptions.areasplinerange.color)
  2304. * @see [fillOpacity](#plotOptions.areasplinerange.fillOpacity)
  2305. *
  2306. * @apioption plotOptions.areasplinerange.fillColor
  2307. */
  2308. /**
  2309. * @see [color](#plotOptions.areasplinerange.color)
  2310. * @see [fillColor](#plotOptions.areasplinerange.fillColor)
  2311. *
  2312. * @default {highcharts} 0.75
  2313. * @default {highstock} 0.75
  2314. * @apioption plotOptions.areasplinerange.fillOpacity
  2315. */
  2316. AreaSplineRangeSeries.defaultOptions = merge(AreaRangeSeries.defaultOptions);
  2317. return AreaSplineRangeSeries;
  2318. }(AreaRangeSeries));
  2319. extend(AreaSplineRangeSeries.prototype, {
  2320. getPointSpline: SplineSeries.prototype.getPointSpline
  2321. });
  2322. SeriesRegistry.registerSeriesType('areasplinerange', AreaSplineRangeSeries);
  2323. /* *
  2324. *
  2325. * Default export
  2326. *
  2327. * */
  2328. /* *
  2329. *
  2330. * API options
  2331. *
  2332. * */
  2333. /**
  2334. * A `areasplinerange` series. If the [type](#series.areasplinerange.type)
  2335. * option is not specified, it is inherited from [chart.type](#chart.type).
  2336. *
  2337. * @extends series,plotOptions.areasplinerange
  2338. * @excluding dataParser, dataURL, stack, step, boostThreshold, boostBlending
  2339. * @product highcharts highstock
  2340. * @requires highcharts-more
  2341. * @apioption series.areasplinerange
  2342. */
  2343. /**
  2344. * @see [fillColor](#series.areasplinerange.fillColor)
  2345. * @see [fillOpacity](#series.areasplinerange.fillOpacity)
  2346. *
  2347. * @apioption series.areasplinerange.color
  2348. */
  2349. /**
  2350. * An array of data points for the series. For the `areasplinerange`
  2351. * series type, points can be given in the following ways:
  2352. *
  2353. * 1. An array of arrays with 3 or 2 values. In this case, the values correspond
  2354. * to `x,low,high`. If the first value is a string, it is applied as the name
  2355. * of the point, and the `x` value is inferred. The `x` value can also be
  2356. * omitted, in which case the inner arrays should be of length 2\. Then the
  2357. * `x` value is automatically calculated, either starting at 0 and
  2358. * incremented by 1, or from `pointStart` and `pointInterval` given in the
  2359. * series options.
  2360. * ```js
  2361. * data: [
  2362. * [0, 0, 5],
  2363. * [1, 9, 1],
  2364. * [2, 5, 2]
  2365. * ]
  2366. * ```
  2367. *
  2368. * 2. An array of objects with named values. The following snippet shows only a
  2369. * few settings, see the complete options set below. If the total number of
  2370. * data points exceeds the series'
  2371. * [turboThreshold](#series.areasplinerange.turboThreshold), this option is
  2372. * not available.
  2373. * ```js
  2374. * data: [{
  2375. * x: 1,
  2376. * low: 5,
  2377. * high: 0,
  2378. * name: "Point2",
  2379. * color: "#00FF00"
  2380. * }, {
  2381. * x: 1,
  2382. * low: 4,
  2383. * high: 1,
  2384. * name: "Point1",
  2385. * color: "#FF00FF"
  2386. * }]
  2387. * ```
  2388. *
  2389. * @sample {highcharts} highcharts/series/data-array-of-arrays/
  2390. * Arrays of numeric x and y
  2391. * @sample {highcharts} highcharts/series/data-array-of-arrays-datetime/
  2392. * Arrays of datetime x and y
  2393. * @sample {highcharts} highcharts/series/data-array-of-name-value/
  2394. * Arrays of point.name and y
  2395. * @sample {highcharts} highcharts/series/data-array-of-objects/
  2396. * Config objects
  2397. *
  2398. * @type {Array<Array<(number|string),number>|Array<(number|string),number,number>|*>}
  2399. * @extends series.arearange.data
  2400. * @product highcharts highstock
  2401. * @apioption series.areasplinerange.data
  2402. */
  2403. /**
  2404. * @see [color](#series.areasplinerange.color)
  2405. * @see [fillOpacity](#series.areasplinerange.fillOpacity)
  2406. *
  2407. * @apioption series.areasplinerange.fillColor
  2408. */
  2409. /**
  2410. * @see [color](#series.areasplinerange.color)
  2411. * @see [fillColor](#series.areasplinerange.fillColor)
  2412. *
  2413. * @default {highcharts} 0.75
  2414. * @default {highstock} 0.75
  2415. * @apioption series.areasplinerange.fillOpacity
  2416. */
  2417. ''; // adds doclets above to transpiled file
  2418. return AreaSplineRangeSeries;
  2419. });
  2420. _registerModule(_modules, 'Series/ColumnRange/ColumnRangePoint.js', [_modules['Core/Series/SeriesRegistry.js'], _modules['Core/Utilities.js']], function (SeriesRegistry, U) {
  2421. /* *
  2422. *
  2423. * (c) 2010-2021 Torstein Honsi
  2424. *
  2425. * License: www.highcharts.com/license
  2426. *
  2427. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  2428. *
  2429. * */
  2430. var __extends = (this && this.__extends) || (function () {
  2431. var extendStatics = function (d,
  2432. b) {
  2433. extendStatics = Object.setPrototypeOf ||
  2434. ({ __proto__: [] } instanceof Array && function (d,
  2435. b) { d.__proto__ = b; }) ||
  2436. function (d,
  2437. b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  2438. return extendStatics(d, b);
  2439. };
  2440. return function (d, b) {
  2441. extendStatics(d, b);
  2442. function __() { this.constructor = d; }
  2443. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  2444. };
  2445. })();
  2446. var _a = SeriesRegistry.seriesTypes,
  2447. ColumnPoint = _a.column.prototype.pointClass,
  2448. AreaRangePoint = _a.arearange.prototype.pointClass;
  2449. var extend = U.extend,
  2450. isNumber = U.isNumber;
  2451. /* *
  2452. *
  2453. * Class
  2454. *
  2455. * */
  2456. var ColumnRangePoint = /** @class */ (function (_super) {
  2457. __extends(ColumnRangePoint, _super);
  2458. function ColumnRangePoint() {
  2459. var _this = _super !== null && _super.apply(this,
  2460. arguments) || this;
  2461. _this.series = void 0;
  2462. _this.options = void 0;
  2463. _this.barX = void 0;
  2464. _this.pointWidth = void 0;
  2465. _this.shapeType = void 0;
  2466. return _this;
  2467. }
  2468. ColumnRangePoint.prototype.isValid = function () {
  2469. return isNumber(this.low);
  2470. };
  2471. return ColumnRangePoint;
  2472. }(AreaRangePoint));
  2473. /* *
  2474. *
  2475. * Prototype properties
  2476. *
  2477. * */
  2478. extend(ColumnRangePoint.prototype, {
  2479. setState: ColumnPoint.prototype.setState
  2480. });
  2481. /* *
  2482. *
  2483. * Default export
  2484. *
  2485. * */
  2486. return ColumnRangePoint;
  2487. });
  2488. _registerModule(_modules, 'Series/ColumnRange/ColumnRangeSeries.js', [_modules['Series/ColumnRange/ColumnRangePoint.js'], _modules['Core/Globals.js'], _modules['Core/Series/SeriesRegistry.js'], _modules['Core/Utilities.js']], function (ColumnRangePoint, H, SeriesRegistry, U) {
  2489. /* *
  2490. *
  2491. * (c) 2010-2021 Torstein Honsi
  2492. *
  2493. * License: www.highcharts.com/license
  2494. *
  2495. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  2496. *
  2497. * */
  2498. var __extends = (this && this.__extends) || (function () {
  2499. var extendStatics = function (d,
  2500. b) {
  2501. extendStatics = Object.setPrototypeOf ||
  2502. ({ __proto__: [] } instanceof Array && function (d,
  2503. b) { d.__proto__ = b; }) ||
  2504. function (d,
  2505. b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  2506. return extendStatics(d, b);
  2507. };
  2508. return function (d, b) {
  2509. extendStatics(d, b);
  2510. function __() { this.constructor = d; }
  2511. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  2512. };
  2513. })();
  2514. var noop = H.noop;
  2515. var _a = SeriesRegistry.seriesTypes,
  2516. AreaRangeSeries = _a.arearange,
  2517. ColumnSeries = _a.column;
  2518. var columnProto = ColumnSeries.prototype;
  2519. var arearangeProto = AreaRangeSeries.prototype;
  2520. var clamp = U.clamp,
  2521. merge = U.merge,
  2522. pick = U.pick,
  2523. extend = U.extend;
  2524. /**
  2525. * The column range is a cartesian series type with higher and lower
  2526. * Y values along an X axis. To display horizontal bars, set
  2527. * [chart.inverted](#chart.inverted) to `true`.
  2528. *
  2529. * @sample {highcharts|highstock} highcharts/demo/columnrange/
  2530. * Inverted column range
  2531. *
  2532. * @extends plotOptions.column
  2533. * @since 2.3.0
  2534. * @excluding negativeColor, stacking, softThreshold, threshold
  2535. * @product highcharts highstock
  2536. * @requires highcharts-more
  2537. * @optionparent plotOptions.columnrange
  2538. */
  2539. var columnRangeOptions = {
  2540. /**
  2541. * Extended data labels for range series types. Range series data labels
  2542. * have no `x` and `y` options. Instead,
  2543. they have `xLow`,
  2544. `xHigh`,
  2545. * `yLow` and `yHigh` options to allow the higher and lower data label
  2546. * sets individually.
  2547. *
  2548. * @declare Highcharts.SeriesAreaRangeDataLabelsOptionsObject
  2549. * @extends plotOptions.arearange.dataLabels
  2550. * @since 2.3.0
  2551. * @product highcharts highstock
  2552. * @apioption plotOptions.columnrange.dataLabels
  2553. */
  2554. pointRange: null,
  2555. /** @ignore-option */
  2556. marker: null,
  2557. states: {
  2558. hover: {
  2559. /** @ignore-option */
  2560. halo: false
  2561. }
  2562. }
  2563. };
  2564. /* *
  2565. *
  2566. * Class
  2567. *
  2568. * */
  2569. /**
  2570. * The ColumnRangeSeries class
  2571. *
  2572. * @private
  2573. * @class
  2574. * @name Highcharts.seriesTypes.columnrange
  2575. *
  2576. * @augments Highcharts.Series
  2577. */
  2578. var ColumnRangeSeries = /** @class */ (function (_super) {
  2579. __extends(ColumnRangeSeries, _super);
  2580. function ColumnRangeSeries() {
  2581. /* *
  2582. *
  2583. * Static properties
  2584. *
  2585. * */
  2586. var _this = _super !== null && _super.apply(this,
  2587. arguments) || this;
  2588. /* *
  2589. *
  2590. * Properties
  2591. *
  2592. * */
  2593. _this.data = void 0;
  2594. _this.points = void 0;
  2595. _this.options = void 0;
  2596. return _this;
  2597. }
  2598. /* *
  2599. *
  2600. * Functions
  2601. *
  2602. * */
  2603. ColumnRangeSeries.prototype.setOptions = function () {
  2604. merge(true, arguments[0], { stacking: void 0 }); // #14359 Prevent side-effect from stacking.
  2605. return arearangeProto.setOptions.apply(this, arguments);
  2606. };
  2607. // eslint-disable-next-line valid-jsdoc
  2608. /**
  2609. * Translate data points from raw values x and y to plotX and plotY
  2610. * @private
  2611. */
  2612. ColumnRangeSeries.prototype.translate = function () {
  2613. var series = this,
  2614. yAxis = series.yAxis,
  2615. xAxis = series.xAxis,
  2616. startAngleRad = xAxis.startAngleRad,
  2617. start,
  2618. chart = series.chart,
  2619. isRadial = series.xAxis.isRadial,
  2620. safeDistance = Math.max(chart.chartWidth,
  2621. chart.chartHeight) + 999,
  2622. plotHigh;
  2623. // eslint-disable-next-line valid-jsdoc
  2624. /**
  2625. * Don't draw too far outside plot area (#6835)
  2626. * @private
  2627. */
  2628. function safeBounds(pixelPos) {
  2629. return clamp(pixelPos, -safeDistance, safeDistance);
  2630. }
  2631. columnProto.translate.apply(series);
  2632. // Set plotLow and plotHigh
  2633. series.points.forEach(function (point) {
  2634. var shapeArgs = point.shapeArgs || {},
  2635. minPointLength = series.options.minPointLength,
  2636. heightDifference,
  2637. height,
  2638. y;
  2639. point.plotHigh = plotHigh = safeBounds(yAxis.translate(point.high, 0, 1, 0, 1));
  2640. point.plotLow = safeBounds(point.plotY);
  2641. // adjust shape
  2642. y = plotHigh;
  2643. height = pick(point.rectPlotY, point.plotY) - plotHigh;
  2644. // Adjust for minPointLength
  2645. if (Math.abs(height) < minPointLength) {
  2646. heightDifference = (minPointLength - height);
  2647. height += heightDifference;
  2648. y -= heightDifference / 2;
  2649. // Adjust for negative ranges or reversed Y axis (#1457)
  2650. }
  2651. else if (height < 0) {
  2652. height *= -1;
  2653. y -= height;
  2654. }
  2655. if (isRadial) {
  2656. start = point.barX + startAngleRad;
  2657. point.shapeType = 'arc';
  2658. point.shapeArgs = series.polarArc(y + height, y, start, start + point.pointWidth);
  2659. }
  2660. else {
  2661. shapeArgs.height = height;
  2662. shapeArgs.y = y;
  2663. var _a = shapeArgs.x,
  2664. x = _a === void 0 ? 0 : _a,
  2665. _b = shapeArgs.width,
  2666. width = _b === void 0 ? 0 : _b;
  2667. point.tooltipPos = chart.inverted ?
  2668. [
  2669. yAxis.len + yAxis.pos - chart.plotLeft - y -
  2670. height / 2,
  2671. xAxis.len + xAxis.pos - chart.plotTop -
  2672. x - width / 2,
  2673. height
  2674. ] : [
  2675. xAxis.left - chart.plotLeft + x +
  2676. width / 2,
  2677. yAxis.pos - chart.plotTop + y + height / 2,
  2678. height
  2679. ]; // don't inherit from column tooltip position - #3372
  2680. }
  2681. });
  2682. };
  2683. // Overrides from modules that may be loaded after this module
  2684. ColumnRangeSeries.prototype.crispCol = function () {
  2685. return columnProto.crispCol.apply(this, arguments);
  2686. };
  2687. ColumnRangeSeries.prototype.drawPoints = function () {
  2688. return columnProto.drawPoints.apply(this, arguments);
  2689. };
  2690. ColumnRangeSeries.prototype.drawTracker = function () {
  2691. return columnProto.drawTracker.apply(this, arguments);
  2692. };
  2693. ColumnRangeSeries.prototype.getColumnMetrics = function () {
  2694. return columnProto.getColumnMetrics.apply(this, arguments);
  2695. };
  2696. ColumnRangeSeries.prototype.pointAttribs = function () {
  2697. return columnProto.pointAttribs.apply(this, arguments);
  2698. };
  2699. ColumnRangeSeries.prototype.adjustForMissingColumns = function () {
  2700. return columnProto.adjustForMissingColumns.apply(this, arguments);
  2701. };
  2702. ColumnRangeSeries.prototype.animate = function () {
  2703. return columnProto.animate.apply(this, arguments);
  2704. };
  2705. ColumnRangeSeries.prototype.translate3dPoints = function () {
  2706. return columnProto.translate3dPoints.apply(this, arguments);
  2707. };
  2708. ColumnRangeSeries.prototype.translate3dShapes = function () {
  2709. return columnProto.translate3dShapes.apply(this, arguments);
  2710. };
  2711. ColumnRangeSeries.defaultOptions = merge(ColumnSeries.defaultOptions, AreaRangeSeries.defaultOptions, columnRangeOptions);
  2712. return ColumnRangeSeries;
  2713. }(AreaRangeSeries));
  2714. extend(ColumnRangeSeries.prototype, {
  2715. directTouch: true,
  2716. trackerGroups: ['group', 'dataLabelsGroup'],
  2717. drawGraph: noop,
  2718. getSymbol: noop,
  2719. polarArc: function () {
  2720. return columnProto.polarArc.apply(this, arguments);
  2721. },
  2722. pointClass: ColumnRangePoint
  2723. });
  2724. SeriesRegistry.registerSeriesType('columnrange', ColumnRangeSeries);
  2725. /* *
  2726. *
  2727. * Default export
  2728. *
  2729. * */
  2730. /* *
  2731. *
  2732. * API options
  2733. *
  2734. * */
  2735. /**
  2736. * A `columnrange` series. If the [type](#series.columnrange.type)
  2737. * option is not specified, it is inherited from
  2738. * [chart.type](#chart.type).
  2739. *
  2740. * @extends series,plotOptions.columnrange
  2741. * @excluding dataParser, dataURL, stack, stacking
  2742. * @product highcharts highstock
  2743. * @requires highcharts-more
  2744. * @apioption series.columnrange
  2745. */
  2746. /**
  2747. * An array of data points for the series. For the `columnrange` series
  2748. * type, points can be given in the following ways:
  2749. *
  2750. * 1. An array of arrays with 3 or 2 values. In this case, the values correspond
  2751. * to `x,low,high`. If the first value is a string, it is applied as the name
  2752. * of the point, and the `x` value is inferred. The `x` value can also be
  2753. * omitted, in which case the inner arrays should be of length 2\. Then the
  2754. * `x` value is automatically calculated, either starting at 0 and
  2755. * incremented by 1, or from `pointStart` and `pointInterval` given in the
  2756. * series options.
  2757. * ```js
  2758. * data: [
  2759. * [0, 4, 2],
  2760. * [1, 2, 1],
  2761. * [2, 9, 10]
  2762. * ]
  2763. * ```
  2764. *
  2765. * 2. An array of objects with named values. The following snippet shows only a
  2766. * few settings, see the complete options set below. If the total number of
  2767. * data points exceeds the series'
  2768. * [turboThreshold](#series.columnrange.turboThreshold), this option is not
  2769. * available.
  2770. * ```js
  2771. * data: [{
  2772. * x: 1,
  2773. * low: 0,
  2774. * high: 4,
  2775. * name: "Point2",
  2776. * color: "#00FF00"
  2777. * }, {
  2778. * x: 1,
  2779. * low: 5,
  2780. * high: 3,
  2781. * name: "Point1",
  2782. * color: "#FF00FF"
  2783. * }]
  2784. * ```
  2785. *
  2786. * @sample {highcharts} highcharts/series/data-array-of-arrays/
  2787. * Arrays of numeric x and y
  2788. * @sample {highcharts} highcharts/series/data-array-of-arrays-datetime/
  2789. * Arrays of datetime x and y
  2790. * @sample {highcharts} highcharts/series/data-array-of-name-value/
  2791. * Arrays of point.name and y
  2792. * @sample {highcharts} highcharts/series/data-array-of-objects/
  2793. * Config objects
  2794. *
  2795. * @type {Array<Array<(number|string),number>|Array<(number|string),number,number>|*>}
  2796. * @extends series.arearange.data
  2797. * @excluding marker
  2798. * @product highcharts highstock
  2799. * @apioption series.columnrange.data
  2800. */
  2801. /**
  2802. * @extends series.columnrange.dataLabels
  2803. * @product highcharts highstock
  2804. * @apioption series.columnrange.data.dataLabels
  2805. */
  2806. /**
  2807. * @excluding halo, lineWidth, lineWidthPlus, marker
  2808. * @product highcharts highstock
  2809. * @apioption series.columnrange.states.hover
  2810. */
  2811. /**
  2812. * @excluding halo, lineWidth, lineWidthPlus, marker
  2813. * @product highcharts highstock
  2814. * @apioption series.columnrange.states.select
  2815. */
  2816. ''; // adds doclets above into transpiled
  2817. return ColumnRangeSeries;
  2818. });
  2819. _registerModule(_modules, 'Series/ColumnPyramid/ColumnPyramidSeries.js', [_modules['Series/Column/ColumnSeries.js'], _modules['Core/Series/SeriesRegistry.js'], _modules['Core/Utilities.js']], function (ColumnSeries, SeriesRegistry, U) {
  2820. /* *
  2821. *
  2822. * (c) 2010-2021 Sebastian Bochan
  2823. *
  2824. * License: www.highcharts.com/license
  2825. *
  2826. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  2827. *
  2828. * */
  2829. var __extends = (this && this.__extends) || (function () {
  2830. var extendStatics = function (d,
  2831. b) {
  2832. extendStatics = Object.setPrototypeOf ||
  2833. ({ __proto__: [] } instanceof Array && function (d,
  2834. b) { d.__proto__ = b; }) ||
  2835. function (d,
  2836. b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  2837. return extendStatics(d, b);
  2838. };
  2839. return function (d, b) {
  2840. extendStatics(d, b);
  2841. function __() { this.constructor = d; }
  2842. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  2843. };
  2844. })();
  2845. var colProto = ColumnSeries.prototype;
  2846. var clamp = U.clamp,
  2847. extend = U.extend,
  2848. merge = U.merge,
  2849. pick = U.pick;
  2850. /**
  2851. * The ColumnPyramidSeries class
  2852. *
  2853. * @private
  2854. * @class
  2855. * @name Highcharts.seriesTypes.columnpyramid
  2856. *
  2857. * @augments Highcharts.Series
  2858. */
  2859. var ColumnPyramidSeries = /** @class */ (function (_super) {
  2860. __extends(ColumnPyramidSeries, _super);
  2861. function ColumnPyramidSeries() {
  2862. /* *
  2863. *
  2864. * Static properties
  2865. *
  2866. * */
  2867. var _this = _super !== null && _super.apply(this,
  2868. arguments) || this;
  2869. /* *
  2870. *
  2871. * Properties
  2872. *
  2873. * */
  2874. _this.data = void 0;
  2875. _this.options = void 0;
  2876. _this.points = void 0;
  2877. return _this;
  2878. }
  2879. /* *
  2880. *
  2881. * Functions
  2882. *
  2883. * */
  2884. /* eslint-disable-next-line valid-jsdoc */
  2885. /**
  2886. * Overrides the column translate method
  2887. * @private
  2888. */
  2889. ColumnPyramidSeries.prototype.translate = function () {
  2890. var series = this,
  2891. chart = series.chart,
  2892. options = series.options,
  2893. dense = series.dense =
  2894. series.closestPointRange * series.xAxis.transA < 2,
  2895. borderWidth = series.borderWidth = pick(options.borderWidth,
  2896. dense ? 0 : 1 // #3635
  2897. ),
  2898. yAxis = series.yAxis,
  2899. threshold = options.threshold,
  2900. translatedThreshold = series.translatedThreshold =
  2901. yAxis.getThreshold(threshold),
  2902. minPointLength = pick(options.minPointLength, 5),
  2903. metrics = series.getColumnMetrics(),
  2904. pointWidth = metrics.width,
  2905. // postprocessed for border width
  2906. seriesBarW = series.barW =
  2907. Math.max(pointWidth, 1 + 2 * borderWidth),
  2908. pointXOffset = series.pointXOffset = metrics.offset;
  2909. if (chart.inverted) {
  2910. translatedThreshold -= 0.5; // #3355
  2911. }
  2912. // When the pointPadding is 0,
  2913. // we want the pyramids to be packed tightly,
  2914. // so we allow individual pyramids to have individual sizes.
  2915. // When pointPadding is greater,
  2916. // we strive for equal-width columns (#2694).
  2917. if (options.pointPadding) {
  2918. seriesBarW = Math.ceil(seriesBarW);
  2919. }
  2920. colProto.translate.apply(series);
  2921. // Record the new values
  2922. series.points.forEach(function (point) {
  2923. var yBottom = pick(point.yBottom,
  2924. translatedThreshold),
  2925. safeDistance = 999 + Math.abs(yBottom),
  2926. plotY = clamp(point.plotY, -safeDistance,
  2927. yAxis.len + safeDistance),
  2928. // Don't draw too far outside plot area
  2929. // (#1303, #2241, #4264)
  2930. barX = point.plotX + pointXOffset,
  2931. barW = seriesBarW / 2,
  2932. barY = Math.min(plotY,
  2933. yBottom),
  2934. barH = Math.max(plotY,
  2935. yBottom) - barY,
  2936. stackTotal,
  2937. stackHeight,
  2938. topPointY,
  2939. topXwidth,
  2940. bottomXwidth,
  2941. invBarPos,
  2942. x1,
  2943. x2,
  2944. x3,
  2945. x4,
  2946. y1,
  2947. y2;
  2948. point.barX = barX;
  2949. point.pointWidth = pointWidth;
  2950. // Fix the tooltip on center of grouped pyramids
  2951. // (#1216, #424, #3648)
  2952. point.tooltipPos = chart.inverted ?
  2953. [
  2954. yAxis.len + yAxis.pos - chart.plotLeft - plotY,
  2955. series.xAxis.len - barX - barW,
  2956. barH
  2957. ] :
  2958. [
  2959. barX + barW,
  2960. plotY + yAxis.pos - chart.plotTop,
  2961. barH
  2962. ];
  2963. stackTotal =
  2964. threshold + (point.total || point.y);
  2965. // overwrite stacktotal (always 100 / -100)
  2966. if (options.stacking === 'percent') {
  2967. stackTotal =
  2968. threshold + (point.y < 0) ?
  2969. -100 :
  2970. 100;
  2971. }
  2972. // get the highest point (if stack, extract from total)
  2973. topPointY = yAxis.toPixels((stackTotal), true);
  2974. // calculate height of stack (in pixels)
  2975. stackHeight =
  2976. chart.plotHeight - topPointY -
  2977. (chart.plotHeight - translatedThreshold);
  2978. // topXwidth and bottomXwidth = width of lines from the center
  2979. // calculated from tanges proportion.
  2980. // Can not be a NaN #12514
  2981. topXwidth = stackHeight ? (barW * (barY - topPointY)) / stackHeight : 0;
  2982. // like topXwidth, but with height of point
  2983. bottomXwidth = stackHeight ? (barW * (barY + barH - topPointY)) / stackHeight : 0;
  2984. /*
  2985. /\
  2986. / \
  2987. x1,y1,------ x2,y1
  2988. / \
  2989. ----------
  2990. x4,y2 x3,y2
  2991. */
  2992. x1 = barX - topXwidth + barW;
  2993. x2 = barX + topXwidth + barW;
  2994. x3 = barX + bottomXwidth + barW;
  2995. x4 = barX - bottomXwidth + barW;
  2996. y1 = barY - minPointLength;
  2997. y2 = barY + barH;
  2998. if (point.y < 0) {
  2999. y1 = barY;
  3000. y2 = barY + barH + minPointLength;
  3001. }
  3002. // inverted chart
  3003. if (chart.inverted) {
  3004. invBarPos = chart.plotWidth - barY;
  3005. stackHeight = (topPointY -
  3006. (chart.plotWidth - translatedThreshold));
  3007. // proportion tanges
  3008. topXwidth = (barW *
  3009. (topPointY - invBarPos)) / stackHeight;
  3010. bottomXwidth = (barW *
  3011. (topPointY - (invBarPos - barH))) / stackHeight;
  3012. x1 = barX + barW + topXwidth; // top bottom
  3013. x2 = x1 - 2 * topXwidth; // top top
  3014. x3 = barX - bottomXwidth + barW; // bottom top
  3015. x4 = barX + bottomXwidth + barW; // bottom bottom
  3016. y1 = barY;
  3017. y2 = barY + barH - minPointLength;
  3018. if (point.y < 0) {
  3019. y2 = barY + barH + minPointLength;
  3020. }
  3021. }
  3022. // Register shape type and arguments to be used in drawPoints
  3023. point.shapeType = 'path';
  3024. point.shapeArgs = {
  3025. // args for datalabels positioning
  3026. x: x1,
  3027. y: y1,
  3028. width: x2 - x1,
  3029. height: barH,
  3030. // path of pyramid
  3031. d: [
  3032. ['M', x1, y1],
  3033. ['L', x2, y1],
  3034. ['L', x3, y2],
  3035. ['L', x4, y2],
  3036. ['Z']
  3037. ]
  3038. };
  3039. });
  3040. };
  3041. /**
  3042. * Column pyramid series display one pyramid per value along an X axis.
  3043. * To display horizontal pyramids, set [chart.inverted](#chart.inverted) to
  3044. * `true`.
  3045. *
  3046. * @sample {highcharts|highstock} highcharts/demo/column-pyramid/
  3047. * Column pyramid
  3048. * @sample {highcharts|highstock} highcharts/plotoptions/columnpyramid-stacked/
  3049. * Column pyramid stacked
  3050. * @sample {highcharts|highstock} highcharts/plotoptions/columnpyramid-inverted/
  3051. * Column pyramid inverted
  3052. *
  3053. * @extends plotOptions.column
  3054. * @since 7.0.0
  3055. * @product highcharts highstock
  3056. * @excluding boostThreshold, borderRadius, crisp, depth, edgeColor,
  3057. * edgeWidth, groupZPadding, negativeColor, softThreshold,
  3058. * threshold, zoneAxis, zones, boostBlending
  3059. * @requires highcharts-more
  3060. * @optionparent plotOptions.columnpyramid
  3061. */
  3062. ColumnPyramidSeries.defaultOptions = merge(ColumnSeries.defaultOptions, {
  3063. // Nothing here
  3064. });
  3065. return ColumnPyramidSeries;
  3066. }(ColumnSeries));
  3067. SeriesRegistry.registerSeriesType('columnpyramid', ColumnPyramidSeries);
  3068. /* *
  3069. *
  3070. * Default export
  3071. *
  3072. * */
  3073. /* *
  3074. *
  3075. * API Options
  3076. *
  3077. * */
  3078. /**
  3079. * A `columnpyramid` series. If the [type](#series.columnpyramid.type) option is
  3080. * not specified, it is inherited from [chart.type](#chart.type).
  3081. *
  3082. * @extends series,plotOptions.columnpyramid
  3083. * @excluding connectEnds, connectNulls, dashStyle, dataParser, dataURL,
  3084. * gapSize, gapUnit, linecap, lineWidth, marker, step,
  3085. * boostThreshold, boostBlending
  3086. * @product highcharts highstock
  3087. * @requires highcharts-more
  3088. * @apioption series.columnpyramid
  3089. */
  3090. /**
  3091. * @excluding halo, lineWidth, lineWidthPlus, marker
  3092. * @product highcharts highstock
  3093. * @apioption series.columnpyramid.states.hover
  3094. */
  3095. /**
  3096. * @excluding halo, lineWidth, lineWidthPlus, marker
  3097. * @product highcharts highstock
  3098. * @apioption series.columnpyramid.states.select
  3099. */
  3100. /**
  3101. * An array of data points for the series. For the `columnpyramid` series type,
  3102. * points can be given in the following ways:
  3103. *
  3104. * 1. An array of numerical values. In this case, the numerical values will be
  3105. * interpreted as `y` options. The `x` values will be automatically
  3106. * calculated, either starting at 0 and incremented by 1, or from
  3107. * `pointStart` and `pointInterval` given in the series options. If the axis
  3108. * has categories, these will be used. Example:
  3109. * ```js
  3110. * data: [0, 5, 3, 5]
  3111. * ```
  3112. *
  3113. * 2. An array of arrays with 2 values. In this case, the values correspond to
  3114. * `x,y`. If the first value is a string, it is applied as the name of the
  3115. * point, and the `x` value is inferred.
  3116. * ```js
  3117. * data: [
  3118. * [0, 6],
  3119. * [1, 2],
  3120. * [2, 6]
  3121. * ]
  3122. * ```
  3123. *
  3124. * 3. An array of objects with named values. The objects are point configuration
  3125. * objects as seen below. If the total number of data points exceeds the
  3126. * series' [turboThreshold](#series.columnpyramid.turboThreshold), this
  3127. * option is not available.
  3128. * ```js
  3129. * data: [{
  3130. * x: 1,
  3131. * y: 9,
  3132. * name: "Point2",
  3133. * color: "#00FF00"
  3134. * }, {
  3135. * x: 1,
  3136. * y: 6,
  3137. * name: "Point1",
  3138. * color: "#FF00FF"
  3139. * }]
  3140. * ```
  3141. *
  3142. * @sample {highcharts} highcharts/chart/reflow-true/
  3143. * Numerical values
  3144. * @sample {highcharts} highcharts/series/data-array-of-arrays/
  3145. * Arrays of numeric x and y
  3146. * @sample {highcharts} highcharts/series/data-array-of-arrays-datetime/
  3147. * Arrays of datetime x and y
  3148. * @sample {highcharts} highcharts/series/data-array-of-name-value/
  3149. * Arrays of point.name and y
  3150. * @sample {highcharts} highcharts/series/data-array-of-objects/
  3151. * Config objects
  3152. *
  3153. * @type {Array<number|Array<(number|string),(number|null)>|null|*>}
  3154. * @extends series.line.data
  3155. * @excluding marker
  3156. * @product highcharts highstock
  3157. * @apioption series.columnpyramid.data
  3158. */
  3159. ''; // adds doclets above to transpiled file;
  3160. return ColumnPyramidSeries;
  3161. });
  3162. _registerModule(_modules, 'Series/Gauge/GaugePoint.js', [_modules['Core/Series/SeriesRegistry.js']], function (SeriesRegistry) {
  3163. /* *
  3164. *
  3165. * (c) 2010-2021 Torstein Honsi
  3166. *
  3167. * License: www.highcharts.com/license
  3168. *
  3169. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  3170. *
  3171. * */
  3172. var __extends = (this && this.__extends) || (function () {
  3173. var extendStatics = function (d,
  3174. b) {
  3175. extendStatics = Object.setPrototypeOf ||
  3176. ({ __proto__: [] } instanceof Array && function (d,
  3177. b) { d.__proto__ = b; }) ||
  3178. function (d,
  3179. b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  3180. return extendStatics(d, b);
  3181. };
  3182. return function (d, b) {
  3183. extendStatics(d, b);
  3184. function __() { this.constructor = d; }
  3185. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  3186. };
  3187. })();
  3188. var Point = SeriesRegistry.series.prototype.pointClass;
  3189. /* *
  3190. *
  3191. * Class
  3192. *
  3193. * */
  3194. var GaugePoint = /** @class */ (function (_super) {
  3195. __extends(GaugePoint, _super);
  3196. function GaugePoint() {
  3197. /* *
  3198. *
  3199. * Properties
  3200. *
  3201. * */
  3202. var _this = _super !== null && _super.apply(this,
  3203. arguments) || this;
  3204. _this.options = void 0;
  3205. _this.series = void 0;
  3206. _this.shapeArgs = void 0;
  3207. return _this;
  3208. /* eslint-enable valid-jsdoc */
  3209. }
  3210. /* *
  3211. *
  3212. * Functions
  3213. *
  3214. * */
  3215. /* eslint-disable valid-jsdoc */
  3216. /**
  3217. * Don't do any hover colors or anything
  3218. * @private
  3219. */
  3220. GaugePoint.prototype.setState = function (state) {
  3221. this.state = state;
  3222. };
  3223. return GaugePoint;
  3224. }(Point));
  3225. /* *
  3226. *
  3227. * Default export
  3228. *
  3229. * */
  3230. return GaugePoint;
  3231. });
  3232. _registerModule(_modules, 'Series/Gauge/GaugeSeries.js', [_modules['Series/Gauge/GaugePoint.js'], _modules['Core/Globals.js'], _modules['Core/Color/Palette.js'], _modules['Core/Series/SeriesRegistry.js'], _modules['Core/Utilities.js']], function (GaugePoint, H, palette, SeriesRegistry, U) {
  3233. /* *
  3234. *
  3235. * (c) 2010-2021 Torstein Honsi
  3236. *
  3237. * License: www.highcharts.com/license
  3238. *
  3239. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  3240. *
  3241. * */
  3242. var __extends = (this && this.__extends) || (function () {
  3243. var extendStatics = function (d,
  3244. b) {
  3245. extendStatics = Object.setPrototypeOf ||
  3246. ({ __proto__: [] } instanceof Array && function (d,
  3247. b) { d.__proto__ = b; }) ||
  3248. function (d,
  3249. b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  3250. return extendStatics(d, b);
  3251. };
  3252. return function (d, b) {
  3253. extendStatics(d, b);
  3254. function __() { this.constructor = d; }
  3255. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  3256. };
  3257. })();
  3258. var noop = H.noop;
  3259. var Series = SeriesRegistry.series,
  3260. ColumnSeries = SeriesRegistry.seriesTypes.column;
  3261. var clamp = U.clamp,
  3262. isNumber = U.isNumber,
  3263. extend = U.extend,
  3264. merge = U.merge,
  3265. pick = U.pick,
  3266. pInt = U.pInt;
  3267. /* *
  3268. *
  3269. * Class
  3270. *
  3271. * */
  3272. /**
  3273. *
  3274. * The `gauge` series type
  3275. *
  3276. * @private
  3277. * @class
  3278. * @name Highcharts.seriesTypes.map
  3279. *
  3280. * @augments Highcharts.Series
  3281. */
  3282. var GaugeSeries = /** @class */ (function (_super) {
  3283. __extends(GaugeSeries, _super);
  3284. function GaugeSeries() {
  3285. /* *
  3286. *
  3287. * Static properties
  3288. *
  3289. * */
  3290. var _this = _super !== null && _super.apply(this,
  3291. arguments) || this;
  3292. /* *
  3293. *
  3294. * Properties
  3295. *
  3296. * */
  3297. _this.data = void 0;
  3298. _this.points = void 0;
  3299. _this.options = void 0;
  3300. _this.yAxis = void 0;
  3301. return _this;
  3302. /* eslint-enable valid-jsdoc */
  3303. }
  3304. /* *
  3305. *
  3306. * Functions
  3307. *
  3308. * */
  3309. /* eslint-disable valid-jsdoc */
  3310. /**
  3311. * Calculate paths etc
  3312. * @private
  3313. */
  3314. GaugeSeries.prototype.translate = function () {
  3315. var series = this,
  3316. yAxis = series.yAxis,
  3317. options = series.options,
  3318. center = yAxis.center;
  3319. series.generatePoints();
  3320. series.points.forEach(function (point) {
  3321. var dialOptions = merge(options.dial,
  3322. point.dial),
  3323. radius = ((pInt(pick(dialOptions.radius, '80%')) * center[2]) /
  3324. 200),
  3325. baseLength = ((pInt(pick(dialOptions.baseLength, '70%')) * radius) /
  3326. 100),
  3327. rearLength = ((pInt(pick(dialOptions.rearLength, '10%')) * radius) /
  3328. 100),
  3329. baseWidth = dialOptions.baseWidth || 3,
  3330. topWidth = dialOptions.topWidth || 1,
  3331. overshoot = options.overshoot,
  3332. rotation = yAxis.startAngleRad + yAxis.translate(point.y,
  3333. null,
  3334. null,
  3335. null,
  3336. true);
  3337. // Handle the wrap and overshoot options
  3338. if (isNumber(overshoot) || options.wrap === false) {
  3339. overshoot = isNumber(overshoot) ?
  3340. (overshoot / 180 * Math.PI) : 0;
  3341. rotation = clamp(rotation, yAxis.startAngleRad - overshoot, yAxis.endAngleRad + overshoot);
  3342. }
  3343. rotation = rotation * 180 / Math.PI;
  3344. point.shapeType = 'path';
  3345. var d = dialOptions.path || [
  3346. ['M', -rearLength, -baseWidth / 2],
  3347. ['L',
  3348. baseLength, -baseWidth / 2],
  3349. ['L',
  3350. radius, -topWidth / 2],
  3351. ['L',
  3352. radius,
  3353. topWidth / 2],
  3354. ['L',
  3355. baseLength,
  3356. baseWidth / 2],
  3357. ['L', -rearLength,
  3358. baseWidth / 2],
  3359. ['Z']
  3360. ];
  3361. point.shapeArgs = {
  3362. d: d,
  3363. translateX: center[0],
  3364. translateY: center[1],
  3365. rotation: rotation
  3366. };
  3367. // Positions for data label
  3368. point.plotX = center[0];
  3369. point.plotY = center[1];
  3370. });
  3371. };
  3372. /**
  3373. * Draw the points where each point is one needle
  3374. * @private
  3375. */
  3376. GaugeSeries.prototype.drawPoints = function () {
  3377. var series = this,
  3378. chart = series.chart,
  3379. center = series.yAxis.center,
  3380. pivot = series.pivot,
  3381. options = series.options,
  3382. pivotOptions = options.pivot,
  3383. renderer = chart.renderer;
  3384. series.points.forEach(function (point) {
  3385. var graphic = point.graphic,
  3386. shapeArgs = point.shapeArgs,
  3387. d = shapeArgs.d,
  3388. dialOptions = merge(options.dial,
  3389. point.dial); // #1233
  3390. if (graphic) {
  3391. graphic.animate(shapeArgs);
  3392. shapeArgs.d = d; // animate alters it
  3393. }
  3394. else {
  3395. point.graphic =
  3396. renderer[point.shapeType](shapeArgs)
  3397. .attr({
  3398. // required by VML when animation is false
  3399. rotation: shapeArgs.rotation,
  3400. zIndex: 1
  3401. })
  3402. .addClass('highcharts-dial')
  3403. .add(series.group);
  3404. }
  3405. // Presentational attributes
  3406. if (!chart.styledMode) {
  3407. point.graphic[graphic ? 'animate' : 'attr']({
  3408. stroke: dialOptions.borderColor || 'none',
  3409. 'stroke-width': dialOptions.borderWidth || 0,
  3410. fill: dialOptions.backgroundColor ||
  3411. palette.neutralColor100
  3412. });
  3413. }
  3414. });
  3415. // Add or move the pivot
  3416. if (pivot) {
  3417. pivot.animate({
  3418. translateX: center[0],
  3419. translateY: center[1]
  3420. });
  3421. }
  3422. else {
  3423. series.pivot =
  3424. renderer.circle(0, 0, pick(pivotOptions.radius, 5))
  3425. .attr({
  3426. zIndex: 2
  3427. })
  3428. .addClass('highcharts-pivot')
  3429. .translate(center[0], center[1])
  3430. .add(series.group);
  3431. // Presentational attributes
  3432. if (!chart.styledMode) {
  3433. series.pivot.attr({
  3434. 'stroke-width': pivotOptions.borderWidth || 0,
  3435. stroke: pivotOptions.borderColor ||
  3436. palette.neutralColor20,
  3437. fill: pivotOptions.backgroundColor ||
  3438. palette.neutralColor100
  3439. });
  3440. }
  3441. }
  3442. };
  3443. /**
  3444. * Animate the arrow up from startAngle
  3445. * @private
  3446. */
  3447. GaugeSeries.prototype.animate = function (init) {
  3448. var series = this;
  3449. if (!init) {
  3450. series.points.forEach(function (point) {
  3451. var graphic = point.graphic;
  3452. if (graphic) {
  3453. // start value
  3454. graphic.attr({
  3455. rotation: series.yAxis.startAngleRad * 180 / Math.PI
  3456. });
  3457. // animate
  3458. graphic.animate({
  3459. rotation: point.shapeArgs.rotation
  3460. }, series.options.animation);
  3461. }
  3462. });
  3463. }
  3464. };
  3465. /**
  3466. * @private
  3467. */
  3468. GaugeSeries.prototype.render = function () {
  3469. this.group = this.plotGroup('group', 'series', this.visible ? 'visible' : 'hidden', this.options.zIndex, this.chart.seriesGroup);
  3470. Series.prototype.render.call(this);
  3471. this.group.clip(this.chart.clipRect);
  3472. };
  3473. /**
  3474. * Extend the basic setData method by running processData and generatePoints
  3475. * immediately, in order to access the points from the legend.
  3476. * @private
  3477. */
  3478. GaugeSeries.prototype.setData = function (data, redraw) {
  3479. Series.prototype.setData.call(this, data, false);
  3480. this.processData();
  3481. this.generatePoints();
  3482. if (pick(redraw, true)) {
  3483. this.chart.redraw();
  3484. }
  3485. };
  3486. /**
  3487. * Define hasData function for non-cartesian series.
  3488. * Returns true if the series has points at all.
  3489. * @private
  3490. */
  3491. GaugeSeries.prototype.hasData = function () {
  3492. return !!this.points.length; // != 0
  3493. };
  3494. /**
  3495. * Gauges are circular plots displaying one or more values with a dial
  3496. * pointing to values along the perimeter.
  3497. *
  3498. * @sample highcharts/demo/gauge-speedometer/
  3499. * Gauge chart
  3500. *
  3501. * @extends plotOptions.line
  3502. * @excluding animationLimit, boostThreshold, colorAxis, colorKey,
  3503. * connectEnds, connectNulls, cropThreshold, dashStyle,
  3504. * dragDrop, findNearestPointBy, getExtremesFromAll, marker,
  3505. * negativeColor, pointPlacement, shadow, softThreshold,
  3506. * stacking, states, step, threshold, turboThreshold, xAxis,
  3507. * zoneAxis, zones, dataSorting, boostBlending
  3508. * @product highcharts
  3509. * @requires highcharts-more
  3510. * @optionparent plotOptions.gauge
  3511. */
  3512. GaugeSeries.defaultOptions = merge(Series.defaultOptions, {
  3513. /**
  3514. * When this option is `true`, the dial will wrap around the axes.
  3515. * For instance, in a full-range gauge going from 0 to 360, a value
  3516. * of 400 will point to 40\. When `wrap` is `false`, the dial stops
  3517. * at 360.
  3518. *
  3519. * @see [overshoot](#plotOptions.gauge.overshoot)
  3520. *
  3521. * @type {boolean}
  3522. * @default true
  3523. * @since 3.0
  3524. * @product highcharts
  3525. * @apioption plotOptions.gauge.wrap
  3526. */
  3527. /**
  3528. * Data labels for the gauge. For gauges, the data labels are
  3529. * enabled by default and shown in a bordered box below the point.
  3530. *
  3531. * @since 2.3.0
  3532. * @product highcharts
  3533. */
  3534. dataLabels: {
  3535. borderColor: palette.neutralColor20,
  3536. borderRadius: 3,
  3537. borderWidth: 1,
  3538. crop: false,
  3539. defer: false,
  3540. enabled: true,
  3541. verticalAlign: 'top',
  3542. y: 15,
  3543. zIndex: 2
  3544. },
  3545. /**
  3546. * Options for the dial or arrow pointer of the gauge.
  3547. *
  3548. * In styled mode, the dial is styled with the
  3549. * `.highcharts-gauge-series .highcharts-dial` rule.
  3550. *
  3551. * @sample {highcharts} highcharts/css/gauge/
  3552. * Styled mode
  3553. *
  3554. * @type {*}
  3555. * @since 2.3.0
  3556. * @product highcharts
  3557. */
  3558. dial: {},
  3559. /**
  3560. * The length of the dial's base part, relative to the total radius
  3561. * or length of the dial.
  3562. *
  3563. * @sample {highcharts} highcharts/plotoptions/gauge-dial/
  3564. * Dial options demonstrated
  3565. *
  3566. * @type {string}
  3567. * @default 70%
  3568. * @since 2.3.0
  3569. * @product highcharts
  3570. * @apioption plotOptions.gauge.dial.baseLength
  3571. */
  3572. /**
  3573. * The pixel width of the base of the gauge dial. The base is the
  3574. * part closest to the pivot, defined by baseLength.
  3575. *
  3576. * @sample {highcharts} highcharts/plotoptions/gauge-dial/
  3577. * Dial options demonstrated
  3578. *
  3579. * @type {number}
  3580. * @default 3
  3581. * @since 2.3.0
  3582. * @product highcharts
  3583. * @apioption plotOptions.gauge.dial.baseWidth
  3584. */
  3585. /**
  3586. * The radius or length of the dial, in percentages relative to the
  3587. * radius of the gauge itself.
  3588. *
  3589. * @sample {highcharts} highcharts/plotoptions/gauge-dial/
  3590. * Dial options demonstrated
  3591. *
  3592. * @type {string}
  3593. * @default 80%
  3594. * @since 2.3.0
  3595. * @product highcharts
  3596. * @apioption plotOptions.gauge.dial.radius
  3597. */
  3598. /**
  3599. * The length of the dial's rear end, the part that extends out on
  3600. * the other side of the pivot. Relative to the dial's length.
  3601. *
  3602. * @sample {highcharts} highcharts/plotoptions/gauge-dial/
  3603. * Dial options demonstrated
  3604. *
  3605. * @type {string}
  3606. * @default 10%
  3607. * @since 2.3.0
  3608. * @product highcharts
  3609. * @apioption plotOptions.gauge.dial.rearLength
  3610. */
  3611. /**
  3612. * The width of the top of the dial, closest to the perimeter. The
  3613. * pivot narrows in from the base to the top.
  3614. *
  3615. * @sample {highcharts} highcharts/plotoptions/gauge-dial/
  3616. * Dial options demonstrated
  3617. *
  3618. * @type {number}
  3619. * @default 1
  3620. * @since 2.3.0
  3621. * @product highcharts
  3622. * @apioption plotOptions.gauge.dial.topWidth
  3623. */
  3624. /**
  3625. * The background or fill color of the gauge's dial.
  3626. *
  3627. * @sample {highcharts} highcharts/plotoptions/gauge-dial/
  3628. * Dial options demonstrated
  3629. *
  3630. * @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
  3631. * @default #000000
  3632. * @since 2.3.0
  3633. * @product highcharts
  3634. * @apioption plotOptions.gauge.dial.backgroundColor
  3635. */
  3636. /**
  3637. * The border color or stroke of the gauge's dial. By default, the
  3638. * borderWidth is 0, so this must be set in addition to a custom
  3639. * border color.
  3640. *
  3641. * @sample {highcharts} highcharts/plotoptions/gauge-dial/
  3642. * Dial options demonstrated
  3643. *
  3644. * @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
  3645. * @default #cccccc
  3646. * @since 2.3.0
  3647. * @product highcharts
  3648. * @apioption plotOptions.gauge.dial.borderColor
  3649. */
  3650. /**
  3651. * The width of the gauge dial border in pixels.
  3652. *
  3653. * @sample {highcharts} highcharts/plotoptions/gauge-dial/
  3654. * Dial options demonstrated
  3655. *
  3656. * @type {number}
  3657. * @default 0
  3658. * @since 2.3.0
  3659. * @product highcharts
  3660. * @apioption plotOptions.gauge.dial.borderWidth
  3661. */
  3662. /**
  3663. * Allow the dial to overshoot the end of the perimeter axis by
  3664. * this many degrees. Say if the gauge axis goes from 0 to 60, a
  3665. * value of 100, or 1000, will show 5 degrees beyond the end of the
  3666. * axis when this option is set to 5.
  3667. *
  3668. * @see [wrap](#plotOptions.gauge.wrap)
  3669. *
  3670. * @sample {highcharts} highcharts/plotoptions/gauge-overshoot/
  3671. * Allow 5 degrees overshoot
  3672. *
  3673. * @type {number}
  3674. * @since 3.0.10
  3675. * @product highcharts
  3676. * @apioption plotOptions.gauge.overshoot
  3677. */
  3678. /**
  3679. * Options for the pivot or the center point of the gauge.
  3680. *
  3681. * In styled mode, the pivot is styled with the
  3682. * `.highcharts-gauge-series .highcharts-pivot` rule.
  3683. *
  3684. * @sample {highcharts} highcharts/css/gauge/
  3685. * Styled mode
  3686. *
  3687. * @type {*}
  3688. * @since 2.3.0
  3689. * @product highcharts
  3690. */
  3691. pivot: {},
  3692. /**
  3693. * The pixel radius of the pivot.
  3694. *
  3695. * @sample {highcharts} highcharts/plotoptions/gauge-pivot/
  3696. * Pivot options demonstrated
  3697. *
  3698. * @type {number}
  3699. * @default 5
  3700. * @since 2.3.0
  3701. * @product highcharts
  3702. * @apioption plotOptions.gauge.pivot.radius
  3703. */
  3704. /**
  3705. * The border or stroke width of the pivot.
  3706. *
  3707. * @sample {highcharts} highcharts/plotoptions/gauge-pivot/
  3708. * Pivot options demonstrated
  3709. *
  3710. * @type {number}
  3711. * @default 0
  3712. * @since 2.3.0
  3713. * @product highcharts
  3714. * @apioption plotOptions.gauge.pivot.borderWidth
  3715. */
  3716. /**
  3717. * The border or stroke color of the pivot. In able to change this,
  3718. * the borderWidth must also be set to something other than the
  3719. * default 0.
  3720. *
  3721. * @sample {highcharts} highcharts/plotoptions/gauge-pivot/
  3722. * Pivot options demonstrated
  3723. *
  3724. * @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
  3725. * @default #cccccc
  3726. * @since 2.3.0
  3727. * @product highcharts
  3728. * @apioption plotOptions.gauge.pivot.borderColor
  3729. */
  3730. /**
  3731. * The background color or fill of the pivot.
  3732. *
  3733. * @sample {highcharts} highcharts/plotoptions/gauge-pivot/
  3734. * Pivot options demonstrated
  3735. *
  3736. * @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
  3737. * @default #000000
  3738. * @since 2.3.0
  3739. * @product highcharts
  3740. * @apioption plotOptions.gauge.pivot.backgroundColor
  3741. */
  3742. tooltip: {
  3743. headerFormat: ''
  3744. },
  3745. /**
  3746. * Whether to display this particular series or series type in the
  3747. * legend. Defaults to false for gauge series.
  3748. *
  3749. * @since 2.3.0
  3750. * @product highcharts
  3751. */
  3752. showInLegend: false
  3753. // Prototype members
  3754. });
  3755. return GaugeSeries;
  3756. }(Series));
  3757. extend(GaugeSeries.prototype, {
  3758. // chart.angular will be set to true when a gauge series is present,
  3759. // and this will be used on the axes
  3760. angular: true,
  3761. directTouch: true,
  3762. drawGraph: noop,
  3763. drawTracker: ColumnSeries.prototype.drawTracker,
  3764. fixedBox: true,
  3765. forceDL: true,
  3766. noSharedTooltip: true,
  3767. pointClass: GaugePoint,
  3768. trackerGroups: ['group', 'dataLabelsGroup']
  3769. });
  3770. SeriesRegistry.registerSeriesType('gauge', GaugeSeries);
  3771. /* *
  3772. *
  3773. * Default export
  3774. *
  3775. * */
  3776. /* *
  3777. *
  3778. * API options
  3779. *
  3780. * */
  3781. /**
  3782. * A `gauge` series. If the [type](#series.gauge.type) option is not
  3783. * specified, it is inherited from [chart.type](#chart.type).
  3784. *
  3785. * @extends series,plotOptions.gauge
  3786. * @excluding animationLimit, boostThreshold, connectEnds, connectNulls,
  3787. * cropThreshold, dashStyle, dataParser, dataURL, findNearestPointBy,
  3788. * getExtremesFromAll, marker, negativeColor, pointPlacement, shadow,
  3789. * softThreshold, stack, stacking, states, step, threshold,
  3790. * turboThreshold, zoneAxis, zones, dataSorting, boostBlending
  3791. * @product highcharts
  3792. * @requires highcharts-more
  3793. * @apioption series.gauge
  3794. */
  3795. /**
  3796. * An array of data points for the series. For the `gauge` series type,
  3797. * points can be given in the following ways:
  3798. *
  3799. * 1. An array of numerical values. In this case, the numerical values will be
  3800. * interpreted as `y` options. Example:
  3801. * ```js
  3802. * data: [0, 5, 3, 5]
  3803. * ```
  3804. *
  3805. * 2. An array of objects with named values. The following snippet shows only a
  3806. * few settings, see the complete options set below. If the total number of
  3807. * data points exceeds the series'
  3808. * [turboThreshold](#series.gauge.turboThreshold), this option is not
  3809. * available.
  3810. * ```js
  3811. * data: [{
  3812. * y: 6,
  3813. * name: "Point2",
  3814. * color: "#00FF00"
  3815. * }, {
  3816. * y: 8,
  3817. * name: "Point1",
  3818. * color: "#FF00FF"
  3819. * }]
  3820. * ```
  3821. *
  3822. * The typical gauge only contains a single data value.
  3823. *
  3824. * @sample {highcharts} highcharts/chart/reflow-true/
  3825. * Numerical values
  3826. * @sample {highcharts} highcharts/series/data-array-of-objects/
  3827. * Config objects
  3828. *
  3829. * @type {Array<number|null|*>}
  3830. * @extends series.line.data
  3831. * @excluding drilldown, marker, x
  3832. * @product highcharts
  3833. * @apioption series.gauge.data
  3834. */
  3835. ''; // adds the doclets above in the transpiled file
  3836. return GaugeSeries;
  3837. });
  3838. _registerModule(_modules, 'Series/BoxPlot/BoxPlotSeries.js', [_modules['Series/Column/ColumnSeries.js'], _modules['Core/Globals.js'], _modules['Core/Color/Palette.js'], _modules['Core/Series/SeriesRegistry.js'], _modules['Core/Utilities.js']], function (ColumnSeries, H, palette, SeriesRegistry, U) {
  3839. /* *
  3840. *
  3841. * (c) 2010-2021 Torstein Honsi
  3842. *
  3843. * License: www.highcharts.com/license
  3844. *
  3845. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  3846. *
  3847. * */
  3848. var __extends = (this && this.__extends) || (function () {
  3849. var extendStatics = function (d,
  3850. b) {
  3851. extendStatics = Object.setPrototypeOf ||
  3852. ({ __proto__: [] } instanceof Array && function (d,
  3853. b) { d.__proto__ = b; }) ||
  3854. function (d,
  3855. b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  3856. return extendStatics(d, b);
  3857. };
  3858. return function (d, b) {
  3859. extendStatics(d, b);
  3860. function __() { this.constructor = d; }
  3861. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  3862. };
  3863. })();
  3864. var noop = H.noop;
  3865. var extend = U.extend,
  3866. merge = U.merge,
  3867. pick = U.pick;
  3868. /**
  3869. * The boxplot series type.
  3870. *
  3871. * @private
  3872. * @class
  3873. * @name Highcharts.seriesTypes#boxplot
  3874. *
  3875. * @augments Highcharts.Series
  3876. */
  3877. /* *
  3878. *
  3879. * Class
  3880. *
  3881. * */
  3882. var BoxPlotSeries = /** @class */ (function (_super) {
  3883. __extends(BoxPlotSeries, _super);
  3884. function BoxPlotSeries() {
  3885. /* *
  3886. *
  3887. * Static Properties
  3888. *
  3889. * */
  3890. var _this = _super !== null && _super.apply(this,
  3891. arguments) || this;
  3892. /* *
  3893. *
  3894. * Properties
  3895. *
  3896. * */
  3897. _this.data = void 0;
  3898. _this.options = void 0;
  3899. _this.points = void 0;
  3900. return _this;
  3901. }
  3902. /* *
  3903. *
  3904. * Functions
  3905. *
  3906. * */
  3907. // Get presentational attributes
  3908. BoxPlotSeries.prototype.pointAttribs = function () {
  3909. // No attributes should be set on point.graphic which is the group
  3910. return {};
  3911. };
  3912. // Translate data points from raw values x and y to plotX and plotY
  3913. BoxPlotSeries.prototype.translate = function () {
  3914. var series = this,
  3915. yAxis = series.yAxis,
  3916. pointArrayMap = series.pointArrayMap;
  3917. _super.prototype.translate.apply(series);
  3918. // do the translation on each point dimension
  3919. series.points.forEach(function (point) {
  3920. pointArrayMap.forEach(function (key) {
  3921. if (point[key] !== null) {
  3922. point[key + 'Plot'] = yAxis.translate(point[key], 0, 1, 0, 1);
  3923. }
  3924. });
  3925. point.plotHigh = point.highPlot; // For data label validation
  3926. });
  3927. };
  3928. // eslint-disable-next-line valid-jsdoc
  3929. /**
  3930. * Draw the data points
  3931. * @private
  3932. */
  3933. BoxPlotSeries.prototype.drawPoints = function () {
  3934. var series = this,
  3935. points = series.points,
  3936. options = series.options,
  3937. chart = series.chart,
  3938. renderer = chart.renderer,
  3939. q1Plot,
  3940. q3Plot,
  3941. highPlot,
  3942. lowPlot,
  3943. medianPlot,
  3944. medianPath,
  3945. crispCorr,
  3946. crispX = 0,
  3947. boxPath,
  3948. width,
  3949. left,
  3950. right,
  3951. halfWidth,
  3952. // error bar inherits this series type but doesn't do quartiles
  3953. doQuartiles = series.doQuartiles !== false,
  3954. pointWiskerLength,
  3955. whiskerLength = series.options.whiskerLength;
  3956. points.forEach(function (point) {
  3957. var graphic = point.graphic,
  3958. verb = graphic ? 'animate' : 'attr',
  3959. shapeArgs = point.shapeArgs,
  3960. boxAttr = {},
  3961. stemAttr = {},
  3962. whiskersAttr = {},
  3963. medianAttr = {},
  3964. color = point.color || series.color;
  3965. if (typeof point.plotY !== 'undefined') {
  3966. // crisp vector coordinates
  3967. width = Math.round(shapeArgs.width);
  3968. left = Math.floor(shapeArgs.x);
  3969. right = left + width;
  3970. halfWidth = Math.round(width / 2);
  3971. q1Plot = Math.floor(doQuartiles ? point.q1Plot : point.lowPlot);
  3972. q3Plot = Math.floor(doQuartiles ? point.q3Plot : point.lowPlot);
  3973. highPlot = Math.floor(point.highPlot);
  3974. lowPlot = Math.floor(point.lowPlot);
  3975. if (!graphic) {
  3976. point.graphic = graphic = renderer.g('point')
  3977. .add(series.group);
  3978. point.stem = renderer.path()
  3979. .addClass('highcharts-boxplot-stem')
  3980. .add(graphic);
  3981. if (whiskerLength) {
  3982. point.whiskers = renderer.path()
  3983. .addClass('highcharts-boxplot-whisker')
  3984. .add(graphic);
  3985. }
  3986. if (doQuartiles) {
  3987. point.box = renderer.path(boxPath)
  3988. .addClass('highcharts-boxplot-box')
  3989. .add(graphic);
  3990. }
  3991. point.medianShape = renderer.path(medianPath)
  3992. .addClass('highcharts-boxplot-median')
  3993. .add(graphic);
  3994. }
  3995. if (!chart.styledMode) {
  3996. // Stem attributes
  3997. stemAttr.stroke =
  3998. point.stemColor || options.stemColor || color;
  3999. stemAttr['stroke-width'] = pick(point.stemWidth, options.stemWidth, options.lineWidth);
  4000. stemAttr.dashstyle = (point.stemDashStyle ||
  4001. options.stemDashStyle ||
  4002. options.dashStyle);
  4003. point.stem.attr(stemAttr);
  4004. // Whiskers attributes
  4005. if (whiskerLength) {
  4006. whiskersAttr.stroke = (point.whiskerColor ||
  4007. options.whiskerColor ||
  4008. color);
  4009. whiskersAttr['stroke-width'] = pick(point.whiskerWidth, options.whiskerWidth, options.lineWidth);
  4010. whiskersAttr.dashstyle = (point.whiskerDashStyle ||
  4011. options.whiskerDashStyle ||
  4012. options.dashStyle);
  4013. point.whiskers.attr(whiskersAttr);
  4014. }
  4015. if (doQuartiles) {
  4016. boxAttr.fill = (point.fillColor ||
  4017. options.fillColor ||
  4018. color);
  4019. boxAttr.stroke = options.lineColor || color;
  4020. boxAttr['stroke-width'] = options.lineWidth || 0;
  4021. boxAttr.dashstyle = (point.boxDashStyle ||
  4022. options.boxDashStyle ||
  4023. options.dashStyle);
  4024. point.box.attr(boxAttr);
  4025. }
  4026. // Median attributes
  4027. medianAttr.stroke = (point.medianColor ||
  4028. options.medianColor ||
  4029. color);
  4030. medianAttr['stroke-width'] = pick(point.medianWidth, options.medianWidth, options.lineWidth);
  4031. medianAttr.dashstyle = (point.medianDashStyle ||
  4032. options.medianDashStyle ||
  4033. options.dashStyle);
  4034. point.medianShape.attr(medianAttr);
  4035. }
  4036. var d = void 0;
  4037. // The stem
  4038. crispCorr = (point.stem.strokeWidth() % 2) / 2;
  4039. crispX = left + halfWidth + crispCorr;
  4040. d = [
  4041. // stem up
  4042. ['M', crispX, q3Plot],
  4043. ['L', crispX, highPlot],
  4044. // stem down
  4045. ['M', crispX, q1Plot],
  4046. ['L', crispX, lowPlot]
  4047. ];
  4048. point.stem[verb]({ d: d });
  4049. // The box
  4050. if (doQuartiles) {
  4051. crispCorr = (point.box.strokeWidth() % 2) / 2;
  4052. q1Plot = Math.floor(q1Plot) + crispCorr;
  4053. q3Plot = Math.floor(q3Plot) + crispCorr;
  4054. left += crispCorr;
  4055. right += crispCorr;
  4056. d = [
  4057. ['M', left, q3Plot],
  4058. ['L', left, q1Plot],
  4059. ['L', right, q1Plot],
  4060. ['L', right, q3Plot],
  4061. ['L', left, q3Plot],
  4062. ['Z']
  4063. ];
  4064. point.box[verb]({ d: d });
  4065. }
  4066. // The whiskers
  4067. if (whiskerLength) {
  4068. crispCorr = (point.whiskers.strokeWidth() % 2) / 2;
  4069. highPlot = highPlot + crispCorr;
  4070. lowPlot = lowPlot + crispCorr;
  4071. pointWiskerLength = (/%$/).test(whiskerLength) ?
  4072. halfWidth * parseFloat(whiskerLength) / 100 :
  4073. whiskerLength / 2;
  4074. d = [
  4075. // High whisker
  4076. ['M', crispX - pointWiskerLength, highPlot],
  4077. ['L', crispX + pointWiskerLength, highPlot],
  4078. // Low whisker
  4079. ['M', crispX - pointWiskerLength, lowPlot],
  4080. ['L', crispX + pointWiskerLength, lowPlot]
  4081. ];
  4082. point.whiskers[verb]({ d: d });
  4083. }
  4084. // The median
  4085. medianPlot = Math.round(point.medianPlot);
  4086. crispCorr = (point.medianShape.strokeWidth() % 2) / 2;
  4087. medianPlot = medianPlot + crispCorr;
  4088. d = [
  4089. ['M', left, medianPlot],
  4090. ['L', right, medianPlot]
  4091. ];
  4092. point.medianShape[verb]({ d: d });
  4093. }
  4094. });
  4095. };
  4096. // return a plain array for speedy calculation
  4097. BoxPlotSeries.prototype.toYData = function (point) {
  4098. return [point.low, point.q1, point.median, point.q3, point.high];
  4099. };
  4100. /**
  4101. * A box plot is a convenient way of depicting groups of data through their
  4102. * five-number summaries: the smallest observation (sample minimum), lower
  4103. * quartile (Q1), median (Q2), upper quartile (Q3), and largest observation
  4104. * (sample maximum).
  4105. *
  4106. * @sample highcharts/demo/box-plot/
  4107. * Box plot
  4108. *
  4109. * @extends plotOptions.column
  4110. * @excluding borderColor, borderRadius, borderWidth, groupZPadding,
  4111. * states, boostThreshold, boostBlending
  4112. * @product highcharts
  4113. * @requires highcharts-more
  4114. * @optionparent plotOptions.boxplot
  4115. */
  4116. BoxPlotSeries.defaultOptions = merge(ColumnSeries.defaultOptions, {
  4117. threshold: null,
  4118. tooltip: {
  4119. pointFormat: '<span style="color:{point.color}">\u25CF</span> <b> ' +
  4120. '{series.name}</b><br/>' +
  4121. 'Maximum: {point.high}<br/>' +
  4122. 'Upper quartile: {point.q3}<br/>' +
  4123. 'Median: {point.median}<br/>' +
  4124. 'Lower quartile: {point.q1}<br/>' +
  4125. 'Minimum: {point.low}<br/>'
  4126. },
  4127. /**
  4128. * The length of the whiskers, the horizontal lines marking low and
  4129. * high values. It can be a numerical pixel value, or a percentage
  4130. * value of the box width. Set `0` to disable whiskers.
  4131. *
  4132. * @sample {highcharts} highcharts/plotoptions/box-plot-styling/
  4133. * True by default
  4134. *
  4135. * @type {number|string}
  4136. * @since 3.0
  4137. * @product highcharts
  4138. */
  4139. whiskerLength: '50%',
  4140. /**
  4141. * The fill color of the box.
  4142. *
  4143. * In styled mode, the fill color can be set with the
  4144. * `.highcharts-boxplot-box` class.
  4145. *
  4146. * @sample {highcharts} highcharts/plotoptions/box-plot-styling/
  4147. * Box plot styling
  4148. *
  4149. * @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
  4150. * @default #ffffff
  4151. * @since 3.0
  4152. * @product highcharts
  4153. */
  4154. fillColor: palette.backgroundColor,
  4155. /**
  4156. * The width of the line surrounding the box. If any of
  4157. * [stemWidth](#plotOptions.boxplot.stemWidth),
  4158. * [medianWidth](#plotOptions.boxplot.medianWidth)
  4159. * or [whiskerWidth](#plotOptions.boxplot.whiskerWidth) are `null`,
  4160. * the lineWidth also applies to these lines.
  4161. *
  4162. * @sample {highcharts} highcharts/plotoptions/box-plot-styling/
  4163. * Box plot styling
  4164. * @sample {highcharts} highcharts/plotoptions/error-bar-styling/
  4165. * Error bar styling
  4166. *
  4167. * @since 3.0
  4168. * @product highcharts
  4169. */
  4170. lineWidth: 1,
  4171. /**
  4172. * The color of the median line. If `undefined`, the general series
  4173. * color applies.
  4174. *
  4175. * In styled mode, the median stroke width can be set with the
  4176. * `.highcharts-boxplot-median` class.
  4177. *
  4178. * @sample {highcharts} highcharts/plotoptions/box-plot-styling/
  4179. * Box plot styling
  4180. * @sample {highcharts} highcharts/css/boxplot/
  4181. * Box plot in styled mode
  4182. * @sample {highcharts} highcharts/plotoptions/error-bar-styling/
  4183. * Error bar styling
  4184. *
  4185. * @type {Highcharts.ColorString|Highcharts.GradientColorObject}
  4186. * @since 3.0
  4187. * @product highcharts
  4188. * @apioption plotOptions.boxplot.medianColor
  4189. */
  4190. /**
  4191. * The pixel width of the median line. If `null`, the
  4192. * [lineWidth](#plotOptions.boxplot.lineWidth) is used.
  4193. *
  4194. * In styled mode, the median stroke width can be set with the
  4195. * `.highcharts-boxplot-median` class.
  4196. *
  4197. * @sample {highcharts} highcharts/plotoptions/box-plot-styling/
  4198. * Box plot styling
  4199. * @sample {highcharts} highcharts/css/boxplot/
  4200. * Box plot in styled mode
  4201. *
  4202. * @type {number|null}
  4203. * @since 3.0
  4204. * @product highcharts
  4205. */
  4206. medianWidth: 2,
  4207. /*
  4208. // States are not working and are removed from docs.
  4209. // Refer to: #2340
  4210. states: {
  4211. hover: {
  4212. brightness: -0.3
  4213. }
  4214. },
  4215. /**
  4216. * The color of the stem, the vertical line extending from the box to
  4217. * the whiskers. If `undefined`, the series color is used.
  4218. *
  4219. * In styled mode, the stem stroke can be set with the
  4220. * `.highcharts-boxplot-stem` class.
  4221. *
  4222. * @sample {highcharts} highcharts/plotoptions/box-plot-styling/
  4223. * Box plot styling
  4224. * @sample {highcharts} highcharts/css/boxplot/
  4225. * Box plot in styled mode
  4226. * @sample {highcharts} highcharts/plotoptions/error-bar-styling/
  4227. * Error bar styling
  4228. *
  4229. * @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
  4230. * @since 3.0
  4231. * @product highcharts
  4232. * @apioption plotOptions.boxplot.stemColor
  4233. */
  4234. /**
  4235. * The dash style of the box.
  4236. *
  4237. * @sample {highcharts} highcharts/plotoptions/box-plot-styling/
  4238. * Box plot styling
  4239. * @sample {highcharts} highcharts/css/boxplot/
  4240. * Box plot in styled mode
  4241. *
  4242. * @type {Highcharts.DashStyleValue}
  4243. * @default Solid
  4244. * @since 8.1.0
  4245. * @product highcharts
  4246. * @apioption plotOptions.boxplot.boxDashStyle
  4247. */
  4248. /**
  4249. * The dash style of the median.
  4250. *
  4251. * @sample {highcharts} highcharts/plotoptions/box-plot-styling/
  4252. * Box plot styling
  4253. * @sample {highcharts} highcharts/css/boxplot/
  4254. * Box plot in styled mode
  4255. *
  4256. * @type {Highcharts.DashStyleValue}
  4257. * @default Solid
  4258. * @since 8.1.0
  4259. * @product highcharts
  4260. * @apioption plotOptions.boxplot.medianDashStyle
  4261. */
  4262. /**
  4263. * The dash style of the stem, the vertical line extending from the
  4264. * box to the whiskers.
  4265. *
  4266. * @sample {highcharts} highcharts/plotoptions/box-plot-styling/
  4267. * Box plot styling
  4268. * @sample {highcharts} highcharts/css/boxplot/
  4269. * Box plot in styled mode
  4270. * @sample {highcharts} highcharts/plotoptions/error-bar-styling/
  4271. * Error bar styling
  4272. *
  4273. * @type {Highcharts.DashStyleValue}
  4274. * @default Solid
  4275. * @since 3.0
  4276. * @product highcharts
  4277. * @apioption plotOptions.boxplot.stemDashStyle
  4278. */
  4279. /**
  4280. * The dash style of the whiskers.
  4281. *
  4282. * @sample {highcharts} highcharts/plotoptions/box-plot-styling/
  4283. * Box plot styling
  4284. * @sample {highcharts} highcharts/css/boxplot/
  4285. * Box plot in styled mode
  4286. *
  4287. * @type {Highcharts.DashStyleValue}
  4288. * @default Solid
  4289. * @since 8.1.0
  4290. * @product highcharts
  4291. * @apioption plotOptions.boxplot.whiskerDashStyle
  4292. */
  4293. /**
  4294. * The width of the stem, the vertical line extending from the box to
  4295. * the whiskers. If `undefined`, the width is inherited from the
  4296. * [lineWidth](#plotOptions.boxplot.lineWidth) option.
  4297. *
  4298. * In styled mode, the stem stroke width can be set with the
  4299. * `.highcharts-boxplot-stem` class.
  4300. *
  4301. * @sample {highcharts} highcharts/plotoptions/box-plot-styling/
  4302. * Box plot styling
  4303. * @sample {highcharts} highcharts/css/boxplot/
  4304. * Box plot in styled mode
  4305. * @sample {highcharts} highcharts/plotoptions/error-bar-styling/
  4306. * Error bar styling
  4307. *
  4308. * @type {number}
  4309. * @since 3.0
  4310. * @product highcharts
  4311. * @apioption plotOptions.boxplot.stemWidth
  4312. */
  4313. /**
  4314. * @default high
  4315. * @apioption plotOptions.boxplot.colorKey
  4316. */
  4317. /**
  4318. * The color of the whiskers, the horizontal lines marking low and high
  4319. * values. When `undefined`, the general series color is used.
  4320. *
  4321. * In styled mode, the whisker stroke can be set with the
  4322. * `.highcharts-boxplot-whisker` class .
  4323. *
  4324. * @sample {highcharts} highcharts/plotoptions/box-plot-styling/
  4325. * Box plot styling
  4326. * @sample {highcharts} highcharts/css/boxplot/
  4327. * Box plot in styled mode
  4328. *
  4329. * @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
  4330. * @since 3.0
  4331. * @product highcharts
  4332. * @apioption plotOptions.boxplot.whiskerColor
  4333. */
  4334. /**
  4335. * The line width of the whiskers, the horizontal lines marking low and
  4336. * high values. When `undefined`, the general
  4337. * [lineWidth](#plotOptions.boxplot.lineWidth) applies.
  4338. *
  4339. * In styled mode, the whisker stroke width can be set with the
  4340. * `.highcharts-boxplot-whisker` class.
  4341. *
  4342. * @sample {highcharts} highcharts/plotoptions/box-plot-styling/
  4343. * Box plot styling
  4344. * @sample {highcharts} highcharts/css/boxplot/
  4345. * Box plot in styled mode
  4346. *
  4347. * @since 3.0
  4348. * @product highcharts
  4349. */
  4350. whiskerWidth: 2
  4351. });
  4352. return BoxPlotSeries;
  4353. }(ColumnSeries));
  4354. extend(BoxPlotSeries.prototype, {
  4355. // array point configs are mapped to this
  4356. pointArrayMap: ['low', 'q1', 'median', 'q3', 'high'],
  4357. // defines the top of the tracker
  4358. pointValKey: 'high',
  4359. // Disable data labels for box plot
  4360. drawDataLabels: noop,
  4361. setStackedPoints: noop // #3890
  4362. });
  4363. /* *
  4364. *
  4365. * Registry
  4366. *
  4367. * */
  4368. SeriesRegistry.registerSeriesType('boxplot', BoxPlotSeries);
  4369. /* *
  4370. *
  4371. * Default Export
  4372. *
  4373. * */
  4374. /* *
  4375. *
  4376. * API Options
  4377. *
  4378. * */
  4379. /**
  4380. * A `boxplot` series. If the [type](#series.boxplot.type) option is
  4381. * not specified, it is inherited from [chart.type](#chart.type).
  4382. *
  4383. * @extends series,plotOptions.boxplot
  4384. * @excluding dataParser, dataURL, marker, stack, stacking, states,
  4385. * boostThreshold, boostBlending
  4386. * @product highcharts
  4387. * @requires highcharts-more
  4388. * @apioption series.boxplot
  4389. */
  4390. /**
  4391. * An array of data points for the series. For the `boxplot` series
  4392. * type, points can be given in the following ways:
  4393. *
  4394. * 1. An array of arrays with 6 or 5 values. In this case, the values correspond
  4395. * to `x,low,q1,median,q3,high`. If the first value is a string, it is
  4396. * applied as the name of the point, and the `x` value is inferred. The `x`
  4397. * value can also be omitted, in which case the inner arrays should be of
  4398. * length 5. Then the `x` value is automatically calculated, either starting
  4399. * at 0 and incremented by 1, or from `pointStart` and `pointInterval` given
  4400. * in the series options.
  4401. * ```js
  4402. * data: [
  4403. * [0, 3, 0, 10, 3, 5],
  4404. * [1, 7, 8, 7, 2, 9],
  4405. * [2, 6, 9, 5, 1, 3]
  4406. * ]
  4407. * ```
  4408. *
  4409. * 2. An array of objects with named values. The following snippet shows only a
  4410. * few settings, see the complete options set below. If the total number of
  4411. * data points exceeds the series'
  4412. * [turboThreshold](#series.boxplot.turboThreshold), this option is not
  4413. * available.
  4414. * ```js
  4415. * data: [{
  4416. * x: 1,
  4417. * low: 4,
  4418. * q1: 9,
  4419. * median: 9,
  4420. * q3: 1,
  4421. * high: 10,
  4422. * name: "Point2",
  4423. * color: "#00FF00"
  4424. * }, {
  4425. * x: 1,
  4426. * low: 5,
  4427. * q1: 7,
  4428. * median: 3,
  4429. * q3: 6,
  4430. * high: 2,
  4431. * name: "Point1",
  4432. * color: "#FF00FF"
  4433. * }]
  4434. * ```
  4435. *
  4436. * @sample {highcharts} highcharts/series/data-array-of-arrays/
  4437. * Arrays of numeric x and y
  4438. * @sample {highcharts} highcharts/series/data-array-of-arrays-datetime/
  4439. * Arrays of datetime x and y
  4440. * @sample {highcharts} highcharts/series/data-array-of-name-value/
  4441. * Arrays of point.name and y
  4442. * @sample {highcharts} highcharts/series/data-array-of-objects/
  4443. * Config objects
  4444. *
  4445. * @type {Array<Array<(number|string),number,number,number,number>|Array<(number|string),number,number,number,number,number>|*>}
  4446. * @extends series.line.data
  4447. * @excluding marker
  4448. * @product highcharts
  4449. * @apioption series.boxplot.data
  4450. */
  4451. /**
  4452. * The `high` value for each data point, signifying the highest value
  4453. * in the sample set. The top whisker is drawn here.
  4454. *
  4455. * @type {number}
  4456. * @product highcharts
  4457. * @apioption series.boxplot.data.high
  4458. */
  4459. /**
  4460. * The `low` value for each data point, signifying the lowest value
  4461. * in the sample set. The bottom whisker is drawn here.
  4462. *
  4463. * @type {number}
  4464. * @product highcharts
  4465. * @apioption series.boxplot.data.low
  4466. */
  4467. /**
  4468. * The median for each data point. This is drawn as a line through the
  4469. * middle area of the box.
  4470. *
  4471. * @type {number}
  4472. * @product highcharts
  4473. * @apioption series.boxplot.data.median
  4474. */
  4475. /**
  4476. * The lower quartile for each data point. This is the bottom of the
  4477. * box.
  4478. *
  4479. * @type {number}
  4480. * @product highcharts
  4481. * @apioption series.boxplot.data.q1
  4482. */
  4483. /**
  4484. * The higher quartile for each data point. This is the top of the box.
  4485. *
  4486. * @type {number}
  4487. * @product highcharts
  4488. * @apioption series.boxplot.data.q3
  4489. */
  4490. /**
  4491. * The dash style of the box.
  4492. *
  4493. * @sample {highcharts} highcharts/plotoptions/box-plot-styling/
  4494. * Box plot styling
  4495. * @sample {highcharts} highcharts/css/boxplot/
  4496. * Box plot in styled mode
  4497. *
  4498. * @type {Highcharts.DashStyleValue}
  4499. * @default Solid
  4500. * @since 8.1.0
  4501. * @product highcharts
  4502. * @apioption series.boxplot.data.boxDashStyle
  4503. */
  4504. /**
  4505. * The dash style of the median.
  4506. *
  4507. * @sample {highcharts} highcharts/plotoptions/box-plot-styling/
  4508. * Box plot styling
  4509. * @sample {highcharts} highcharts/css/boxplot/
  4510. * Box plot in styled mode
  4511. *
  4512. * @type {Highcharts.DashStyleValue}
  4513. * @default Solid
  4514. * @since 8.1.0
  4515. * @product highcharts
  4516. * @apioption series.boxplot.data.medianDashStyle
  4517. */
  4518. /**
  4519. * The dash style of the stem.
  4520. *
  4521. * @sample {highcharts} highcharts/plotoptions/box-plot-styling/
  4522. * Box plot styling
  4523. * @sample {highcharts} highcharts/css/boxplot/
  4524. * Box plot in styled mode
  4525. *
  4526. * @type {Highcharts.DashStyleValue}
  4527. * @default Solid
  4528. * @since 8.1.0
  4529. * @product highcharts
  4530. * @apioption series.boxplot.data.stemDashStyle
  4531. */
  4532. /**
  4533. * The dash style of the whiskers.
  4534. *
  4535. * @sample {highcharts} highcharts/plotoptions/box-plot-styling/
  4536. * Box plot styling
  4537. * @sample {highcharts} highcharts/css/boxplot/
  4538. * Box plot in styled mode
  4539. *
  4540. * @type {Highcharts.DashStyleValue}
  4541. * @default Solid
  4542. * @since 8.1.0
  4543. * @product highcharts
  4544. * @apioption series.boxplot.data.whiskerDashStyle
  4545. */
  4546. ''; // adds doclets above to transpiled file
  4547. return BoxPlotSeries;
  4548. });
  4549. _registerModule(_modules, 'Series/ErrorBar/ErrorBarSeries.js', [_modules['Series/BoxPlot/BoxPlotSeries.js'], _modules['Series/Column/ColumnSeries.js'], _modules['Core/Color/Palette.js'], _modules['Core/Series/SeriesRegistry.js'], _modules['Core/Utilities.js']], function (BoxPlotSeries, ColumnSeries, palette, SeriesRegistry, U) {
  4550. /* *
  4551. *
  4552. * (c) 2010-2021 Torstein Honsi
  4553. *
  4554. * License: www.highcharts.com/license
  4555. *
  4556. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  4557. *
  4558. * */
  4559. var __extends = (this && this.__extends) || (function () {
  4560. var extendStatics = function (d,
  4561. b) {
  4562. extendStatics = Object.setPrototypeOf ||
  4563. ({ __proto__: [] } instanceof Array && function (d,
  4564. b) { d.__proto__ = b; }) ||
  4565. function (d,
  4566. b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  4567. return extendStatics(d, b);
  4568. };
  4569. return function (d, b) {
  4570. extendStatics(d, b);
  4571. function __() { this.constructor = d; }
  4572. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  4573. };
  4574. })();
  4575. var AreaRangeSeries = SeriesRegistry.seriesTypes.arearange;
  4576. var merge = U.merge,
  4577. extend = U.extend;
  4578. /**
  4579. * Errorbar series type
  4580. *
  4581. * @private
  4582. * @class
  4583. * @name Highcharts.seriesTypes.errorbar
  4584. *
  4585. * @augments Highcharts.Series
  4586. *
  4587. */
  4588. var ErrorBarSeries = /** @class */ (function (_super) {
  4589. __extends(ErrorBarSeries, _super);
  4590. function ErrorBarSeries() {
  4591. /* *
  4592. *
  4593. * Static properties
  4594. *
  4595. * */
  4596. var _this = _super !== null && _super.apply(this,
  4597. arguments) || this;
  4598. /* *
  4599. *
  4600. * Properties
  4601. *
  4602. * */
  4603. _this.data = void 0;
  4604. _this.options = void 0;
  4605. _this.points = void 0;
  4606. return _this;
  4607. }
  4608. /* *
  4609. *
  4610. * Functions
  4611. *
  4612. * */
  4613. // Get the width and X offset, either on top of the linked series
  4614. // column or standalone
  4615. ErrorBarSeries.prototype.getColumnMetrics = function () {
  4616. return ((this.linkedParent && this.linkedParent.columnMetrics) ||
  4617. ColumnSeries.prototype.getColumnMetrics.call(this));
  4618. };
  4619. ErrorBarSeries.prototype.drawDataLabels = function () {
  4620. var valKey = this.pointValKey;
  4621. if (AreaRangeSeries) {
  4622. AreaRangeSeries.prototype.drawDataLabels.call(this);
  4623. // Arearange drawDataLabels does not reset point.y to high,
  4624. // but to low after drawing (#4133)
  4625. this.data.forEach(function (point) {
  4626. point.y = point[valKey];
  4627. });
  4628. }
  4629. };
  4630. // return a plain array for speedy calculation
  4631. ErrorBarSeries.prototype.toYData = function (point) {
  4632. return [point.low, point.high];
  4633. };
  4634. /**
  4635. * Error bars are a graphical representation of the variability of data and
  4636. * are used on graphs to indicate the error, or uncertainty in a reported
  4637. * measurement.
  4638. *
  4639. * @sample highcharts/demo/error-bar/
  4640. * Error bars on a column series
  4641. * @sample highcharts/series-errorbar/on-scatter/
  4642. * Error bars on a scatter series
  4643. *
  4644. * @extends plotOptions.boxplot
  4645. * @excluding boostBlending, boostThreshold
  4646. * @product highcharts highstock
  4647. * @requires highcharts-more
  4648. * @optionparent plotOptions.errorbar
  4649. */
  4650. ErrorBarSeries.defaultOptions = merge(BoxPlotSeries.defaultOptions, {
  4651. /**
  4652. * The main color of the bars. This can be overridden by
  4653. * [stemColor](#plotOptions.errorbar.stemColor) and
  4654. * [whiskerColor](#plotOptions.errorbar.whiskerColor) individually.
  4655. *
  4656. * @sample {highcharts} highcharts/plotoptions/error-bar-styling/
  4657. * Error bar styling
  4658. *
  4659. * @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
  4660. * @default #000000
  4661. * @since 3.0
  4662. * @product highcharts
  4663. */
  4664. color: palette.neutralColor100,
  4665. grouping: false,
  4666. /**
  4667. * The parent series of the error bar. The default value links it to
  4668. * the previous series. Otherwise, use the id of the parent series.
  4669. *
  4670. * @since 3.0
  4671. * @product highcharts
  4672. */
  4673. linkedTo: ':previous',
  4674. tooltip: {
  4675. pointFormat: '<span style="color:{point.color}">\u25CF</span> {series.name}: <b>{point.low}</b> - <b>{point.high}</b><br/>'
  4676. },
  4677. /**
  4678. * The line width of the whiskers, the horizontal lines marking
  4679. * low and high values. When `null`, the general
  4680. * [lineWidth](#plotOptions.errorbar.lineWidth) applies.
  4681. *
  4682. * @sample {highcharts} highcharts/plotoptions/error-bar-styling/
  4683. * Error bar styling
  4684. *
  4685. * @type {number}
  4686. * @since 3.0
  4687. * @product highcharts
  4688. */
  4689. whiskerWidth: null
  4690. });
  4691. return ErrorBarSeries;
  4692. }(BoxPlotSeries));
  4693. extend(ErrorBarSeries.prototype, {
  4694. // array point configs are mapped to this
  4695. pointArrayMap: ['low', 'high'],
  4696. pointValKey: 'high',
  4697. doQuartiles: false
  4698. });
  4699. SeriesRegistry.registerSeriesType('errorbar', ErrorBarSeries);
  4700. /* *
  4701. *
  4702. * Default export
  4703. *
  4704. * */
  4705. /* *
  4706. *
  4707. * API options
  4708. *
  4709. * */
  4710. /**
  4711. * A `errorbar` series. If the [type](#series.errorbar.type) option
  4712. * is not specified, it is inherited from [chart.type](#chart.type).
  4713. *
  4714. * @extends series,plotOptions.errorbar
  4715. * @excluding dataParser, dataURL, stack, stacking, boostThreshold,
  4716. * boostBlending
  4717. * @product highcharts
  4718. * @requires highcharts-more
  4719. * @apioption series.errorbar
  4720. */
  4721. /**
  4722. * An array of data points for the series. For the `errorbar` series
  4723. * type, points can be given in the following ways:
  4724. *
  4725. * 1. An array of arrays with 3 or 2 values. In this case, the values correspond
  4726. * to `x,low,high`. If the first value is a string, it is applied as the name
  4727. * of the point, and the `x` value is inferred. The `x` value can also be
  4728. * omitted, in which case the inner arrays should be of length 2\. Then the
  4729. * `x` value is automatically calculated, either starting at 0 and
  4730. * incremented by 1, or from `pointStart` and `pointInterval` given in the
  4731. * series options.
  4732. * ```js
  4733. * data: [
  4734. * [0, 10, 2],
  4735. * [1, 1, 8],
  4736. * [2, 4, 5]
  4737. * ]
  4738. * ```
  4739. *
  4740. * 2. An array of objects with named values. The following snippet shows only a
  4741. * few settings, see the complete options set below. If the total number of
  4742. * data points exceeds the series'
  4743. * [turboThreshold](#series.errorbar.turboThreshold), this option is not
  4744. * available.
  4745. * ```js
  4746. * data: [{
  4747. * x: 1,
  4748. * low: 0,
  4749. * high: 0,
  4750. * name: "Point2",
  4751. * color: "#00FF00"
  4752. * }, {
  4753. * x: 1,
  4754. * low: 5,
  4755. * high: 5,
  4756. * name: "Point1",
  4757. * color: "#FF00FF"
  4758. * }]
  4759. * ```
  4760. *
  4761. * @sample {highcharts} highcharts/series/data-array-of-arrays/
  4762. * Arrays of numeric x and y
  4763. * @sample {highcharts} highcharts/series/data-array-of-arrays-datetime/
  4764. * Arrays of datetime x and y
  4765. * @sample {highcharts} highcharts/series/data-array-of-name-value/
  4766. * Arrays of point.name and y
  4767. * @sample {highcharts} highcharts/series/data-array-of-objects/
  4768. * Config objects
  4769. *
  4770. * @type {Array<Array<(number|string),number>|Array<(number|string),number,number>|*>}
  4771. * @extends series.arearange.data
  4772. * @excluding dataLabels, drilldown, marker, states
  4773. * @product highcharts
  4774. * @apioption series.errorbar.data
  4775. */
  4776. ''; // adds doclets above to transpiled file
  4777. return ErrorBarSeries;
  4778. });
  4779. _registerModule(_modules, 'Core/Axis/WaterfallAxis.js', [_modules['Extensions/Stacking.js'], _modules['Core/Utilities.js']], function (StackItem, U) {
  4780. /* *
  4781. *
  4782. * (c) 2010-2021 Torstein Honsi
  4783. *
  4784. * License: www.highcharts.com/license
  4785. *
  4786. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  4787. *
  4788. * */
  4789. var addEvent = U.addEvent,
  4790. objectEach = U.objectEach;
  4791. /**
  4792. * @private
  4793. */
  4794. var WaterfallAxis;
  4795. (function (WaterfallAxis) {
  4796. /* *
  4797. *
  4798. * Interfaces
  4799. *
  4800. * */
  4801. /* *
  4802. *
  4803. * Classes
  4804. *
  4805. * */
  4806. /**
  4807. * @private
  4808. */
  4809. var Composition = /** @class */ (function () {
  4810. /* eslint-disable no-invalid-this, valid-jsdoc */
  4811. /* *
  4812. *
  4813. * Constructors
  4814. *
  4815. * */
  4816. /**
  4817. * @private
  4818. */
  4819. function Composition(axis) {
  4820. this.axis = axis;
  4821. this.stacks = {
  4822. changed: false
  4823. };
  4824. }
  4825. /* *
  4826. *
  4827. * Functions
  4828. *
  4829. * */
  4830. /**
  4831. * Calls StackItem.prototype.render function that creates and renders
  4832. * stack total label for each waterfall stack item.
  4833. *
  4834. * @private
  4835. * @function Highcharts.Axis#renderWaterfallStackTotals
  4836. */
  4837. Composition.prototype.renderStackTotals = function () {
  4838. var yAxis = this.axis,
  4839. waterfallStacks = yAxis.waterfall.stacks,
  4840. stackTotalGroup = yAxis.stacking && yAxis.stacking.stackTotalGroup,
  4841. dummyStackItem = new StackItem(yAxis,
  4842. yAxis.options.stackLabels,
  4843. false, 0,
  4844. void 0);
  4845. this.dummyStackItem = dummyStackItem;
  4846. // Render each waterfall stack total
  4847. objectEach(waterfallStacks, function (type) {
  4848. objectEach(type, function (stackItem) {
  4849. dummyStackItem.total = stackItem.stackTotal;
  4850. if (stackItem.label) {
  4851. dummyStackItem.label = stackItem.label;
  4852. }
  4853. StackItem.prototype.render.call(dummyStackItem, stackTotalGroup);
  4854. stackItem.label = dummyStackItem.label;
  4855. delete dummyStackItem.label;
  4856. });
  4857. });
  4858. dummyStackItem.total = null;
  4859. };
  4860. return Composition;
  4861. }());
  4862. WaterfallAxis.Composition = Composition;
  4863. /* *
  4864. *
  4865. * Functions
  4866. *
  4867. * */
  4868. /* eslint-disable no-invalid-this, valid-jsdoc */
  4869. /**
  4870. * @private
  4871. */
  4872. function compose(AxisClass, ChartClass) {
  4873. addEvent(AxisClass, 'init', onInit);
  4874. addEvent(AxisClass, 'afterBuildStacks', onAfterBuildStacks);
  4875. addEvent(AxisClass, 'afterRender', onAfterRender);
  4876. addEvent(ChartClass, 'beforeRedraw', onBeforeRedraw);
  4877. }
  4878. WaterfallAxis.compose = compose;
  4879. /**
  4880. * @private
  4881. */
  4882. function onAfterBuildStacks() {
  4883. var axis = this;
  4884. var stacks = axis.waterfall.stacks;
  4885. if (stacks) {
  4886. stacks.changed = false;
  4887. delete stacks.alreadyChanged;
  4888. }
  4889. }
  4890. /**
  4891. * @private
  4892. */
  4893. function onAfterRender() {
  4894. var axis = this;
  4895. var stackLabelOptions = axis.options.stackLabels;
  4896. if (stackLabelOptions && stackLabelOptions.enabled &&
  4897. axis.waterfall.stacks) {
  4898. axis.waterfall.renderStackTotals();
  4899. }
  4900. }
  4901. /**
  4902. * @private
  4903. */
  4904. function onBeforeRedraw() {
  4905. var axes = this.axes,
  4906. series = this.series,
  4907. i = series.length;
  4908. while (i--) {
  4909. if (series[i].options.stacking) {
  4910. axes.forEach(function (axis) {
  4911. if (!axis.isXAxis) {
  4912. axis.waterfall.stacks.changed = true;
  4913. }
  4914. });
  4915. i = 0;
  4916. }
  4917. }
  4918. }
  4919. /**
  4920. * @private
  4921. */
  4922. function onInit() {
  4923. var axis = this;
  4924. if (!axis.waterfall) {
  4925. axis.waterfall = new Composition(axis);
  4926. }
  4927. }
  4928. })(WaterfallAxis || (WaterfallAxis = {}));
  4929. /* *
  4930. *
  4931. * Default Export
  4932. *
  4933. * */
  4934. return WaterfallAxis;
  4935. });
  4936. _registerModule(_modules, 'Series/Waterfall/WaterfallPoint.js', [_modules['Series/Column/ColumnSeries.js'], _modules['Core/Series/Point.js'], _modules['Core/Utilities.js']], function (ColumnSeries, Point, U) {
  4937. /* *
  4938. *
  4939. * (c) 2010-2021 Torstein Honsi
  4940. *
  4941. * License: www.highcharts.com/license
  4942. *
  4943. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  4944. *
  4945. * */
  4946. var __extends = (this && this.__extends) || (function () {
  4947. var extendStatics = function (d,
  4948. b) {
  4949. extendStatics = Object.setPrototypeOf ||
  4950. ({ __proto__: [] } instanceof Array && function (d,
  4951. b) { d.__proto__ = b; }) ||
  4952. function (d,
  4953. b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  4954. return extendStatics(d, b);
  4955. };
  4956. return function (d, b) {
  4957. extendStatics(d, b);
  4958. function __() { this.constructor = d; }
  4959. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  4960. };
  4961. })();
  4962. var isNumber = U.isNumber;
  4963. /* *
  4964. *
  4965. * Class
  4966. *
  4967. * */
  4968. var WaterfallPoint = /** @class */ (function (_super) {
  4969. __extends(WaterfallPoint, _super);
  4970. function WaterfallPoint() {
  4971. var _this = _super !== null && _super.apply(this,
  4972. arguments) || this;
  4973. _this.options = void 0;
  4974. _this.series = void 0;
  4975. return _this;
  4976. }
  4977. /* *
  4978. *
  4979. * Functions
  4980. *
  4981. * */
  4982. WaterfallPoint.prototype.getClassName = function () {
  4983. var className = Point.prototype.getClassName.call(this);
  4984. if (this.isSum) {
  4985. className += ' highcharts-sum';
  4986. }
  4987. else if (this.isIntermediateSum) {
  4988. className += ' highcharts-intermediate-sum';
  4989. }
  4990. return className;
  4991. };
  4992. // Pass the null test in ColumnSeries.translate.
  4993. WaterfallPoint.prototype.isValid = function () {
  4994. return (isNumber(this.y) ||
  4995. this.isSum ||
  4996. Boolean(this.isIntermediateSum));
  4997. };
  4998. return WaterfallPoint;
  4999. }(ColumnSeries.prototype.pointClass));
  5000. /* *
  5001. *
  5002. * Export
  5003. *
  5004. * */
  5005. return WaterfallPoint;
  5006. });
  5007. _registerModule(_modules, 'Series/Waterfall/WaterfallSeries.js', [_modules['Core/Chart/Chart.js'], _modules['Core/Globals.js'], _modules['Core/Color/Palette.js'], _modules['Core/Series/SeriesRegistry.js'], _modules['Core/Utilities.js'], _modules['Core/Axis/WaterfallAxis.js'], _modules['Series/Waterfall/WaterfallPoint.js']], function (Chart, H, palette, SeriesRegistry, U, WaterfallAxis, WaterfallPoint) {
  5008. /* *
  5009. *
  5010. * (c) 2010-2021 Torstein Honsi
  5011. *
  5012. * License: www.highcharts.com/license
  5013. *
  5014. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  5015. *
  5016. * */
  5017. var __extends = (this && this.__extends) || (function () {
  5018. var extendStatics = function (d,
  5019. b) {
  5020. extendStatics = Object.setPrototypeOf ||
  5021. ({ __proto__: [] } instanceof Array && function (d,
  5022. b) { d.__proto__ = b; }) ||
  5023. function (d,
  5024. b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  5025. return extendStatics(d, b);
  5026. };
  5027. return function (d, b) {
  5028. extendStatics(d, b);
  5029. function __() { this.constructor = d; }
  5030. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  5031. };
  5032. })();
  5033. var _a = SeriesRegistry.seriesTypes,
  5034. ColumnSeries = _a.column,
  5035. LineSeries = _a.line;
  5036. var arrayMax = U.arrayMax,
  5037. arrayMin = U.arrayMin,
  5038. correctFloat = U.correctFloat,
  5039. extend = U.extend,
  5040. merge = U.merge,
  5041. objectEach = U.objectEach,
  5042. pick = U.pick;
  5043. /**
  5044. * Returns true if the key is a direct property of the object.
  5045. * @private
  5046. * @param {*} obj - Object with property to test
  5047. * @param {string} key - Property key to test
  5048. * @return {boolean} - Whether it is a direct property
  5049. */
  5050. function ownProp(obj, key) {
  5051. return Object.hasOwnProperty.call(obj, key);
  5052. }
  5053. /* eslint-disable no-invalid-this, valid-jsdoc */
  5054. // eslint-disable-next-line valid-jsdoc
  5055. /**
  5056. * Waterfall series type.
  5057. *
  5058. * @private
  5059. */
  5060. var WaterfallSeries = /** @class */ (function (_super) {
  5061. __extends(WaterfallSeries, _super);
  5062. function WaterfallSeries() {
  5063. /* *
  5064. *
  5065. * Static properties
  5066. *
  5067. * */
  5068. var _this = _super !== null && _super.apply(this,
  5069. arguments) || this;
  5070. /* *
  5071. *
  5072. * Properties
  5073. *
  5074. * */
  5075. _this.chart = void 0;
  5076. _this.data = void 0;
  5077. _this.options = void 0;
  5078. _this.points = void 0;
  5079. _this.stackedYNeg = void 0;
  5080. _this.stackedYPos = void 0;
  5081. _this.stackKey = void 0;
  5082. _this.xData = void 0;
  5083. _this.yAxis = void 0;
  5084. _this.yData = void 0;
  5085. return _this;
  5086. }
  5087. /* *
  5088. *
  5089. * Functions
  5090. *
  5091. * */
  5092. // After generating points, set y-values for all sums.
  5093. WaterfallSeries.prototype.generatePoints = function () {
  5094. var point,
  5095. len,
  5096. i,
  5097. y;
  5098. // Parent call:
  5099. ColumnSeries.prototype.generatePoints.apply(this);
  5100. for (i = 0, len = this.points.length; i < len; i++) {
  5101. point = this.points[i];
  5102. y = this.processedYData[i];
  5103. // override point value for sums
  5104. // #3710 Update point does not propagate to sum
  5105. if (point.isIntermediateSum || point.isSum) {
  5106. point.y = correctFloat(y);
  5107. }
  5108. }
  5109. };
  5110. // Translate data points from raw values
  5111. WaterfallSeries.prototype.translate = function () {
  5112. var series = this,
  5113. options = series.options,
  5114. yAxis = series.yAxis,
  5115. len,
  5116. i,
  5117. points,
  5118. point,
  5119. shapeArgs,
  5120. y,
  5121. yValue,
  5122. previousY,
  5123. previousIntermediate,
  5124. range,
  5125. minPointLength = pick(options.minPointLength, 5),
  5126. halfMinPointLength = minPointLength / 2,
  5127. threshold = options.threshold,
  5128. stacking = options.stacking,
  5129. tooltipY,
  5130. actualStack = yAxis.waterfall.stacks[series.stackKey],
  5131. actualStackX,
  5132. dummyStackItem,
  5133. total,
  5134. pointY,
  5135. yPos,
  5136. hPos;
  5137. // run column series translate
  5138. ColumnSeries.prototype.translate.apply(series);
  5139. previousY = previousIntermediate = threshold;
  5140. points = series.points;
  5141. for (i = 0, len = points.length; i < len; i++) {
  5142. // cache current point object
  5143. point = points[i];
  5144. yValue = series.processedYData[i];
  5145. shapeArgs = point.shapeArgs;
  5146. range = [0, yValue];
  5147. pointY = point.y;
  5148. // code responsible for correct positions of stacked points
  5149. // starts here
  5150. if (stacking) {
  5151. if (actualStack) {
  5152. actualStackX = actualStack[i];
  5153. if (stacking === 'overlap') {
  5154. total =
  5155. actualStackX.stackState[actualStackX.stateIndex--];
  5156. y = pointY >= 0 ? total : total - pointY;
  5157. if (ownProp(actualStackX, 'absolutePos')) {
  5158. delete actualStackX.absolutePos;
  5159. }
  5160. if (ownProp(actualStackX, 'absoluteNeg')) {
  5161. delete actualStackX.absoluteNeg;
  5162. }
  5163. }
  5164. else {
  5165. if (pointY >= 0) {
  5166. total = actualStackX.threshold +
  5167. actualStackX.posTotal;
  5168. actualStackX.posTotal -= pointY;
  5169. y = total;
  5170. }
  5171. else {
  5172. total = actualStackX.threshold +
  5173. actualStackX.negTotal;
  5174. actualStackX.negTotal -= pointY;
  5175. y = total - pointY;
  5176. }
  5177. if (!actualStackX.posTotal) {
  5178. if (ownProp(actualStackX, 'absolutePos')) {
  5179. actualStackX.posTotal =
  5180. actualStackX.absolutePos;
  5181. delete actualStackX.absolutePos;
  5182. }
  5183. }
  5184. if (!actualStackX.negTotal) {
  5185. if (ownProp(actualStackX, 'absoluteNeg')) {
  5186. actualStackX.negTotal =
  5187. actualStackX.absoluteNeg;
  5188. delete actualStackX.absoluteNeg;
  5189. }
  5190. }
  5191. }
  5192. if (!point.isSum) {
  5193. // the connectorThreshold property is later used in
  5194. // getCrispPath function to draw a connector line in a
  5195. // correct place
  5196. actualStackX.connectorThreshold =
  5197. actualStackX.threshold + actualStackX.stackTotal;
  5198. }
  5199. if (yAxis.reversed) {
  5200. yPos = (pointY >= 0) ? (y - pointY) : (y + pointY);
  5201. hPos = y;
  5202. }
  5203. else {
  5204. yPos = y;
  5205. hPos = y - pointY;
  5206. }
  5207. point.below = yPos <= pick(threshold, 0);
  5208. shapeArgs.y = yAxis.translate(yPos, 0, 1, 0, 1);
  5209. shapeArgs.height = Math.abs(shapeArgs.y -
  5210. yAxis.translate(hPos, 0, 1, 0, 1));
  5211. dummyStackItem = yAxis.waterfall.dummyStackItem;
  5212. if (dummyStackItem) {
  5213. dummyStackItem.x = i;
  5214. dummyStackItem.label = actualStack[i].label;
  5215. dummyStackItem.setOffset(series.pointXOffset || 0, series.barW || 0, series.stackedYNeg[i], series.stackedYPos[i]);
  5216. }
  5217. }
  5218. }
  5219. else {
  5220. // up points
  5221. y =
  5222. Math.max(previousY, previousY + pointY) + range[0];
  5223. shapeArgs.y =
  5224. yAxis.translate(y, 0, 1, 0, 1);
  5225. // sum points
  5226. if (point.isSum) {
  5227. shapeArgs.y = yAxis.translate(range[1], 0, 1, 0, 1);
  5228. shapeArgs.height = Math.min(yAxis.translate(range[0], 0, 1, 0, 1), yAxis.len) - shapeArgs.y; // #4256
  5229. }
  5230. else if (point.isIntermediateSum) {
  5231. if (pointY >= 0) {
  5232. yPos = range[1] + previousIntermediate;
  5233. hPos = previousIntermediate;
  5234. }
  5235. else {
  5236. yPos = previousIntermediate;
  5237. hPos = range[1] + previousIntermediate;
  5238. }
  5239. if (yAxis.reversed) {
  5240. // swapping values
  5241. yPos ^= hPos;
  5242. hPos ^= yPos;
  5243. yPos ^= hPos;
  5244. }
  5245. shapeArgs.y = yAxis.translate(yPos, 0, 1, 0, 1);
  5246. shapeArgs.height = Math.abs(shapeArgs.y -
  5247. Math.min(yAxis.translate(hPos, 0, 1, 0, 1), yAxis.len));
  5248. previousIntermediate += range[1];
  5249. // If it's not the sum point, update previous stack end position
  5250. // and get shape height (#3886)
  5251. }
  5252. else {
  5253. shapeArgs.height = yValue > 0 ?
  5254. yAxis.translate(previousY, 0, 1, 0, 1) - shapeArgs.y :
  5255. yAxis.translate(previousY, 0, 1, 0, 1) - yAxis.translate(previousY - yValue, 0, 1, 0, 1);
  5256. previousY += yValue;
  5257. point.below = previousY < pick(threshold, 0);
  5258. }
  5259. // #3952 Negative sum or intermediate sum not rendered correctly
  5260. if (shapeArgs.height < 0) {
  5261. shapeArgs.y += shapeArgs.height;
  5262. shapeArgs.height *= -1;
  5263. }
  5264. }
  5265. point.plotY = shapeArgs.y =
  5266. Math.round(shapeArgs.y) - (series.borderWidth % 2) / 2;
  5267. // #3151
  5268. shapeArgs.height =
  5269. Math.max(Math.round(shapeArgs.height), 0.001);
  5270. point.yBottom = shapeArgs.y + shapeArgs.height;
  5271. if (shapeArgs.height <= minPointLength && !point.isNull) {
  5272. shapeArgs.height = minPointLength;
  5273. shapeArgs.y -= halfMinPointLength;
  5274. point.plotY = shapeArgs.y;
  5275. if (point.y < 0) {
  5276. point.minPointLengthOffset = -halfMinPointLength;
  5277. }
  5278. else {
  5279. point.minPointLengthOffset = halfMinPointLength;
  5280. }
  5281. }
  5282. else {
  5283. if (point.isNull) {
  5284. shapeArgs.width = 0;
  5285. }
  5286. point.minPointLengthOffset = 0;
  5287. }
  5288. // Correct tooltip placement (#3014)
  5289. tooltipY =
  5290. point.plotY + (point.negative ? shapeArgs.height : 0);
  5291. if (series.chart.inverted) {
  5292. point.tooltipPos[0] = yAxis.len - tooltipY;
  5293. }
  5294. else {
  5295. point.tooltipPos[1] = tooltipY;
  5296. }
  5297. }
  5298. };
  5299. // Call default processData then override yData to reflect waterfall's
  5300. // extremes on yAxis
  5301. WaterfallSeries.prototype.processData = function (force) {
  5302. var series = this,
  5303. options = series.options,
  5304. yData = series.yData,
  5305. // #3710 Update point does not propagate to sum
  5306. points = options.data,
  5307. point,
  5308. dataLength = yData.length,
  5309. threshold = options.threshold || 0,
  5310. subSum,
  5311. sum,
  5312. dataMin,
  5313. dataMax,
  5314. y,
  5315. i;
  5316. sum = subSum = dataMin = dataMax = 0;
  5317. for (i = 0; i < dataLength; i++) {
  5318. y = yData[i];
  5319. point = points && points[i] ? points[i] : {};
  5320. if (y === 'sum' || point.isSum) {
  5321. yData[i] = correctFloat(sum);
  5322. }
  5323. else if (y === 'intermediateSum' ||
  5324. point.isIntermediateSum) {
  5325. yData[i] = correctFloat(subSum);
  5326. subSum = 0;
  5327. }
  5328. else {
  5329. sum += y;
  5330. subSum += y;
  5331. }
  5332. dataMin = Math.min(sum, dataMin);
  5333. dataMax = Math.max(sum, dataMax);
  5334. }
  5335. _super.prototype.processData.call(this, force);
  5336. // Record extremes only if stacking was not set:
  5337. if (!options.stacking) {
  5338. series.dataMin = dataMin + threshold;
  5339. series.dataMax = dataMax;
  5340. }
  5341. return;
  5342. };
  5343. // Return y value or string if point is sum
  5344. WaterfallSeries.prototype.toYData = function (pt) {
  5345. if (pt.isSum) {
  5346. return 'sum';
  5347. }
  5348. if (pt.isIntermediateSum) {
  5349. return 'intermediateSum';
  5350. }
  5351. return pt.y;
  5352. };
  5353. WaterfallSeries.prototype.updateParallelArrays = function (point, i) {
  5354. _super.prototype.updateParallelArrays.call(this, point, i);
  5355. // Prevent initial sums from triggering an error (#3245, #7559)
  5356. if (this.yData[0] === 'sum' || this.yData[0] === 'intermediateSum') {
  5357. this.yData[0] = null;
  5358. }
  5359. };
  5360. // Postprocess mapping between options and SVG attributes
  5361. WaterfallSeries.prototype.pointAttribs = function (point, state) {
  5362. var upColor = this.options.upColor,
  5363. attr;
  5364. // Set or reset up color (#3710, update to negative)
  5365. if (upColor && !point.options.color) {
  5366. point.color = point.y > 0 ? upColor : null;
  5367. }
  5368. attr = ColumnSeries.prototype.pointAttribs.call(this, point, state);
  5369. // The dashStyle option in waterfall applies to the graph, not
  5370. // the points
  5371. delete attr.dashstyle;
  5372. return attr;
  5373. };
  5374. // Return an empty path initially, because we need to know the stroke-width
  5375. // in order to set the final path.
  5376. WaterfallSeries.prototype.getGraphPath = function () {
  5377. return [['M', 0, 0]];
  5378. };
  5379. // Draw columns' connector lines
  5380. WaterfallSeries.prototype.getCrispPath = function () {
  5381. var data = this.data,
  5382. yAxis = this.yAxis,
  5383. length = data.length,
  5384. graphNormalizer = Math.round(this.graph.strokeWidth()) % 2 / 2,
  5385. borderNormalizer = Math.round(this.borderWidth) % 2 / 2,
  5386. reversedXAxis = this.xAxis.reversed,
  5387. reversedYAxis = this.yAxis.reversed,
  5388. stacking = this.options.stacking,
  5389. path = [],
  5390. connectorThreshold,
  5391. prevStack,
  5392. prevStackX,
  5393. prevPoint,
  5394. yPos,
  5395. isPos,
  5396. prevArgs,
  5397. pointArgs,
  5398. i;
  5399. for (i = 1; i < length; i++) {
  5400. pointArgs = data[i].shapeArgs;
  5401. prevPoint = data[i - 1];
  5402. prevArgs = data[i - 1].shapeArgs;
  5403. prevStack = yAxis.waterfall.stacks[this.stackKey];
  5404. isPos = prevPoint.y > 0 ? -prevArgs.height : 0;
  5405. if (prevStack && prevArgs && pointArgs) {
  5406. prevStackX = prevStack[i - 1];
  5407. // y position of the connector is different when series are
  5408. // stacked, yAxis is reversed and it also depends on point's
  5409. // value
  5410. if (stacking) {
  5411. connectorThreshold = prevStackX.connectorThreshold;
  5412. yPos = Math.round((yAxis.translate(connectorThreshold, 0, 1, 0, 1) +
  5413. (reversedYAxis ? isPos : 0))) - graphNormalizer;
  5414. }
  5415. else {
  5416. yPos =
  5417. prevArgs.y + prevPoint.minPointLengthOffset +
  5418. borderNormalizer - graphNormalizer;
  5419. }
  5420. path.push([
  5421. 'M',
  5422. (prevArgs.x || 0) + (reversedXAxis ?
  5423. 0 :
  5424. (prevArgs.width || 0)),
  5425. yPos
  5426. ], [
  5427. 'L',
  5428. (pointArgs.x || 0) + (reversedXAxis ?
  5429. (pointArgs.width || 0) :
  5430. 0),
  5431. yPos
  5432. ]);
  5433. }
  5434. if (prevArgs &&
  5435. path.length &&
  5436. ((!stacking && prevPoint.y < 0 && !reversedYAxis) ||
  5437. (prevPoint.y > 0 && reversedYAxis))) {
  5438. var nextLast = path[path.length - 2];
  5439. if (nextLast && typeof nextLast[2] === 'number') {
  5440. nextLast[2] += prevArgs.height || 0;
  5441. }
  5442. var last = path[path.length - 1];
  5443. if (last && typeof last[2] === 'number') {
  5444. last[2] += prevArgs.height || 0;
  5445. }
  5446. }
  5447. }
  5448. return path;
  5449. };
  5450. // The graph is initially drawn with an empty definition, then updated with
  5451. // crisp rendering.
  5452. WaterfallSeries.prototype.drawGraph = function () {
  5453. LineSeries.prototype.drawGraph.call(this);
  5454. this.graph.attr({
  5455. d: this.getCrispPath()
  5456. });
  5457. };
  5458. // Waterfall has stacking along the x-values too.
  5459. WaterfallSeries.prototype.setStackedPoints = function () {
  5460. var series = this,
  5461. options = series.options,
  5462. waterfallStacks = series.yAxis.waterfall.stacks,
  5463. seriesThreshold = options.threshold,
  5464. stackThreshold = seriesThreshold || 0,
  5465. interSum = stackThreshold,
  5466. stackKey = series.stackKey,
  5467. xData = series.xData,
  5468. xLength = xData.length,
  5469. actualStack,
  5470. actualStackX,
  5471. totalYVal,
  5472. actualSum,
  5473. prevSum,
  5474. statesLen,
  5475. posTotal,
  5476. negTotal,
  5477. xPoint,
  5478. yVal,
  5479. x,
  5480. alreadyChanged,
  5481. changed;
  5482. // function responsible for calculating correct values for stackState
  5483. // array of each stack item. The arguments are: firstS - the value for
  5484. // the first state, nextS - the difference between the previous and the
  5485. // newest state, sInx - counter used in the for that updates each state
  5486. // when necessary, sOff - offset that must be added to each state when
  5487. // they need to be updated (if point isn't a total sum)
  5488. // eslint-disable-next-line require-jsdoc
  5489. function calculateStackState(firstS, nextS, sInx, sOff) {
  5490. if (!statesLen) {
  5491. actualStackX.stackState[0] = firstS;
  5492. statesLen = actualStackX.stackState.length;
  5493. }
  5494. else {
  5495. for (sInx; sInx < statesLen; sInx++) {
  5496. actualStackX.stackState[sInx] += sOff;
  5497. }
  5498. }
  5499. actualStackX.stackState.push(actualStackX.stackState[statesLen - 1] + nextS);
  5500. }
  5501. series.yAxis.stacking.usePercentage = false;
  5502. totalYVal = actualSum = prevSum = stackThreshold;
  5503. // code responsible for creating stacks for waterfall series
  5504. if (series.visible ||
  5505. !series.chart.options.chart.ignoreHiddenSeries) {
  5506. changed = waterfallStacks.changed;
  5507. alreadyChanged = waterfallStacks.alreadyChanged;
  5508. // in case of a redraw, stack for each x value must be
  5509. // emptied (only for the first series in a specific stack)
  5510. // and recalculated once more
  5511. if (alreadyChanged &&
  5512. alreadyChanged.indexOf(stackKey) < 0) {
  5513. changed = true;
  5514. }
  5515. if (!waterfallStacks[stackKey]) {
  5516. waterfallStacks[stackKey] = {};
  5517. }
  5518. actualStack = waterfallStacks[stackKey];
  5519. for (var i = 0; i < xLength; i++) {
  5520. x = xData[i];
  5521. if (!actualStack[x] || changed) {
  5522. actualStack[x] = {
  5523. negTotal: 0,
  5524. posTotal: 0,
  5525. stackTotal: 0,
  5526. threshold: 0,
  5527. stateIndex: 0,
  5528. stackState: [],
  5529. label: ((changed &&
  5530. actualStack[x]) ?
  5531. actualStack[x].label :
  5532. void 0)
  5533. };
  5534. }
  5535. actualStackX = actualStack[x];
  5536. yVal = series.yData[i];
  5537. if (yVal >= 0) {
  5538. actualStackX.posTotal += yVal;
  5539. }
  5540. else {
  5541. actualStackX.negTotal += yVal;
  5542. }
  5543. // points do not exist yet, so raw data is used
  5544. xPoint = options.data[i];
  5545. posTotal = actualStackX.absolutePos =
  5546. actualStackX.posTotal;
  5547. negTotal = actualStackX.absoluteNeg =
  5548. actualStackX.negTotal;
  5549. actualStackX.stackTotal = posTotal + negTotal;
  5550. statesLen = actualStackX.stackState.length;
  5551. if (xPoint && xPoint.isIntermediateSum) {
  5552. calculateStackState(prevSum, actualSum, 0, prevSum);
  5553. prevSum = actualSum;
  5554. actualSum = seriesThreshold;
  5555. // swapping values
  5556. stackThreshold ^= interSum;
  5557. interSum ^= stackThreshold;
  5558. stackThreshold ^= interSum;
  5559. }
  5560. else if (xPoint && xPoint.isSum) {
  5561. calculateStackState(seriesThreshold, totalYVal, statesLen);
  5562. stackThreshold = seriesThreshold;
  5563. }
  5564. else {
  5565. calculateStackState(stackThreshold, yVal, 0, totalYVal);
  5566. if (xPoint) {
  5567. totalYVal += yVal;
  5568. actualSum += yVal;
  5569. }
  5570. }
  5571. actualStackX.stateIndex++;
  5572. actualStackX.threshold = stackThreshold;
  5573. stackThreshold += actualStackX.stackTotal;
  5574. }
  5575. waterfallStacks.changed = false;
  5576. if (!waterfallStacks.alreadyChanged) {
  5577. waterfallStacks.alreadyChanged = [];
  5578. }
  5579. waterfallStacks.alreadyChanged.push(stackKey);
  5580. }
  5581. };
  5582. // Extremes for a non-stacked series are recorded in processData.
  5583. // In case of stacking, use Series.stackedYData to calculate extremes.
  5584. WaterfallSeries.prototype.getExtremes = function () {
  5585. var stacking = this.options.stacking,
  5586. yAxis,
  5587. waterfallStacks,
  5588. stackedYNeg,
  5589. stackedYPos;
  5590. if (stacking) {
  5591. yAxis = this.yAxis;
  5592. waterfallStacks = yAxis.waterfall.stacks;
  5593. stackedYNeg = this.stackedYNeg = [];
  5594. stackedYPos = this.stackedYPos = [];
  5595. // the visible y range can be different when stacking is set to
  5596. // overlap and different when it's set to normal
  5597. if (stacking === 'overlap') {
  5598. objectEach(waterfallStacks[this.stackKey], function (stackX) {
  5599. stackedYNeg.push(arrayMin(stackX.stackState));
  5600. stackedYPos.push(arrayMax(stackX.stackState));
  5601. });
  5602. }
  5603. else {
  5604. objectEach(waterfallStacks[this.stackKey], function (stackX) {
  5605. stackedYNeg.push(stackX.negTotal + stackX.threshold);
  5606. stackedYPos.push(stackX.posTotal + stackX.threshold);
  5607. });
  5608. }
  5609. return {
  5610. dataMin: arrayMin(stackedYNeg),
  5611. dataMax: arrayMax(stackedYPos)
  5612. };
  5613. }
  5614. // When not stacking, data extremes have already been computed in the
  5615. // processData function.
  5616. return {
  5617. dataMin: this.dataMin,
  5618. dataMax: this.dataMax
  5619. };
  5620. };
  5621. /**
  5622. * A waterfall chart displays sequentially introduced positive or negative
  5623. * values in cumulative columns.
  5624. *
  5625. * @sample highcharts/demo/waterfall/
  5626. * Waterfall chart
  5627. * @sample highcharts/plotoptions/waterfall-inverted/
  5628. * Horizontal (inverted) waterfall
  5629. * @sample highcharts/plotoptions/waterfall-stacked/
  5630. * Stacked waterfall chart
  5631. *
  5632. * @extends plotOptions.column
  5633. * @excluding boostThreshold, boostBlending
  5634. * @product highcharts
  5635. * @requires highcharts-more
  5636. * @optionparent plotOptions.waterfall
  5637. */
  5638. WaterfallSeries.defaultOptions = merge(ColumnSeries.defaultOptions, {
  5639. /**
  5640. * @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
  5641. * @apioption plotOptions.waterfall.color
  5642. */
  5643. /**
  5644. * The color used specifically for positive point columns. When not
  5645. * specified, the general series color is used.
  5646. *
  5647. * In styled mode, the waterfall colors can be set with the
  5648. * `.highcharts-point-negative`, `.highcharts-sum` and
  5649. * `.highcharts-intermediate-sum` classes.
  5650. *
  5651. * @sample {highcharts} highcharts/demo/waterfall/
  5652. * Waterfall
  5653. *
  5654. * @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
  5655. * @product highcharts
  5656. * @apioption plotOptions.waterfall.upColor
  5657. */
  5658. dataLabels: {
  5659. inside: true
  5660. },
  5661. /**
  5662. * The width of the line connecting waterfall columns.
  5663. *
  5664. * @product highcharts
  5665. */
  5666. lineWidth: 1,
  5667. /**
  5668. * The color of the line that connects columns in a waterfall series.
  5669. *
  5670. * In styled mode, the stroke can be set with the `.highcharts-graph`
  5671. * class.
  5672. *
  5673. * @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
  5674. * @since 3.0
  5675. * @product highcharts
  5676. */
  5677. lineColor: palette.neutralColor80,
  5678. /**
  5679. * A name for the dash style to use for the line connecting the columns
  5680. * of the waterfall series. Possible values: Dash, DashDot, Dot,
  5681. * LongDash, LongDashDot, LongDashDotDot, ShortDash, ShortDashDot,
  5682. * ShortDashDotDot, ShortDot, Solid
  5683. *
  5684. * In styled mode, the stroke dash-array can be set with the
  5685. * `.highcharts-graph` class.
  5686. *
  5687. * @type {Highcharts.DashStyleValue}
  5688. * @since 3.0
  5689. * @product highcharts
  5690. */
  5691. dashStyle: 'Dot',
  5692. /**
  5693. * The color of the border of each waterfall column.
  5694. *
  5695. * In styled mode, the border stroke can be set with the
  5696. * `.highcharts-point` class.
  5697. *
  5698. * @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
  5699. * @since 3.0
  5700. * @product highcharts
  5701. */
  5702. borderColor: palette.neutralColor80,
  5703. states: {
  5704. hover: {
  5705. lineWidthPlus: 0 // #3126
  5706. }
  5707. }
  5708. });
  5709. return WaterfallSeries;
  5710. }(ColumnSeries));
  5711. extend(WaterfallSeries.prototype, {
  5712. getZonesGraphs: LineSeries.prototype.getZonesGraphs,
  5713. pointValKey: 'y',
  5714. // Property needed to prevent lines between the columns from disappearing
  5715. // when negativeColor is used.
  5716. showLine: true,
  5717. pointClass: WaterfallPoint
  5718. });
  5719. SeriesRegistry.registerSeriesType('waterfall', WaterfallSeries);
  5720. WaterfallAxis.compose(H.Axis, Chart);
  5721. /* *
  5722. *
  5723. * Export
  5724. *
  5725. * */
  5726. /**
  5727. *
  5728. * API Options
  5729. *
  5730. */
  5731. /**
  5732. * A `waterfall` series. If the [type](#series.waterfall.type) option
  5733. * is not specified, it is inherited from [chart.type](#chart.type).
  5734. *
  5735. * @extends series,plotOptions.waterfall
  5736. * @excluding dataParser, dataURL, boostThreshold, boostBlending
  5737. * @product highcharts
  5738. * @requires highcharts-more
  5739. * @apioption series.waterfall
  5740. */
  5741. /**
  5742. * An array of data points for the series. For the `waterfall` series
  5743. * type, points can be given in the following ways:
  5744. *
  5745. * 1. An array of numerical values. In this case, the numerical values will be
  5746. * interpreted as `y` options. The `x` values will be automatically
  5747. * calculated, either starting at 0 and incremented by 1, or from
  5748. * `pointStart` and `pointInterval` given in the series options. If the axis
  5749. * has categories, these will be used. Example:
  5750. * ```js
  5751. * data: [0, 5, 3, 5]
  5752. * ```
  5753. *
  5754. * 2. An array of arrays with 2 values. In this case, the values correspond to
  5755. * `x,y`. If the first value is a string, it is applied as the name of the
  5756. * point, and the `x` value is inferred.
  5757. * ```js
  5758. * data: [
  5759. * [0, 7],
  5760. * [1, 8],
  5761. * [2, 3]
  5762. * ]
  5763. * ```
  5764. *
  5765. * 3. An array of objects with named values. The following snippet shows only a
  5766. * few settings, see the complete options set below. If the total number of
  5767. * data points exceeds the series'
  5768. * [turboThreshold](#series.waterfall.turboThreshold), this option is not
  5769. * available.
  5770. * ```js
  5771. * data: [{
  5772. * x: 1,
  5773. * y: 8,
  5774. * name: "Point2",
  5775. * color: "#00FF00"
  5776. * }, {
  5777. * x: 1,
  5778. * y: 8,
  5779. * name: "Point1",
  5780. * color: "#FF00FF"
  5781. * }]
  5782. * ```
  5783. *
  5784. * @sample {highcharts} highcharts/chart/reflow-true/
  5785. * Numerical values
  5786. * @sample {highcharts} highcharts/series/data-array-of-arrays/
  5787. * Arrays of numeric x and y
  5788. * @sample {highcharts} highcharts/series/data-array-of-arrays-datetime/
  5789. * Arrays of datetime x and y
  5790. * @sample {highcharts} highcharts/series/data-array-of-name-value/
  5791. * Arrays of point.name and y
  5792. * @sample {highcharts} highcharts/series/data-array-of-objects/
  5793. * Config objects
  5794. *
  5795. * @type {Array<number|Array<(number|string),(number|null)>|null|*>}
  5796. * @extends series.line.data
  5797. * @excluding marker
  5798. * @product highcharts
  5799. * @apioption series.waterfall.data
  5800. */
  5801. /**
  5802. * When this property is true, the points acts as a summary column for
  5803. * the values added or substracted since the last intermediate sum,
  5804. * or since the start of the series. The `y` value is ignored.
  5805. *
  5806. * @sample {highcharts} highcharts/demo/waterfall/
  5807. * Waterfall
  5808. *
  5809. * @type {boolean}
  5810. * @default false
  5811. * @product highcharts
  5812. * @apioption series.waterfall.data.isIntermediateSum
  5813. */
  5814. /**
  5815. * When this property is true, the point display the total sum across
  5816. * the entire series. The `y` value is ignored.
  5817. *
  5818. * @sample {highcharts} highcharts/demo/waterfall/
  5819. * Waterfall
  5820. *
  5821. * @type {boolean}
  5822. * @default false
  5823. * @product highcharts
  5824. * @apioption series.waterfall.data.isSum
  5825. */
  5826. ''; // adds doclets above to transpiled file
  5827. return WaterfallSeries;
  5828. });
  5829. _registerModule(_modules, 'Series/Polygon/PolygonSeries.js', [_modules['Core/Globals.js'], _modules['Mixins/LegendSymbol.js'], _modules['Core/Series/SeriesRegistry.js'], _modules['Core/Utilities.js']], function (H, LegendSymbolMixin, SeriesRegistry, U) {
  5830. /* *
  5831. *
  5832. * (c) 2010-2021 Torstein Honsi
  5833. *
  5834. * License: www.highcharts.com/license
  5835. *
  5836. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  5837. *
  5838. * */
  5839. var __extends = (this && this.__extends) || (function () {
  5840. var extendStatics = function (d,
  5841. b) {
  5842. extendStatics = Object.setPrototypeOf ||
  5843. ({ __proto__: [] } instanceof Array && function (d,
  5844. b) { d.__proto__ = b; }) ||
  5845. function (d,
  5846. b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  5847. return extendStatics(d, b);
  5848. };
  5849. return function (d, b) {
  5850. extendStatics(d, b);
  5851. function __() { this.constructor = d; }
  5852. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  5853. };
  5854. })();
  5855. var noop = H.noop;
  5856. var Series = SeriesRegistry.series,
  5857. _a = SeriesRegistry.seriesTypes,
  5858. AreaSeries = _a.area,
  5859. LineSeries = _a.line,
  5860. ScatterSeries = _a.scatter;
  5861. var extend = U.extend,
  5862. merge = U.merge;
  5863. /* *
  5864. *
  5865. * Class
  5866. *
  5867. * */
  5868. var PolygonSeries = /** @class */ (function (_super) {
  5869. __extends(PolygonSeries, _super);
  5870. function PolygonSeries() {
  5871. /* *
  5872. *
  5873. * Static properties
  5874. *
  5875. * */
  5876. var _this = _super !== null && _super.apply(this,
  5877. arguments) || this;
  5878. _this.data = void 0;
  5879. _this.options = void 0;
  5880. _this.points = void 0;
  5881. return _this;
  5882. }
  5883. /* *
  5884. *
  5885. * Functions
  5886. *
  5887. * */
  5888. PolygonSeries.prototype.getGraphPath = function () {
  5889. var graphPath = LineSeries.prototype.getGraphPath.call(this),
  5890. i = graphPath.length + 1;
  5891. // Close all segments
  5892. while (i--) {
  5893. if ((i === graphPath.length || graphPath[i][0] === 'M') && i > 0) {
  5894. graphPath.splice(i, 0, ['Z']);
  5895. }
  5896. }
  5897. this.areaPath = graphPath;
  5898. return graphPath;
  5899. };
  5900. PolygonSeries.prototype.drawGraph = function () {
  5901. // Hack into the fill logic in area.drawGraph
  5902. this.options.fillColor = this.color;
  5903. AreaSeries.prototype.drawGraph.call(this);
  5904. };
  5905. /**
  5906. * A polygon series can be used to draw any freeform shape in the cartesian
  5907. * coordinate system. A fill is applied with the `color` option, and
  5908. * stroke is applied through `lineWidth` and `lineColor` options.
  5909. *
  5910. * @sample {highcharts} highcharts/demo/polygon/
  5911. * Polygon
  5912. * @sample {highstock} highcharts/demo/polygon/
  5913. * Polygon
  5914. *
  5915. * @extends plotOptions.scatter
  5916. * @since 4.1.0
  5917. * @excluding jitter, softThreshold, threshold, cluster, boostThreshold,
  5918. * boostBlending
  5919. * @product highcharts highstock
  5920. * @requires highcharts-more
  5921. * @optionparent plotOptions.polygon
  5922. */
  5923. PolygonSeries.defaultOptions = merge(ScatterSeries.defaultOptions, {
  5924. marker: {
  5925. enabled: false,
  5926. states: {
  5927. hover: {
  5928. enabled: false
  5929. }
  5930. }
  5931. },
  5932. stickyTracking: false,
  5933. tooltip: {
  5934. followPointer: true,
  5935. pointFormat: ''
  5936. },
  5937. trackByArea: true
  5938. });
  5939. return PolygonSeries;
  5940. }(ScatterSeries));
  5941. extend(PolygonSeries.prototype, {
  5942. type: 'polygon',
  5943. drawLegendSymbol: LegendSymbolMixin.drawRectangle,
  5944. drawTracker: Series.prototype.drawTracker,
  5945. setStackedPoints: noop // No stacking points on polygons (#5310)
  5946. });
  5947. SeriesRegistry.registerSeriesType('polygon', PolygonSeries);
  5948. /* *
  5949. *
  5950. * Export
  5951. *
  5952. * */
  5953. /* *
  5954. *
  5955. * API Options
  5956. *
  5957. * */
  5958. /**
  5959. * A `polygon` series. If the [type](#series.polygon.type) option is
  5960. * not specified, it is inherited from [chart.type](#chart.type).
  5961. *
  5962. * @extends series,plotOptions.polygon
  5963. * @excluding dataParser, dataURL, stack, boostThreshold, boostBlending
  5964. * @product highcharts highstock
  5965. * @requires highcharts-more
  5966. * @apioption series.polygon
  5967. */
  5968. /**
  5969. * An array of data points for the series. For the `polygon` series
  5970. * type, points can be given in the following ways:
  5971. *
  5972. * 1. An array of numerical values. In this case, the numerical values will be
  5973. * interpreted as `y` options. The `x` values will be automatically
  5974. * calculated, either starting at 0 and incremented by 1, or from
  5975. * `pointStart` and `pointInterval` given in the series options. If the axis
  5976. * has categories, these will be used. Example:
  5977. * ```js
  5978. * data: [0, 5, 3, 5]
  5979. * ```
  5980. *
  5981. * 2. An array of arrays with 2 values. In this case, the values correspond to
  5982. * `x,y`. If the first value is a string, it is applied as the name of the
  5983. * point, and the `x` value is inferred.
  5984. * ```js
  5985. * data: [
  5986. * [0, 10],
  5987. * [1, 3],
  5988. * [2, 1]
  5989. * ]
  5990. * ```
  5991. *
  5992. * 3. An array of objects with named values. The following snippet shows only a
  5993. * few settings, see the complete options set below. If the total number of
  5994. * data points exceeds the series'
  5995. * [turboThreshold](#series.polygon.turboThreshold), this option is not
  5996. * available.
  5997. * ```js
  5998. * data: [{
  5999. * x: 1,
  6000. * y: 1,
  6001. * name: "Point2",
  6002. * color: "#00FF00"
  6003. * }, {
  6004. * x: 1,
  6005. * y: 8,
  6006. * name: "Point1",
  6007. * color: "#FF00FF"
  6008. * }]
  6009. * ```
  6010. *
  6011. * @sample {highcharts} highcharts/chart/reflow-true/
  6012. * Numerical values
  6013. * @sample {highcharts} highcharts/series/data-array-of-arrays/
  6014. * Arrays of numeric x and y
  6015. * @sample {highcharts} highcharts/series/data-array-of-arrays-datetime/
  6016. * Arrays of datetime x and y
  6017. * @sample {highcharts} highcharts/series/data-array-of-name-value/
  6018. * Arrays of point.name and y
  6019. * @sample {highcharts} highcharts/series/data-array-of-objects/
  6020. * Config objects
  6021. *
  6022. * @type {Array<number|Array<(number|string),(number|null)>|null|*>}
  6023. * @extends series.line.data
  6024. * @product highcharts highstock
  6025. * @apioption series.polygon.data
  6026. */
  6027. ''; // adds doclets above to transpiled file
  6028. return PolygonSeries;
  6029. });
  6030. _registerModule(_modules, 'Series/Bubble/BubblePoint.js', [_modules['Core/Series/Point.js'], _modules['Core/Series/SeriesRegistry.js'], _modules['Core/Utilities.js']], function (Point, SeriesRegistry, U) {
  6031. /* *
  6032. *
  6033. * (c) 2010-2021 Torstein Honsi
  6034. *
  6035. * License: www.highcharts.com/license
  6036. *
  6037. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  6038. *
  6039. * */
  6040. var __extends = (this && this.__extends) || (function () {
  6041. var extendStatics = function (d,
  6042. b) {
  6043. extendStatics = Object.setPrototypeOf ||
  6044. ({ __proto__: [] } instanceof Array && function (d,
  6045. b) { d.__proto__ = b; }) ||
  6046. function (d,
  6047. b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  6048. return extendStatics(d, b);
  6049. };
  6050. return function (d, b) {
  6051. extendStatics(d, b);
  6052. function __() { this.constructor = d; }
  6053. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  6054. };
  6055. })();
  6056. var ScatterPoint = SeriesRegistry.seriesTypes.scatter.prototype.pointClass;
  6057. var extend = U.extend;
  6058. /* *
  6059. *
  6060. * Class
  6061. *
  6062. * */
  6063. var BubblePoint = /** @class */ (function (_super) {
  6064. __extends(BubblePoint, _super);
  6065. function BubblePoint() {
  6066. /* *
  6067. *
  6068. * Properties
  6069. *
  6070. * */
  6071. var _this = _super !== null && _super.apply(this,
  6072. arguments) || this;
  6073. _this.options = void 0;
  6074. _this.series = void 0;
  6075. return _this;
  6076. /* eslint-enable valid-jsdoc */
  6077. }
  6078. /* *
  6079. *
  6080. * Functions
  6081. *
  6082. * */
  6083. /* eslint-disable valid-jsdoc */
  6084. /**
  6085. * @private
  6086. */
  6087. BubblePoint.prototype.haloPath = function (size) {
  6088. return Point.prototype.haloPath.call(this,
  6089. // #6067
  6090. size === 0 ? 0 : (this.marker ? this.marker.radius || 0 : 0) + size);
  6091. };
  6092. return BubblePoint;
  6093. }(ScatterPoint));
  6094. extend(BubblePoint.prototype, {
  6095. ttBelow: false
  6096. });
  6097. /* *
  6098. *
  6099. * Default Export
  6100. *
  6101. * */
  6102. return BubblePoint;
  6103. });
  6104. _registerModule(_modules, 'Series/Bubble/BubbleLegend.js', [_modules['Core/Chart/Chart.js'], _modules['Core/Color/Color.js'], _modules['Core/FormatUtilities.js'], _modules['Core/Globals.js'], _modules['Core/Legend.js'], _modules['Core/Options.js'], _modules['Core/Color/Palette.js'], _modules['Core/Series/Series.js'], _modules['Core/Utilities.js']], function (Chart, Color, F, H, Legend, O, palette, Series, U) {
  6105. /* *
  6106. *
  6107. * (c) 2010-2021 Highsoft AS
  6108. *
  6109. * Author: Paweł Potaczek
  6110. *
  6111. * License: www.highcharts.com/license
  6112. *
  6113. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  6114. *
  6115. * */
  6116. var color = Color.parse;
  6117. var noop = H.noop;
  6118. var setOptions = O.setOptions;
  6119. var addEvent = U.addEvent,
  6120. arrayMax = U.arrayMax,
  6121. arrayMin = U.arrayMin,
  6122. isNumber = U.isNumber,
  6123. merge = U.merge,
  6124. objectEach = U.objectEach,
  6125. pick = U.pick,
  6126. stableSort = U.stableSort,
  6127. wrap = U.wrap;
  6128. /**
  6129. * @interface Highcharts.BubbleLegendFormatterContextObject
  6130. */ /**
  6131. * The center y position of the range.
  6132. * @name Highcharts.BubbleLegendFormatterContextObject#center
  6133. * @type {number}
  6134. */ /**
  6135. * The radius of the bubble range.
  6136. * @name Highcharts.BubbleLegendFormatterContextObject#radius
  6137. * @type {number}
  6138. */ /**
  6139. * The bubble value.
  6140. * @name Highcharts.BubbleLegendFormatterContextObject#value
  6141. * @type {number}
  6142. */
  6143. ''; // detach doclets above
  6144. setOptions({
  6145. legend: {
  6146. /**
  6147. * The bubble legend is an additional element in legend which
  6148. * presents the scale of the bubble series. Individual bubble ranges
  6149. * can be defined by user or calculated from series. In the case of
  6150. * automatically calculated ranges, a 1px margin of error is
  6151. * permitted.
  6152. *
  6153. * @since 7.0.0
  6154. * @product highcharts highstock highmaps
  6155. * @requires highcharts-more
  6156. * @optionparent legend.bubbleLegend
  6157. */
  6158. bubbleLegend: {
  6159. /**
  6160. * The color of the ranges borders, can be also defined for an
  6161. * individual range.
  6162. *
  6163. * @sample highcharts/bubble-legend/similartoseries/
  6164. * Similar look to the bubble series
  6165. * @sample highcharts/bubble-legend/bordercolor/
  6166. * Individual bubble border color
  6167. *
  6168. * @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
  6169. */
  6170. borderColor: void 0,
  6171. /**
  6172. * The width of the ranges borders in pixels, can be also
  6173. * defined for an individual range.
  6174. */
  6175. borderWidth: 2,
  6176. /**
  6177. * An additional class name to apply to the bubble legend'
  6178. * circle graphical elements. This option does not replace
  6179. * default class names of the graphical element.
  6180. *
  6181. * @sample {highcharts} highcharts/css/bubble-legend/
  6182. * Styling by CSS
  6183. *
  6184. * @type {string}
  6185. */
  6186. className: void 0,
  6187. /**
  6188. * The main color of the bubble legend. Applies to ranges, if
  6189. * individual color is not defined.
  6190. *
  6191. * @sample highcharts/bubble-legend/similartoseries/
  6192. * Similar look to the bubble series
  6193. * @sample highcharts/bubble-legend/color/
  6194. * Individual bubble color
  6195. *
  6196. * @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
  6197. */
  6198. color: void 0,
  6199. /**
  6200. * An additional class name to apply to the bubble legend's
  6201. * connector graphical elements. This option does not replace
  6202. * default class names of the graphical element.
  6203. *
  6204. * @sample {highcharts} highcharts/css/bubble-legend/
  6205. * Styling by CSS
  6206. *
  6207. * @type {string}
  6208. */
  6209. connectorClassName: void 0,
  6210. /**
  6211. * The color of the connector, can be also defined
  6212. * for an individual range.
  6213. *
  6214. * @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
  6215. */
  6216. connectorColor: void 0,
  6217. /**
  6218. * The length of the connectors in pixels. If labels are
  6219. * centered, the distance is reduced to 0.
  6220. *
  6221. * @sample highcharts/bubble-legend/connectorandlabels/
  6222. * Increased connector length
  6223. */
  6224. connectorDistance: 60,
  6225. /**
  6226. * The width of the connectors in pixels.
  6227. *
  6228. * @sample highcharts/bubble-legend/connectorandlabels/
  6229. * Increased connector width
  6230. */
  6231. connectorWidth: 1,
  6232. /**
  6233. * Enable or disable the bubble legend.
  6234. */
  6235. enabled: false,
  6236. /**
  6237. * Options for the bubble legend labels.
  6238. */
  6239. labels: {
  6240. /**
  6241. * An additional class name to apply to the bubble legend
  6242. * label graphical elements. This option does not replace
  6243. * default class names of the graphical element.
  6244. *
  6245. * @sample {highcharts} highcharts/css/bubble-legend/
  6246. * Styling by CSS
  6247. *
  6248. * @type {string}
  6249. */
  6250. className: void 0,
  6251. /**
  6252. * Whether to allow data labels to overlap.
  6253. */
  6254. allowOverlap: false,
  6255. /**
  6256. * A format string for the bubble legend labels. Available
  6257. * variables are the same as for `formatter`.
  6258. *
  6259. * @sample highcharts/bubble-legend/format/
  6260. * Add a unit
  6261. *
  6262. * @type {string}
  6263. */
  6264. format: '',
  6265. /**
  6266. * Available `this` properties are:
  6267. *
  6268. * - `this.value`: The bubble value.
  6269. *
  6270. * - `this.radius`: The radius of the bubble range.
  6271. *
  6272. * - `this.center`: The center y position of the range.
  6273. *
  6274. * @type {Highcharts.FormatterCallbackFunction<Highcharts.BubbleLegendFormatterContextObject>}
  6275. */
  6276. formatter: void 0,
  6277. /**
  6278. * The alignment of the labels compared to the bubble
  6279. * legend. Can be one of `left`, `center` or `right`.
  6280. *
  6281. * @sample highcharts/bubble-legend/connectorandlabels/
  6282. * Labels on left
  6283. *
  6284. * @type {Highcharts.AlignValue}
  6285. */
  6286. align: 'right',
  6287. /**
  6288. * CSS styles for the labels.
  6289. *
  6290. * @type {Highcharts.CSSObject}
  6291. */
  6292. style: {
  6293. /** @ignore-option */
  6294. fontSize: '10px',
  6295. /** @ignore-option */
  6296. color: palette.neutralColor100
  6297. },
  6298. /**
  6299. * The x position offset of the label relative to the
  6300. * connector.
  6301. */
  6302. x: 0,
  6303. /**
  6304. * The y position offset of the label relative to the
  6305. * connector.
  6306. */
  6307. y: 0
  6308. },
  6309. /**
  6310. * Miximum bubble legend range size. If values for ranges are
  6311. * not specified, the `minSize` and the `maxSize` are calculated
  6312. * from bubble series.
  6313. */
  6314. maxSize: 60,
  6315. /**
  6316. * Minimum bubble legend range size. If values for ranges are
  6317. * not specified, the `minSize` and the `maxSize` are calculated
  6318. * from bubble series.
  6319. */
  6320. minSize: 10,
  6321. /**
  6322. * The position of the bubble legend in the legend.
  6323. * @sample highcharts/bubble-legend/connectorandlabels/
  6324. * Bubble legend as last item in legend
  6325. */
  6326. legendIndex: 0,
  6327. /**
  6328. * Options for specific range. One range consists of bubble,
  6329. * label and connector.
  6330. *
  6331. * @sample highcharts/bubble-legend/ranges/
  6332. * Manually defined ranges
  6333. * @sample highcharts/bubble-legend/autoranges/
  6334. * Auto calculated ranges
  6335. *
  6336. * @type {Array<*>}
  6337. */
  6338. ranges: {
  6339. /**
  6340. * Range size value, similar to bubble Z data.
  6341. * @type {number}
  6342. */
  6343. value: void 0,
  6344. /**
  6345. * The color of the border for individual range.
  6346. * @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
  6347. */
  6348. borderColor: void 0,
  6349. /**
  6350. * The color of the bubble for individual range.
  6351. * @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
  6352. */
  6353. color: void 0,
  6354. /**
  6355. * The color of the connector for individual range.
  6356. * @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
  6357. */
  6358. connectorColor: void 0
  6359. },
  6360. /**
  6361. * Whether the bubble legend range value should be represented
  6362. * by the area or the width of the bubble. The default, area,
  6363. * corresponds best to the human perception of the size of each
  6364. * bubble.
  6365. *
  6366. * @sample highcharts/bubble-legend/ranges/
  6367. * Size by width
  6368. *
  6369. * @type {Highcharts.BubbleSizeByValue}
  6370. */
  6371. sizeBy: 'area',
  6372. /**
  6373. * When this is true, the absolute value of z determines the
  6374. * size of the bubble. This means that with the default
  6375. * zThreshold of 0, a bubble of value -1 will have the same size
  6376. * as a bubble of value 1, while a bubble of value 0 will have a
  6377. * smaller size according to minSize.
  6378. */
  6379. sizeByAbsoluteValue: false,
  6380. /**
  6381. * Define the visual z index of the bubble legend.
  6382. */
  6383. zIndex: 1,
  6384. /**
  6385. * Ranges with with lower value than zThreshold, are skipped.
  6386. */
  6387. zThreshold: 0
  6388. }
  6389. }
  6390. });
  6391. /* eslint-disable no-invalid-this, valid-jsdoc */
  6392. /**
  6393. * BubbleLegend class.
  6394. *
  6395. * @private
  6396. * @class
  6397. * @name Highcharts.BubbleLegend
  6398. * @param {Highcharts.LegendBubbleLegendOptions} options
  6399. * Bubble legend options
  6400. * @param {Highcharts.Legend} legend
  6401. * Legend
  6402. */
  6403. var BubbleLegend = /** @class */ (function () {
  6404. function BubbleLegend(options, legend) {
  6405. this.chart = void 0;
  6406. this.fontMetrics = void 0;
  6407. this.legend = void 0;
  6408. this.legendGroup = void 0;
  6409. this.legendItem = void 0;
  6410. this.legendItemHeight = void 0;
  6411. this.legendItemWidth = void 0;
  6412. this.legendSymbol = void 0;
  6413. this.maxLabel = void 0;
  6414. this.movementX = void 0;
  6415. this.ranges = void 0;
  6416. this.visible = void 0;
  6417. this.symbols = void 0;
  6418. this.options = void 0;
  6419. this.setState = noop;
  6420. this.init(options, legend);
  6421. }
  6422. /**
  6423. * Create basic bubbleLegend properties similar to item in legend.
  6424. *
  6425. * @private
  6426. * @function Highcharts.BubbleLegend#init
  6427. * @param {Highcharts.LegendBubbleLegendOptions} options
  6428. * Bubble legend options
  6429. * @param {Highcharts.Legend} legend
  6430. * Legend
  6431. * @return {void}
  6432. */
  6433. BubbleLegend.prototype.init = function (options, legend) {
  6434. this.options = options;
  6435. this.visible = true;
  6436. this.chart = legend.chart;
  6437. this.legend = legend;
  6438. };
  6439. /**
  6440. * Depending on the position option, add bubbleLegend to legend items.
  6441. *
  6442. * @private
  6443. * @function Highcharts.BubbleLegend#addToLegend
  6444. * @param {Array<(Highcharts.Point|Highcharts.Series)>}
  6445. * All legend items
  6446. * @return {void}
  6447. */
  6448. BubbleLegend.prototype.addToLegend = function (items) {
  6449. // Insert bubbleLegend into legend items
  6450. items.splice(this.options.legendIndex, 0, this);
  6451. };
  6452. /**
  6453. * Calculate ranges, sizes and call the next steps of bubbleLegend
  6454. * creation.
  6455. *
  6456. * @private
  6457. * @function Highcharts.BubbleLegend#drawLegendSymbol
  6458. * @param {Highcharts.Legend} legend
  6459. * Legend instance
  6460. * @return {void}
  6461. */
  6462. BubbleLegend.prototype.drawLegendSymbol = function (legend) {
  6463. var chart = this.chart,
  6464. options = this.options,
  6465. size,
  6466. itemDistance = pick(legend.options.itemDistance, 20),
  6467. connectorSpace,
  6468. ranges = options.ranges,
  6469. radius,
  6470. maxLabel,
  6471. connectorDistance = options.connectorDistance;
  6472. // Predict label dimensions
  6473. this.fontMetrics = chart.renderer.fontMetrics(options.labels.style.fontSize);
  6474. // Do not create bubbleLegend now if ranges or ranges valeus are not
  6475. // specified or if are empty array.
  6476. if (!ranges || !ranges.length || !isNumber(ranges[0].value)) {
  6477. legend.options.bubbleLegend.autoRanges = true;
  6478. return;
  6479. }
  6480. // Sort ranges to right render order
  6481. stableSort(ranges, function (a, b) {
  6482. return b.value - a.value;
  6483. });
  6484. this.ranges = ranges;
  6485. this.setOptions();
  6486. this.render();
  6487. // Get max label size
  6488. maxLabel = this.getMaxLabelSize();
  6489. radius = this.ranges[0].radius;
  6490. size = radius * 2;
  6491. // Space for connectors and labels.
  6492. connectorSpace =
  6493. connectorDistance - radius + maxLabel.width;
  6494. connectorSpace = connectorSpace > 0 ? connectorSpace : 0;
  6495. this.maxLabel = maxLabel;
  6496. this.movementX = options.labels.align === 'left' ?
  6497. connectorSpace : 0;
  6498. this.legendItemWidth = size + connectorSpace + itemDistance;
  6499. this.legendItemHeight = size + this.fontMetrics.h / 2;
  6500. };
  6501. /**
  6502. * Set style options for each bubbleLegend range.
  6503. *
  6504. * @private
  6505. * @function Highcharts.BubbleLegend#setOptions
  6506. * @return {void}
  6507. */
  6508. BubbleLegend.prototype.setOptions = function () {
  6509. var ranges = this.ranges,
  6510. options = this.options,
  6511. series = this.chart.series[options.seriesIndex],
  6512. baseline = this.legend.baseline,
  6513. bubbleAttribs = {
  6514. zIndex: options.zIndex,
  6515. 'stroke-width': options.borderWidth
  6516. },
  6517. connectorAttribs = {
  6518. zIndex: options.zIndex,
  6519. 'stroke-width': options.connectorWidth
  6520. },
  6521. labelAttribs = {
  6522. align: (this.legend.options.rtl ||
  6523. options.labels.align === 'left') ? 'right' : 'left',
  6524. zIndex: options.zIndex
  6525. },
  6526. fillOpacity = series.options.marker.fillOpacity,
  6527. styledMode = this.chart.styledMode;
  6528. // Allow to parts of styles be used individually for range
  6529. ranges.forEach(function (range, i) {
  6530. if (!styledMode) {
  6531. bubbleAttribs.stroke = pick(range.borderColor, options.borderColor, series.color);
  6532. bubbleAttribs.fill = pick(range.color, options.color, fillOpacity !== 1 ?
  6533. color(series.color).setOpacity(fillOpacity)
  6534. .get('rgba') :
  6535. series.color);
  6536. connectorAttribs.stroke = pick(range.connectorColor, options.connectorColor, series.color);
  6537. }
  6538. // Set options needed for rendering each range
  6539. ranges[i].radius = this.getRangeRadius(range.value);
  6540. ranges[i] = merge(ranges[i], {
  6541. center: (ranges[0].radius - ranges[i].radius +
  6542. baseline)
  6543. });
  6544. if (!styledMode) {
  6545. merge(true, ranges[i], {
  6546. bubbleAttribs: merge(bubbleAttribs),
  6547. connectorAttribs: merge(connectorAttribs),
  6548. labelAttribs: labelAttribs
  6549. });
  6550. }
  6551. }, this);
  6552. };
  6553. /**
  6554. * Calculate radius for each bubble range,
  6555. * used code from BubbleSeries.js 'getRadius' method.
  6556. *
  6557. * @private
  6558. * @function Highcharts.BubbleLegend#getRangeRadius
  6559. * @param {number} value
  6560. * Range value
  6561. * @return {number|null}
  6562. * Radius for one range
  6563. */
  6564. BubbleLegend.prototype.getRangeRadius = function (value) {
  6565. var options = this.options,
  6566. seriesIndex = this.options.seriesIndex,
  6567. bubbleSeries = this.chart.series[seriesIndex],
  6568. zMax = options.ranges[0].value,
  6569. zMin = options.ranges[options.ranges.length - 1].value,
  6570. minSize = options.minSize,
  6571. maxSize = options.maxSize;
  6572. return bubbleSeries.getRadius.call(this, zMin, zMax, minSize, maxSize, value);
  6573. };
  6574. /**
  6575. * Render the legendSymbol group.
  6576. *
  6577. * @private
  6578. * @function Highcharts.BubbleLegend#render
  6579. * @return {void}
  6580. */
  6581. BubbleLegend.prototype.render = function () {
  6582. var renderer = this.chart.renderer,
  6583. zThreshold = this.options.zThreshold;
  6584. if (!this.symbols) {
  6585. this.symbols = {
  6586. connectors: [],
  6587. bubbleItems: [],
  6588. labels: []
  6589. };
  6590. }
  6591. // Nesting SVG groups to enable handleOverflow
  6592. this.legendSymbol = renderer.g('bubble-legend');
  6593. this.legendItem = renderer.g('bubble-legend-item');
  6594. // To enable default 'hideOverlappingLabels' method
  6595. this.legendSymbol.translateX = 0;
  6596. this.legendSymbol.translateY = 0;
  6597. this.ranges.forEach(function (range) {
  6598. if (range.value >= zThreshold) {
  6599. this.renderRange(range);
  6600. }
  6601. }, this);
  6602. // To use handleOverflow method
  6603. this.legendSymbol.add(this.legendItem);
  6604. this.legendItem.add(this.legendGroup);
  6605. this.hideOverlappingLabels();
  6606. };
  6607. /**
  6608. * Render one range, consisting of bubble symbol, connector and label.
  6609. *
  6610. * @private
  6611. * @function Highcharts.BubbleLegend#renderRange
  6612. * @param {Highcharts.LegendBubbleLegendRangesOptions} range
  6613. * Range options
  6614. * @return {void}
  6615. */
  6616. BubbleLegend.prototype.renderRange = function (range) {
  6617. var mainRange = this.ranges[0],
  6618. legend = this.legend,
  6619. options = this.options,
  6620. labelsOptions = options.labels,
  6621. chart = this.chart,
  6622. bubbleSeries = chart.series[options.seriesIndex],
  6623. renderer = chart.renderer,
  6624. symbols = this.symbols,
  6625. labels = symbols.labels,
  6626. label,
  6627. elementCenter = range.center,
  6628. absoluteRadius = Math.abs(range.radius),
  6629. connectorDistance = options.connectorDistance || 0,
  6630. labelsAlign = labelsOptions.align,
  6631. rtl = legend.options.rtl,
  6632. connectorLength = rtl || labelsAlign === 'left' ?
  6633. -connectorDistance : connectorDistance,
  6634. borderWidth = options.borderWidth,
  6635. connectorWidth = options.connectorWidth,
  6636. posX = mainRange.radius || 0,
  6637. posY = elementCenter - absoluteRadius -
  6638. borderWidth / 2 + connectorWidth / 2,
  6639. labelY,
  6640. labelX,
  6641. fontMetrics = this.fontMetrics,
  6642. labelMovement = fontMetrics.f / 2 -
  6643. (fontMetrics.h - fontMetrics.f) / 2,
  6644. crispMovement = (posY % 1 ? 1 : 0.5) -
  6645. (connectorWidth % 2 ? 0 : 0.5),
  6646. styledMode = renderer.styledMode;
  6647. // Set options for centered labels
  6648. if (labelsAlign === 'center') {
  6649. connectorLength = 0; // do not use connector
  6650. options.connectorDistance = 0;
  6651. range.labelAttribs.align = 'center';
  6652. }
  6653. labelY = posY + options.labels.y;
  6654. labelX = posX + connectorLength + options.labels.x;
  6655. // Render bubble symbol
  6656. symbols.bubbleItems.push(renderer
  6657. .circle(posX, elementCenter + crispMovement, absoluteRadius)
  6658. .attr(styledMode ? {} : range.bubbleAttribs)
  6659. .addClass((styledMode ?
  6660. 'highcharts-color-' +
  6661. bubbleSeries.colorIndex + ' ' :
  6662. '') +
  6663. 'highcharts-bubble-legend-symbol ' +
  6664. (options.className || '')).add(this.legendSymbol));
  6665. // Render connector
  6666. symbols.connectors.push(renderer
  6667. .path(renderer.crispLine([
  6668. ['M', posX, posY],
  6669. ['L', posX + connectorLength, posY]
  6670. ], options.connectorWidth))
  6671. .attr((styledMode ? {} : range.connectorAttribs))
  6672. .addClass((styledMode ?
  6673. 'highcharts-color-' +
  6674. this.options.seriesIndex + ' ' : '') +
  6675. 'highcharts-bubble-legend-connectors ' +
  6676. (options.connectorClassName || '')).add(this.legendSymbol));
  6677. // Render label
  6678. label = renderer
  6679. .text(this.formatLabel(range), labelX, labelY + labelMovement)
  6680. .attr((styledMode ? {} : range.labelAttribs))
  6681. .css(styledMode ? {} : labelsOptions.style)
  6682. .addClass('highcharts-bubble-legend-labels ' +
  6683. (options.labels.className || '')).add(this.legendSymbol);
  6684. labels.push(label);
  6685. // To enable default 'hideOverlappingLabels' method
  6686. label.placed = true;
  6687. label.alignAttr = {
  6688. x: labelX,
  6689. y: labelY + labelMovement
  6690. };
  6691. };
  6692. /**
  6693. * Get the label which takes up the most space.
  6694. *
  6695. * @private
  6696. * @function Highcharts.BubbleLegend#getMaxLabelSize
  6697. * @return {Highcharts.BBoxObject}
  6698. */
  6699. BubbleLegend.prototype.getMaxLabelSize = function () {
  6700. var labels = this.symbols.labels,
  6701. maxLabel,
  6702. labelSize;
  6703. labels.forEach(function (label) {
  6704. labelSize = label.getBBox(true);
  6705. if (maxLabel) {
  6706. maxLabel = labelSize.width > maxLabel.width ?
  6707. labelSize : maxLabel;
  6708. }
  6709. else {
  6710. maxLabel = labelSize;
  6711. }
  6712. });
  6713. return maxLabel || {};
  6714. };
  6715. /**
  6716. * Get formatted label for range.
  6717. *
  6718. * @private
  6719. * @function Highcharts.BubbleLegend#formatLabel
  6720. * @param {Highcharts.LegendBubbleLegendRangesOptions} range
  6721. * Range options
  6722. * @return {string}
  6723. * Range label text
  6724. */
  6725. BubbleLegend.prototype.formatLabel = function (range) {
  6726. var options = this.options,
  6727. formatter = options.labels.formatter,
  6728. format = options.labels.format;
  6729. var numberFormatter = this.chart.numberFormatter;
  6730. return format ? F.format(format, range) :
  6731. formatter ? formatter.call(range) :
  6732. numberFormatter(range.value, 1);
  6733. };
  6734. /**
  6735. * By using default chart 'hideOverlappingLabels' method, hide or show
  6736. * labels and connectors.
  6737. *
  6738. * @private
  6739. * @function Highcharts.BubbleLegend#hideOverlappingLabels
  6740. * @return {void}
  6741. */
  6742. BubbleLegend.prototype.hideOverlappingLabels = function () {
  6743. var chart = this.chart,
  6744. allowOverlap = this.options.labels.allowOverlap,
  6745. symbols = this.symbols;
  6746. if (!allowOverlap && symbols) {
  6747. chart.hideOverlappingLabels(symbols.labels);
  6748. // Hide or show connectors
  6749. symbols.labels.forEach(function (label, index) {
  6750. if (!label.newOpacity) {
  6751. symbols.connectors[index].hide();
  6752. }
  6753. else if (label.newOpacity !== label.oldOpacity) {
  6754. symbols.connectors[index].show();
  6755. }
  6756. });
  6757. }
  6758. };
  6759. /**
  6760. * Calculate ranges from created series.
  6761. *
  6762. * @private
  6763. * @function Highcharts.BubbleLegend#getRanges
  6764. * @return {Array<Highcharts.LegendBubbleLegendRangesOptions>}
  6765. * Array of range objects
  6766. */
  6767. BubbleLegend.prototype.getRanges = function () {
  6768. var bubbleLegend = this.legend.bubbleLegend,
  6769. series = bubbleLegend.chart.series,
  6770. ranges,
  6771. rangesOptions = bubbleLegend.options.ranges,
  6772. zData,
  6773. minZ = Number.MAX_VALUE,
  6774. maxZ = -Number.MAX_VALUE;
  6775. series.forEach(function (s) {
  6776. // Find the min and max Z, like in bubble series
  6777. if (s.isBubble && !s.ignoreSeries) {
  6778. zData = s.zData.filter(isNumber);
  6779. if (zData.length) {
  6780. minZ = pick(s.options.zMin, Math.min(minZ, Math.max(arrayMin(zData), s.options.displayNegative === false ?
  6781. s.options.zThreshold :
  6782. -Number.MAX_VALUE)));
  6783. maxZ = pick(s.options.zMax, Math.max(maxZ, arrayMax(zData)));
  6784. }
  6785. }
  6786. });
  6787. // Set values for ranges
  6788. if (minZ === maxZ) {
  6789. // Only one range if min and max values are the same.
  6790. ranges = [{ value: maxZ }];
  6791. }
  6792. else {
  6793. ranges = [
  6794. { value: minZ },
  6795. { value: (minZ + maxZ) / 2 },
  6796. { value: maxZ, autoRanges: true }
  6797. ];
  6798. }
  6799. // Prevent reverse order of ranges after redraw
  6800. if (rangesOptions.length && rangesOptions[0].radius) {
  6801. ranges.reverse();
  6802. }
  6803. // Merge ranges values with user options
  6804. ranges.forEach(function (range, i) {
  6805. if (rangesOptions && rangesOptions[i]) {
  6806. ranges[i] = merge(rangesOptions[i], range);
  6807. }
  6808. });
  6809. return ranges;
  6810. };
  6811. /**
  6812. * Calculate bubble legend sizes from rendered series.
  6813. *
  6814. * @private
  6815. * @function Highcharts.BubbleLegend#predictBubbleSizes
  6816. * @return {Array<number,number>}
  6817. * Calculated min and max bubble sizes
  6818. */
  6819. BubbleLegend.prototype.predictBubbleSizes = function () {
  6820. var chart = this.chart,
  6821. fontMetrics = this.fontMetrics,
  6822. legendOptions = chart.legend.options,
  6823. floating = legendOptions.floating,
  6824. horizontal = legendOptions.layout === 'horizontal',
  6825. lastLineHeight = horizontal ? chart.legend.lastLineHeight : 0,
  6826. plotSizeX = chart.plotSizeX,
  6827. plotSizeY = chart.plotSizeY,
  6828. bubbleSeries = chart.series[this.options.seriesIndex],
  6829. minSize = Math.ceil(bubbleSeries.minPxSize),
  6830. maxPxSize = Math.ceil(bubbleSeries.maxPxSize),
  6831. maxSize = bubbleSeries.options.maxSize,
  6832. plotSize = Math.min(plotSizeY,
  6833. plotSizeX),
  6834. calculatedSize;
  6835. // Calculate prediceted max size of bubble
  6836. if (floating || !(/%$/.test(maxSize))) {
  6837. calculatedSize = maxPxSize;
  6838. }
  6839. else {
  6840. maxSize = parseFloat(maxSize);
  6841. calculatedSize = ((plotSize + lastLineHeight -
  6842. fontMetrics.h / 2) * maxSize / 100) / (maxSize / 100 + 1);
  6843. // Get maxPxSize from bubble series if calculated bubble legend
  6844. // size will not affect to bubbles series.
  6845. if ((horizontal && plotSizeY - calculatedSize >=
  6846. plotSizeX) || (!horizontal && plotSizeX -
  6847. calculatedSize >= plotSizeY)) {
  6848. calculatedSize = maxPxSize;
  6849. }
  6850. }
  6851. return [minSize, Math.ceil(calculatedSize)];
  6852. };
  6853. /**
  6854. * Correct ranges with calculated sizes.
  6855. *
  6856. * @private
  6857. * @function Highcharts.BubbleLegend#updateRanges
  6858. * @param {number} min
  6859. * @param {number} max
  6860. * @return {void}
  6861. */
  6862. BubbleLegend.prototype.updateRanges = function (min, max) {
  6863. var bubbleLegendOptions = this.legend.options.bubbleLegend;
  6864. bubbleLegendOptions.minSize = min;
  6865. bubbleLegendOptions.maxSize = max;
  6866. bubbleLegendOptions.ranges = this.getRanges();
  6867. };
  6868. /**
  6869. * Because of the possibility of creating another legend line, predicted
  6870. * bubble legend sizes may differ by a few pixels, so it is necessary to
  6871. * correct them.
  6872. *
  6873. * @private
  6874. * @function Highcharts.BubbleLegend#correctSizes
  6875. * @return {void}
  6876. */
  6877. BubbleLegend.prototype.correctSizes = function () {
  6878. var legend = this.legend,
  6879. chart = this.chart,
  6880. bubbleSeries = chart.series[this.options.seriesIndex],
  6881. bubbleSeriesSize = bubbleSeries.maxPxSize,
  6882. bubbleLegendSize = this.options.maxSize;
  6883. if (Math.abs(Math.ceil(bubbleSeriesSize) - bubbleLegendSize) >
  6884. 1) {
  6885. this.updateRanges(this.options.minSize, bubbleSeries.maxPxSize);
  6886. legend.render();
  6887. }
  6888. };
  6889. return BubbleLegend;
  6890. }());
  6891. // Start the bubble legend creation process.
  6892. addEvent(Legend, 'afterGetAllItems', function (e) {
  6893. var legend = this,
  6894. bubbleLegend = legend.bubbleLegend,
  6895. legendOptions = legend.options,
  6896. options = legendOptions.bubbleLegend,
  6897. bubbleSeriesIndex = legend.chart.getVisibleBubbleSeriesIndex();
  6898. // Remove unnecessary element
  6899. if (bubbleLegend && bubbleLegend.ranges && bubbleLegend.ranges.length) {
  6900. // Allow change the way of calculating ranges in update
  6901. if (options.ranges.length) {
  6902. options.autoRanges =
  6903. !!options.ranges[0].autoRanges;
  6904. }
  6905. // Update bubbleLegend dimensions in each redraw
  6906. legend.destroyItem(bubbleLegend);
  6907. }
  6908. // Create bubble legend
  6909. if (bubbleSeriesIndex >= 0 &&
  6910. legendOptions.enabled &&
  6911. options.enabled) {
  6912. options.seriesIndex = bubbleSeriesIndex;
  6913. legend.bubbleLegend = new H.BubbleLegend(options, legend);
  6914. legend.bubbleLegend.addToLegend(e.allItems);
  6915. }
  6916. });
  6917. /**
  6918. * Check if there is at least one visible bubble series.
  6919. *
  6920. * @private
  6921. * @function Highcharts.Chart#getVisibleBubbleSeriesIndex
  6922. * @return {number}
  6923. * First visible bubble series index
  6924. */
  6925. Chart.prototype.getVisibleBubbleSeriesIndex = function () {
  6926. var series = this.series,
  6927. i = 0;
  6928. while (i < series.length) {
  6929. if (series[i] &&
  6930. series[i].isBubble &&
  6931. series[i].visible &&
  6932. series[i].zData.length) {
  6933. return i;
  6934. }
  6935. i++;
  6936. }
  6937. return -1;
  6938. };
  6939. /**
  6940. * Calculate height for each row in legend.
  6941. *
  6942. * @private
  6943. * @function Highcharts.Legend#getLinesHeights
  6944. * @return {Array<Highcharts.Dictionary<number>>}
  6945. * Informations about line height and items amount
  6946. */
  6947. Legend.prototype.getLinesHeights = function () {
  6948. var items = this.allItems,
  6949. lines = [],
  6950. lastLine,
  6951. length = items.length,
  6952. i = 0,
  6953. j = 0;
  6954. for (i = 0; i < length; i++) {
  6955. if (items[i].legendItemHeight) {
  6956. // for bubbleLegend
  6957. items[i].itemHeight = items[i].legendItemHeight;
  6958. }
  6959. if ( // Line break
  6960. items[i] === items[length - 1] ||
  6961. items[i + 1] &&
  6962. items[i]._legendItemPos[1] !==
  6963. items[i + 1]._legendItemPos[1]) {
  6964. lines.push({ height: 0 });
  6965. lastLine = lines[lines.length - 1];
  6966. // Find the highest item in line
  6967. for (j; j <= i; j++) {
  6968. if (items[j].itemHeight > lastLine.height) {
  6969. lastLine.height = items[j].itemHeight;
  6970. }
  6971. }
  6972. lastLine.step = i;
  6973. }
  6974. }
  6975. return lines;
  6976. };
  6977. /**
  6978. * Correct legend items translation in case of different elements heights.
  6979. *
  6980. * @private
  6981. * @function Highcharts.Legend#retranslateItems
  6982. * @param {Array<Highcharts.Dictionary<number>>} lines
  6983. * Informations about line height and items amount
  6984. * @return {void}
  6985. */
  6986. Legend.prototype.retranslateItems = function (lines) {
  6987. var items = this.allItems,
  6988. orgTranslateX,
  6989. orgTranslateY,
  6990. movementX,
  6991. rtl = this.options.rtl,
  6992. actualLine = 0;
  6993. items.forEach(function (item, index) {
  6994. orgTranslateX = item.legendGroup.translateX;
  6995. orgTranslateY = item._legendItemPos[1];
  6996. movementX = item.movementX;
  6997. if (movementX || (rtl && item.ranges)) {
  6998. movementX = rtl ?
  6999. orgTranslateX - item.options.maxSize / 2 :
  7000. orgTranslateX + movementX;
  7001. item.legendGroup.attr({ translateX: movementX });
  7002. }
  7003. if (index > lines[actualLine].step) {
  7004. actualLine++;
  7005. }
  7006. item.legendGroup.attr({
  7007. translateY: Math.round(orgTranslateY + lines[actualLine].height / 2)
  7008. });
  7009. item._legendItemPos[1] = orgTranslateY +
  7010. lines[actualLine].height / 2;
  7011. });
  7012. };
  7013. // Toggle bubble legend depending on the visible status of bubble series.
  7014. addEvent(Series, 'legendItemClick', function () {
  7015. var series = this,
  7016. chart = series.chart,
  7017. visible = series.visible,
  7018. legend = series.chart.legend,
  7019. status;
  7020. if (legend && legend.bubbleLegend) {
  7021. // Temporary correct 'visible' property
  7022. series.visible = !visible;
  7023. // Save future status for getRanges method
  7024. series.ignoreSeries = visible;
  7025. // Check if at lest one bubble series is visible
  7026. status = chart.getVisibleBubbleSeriesIndex() >= 0;
  7027. // Hide bubble legend if all bubble series are disabled
  7028. if (legend.bubbleLegend.visible !== status) {
  7029. // Show or hide bubble legend
  7030. legend.update({
  7031. bubbleLegend: { enabled: status }
  7032. });
  7033. legend.bubbleLegend.visible = status; // Restore default status
  7034. }
  7035. series.visible = visible;
  7036. }
  7037. });
  7038. // If ranges are not specified, determine ranges from rendered bubble series
  7039. // and render legend again.
  7040. wrap(Chart.prototype, 'drawChartBox', function (proceed, options, callback) {
  7041. var chart = this,
  7042. legend = chart.legend,
  7043. bubbleSeries = chart.getVisibleBubbleSeriesIndex() >= 0,
  7044. bubbleLegendOptions,
  7045. bubbleSizes;
  7046. if (legend && legend.options.enabled && legend.bubbleLegend &&
  7047. legend.options.bubbleLegend.autoRanges && bubbleSeries) {
  7048. bubbleLegendOptions = legend.bubbleLegend.options;
  7049. bubbleSizes = legend.bubbleLegend.predictBubbleSizes();
  7050. legend.bubbleLegend.updateRanges(bubbleSizes[0], bubbleSizes[1]);
  7051. // Disable animation on init
  7052. if (!bubbleLegendOptions.placed) {
  7053. legend.group.placed = false;
  7054. legend.allItems.forEach(function (item) {
  7055. item.legendGroup.translateY = null;
  7056. });
  7057. }
  7058. // Create legend with bubbleLegend
  7059. legend.render();
  7060. chart.getMargins();
  7061. chart.axes.forEach(function (axis) {
  7062. if (axis.visible) { // #11448
  7063. axis.render();
  7064. }
  7065. if (!bubbleLegendOptions.placed) {
  7066. axis.setScale();
  7067. axis.updateNames();
  7068. // Disable axis animation on init
  7069. objectEach(axis.ticks, function (tick) {
  7070. tick.isNew = true;
  7071. tick.isNewLabel = true;
  7072. });
  7073. }
  7074. });
  7075. bubbleLegendOptions.placed = true;
  7076. // After recalculate axes, calculate margins again.
  7077. chart.getMargins();
  7078. // Call default 'drawChartBox' method.
  7079. proceed.call(chart, options, callback);
  7080. // Check bubble legend sizes and correct them if necessary.
  7081. legend.bubbleLegend.correctSizes();
  7082. // Correct items positions with different dimensions in legend.
  7083. legend.retranslateItems(legend.getLinesHeights());
  7084. }
  7085. else {
  7086. proceed.call(chart, options, callback);
  7087. // Allow color change on static bubble legend after click on legend
  7088. if (legend && legend.options.enabled && legend.bubbleLegend) {
  7089. legend.render();
  7090. legend.retranslateItems(legend.getLinesHeights());
  7091. }
  7092. }
  7093. });
  7094. H.BubbleLegend = BubbleLegend;
  7095. return H.BubbleLegend;
  7096. });
  7097. _registerModule(_modules, 'Series/Bubble/BubbleSeries.js', [_modules['Core/Axis/Axis.js'], _modules['Series/Bubble/BubblePoint.js'], _modules['Core/Color/Color.js'], _modules['Core/Globals.js'], _modules['Core/Series/Series.js'], _modules['Core/Series/SeriesRegistry.js'], _modules['Core/Utilities.js']], function (Axis, BubblePoint, Color, H, Series, SeriesRegistry, U) {
  7098. /* *
  7099. *
  7100. * (c) 2010-2021 Torstein Honsi
  7101. *
  7102. * License: www.highcharts.com/license
  7103. *
  7104. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  7105. *
  7106. * */
  7107. var __extends = (this && this.__extends) || (function () {
  7108. var extendStatics = function (d,
  7109. b) {
  7110. extendStatics = Object.setPrototypeOf ||
  7111. ({ __proto__: [] } instanceof Array && function (d,
  7112. b) { d.__proto__ = b; }) ||
  7113. function (d,
  7114. b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  7115. return extendStatics(d, b);
  7116. };
  7117. return function (d, b) {
  7118. extendStatics(d, b);
  7119. function __() { this.constructor = d; }
  7120. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  7121. };
  7122. })();
  7123. var color = Color.parse;
  7124. var noop = H.noop;
  7125. var _a = SeriesRegistry.seriesTypes,
  7126. ColumnSeries = _a.column,
  7127. ScatterSeries = _a.scatter;
  7128. var arrayMax = U.arrayMax,
  7129. arrayMin = U.arrayMin,
  7130. clamp = U.clamp,
  7131. extend = U.extend,
  7132. isNumber = U.isNumber,
  7133. merge = U.merge,
  7134. pick = U.pick,
  7135. pInt = U.pInt;
  7136. /* *
  7137. *
  7138. * Class
  7139. *
  7140. * */
  7141. var BubbleSeries = /** @class */ (function (_super) {
  7142. __extends(BubbleSeries, _super);
  7143. function BubbleSeries() {
  7144. /* *
  7145. *
  7146. * Static Properties
  7147. *
  7148. * */
  7149. var _this = _super !== null && _super.apply(this,
  7150. arguments) || this;
  7151. /* *
  7152. *
  7153. * Properties
  7154. *
  7155. * */
  7156. _this.data = void 0;
  7157. _this.maxPxSize = void 0;
  7158. _this.minPxSize = void 0;
  7159. _this.options = void 0;
  7160. _this.points = void 0;
  7161. _this.radii = void 0;
  7162. _this.yData = void 0;
  7163. _this.zData = void 0;
  7164. return _this;
  7165. /* eslint-enable valid-jsdoc */
  7166. }
  7167. /* *
  7168. *
  7169. * Functions
  7170. *
  7171. * */
  7172. /* eslint-disable valid-jsdoc */
  7173. /**
  7174. * Perform animation on the bubbles
  7175. * @private
  7176. */
  7177. BubbleSeries.prototype.animate = function (init) {
  7178. if (!init &&
  7179. this.points.length < this.options.animationLimit // #8099
  7180. ) {
  7181. this.points.forEach(function (point) {
  7182. var graphic = point.graphic;
  7183. if (graphic && graphic.width) { // URL symbols don't have width
  7184. // Start values
  7185. if (!this.hasRendered) {
  7186. graphic.attr({
  7187. x: point.plotX,
  7188. y: point.plotY,
  7189. width: 1,
  7190. height: 1
  7191. });
  7192. }
  7193. // Run animation
  7194. graphic.animate(this.markerAttribs(point), this.options.animation);
  7195. }
  7196. }, this);
  7197. }
  7198. };
  7199. /**
  7200. * Get the radius for each point based on the minSize, maxSize and each
  7201. * point's Z value. This must be done prior to Series.translate because
  7202. * the axis needs to add padding in accordance with the point sizes.
  7203. * @private
  7204. */
  7205. BubbleSeries.prototype.getRadii = function (zMin, zMax, series) {
  7206. var len,
  7207. i,
  7208. zData = this.zData,
  7209. yData = this.yData,
  7210. minSize = series.minPxSize,
  7211. maxSize = series.maxPxSize,
  7212. radii = [],
  7213. value;
  7214. // Set the shape type and arguments to be picked up in drawPoints
  7215. for (i = 0, len = zData.length; i < len; i++) {
  7216. value = zData[i];
  7217. // Separate method to get individual radius for bubbleLegend
  7218. radii.push(this.getRadius(zMin, zMax, minSize, maxSize, value, yData[i]));
  7219. }
  7220. this.radii = radii;
  7221. };
  7222. /**
  7223. * Get the individual radius for one point.
  7224. * @private
  7225. */
  7226. BubbleSeries.prototype.getRadius = function (zMin, zMax, minSize, maxSize, value, yValue) {
  7227. var options = this.options,
  7228. sizeByArea = options.sizeBy !== 'width',
  7229. zThreshold = options.zThreshold,
  7230. zRange = zMax - zMin,
  7231. pos = 0.5;
  7232. // #8608 - bubble should be visible when z is undefined
  7233. if (yValue === null || value === null) {
  7234. return null;
  7235. }
  7236. if (isNumber(value)) {
  7237. // When sizing by threshold, the absolute value of z determines
  7238. // the size of the bubble.
  7239. if (options.sizeByAbsoluteValue) {
  7240. value = Math.abs(value - zThreshold);
  7241. zMax = zRange = Math.max(zMax - zThreshold, Math.abs(zMin - zThreshold));
  7242. zMin = 0;
  7243. }
  7244. // Issue #4419 - if value is less than zMin, push a radius that's
  7245. // always smaller than the minimum size
  7246. if (value < zMin) {
  7247. return minSize / 2 - 1;
  7248. }
  7249. // Relative size, a number between 0 and 1
  7250. if (zRange > 0) {
  7251. pos = (value - zMin) / zRange;
  7252. }
  7253. }
  7254. if (sizeByArea && pos >= 0) {
  7255. pos = Math.sqrt(pos);
  7256. }
  7257. return Math.ceil(minSize + pos * (maxSize - minSize)) / 2;
  7258. };
  7259. /**
  7260. * Define hasData function for non-cartesian series.
  7261. * Returns true if the series has points at all.
  7262. * @private
  7263. */
  7264. BubbleSeries.prototype.hasData = function () {
  7265. return !!this.processedXData.length; // != 0
  7266. };
  7267. /**
  7268. * @private
  7269. */
  7270. BubbleSeries.prototype.pointAttribs = function (point, state) {
  7271. var markerOptions = this.options.marker,
  7272. fillOpacity = markerOptions.fillOpacity,
  7273. attr = Series.prototype.pointAttribs.call(this,
  7274. point,
  7275. state);
  7276. if (fillOpacity !== 1) {
  7277. attr.fill = color(attr.fill)
  7278. .setOpacity(fillOpacity)
  7279. .get('rgba');
  7280. }
  7281. return attr;
  7282. };
  7283. /**
  7284. * Extend the base translate method to handle bubble size
  7285. * @private
  7286. */
  7287. BubbleSeries.prototype.translate = function () {
  7288. var i,
  7289. data = this.data,
  7290. point,
  7291. radius,
  7292. radii = this.radii;
  7293. // Run the parent method
  7294. _super.prototype.translate.call(this);
  7295. // Set the shape type and arguments to be picked up in drawPoints
  7296. i = data.length;
  7297. while (i--) {
  7298. point = data[i];
  7299. radius = radii ? radii[i] : 0; // #1737
  7300. if (isNumber(radius) && radius >= this.minPxSize / 2) {
  7301. // Shape arguments
  7302. point.marker = extend(point.marker, {
  7303. radius: radius,
  7304. width: 2 * radius,
  7305. height: 2 * radius
  7306. });
  7307. // Alignment box for the data label
  7308. point.dlBox = {
  7309. x: point.plotX - radius,
  7310. y: point.plotY - radius,
  7311. width: 2 * radius,
  7312. height: 2 * radius
  7313. };
  7314. }
  7315. else { // below zThreshold
  7316. // #1691
  7317. point.shapeArgs = point.plotY = point.dlBox = void 0;
  7318. }
  7319. }
  7320. };
  7321. /**
  7322. * A bubble series is a three dimensional series type where each point
  7323. * renders an X, Y and Z value. Each points is drawn as a bubble where the
  7324. * position along the X and Y axes mark the X and Y values, and the size of
  7325. * the bubble relates to the Z value.
  7326. *
  7327. * @sample {highcharts} highcharts/demo/bubble/
  7328. * Bubble chart
  7329. *
  7330. * @extends plotOptions.scatter
  7331. * @excluding cluster
  7332. * @product highcharts highstock
  7333. * @requires highcharts-more
  7334. * @optionparent plotOptions.bubble
  7335. */
  7336. BubbleSeries.defaultOptions = merge(ScatterSeries.defaultOptions, {
  7337. dataLabels: {
  7338. formatter: function () {
  7339. return this.point.z;
  7340. },
  7341. inside: true,
  7342. verticalAlign: 'middle'
  7343. },
  7344. /**
  7345. * If there are more points in the series than the `animationLimit`, the
  7346. * animation won't run. Animation affects overall performance and
  7347. * doesn't work well with heavy data series.
  7348. *
  7349. * @since 6.1.0
  7350. */
  7351. animationLimit: 250,
  7352. /**
  7353. * Whether to display negative sized bubbles. The threshold is given
  7354. * by the [zThreshold](#plotOptions.bubble.zThreshold) option, and negative
  7355. * bubbles can be visualized by setting
  7356. * [negativeColor](#plotOptions.bubble.negativeColor).
  7357. *
  7358. * @sample {highcharts} highcharts/plotoptions/bubble-negative/
  7359. * Negative bubbles
  7360. *
  7361. * @type {boolean}
  7362. * @default true
  7363. * @since 3.0
  7364. * @apioption plotOptions.bubble.displayNegative
  7365. */
  7366. /**
  7367. * @extends plotOptions.series.marker
  7368. * @excluding enabled, enabledThreshold, height, radius, width
  7369. */
  7370. marker: {
  7371. lineColor: null,
  7372. lineWidth: 1,
  7373. /**
  7374. * The fill opacity of the bubble markers.
  7375. */
  7376. fillOpacity: 0.5,
  7377. /**
  7378. * In bubble charts, the radius is overridden and determined based
  7379. * on the point's data value.
  7380. *
  7381. * @ignore-option
  7382. */
  7383. radius: null,
  7384. states: {
  7385. hover: {
  7386. radiusPlus: 0
  7387. }
  7388. },
  7389. /**
  7390. * A predefined shape or symbol for the marker. Possible values are
  7391. * "circle", "square", "diamond", "triangle" and "triangle-down".
  7392. *
  7393. * Additionally, the URL to a graphic can be given on the form
  7394. * `url(graphic.png)`. Note that for the image to be applied to
  7395. * exported charts, its URL needs to be accessible by the export
  7396. * server.
  7397. *
  7398. * Custom callbacks for symbol path generation can also be added to
  7399. * `Highcharts.SVGRenderer.prototype.symbols`. The callback is then
  7400. * used by its method name, as shown in the demo.
  7401. *
  7402. * @sample {highcharts} highcharts/plotoptions/bubble-symbol/
  7403. * Bubble chart with various symbols
  7404. * @sample {highcharts} highcharts/plotoptions/series-marker-symbol/
  7405. * General chart with predefined, graphic and custom markers
  7406. *
  7407. * @type {Highcharts.SymbolKeyValue|string}
  7408. * @since 5.0.11
  7409. */
  7410. symbol: 'circle'
  7411. },
  7412. /**
  7413. * Minimum bubble size. Bubbles will automatically size between the
  7414. * `minSize` and `maxSize` to reflect the `z` value of each bubble.
  7415. * Can be either pixels (when no unit is given), or a percentage of
  7416. * the smallest one of the plot width and height.
  7417. *
  7418. * @sample {highcharts} highcharts/plotoptions/bubble-size/
  7419. * Bubble size
  7420. *
  7421. * @type {number|string}
  7422. * @since 3.0
  7423. * @product highcharts highstock
  7424. */
  7425. minSize: 8,
  7426. /**
  7427. * Maximum bubble size. Bubbles will automatically size between the
  7428. * `minSize` and `maxSize` to reflect the `z` value of each bubble.
  7429. * Can be either pixels (when no unit is given), or a percentage of
  7430. * the smallest one of the plot width and height.
  7431. *
  7432. * @sample {highcharts} highcharts/plotoptions/bubble-size/
  7433. * Bubble size
  7434. *
  7435. * @type {number|string}
  7436. * @since 3.0
  7437. * @product highcharts highstock
  7438. */
  7439. maxSize: '20%',
  7440. /**
  7441. * When a point's Z value is below the
  7442. * [zThreshold](#plotOptions.bubble.zThreshold)
  7443. * setting, this color is used.
  7444. *
  7445. * @sample {highcharts} highcharts/plotoptions/bubble-negative/
  7446. * Negative bubbles
  7447. *
  7448. * @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
  7449. * @since 3.0
  7450. * @product highcharts
  7451. * @apioption plotOptions.bubble.negativeColor
  7452. */
  7453. /**
  7454. * Whether the bubble's value should be represented by the area or the
  7455. * width of the bubble. The default, `area`, corresponds best to the
  7456. * human perception of the size of each bubble.
  7457. *
  7458. * @sample {highcharts} highcharts/plotoptions/bubble-sizeby/
  7459. * Comparison of area and size
  7460. *
  7461. * @type {Highcharts.BubbleSizeByValue}
  7462. * @default area
  7463. * @since 3.0.7
  7464. * @apioption plotOptions.bubble.sizeBy
  7465. */
  7466. /**
  7467. * When this is true, the absolute value of z determines the size of
  7468. * the bubble. This means that with the default `zThreshold` of 0, a
  7469. * bubble of value -1 will have the same size as a bubble of value 1,
  7470. * while a bubble of value 0 will have a smaller size according to
  7471. * `minSize`.
  7472. *
  7473. * @sample {highcharts} highcharts/plotoptions/bubble-sizebyabsolutevalue/
  7474. * Size by absolute value, various thresholds
  7475. *
  7476. * @type {boolean}
  7477. * @default false
  7478. * @since 4.1.9
  7479. * @product highcharts
  7480. * @apioption plotOptions.bubble.sizeByAbsoluteValue
  7481. */
  7482. /**
  7483. * When this is true, the series will not cause the Y axis to cross
  7484. * the zero plane (or [threshold](#plotOptions.series.threshold) option)
  7485. * unless the data actually crosses the plane.
  7486. *
  7487. * For example, if `softThreshold` is `false`, a series of 0, 1, 2,
  7488. * 3 will make the Y axis show negative values according to the
  7489. * `minPadding` option. If `softThreshold` is `true`, the Y axis starts
  7490. * at 0.
  7491. *
  7492. * @since 4.1.9
  7493. * @product highcharts
  7494. */
  7495. softThreshold: false,
  7496. states: {
  7497. hover: {
  7498. halo: {
  7499. size: 5
  7500. }
  7501. }
  7502. },
  7503. tooltip: {
  7504. pointFormat: '({point.x}, {point.y}), Size: {point.z}'
  7505. },
  7506. turboThreshold: 0,
  7507. /**
  7508. * The minimum for the Z value range. Defaults to the highest Z value
  7509. * in the data.
  7510. *
  7511. * @see [zMin](#plotOptions.bubble.zMin)
  7512. *
  7513. * @sample {highcharts} highcharts/plotoptions/bubble-zmin-zmax/
  7514. * Z has a possible range of 0-100
  7515. *
  7516. * @type {number}
  7517. * @since 4.0.3
  7518. * @product highcharts
  7519. * @apioption plotOptions.bubble.zMax
  7520. */
  7521. /**
  7522. * @default z
  7523. * @apioption plotOptions.bubble.colorKey
  7524. */
  7525. /**
  7526. * The minimum for the Z value range. Defaults to the lowest Z value
  7527. * in the data.
  7528. *
  7529. * @see [zMax](#plotOptions.bubble.zMax)
  7530. *
  7531. * @sample {highcharts} highcharts/plotoptions/bubble-zmin-zmax/
  7532. * Z has a possible range of 0-100
  7533. *
  7534. * @type {number}
  7535. * @since 4.0.3
  7536. * @product highcharts
  7537. * @apioption plotOptions.bubble.zMin
  7538. */
  7539. /**
  7540. * When [displayNegative](#plotOptions.bubble.displayNegative) is `false`,
  7541. * bubbles with lower Z values are skipped. When `displayNegative`
  7542. * is `true` and a [negativeColor](#plotOptions.bubble.negativeColor)
  7543. * is given, points with lower Z is colored.
  7544. *
  7545. * @sample {highcharts} highcharts/plotoptions/bubble-negative/
  7546. * Negative bubbles
  7547. *
  7548. * @since 3.0
  7549. * @product highcharts
  7550. */
  7551. zThreshold: 0,
  7552. zoneAxis: 'z'
  7553. });
  7554. return BubbleSeries;
  7555. }(ScatterSeries));
  7556. extend(BubbleSeries.prototype, {
  7557. alignDataLabel: ColumnSeries.prototype.alignDataLabel,
  7558. applyZones: noop,
  7559. bubblePadding: true,
  7560. buildKDTree: noop,
  7561. directTouch: true,
  7562. isBubble: true,
  7563. pointArrayMap: ['y', 'z'],
  7564. pointClass: BubblePoint,
  7565. parallelArrays: ['x', 'y', 'z'],
  7566. trackerGroups: ['group', 'dataLabelsGroup'],
  7567. specialGroup: 'group',
  7568. zoneAxis: 'z'
  7569. });
  7570. /* *
  7571. *
  7572. * Axis ?
  7573. *
  7574. * */
  7575. // Add logic to pad each axis with the amount of pixels necessary to avoid the
  7576. // bubbles to overflow.
  7577. Axis.prototype.beforePadding = function () {
  7578. var axis = this,
  7579. axisLength = this.len,
  7580. chart = this.chart,
  7581. pxMin = 0,
  7582. pxMax = axisLength,
  7583. isXAxis = this.isXAxis,
  7584. dataKey = isXAxis ? 'xData' : 'yData',
  7585. min = this.min,
  7586. extremes = {},
  7587. smallestSize = Math.min(chart.plotWidth,
  7588. chart.plotHeight),
  7589. zMin = Number.MAX_VALUE,
  7590. zMax = -Number.MAX_VALUE,
  7591. range = this.max - min,
  7592. transA = axisLength / range,
  7593. activeSeries = [];
  7594. // Handle padding on the second pass, or on redraw
  7595. this.series.forEach(function (series) {
  7596. var seriesOptions = series.options,
  7597. zData;
  7598. if (series.bubblePadding &&
  7599. (series.visible || !chart.options.chart.ignoreHiddenSeries)) {
  7600. // Correction for #1673
  7601. axis.allowZoomOutside = true;
  7602. // Cache it
  7603. activeSeries.push(series);
  7604. if (isXAxis) { // because X axis is evaluated first
  7605. // For each series, translate the size extremes to pixel values
  7606. ['minSize', 'maxSize'].forEach(function (prop) {
  7607. var length = seriesOptions[prop],
  7608. isPercent = /%$/.test(length);
  7609. length = pInt(length);
  7610. extremes[prop] = isPercent ?
  7611. smallestSize * length / 100 :
  7612. length;
  7613. });
  7614. series.minPxSize = extremes.minSize;
  7615. // Prioritize min size if conflict to make sure bubbles are
  7616. // always visible. #5873
  7617. series.maxPxSize = Math.max(extremes.maxSize, extremes.minSize);
  7618. // Find the min and max Z
  7619. zData = series.zData.filter(isNumber);
  7620. if (zData.length) { // #1735
  7621. zMin = pick(seriesOptions.zMin, clamp(arrayMin(zData), seriesOptions.displayNegative === false ?
  7622. seriesOptions.zThreshold :
  7623. -Number.MAX_VALUE, zMin));
  7624. zMax = pick(seriesOptions.zMax, Math.max(zMax, arrayMax(zData)));
  7625. }
  7626. }
  7627. }
  7628. });
  7629. activeSeries.forEach(function (series) {
  7630. var data = series[dataKey],
  7631. i = data.length,
  7632. radius;
  7633. if (isXAxis) {
  7634. series.getRadii(zMin, zMax, series);
  7635. }
  7636. if (range > 0) {
  7637. while (i--) {
  7638. if (isNumber(data[i]) &&
  7639. axis.dataMin <= data[i] &&
  7640. data[i] <= axis.max) {
  7641. radius = series.radii ? series.radii[i] : 0;
  7642. pxMin = Math.min(((data[i] - min) * transA) - radius, pxMin);
  7643. pxMax = Math.max(((data[i] - min) * transA) + radius, pxMax);
  7644. }
  7645. }
  7646. }
  7647. });
  7648. // Apply the padding to the min and max properties
  7649. if (activeSeries.length && range > 0 && !this.logarithmic) {
  7650. pxMax -= axisLength;
  7651. transA *= (axisLength +
  7652. Math.max(0, pxMin) - // #8901
  7653. Math.min(pxMax, axisLength)) / axisLength;
  7654. [
  7655. ['min', 'userMin', pxMin],
  7656. ['max', 'userMax', pxMax]
  7657. ].forEach(function (keys) {
  7658. if (typeof pick(axis.options[keys[0]], axis[keys[1]]) === 'undefined') {
  7659. axis[keys[0]] += keys[2] / transA;
  7660. }
  7661. });
  7662. }
  7663. /* eslint-enable valid-jsdoc */
  7664. };
  7665. SeriesRegistry.registerSeriesType('bubble', BubbleSeries);
  7666. /* *
  7667. *
  7668. * Default Export
  7669. *
  7670. * */
  7671. /* *
  7672. *
  7673. * API Declarations
  7674. *
  7675. * */
  7676. /**
  7677. * @typedef {"area"|"width"} Highcharts.BubbleSizeByValue
  7678. */
  7679. ''; // detach doclets above
  7680. /* *
  7681. *
  7682. * API Options
  7683. *
  7684. * */
  7685. /**
  7686. * A `bubble` series. If the [type](#series.bubble.type) option is
  7687. * not specified, it is inherited from [chart.type](#chart.type).
  7688. *
  7689. * @extends series,plotOptions.bubble
  7690. * @excluding dataParser, dataURL, stack
  7691. * @product highcharts highstock
  7692. * @requires highcharts-more
  7693. * @apioption series.bubble
  7694. */
  7695. /**
  7696. * An array of data points for the series. For the `bubble` series type,
  7697. * points can be given in the following ways:
  7698. *
  7699. * 1. An array of arrays with 3 or 2 values. In this case, the values correspond
  7700. * to `x,y,z`. If the first value is a string, it is applied as the name of
  7701. * the point, and the `x` value is inferred. The `x` value can also be
  7702. * omitted, in which case the inner arrays should be of length 2\. Then the
  7703. * `x` value is automatically calculated, either starting at 0 and
  7704. * incremented by 1, or from `pointStart` and `pointInterval` given in the
  7705. * series options.
  7706. * ```js
  7707. * data: [
  7708. * [0, 1, 2],
  7709. * [1, 5, 5],
  7710. * [2, 0, 2]
  7711. * ]
  7712. * ```
  7713. *
  7714. * 2. An array of objects with named values. The following snippet shows only a
  7715. * few settings, see the complete options set below. If the total number of
  7716. * data points exceeds the series'
  7717. * [turboThreshold](#series.bubble.turboThreshold), this option is not
  7718. * available.
  7719. * ```js
  7720. * data: [{
  7721. * x: 1,
  7722. * y: 1,
  7723. * z: 1,
  7724. * name: "Point2",
  7725. * color: "#00FF00"
  7726. * }, {
  7727. * x: 1,
  7728. * y: 5,
  7729. * z: 4,
  7730. * name: "Point1",
  7731. * color: "#FF00FF"
  7732. * }]
  7733. * ```
  7734. *
  7735. * @sample {highcharts} highcharts/series/data-array-of-arrays/
  7736. * Arrays of numeric x and y
  7737. * @sample {highcharts} highcharts/series/data-array-of-arrays-datetime/
  7738. * Arrays of datetime x and y
  7739. * @sample {highcharts} highcharts/series/data-array-of-name-value/
  7740. * Arrays of point.name and y
  7741. * @sample {highcharts} highcharts/series/data-array-of-objects/
  7742. * Config objects
  7743. *
  7744. * @type {Array<Array<(number|string),number>|Array<(number|string),number,number>|*>}
  7745. * @extends series.line.data
  7746. * @product highcharts
  7747. * @apioption series.bubble.data
  7748. */
  7749. /**
  7750. * @extends series.line.data.marker
  7751. * @excluding enabledThreshold, height, radius, width
  7752. * @product highcharts
  7753. * @apioption series.bubble.data.marker
  7754. */
  7755. /**
  7756. * The size value for each bubble. The bubbles' diameters are computed
  7757. * based on the `z`, and controlled by series options like `minSize`,
  7758. * `maxSize`, `sizeBy`, `zMin` and `zMax`.
  7759. *
  7760. * @type {number|null}
  7761. * @product highcharts
  7762. * @apioption series.bubble.data.z
  7763. */
  7764. /**
  7765. * @excluding enabled, enabledThreshold, height, radius, width
  7766. * @apioption series.bubble.marker
  7767. */
  7768. ''; // adds doclets above to transpiled file
  7769. return BubbleSeries;
  7770. });
  7771. _registerModule(_modules, 'Series/PackedBubble/PackedBubblePoint.js', [_modules['Core/Chart/Chart.js'], _modules['Core/Series/Point.js'], _modules['Core/Series/SeriesRegistry.js']], function (Chart, Point, SeriesRegistry) {
  7772. /* *
  7773. *
  7774. * (c) 2010-2021 Grzegorz Blachlinski, Sebastian Bochan
  7775. *
  7776. * License: www.highcharts.com/license
  7777. *
  7778. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  7779. *
  7780. * */
  7781. var __extends = (this && this.__extends) || (function () {
  7782. var extendStatics = function (d,
  7783. b) {
  7784. extendStatics = Object.setPrototypeOf ||
  7785. ({ __proto__: [] } instanceof Array && function (d,
  7786. b) { d.__proto__ = b; }) ||
  7787. function (d,
  7788. b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  7789. return extendStatics(d, b);
  7790. };
  7791. return function (d, b) {
  7792. extendStatics(d, b);
  7793. function __() { this.constructor = d; }
  7794. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  7795. };
  7796. })();
  7797. var BubbleSeries = SeriesRegistry.seriesTypes.bubble;
  7798. /* *
  7799. *
  7800. * Class
  7801. *
  7802. * */
  7803. var PackedBubblePoint = /** @class */ (function (_super) {
  7804. __extends(PackedBubblePoint, _super);
  7805. function PackedBubblePoint() {
  7806. /* *
  7807. *
  7808. * Properties
  7809. *
  7810. * */
  7811. var _this = _super !== null && _super.apply(this,
  7812. arguments) || this;
  7813. _this.degree = NaN;
  7814. _this.mass = NaN;
  7815. _this.radius = NaN;
  7816. _this.options = void 0;
  7817. _this.series = void 0;
  7818. _this.value = null;
  7819. return _this;
  7820. /* eslint-enable valid-jsdoc */
  7821. }
  7822. /* *
  7823. *
  7824. * Functions
  7825. *
  7826. * */
  7827. /* eslint-disable valid-jsdoc */
  7828. /**
  7829. * Destroy point.
  7830. * Then remove point from the layout.
  7831. * @private
  7832. */
  7833. PackedBubblePoint.prototype.destroy = function () {
  7834. if (this.series.layout) {
  7835. this.series.layout.removeElementFromCollection(this, this.series.layout.nodes);
  7836. }
  7837. return Point.prototype.destroy.apply(this, arguments);
  7838. };
  7839. PackedBubblePoint.prototype.firePointEvent = function () {
  7840. var point = this,
  7841. series = this.series,
  7842. seriesOptions = series.options;
  7843. if (this.isParentNode && seriesOptions.parentNode) {
  7844. var temp = seriesOptions.allowPointSelect;
  7845. seriesOptions.allowPointSelect = seriesOptions.parentNode.allowPointSelect;
  7846. Point.prototype.firePointEvent.apply(this, arguments);
  7847. seriesOptions.allowPointSelect = temp;
  7848. }
  7849. else {
  7850. Point.prototype.firePointEvent.apply(this, arguments);
  7851. }
  7852. };
  7853. PackedBubblePoint.prototype.select = function () {
  7854. var point = this,
  7855. series = this.series,
  7856. chart = series.chart;
  7857. if (point.isParentNode) {
  7858. chart.getSelectedPoints = chart.getSelectedParentNodes;
  7859. Point.prototype.select.apply(this, arguments);
  7860. chart.getSelectedPoints = Chart.prototype.getSelectedPoints;
  7861. }
  7862. else {
  7863. Point.prototype.select.apply(this, arguments);
  7864. }
  7865. };
  7866. return PackedBubblePoint;
  7867. }(BubbleSeries.prototype.pointClass));
  7868. /* *
  7869. *
  7870. * Default Export
  7871. *
  7872. * */
  7873. return PackedBubblePoint;
  7874. });
  7875. _registerModule(_modules, 'Series/Networkgraph/DraggableNodes.js', [_modules['Core/Chart/Chart.js'], _modules['Core/Globals.js'], _modules['Core/Utilities.js']], function (Chart, H, U) {
  7876. /* *
  7877. *
  7878. * Networkgraph series
  7879. *
  7880. * (c) 2010-2021 Paweł Fus
  7881. *
  7882. * License: www.highcharts.com/license
  7883. *
  7884. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  7885. *
  7886. * */
  7887. var addEvent = U.addEvent;
  7888. /* eslint-disable no-invalid-this, valid-jsdoc */
  7889. H.dragNodesMixin = {
  7890. /**
  7891. * Mouse down action, initializing drag&drop mode.
  7892. *
  7893. * @private
  7894. * @param {Highcharts.Point} point The point that event occured.
  7895. * @param {Highcharts.PointerEventObject} event Browser event, before normalization.
  7896. * @return {void}
  7897. */
  7898. onMouseDown: function (point, event) {
  7899. var normalizedEvent = this.chart.pointer.normalize(event);
  7900. point.fixedPosition = {
  7901. chartX: normalizedEvent.chartX,
  7902. chartY: normalizedEvent.chartY,
  7903. plotX: point.plotX,
  7904. plotY: point.plotY
  7905. };
  7906. point.inDragMode = true;
  7907. },
  7908. /**
  7909. * Mouse move action during drag&drop.
  7910. *
  7911. * @private
  7912. *
  7913. * @param {global.Event} event Browser event, before normalization.
  7914. * @param {Highcharts.Point} point The point that event occured.
  7915. *
  7916. * @return {void}
  7917. */
  7918. onMouseMove: function (point, event) {
  7919. if (point.fixedPosition && point.inDragMode) {
  7920. var series = this,
  7921. chart = series.chart,
  7922. normalizedEvent = chart.pointer.normalize(event),
  7923. diffX = point.fixedPosition.chartX - normalizedEvent.chartX,
  7924. diffY = point.fixedPosition.chartY - normalizedEvent.chartY,
  7925. newPlotX = void 0,
  7926. newPlotY = void 0,
  7927. graphLayoutsLookup = chart.graphLayoutsLookup;
  7928. // At least 5px to apply change (avoids simple click):
  7929. if (Math.abs(diffX) > 5 || Math.abs(diffY) > 5) {
  7930. newPlotX = point.fixedPosition.plotX - diffX;
  7931. newPlotY = point.fixedPosition.plotY - diffY;
  7932. if (chart.isInsidePlot(newPlotX, newPlotY)) {
  7933. point.plotX = newPlotX;
  7934. point.plotY = newPlotY;
  7935. point.hasDragged = true;
  7936. this.redrawHalo(point);
  7937. graphLayoutsLookup.forEach(function (layout) {
  7938. layout.restartSimulation();
  7939. });
  7940. }
  7941. }
  7942. }
  7943. },
  7944. /**
  7945. * Mouse up action, finalizing drag&drop.
  7946. *
  7947. * @private
  7948. * @param {Highcharts.Point} point The point that event occured.
  7949. * @return {void}
  7950. */
  7951. onMouseUp: function (point, event) {
  7952. if (point.fixedPosition) {
  7953. if (point.hasDragged) {
  7954. if (this.layout.enableSimulation) {
  7955. this.layout.start();
  7956. }
  7957. else {
  7958. this.chart.redraw();
  7959. }
  7960. }
  7961. point.inDragMode = point.hasDragged = false;
  7962. if (!this.options.fixedDraggable) {
  7963. delete point.fixedPosition;
  7964. }
  7965. }
  7966. },
  7967. // Draggable mode:
  7968. /**
  7969. * Redraw halo on mousemove during the drag&drop action.
  7970. *
  7971. * @private
  7972. * @param {Highcharts.Point} point The point that should show halo.
  7973. * @return {void}
  7974. */
  7975. redrawHalo: function (point) {
  7976. if (point && this.halo) {
  7977. this.halo.attr({
  7978. d: point.haloPath(this.options.states.hover.halo.size)
  7979. });
  7980. }
  7981. }
  7982. };
  7983. /*
  7984. * Draggable mode:
  7985. */
  7986. addEvent(Chart, 'load', function () {
  7987. var chart = this,
  7988. mousedownUnbinder,
  7989. mousemoveUnbinder,
  7990. mouseupUnbinder;
  7991. if (chart.container) {
  7992. mousedownUnbinder = addEvent(chart.container, 'mousedown', function (event) {
  7993. var point = chart.hoverPoint;
  7994. if (point &&
  7995. point.series &&
  7996. point.series.hasDraggableNodes &&
  7997. point.series.options.draggable) {
  7998. point.series.onMouseDown(point, event);
  7999. mousemoveUnbinder = addEvent(chart.container, 'mousemove', function (e) {
  8000. return point &&
  8001. point.series &&
  8002. point.series.onMouseMove(point, e);
  8003. });
  8004. mouseupUnbinder = addEvent(chart.container.ownerDocument, 'mouseup', function (e) {
  8005. mousemoveUnbinder();
  8006. mouseupUnbinder();
  8007. return point &&
  8008. point.series &&
  8009. point.series.onMouseUp(point, e);
  8010. });
  8011. }
  8012. });
  8013. }
  8014. addEvent(chart, 'destroy', function () {
  8015. mousedownUnbinder();
  8016. });
  8017. });
  8018. });
  8019. _registerModule(_modules, 'Series/Networkgraph/Integrations.js', [_modules['Core/Globals.js']], function (H) {
  8020. /* *
  8021. *
  8022. * Networkgraph series
  8023. *
  8024. * (c) 2010-2021 Paweł Fus
  8025. *
  8026. * License: www.highcharts.com/license
  8027. *
  8028. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  8029. *
  8030. * */
  8031. /* eslint-disable no-invalid-this, valid-jsdoc */
  8032. H.networkgraphIntegrations = {
  8033. verlet: {
  8034. /**
  8035. * Attractive force funtion. Can be replaced by API's
  8036. * `layoutAlgorithm.attractiveForce`
  8037. *
  8038. * @private
  8039. * @param {number} d current distance between two nodes
  8040. * @param {number} k expected distance between two nodes
  8041. * @return {number} force
  8042. */
  8043. attractiveForceFunction: function (d, k) {
  8044. // Used in API:
  8045. return (k - d) / d;
  8046. },
  8047. /**
  8048. * Repulsive force funtion. Can be replaced by API's
  8049. * `layoutAlgorithm.repulsiveForce`
  8050. *
  8051. * @private
  8052. * @param {number} d current distance between two nodes
  8053. * @param {number} k expected distance between two nodes
  8054. * @return {number} force
  8055. */
  8056. repulsiveForceFunction: function (d, k) {
  8057. // Used in API:
  8058. return (k - d) / d * (k > d ? 1 : 0); // Force only for close nodes
  8059. },
  8060. /**
  8061. * Barycenter force. Calculate and applys barycenter forces on the
  8062. * nodes. Making them closer to the center of their barycenter point.
  8063. *
  8064. * In Verlet integration, force is applied on a node immidatelly to it's
  8065. * `plotX` and `plotY` position.
  8066. *
  8067. * @private
  8068. * @return {void}
  8069. */
  8070. barycenter: function () {
  8071. var gravitationalConstant = this.options.gravitationalConstant,
  8072. xFactor = this.barycenter.xFactor,
  8073. yFactor = this.barycenter.yFactor;
  8074. // To consider:
  8075. xFactor = (xFactor - (this.box.left + this.box.width) / 2) *
  8076. gravitationalConstant;
  8077. yFactor = (yFactor - (this.box.top + this.box.height) / 2) *
  8078. gravitationalConstant;
  8079. this.nodes.forEach(function (node) {
  8080. if (!node.fixedPosition) {
  8081. node.plotX -=
  8082. xFactor / node.mass / node.degree;
  8083. node.plotY -=
  8084. yFactor / node.mass / node.degree;
  8085. }
  8086. });
  8087. },
  8088. /**
  8089. * Repulsive force.
  8090. *
  8091. * In Verlet integration, force is applied on a node immidatelly to it's
  8092. * `plotX` and `plotY` position.
  8093. *
  8094. * @private
  8095. * @param {Highcharts.Point} node
  8096. * Node that should be translated by force.
  8097. * @param {number} force
  8098. * Force calcualated in `repulsiveForceFunction`
  8099. * @param {Highcharts.PositionObject} distance
  8100. * Distance between two nodes e.g. `{x, y}`
  8101. * @return {void}
  8102. */
  8103. repulsive: function (node, force, distanceXY) {
  8104. var factor = force * this.diffTemperature / node.mass / node.degree;
  8105. if (!node.fixedPosition) {
  8106. node.plotX += distanceXY.x * factor;
  8107. node.plotY += distanceXY.y * factor;
  8108. }
  8109. },
  8110. /**
  8111. * Attractive force.
  8112. *
  8113. * In Verlet integration, force is applied on a node immidatelly to it's
  8114. * `plotX` and `plotY` position.
  8115. *
  8116. * @private
  8117. * @param {Highcharts.Point} link
  8118. * Link that connects two nodes
  8119. * @param {number} force
  8120. * Force calcualated in `repulsiveForceFunction`
  8121. * @param {Highcharts.PositionObject} distance
  8122. * Distance between two nodes e.g. `{x, y}`
  8123. * @return {void}
  8124. */
  8125. attractive: function (link, force, distanceXY) {
  8126. var massFactor = link.getMass(),
  8127. translatedX = -distanceXY.x * force * this.diffTemperature,
  8128. translatedY = -distanceXY.y * force * this.diffTemperature;
  8129. if (!link.fromNode.fixedPosition) {
  8130. link.fromNode.plotX -=
  8131. translatedX * massFactor.fromNode / link.fromNode.degree;
  8132. link.fromNode.plotY -=
  8133. translatedY * massFactor.fromNode / link.fromNode.degree;
  8134. }
  8135. if (!link.toNode.fixedPosition) {
  8136. link.toNode.plotX +=
  8137. translatedX * massFactor.toNode / link.toNode.degree;
  8138. link.toNode.plotY +=
  8139. translatedY * massFactor.toNode / link.toNode.degree;
  8140. }
  8141. },
  8142. /**
  8143. * Integration method.
  8144. *
  8145. * In Verlet integration, forces are applied on node immidatelly to it's
  8146. * `plotX` and `plotY` position.
  8147. *
  8148. * Verlet without velocity:
  8149. *
  8150. * x(n+1) = 2 * x(n) - x(n-1) + A(T) * deltaT ^ 2
  8151. *
  8152. * where:
  8153. * - x(n+1) - new position
  8154. * - x(n) - current position
  8155. * - x(n-1) - previous position
  8156. *
  8157. * Assuming A(t) = 0 (no acceleration) and (deltaT = 1) we get:
  8158. *
  8159. * x(n+1) = x(n) + (x(n) - x(n-1))
  8160. *
  8161. * where:
  8162. * - (x(n) - x(n-1)) - position change
  8163. *
  8164. * TO DO:
  8165. * Consider Verlet with velocity to support additional
  8166. * forces. Or even Time-Corrected Verlet by Jonathan
  8167. * "lonesock" Dummer
  8168. *
  8169. * @private
  8170. * @param {Highcharts.NetworkgraphLayout} layout layout object
  8171. * @param {Highcharts.Point} node node that should be translated
  8172. * @return {void}
  8173. */
  8174. integrate: function (layout, node) {
  8175. var friction = -layout.options.friction,
  8176. maxSpeed = layout.options.maxSpeed,
  8177. prevX = node.prevX,
  8178. prevY = node.prevY,
  8179. // Apply friciton:
  8180. diffX = ((node.plotX + node.dispX -
  8181. prevX) * friction),
  8182. diffY = ((node.plotY + node.dispY -
  8183. prevY) * friction),
  8184. abs = Math.abs,
  8185. signX = abs(diffX) / (diffX || 1), // need to deal with 0
  8186. signY = abs(diffY) / (diffY || 1);
  8187. // Apply max speed:
  8188. diffX = signX * Math.min(maxSpeed, Math.abs(diffX));
  8189. diffY = signY * Math.min(maxSpeed, Math.abs(diffY));
  8190. // Store for the next iteration:
  8191. node.prevX = node.plotX + node.dispX;
  8192. node.prevY = node.plotY + node.dispY;
  8193. // Update positions:
  8194. node.plotX += diffX;
  8195. node.plotY += diffY;
  8196. node.temperature = layout.vectorLength({
  8197. x: diffX,
  8198. y: diffY
  8199. });
  8200. },
  8201. /**
  8202. * Estiamte the best possible distance between two nodes, making graph
  8203. * readable.
  8204. *
  8205. * @private
  8206. * @param {Highcharts.NetworkgraphLayout} layout layout object
  8207. * @return {number}
  8208. */
  8209. getK: function (layout) {
  8210. return Math.pow(layout.box.width * layout.box.height / layout.nodes.length, 0.5);
  8211. }
  8212. },
  8213. euler: {
  8214. /**
  8215. * Attractive force funtion. Can be replaced by API's
  8216. * `layoutAlgorithm.attractiveForce`
  8217. *
  8218. * Other forces that can be used:
  8219. *
  8220. * basic, not recommended:
  8221. * `function (d, k) { return d / k }`
  8222. *
  8223. * @private
  8224. * @param {number} d current distance between two nodes
  8225. * @param {number} k expected distance between two nodes
  8226. * @return {number} force
  8227. */
  8228. attractiveForceFunction: function (d, k) {
  8229. return d * d / k;
  8230. },
  8231. /**
  8232. * Repulsive force funtion. Can be replaced by API's
  8233. * `layoutAlgorithm.repulsiveForce`.
  8234. *
  8235. * Other forces that can be used:
  8236. *
  8237. * basic, not recommended:
  8238. * `function (d, k) { return k / d }`
  8239. *
  8240. * standard:
  8241. * `function (d, k) { return k * k / d }`
  8242. *
  8243. * grid-variant:
  8244. * `function (d, k) { return k * k / d * (2 * k - d > 0 ? 1 : 0) }`
  8245. *
  8246. * @private
  8247. * @param {number} d current distance between two nodes
  8248. * @param {number} k expected distance between two nodes
  8249. * @return {number} force
  8250. */
  8251. repulsiveForceFunction: function (d, k) {
  8252. return k * k / d;
  8253. },
  8254. /**
  8255. * Barycenter force. Calculate and applys barycenter forces on the
  8256. * nodes. Making them closer to the center of their barycenter point.
  8257. *
  8258. * In Euler integration, force is stored in a node, not changing it's
  8259. * position. Later, in `integrate()` forces are applied on nodes.
  8260. *
  8261. * @private
  8262. * @return {void}
  8263. */
  8264. barycenter: function () {
  8265. var gravitationalConstant = this.options.gravitationalConstant,
  8266. xFactor = this.barycenter.xFactor,
  8267. yFactor = this.barycenter.yFactor;
  8268. this.nodes.forEach(function (node) {
  8269. if (!node.fixedPosition) {
  8270. var degree = node.getDegree(),
  8271. phi = degree * (1 + degree / 2);
  8272. node.dispX += ((xFactor - node.plotX) *
  8273. gravitationalConstant *
  8274. phi / node.degree);
  8275. node.dispY += ((yFactor - node.plotY) *
  8276. gravitationalConstant *
  8277. phi / node.degree);
  8278. }
  8279. });
  8280. },
  8281. /**
  8282. * Repulsive force.
  8283. *
  8284. * @private
  8285. * @param {Highcharts.Point} node
  8286. * Node that should be translated by force.
  8287. * @param {number} force
  8288. * Force calcualated in `repulsiveForceFunction`
  8289. * @param {Highcharts.PositionObject} distanceXY
  8290. * Distance between two nodes e.g. `{x, y}`
  8291. * @return {void}
  8292. */
  8293. repulsive: function (node, force, distanceXY, distanceR) {
  8294. node.dispX +=
  8295. (distanceXY.x / distanceR) * force / node.degree;
  8296. node.dispY +=
  8297. (distanceXY.y / distanceR) * force / node.degree;
  8298. },
  8299. /**
  8300. * Attractive force.
  8301. *
  8302. * In Euler integration, force is stored in a node, not changing it's
  8303. * position. Later, in `integrate()` forces are applied on nodes.
  8304. *
  8305. * @private
  8306. * @param {Highcharts.Point} link
  8307. * Link that connects two nodes
  8308. * @param {number} force
  8309. * Force calcualated in `repulsiveForceFunction`
  8310. * @param {Highcharts.PositionObject} distanceXY
  8311. * Distance between two nodes e.g. `{x, y}`
  8312. * @param {number} distanceR
  8313. * @return {void}
  8314. */
  8315. attractive: function (link, force, distanceXY, distanceR) {
  8316. var massFactor = link.getMass(),
  8317. translatedX = (distanceXY.x / distanceR) * force,
  8318. translatedY = (distanceXY.y / distanceR) * force;
  8319. if (!link.fromNode.fixedPosition) {
  8320. link.fromNode.dispX -=
  8321. translatedX * massFactor.fromNode / link.fromNode.degree;
  8322. link.fromNode.dispY -=
  8323. translatedY * massFactor.fromNode / link.fromNode.degree;
  8324. }
  8325. if (!link.toNode.fixedPosition) {
  8326. link.toNode.dispX +=
  8327. translatedX * massFactor.toNode / link.toNode.degree;
  8328. link.toNode.dispY +=
  8329. translatedY * massFactor.toNode / link.toNode.degree;
  8330. }
  8331. },
  8332. /**
  8333. * Integration method.
  8334. *
  8335. * In Euler integration, force were stored in a node, not changing it's
  8336. * position. Now, in the integrator method, we apply changes.
  8337. *
  8338. * Euler:
  8339. *
  8340. * Basic form: `x(n+1) = x(n) + v(n)`
  8341. *
  8342. * With Rengoild-Fruchterman we get:
  8343. * `x(n+1) = x(n) + v(n) / length(v(n)) * min(v(n), temperature(n))`
  8344. * where:
  8345. * - `x(n+1)`: next position
  8346. * - `x(n)`: current position
  8347. * - `v(n)`: velocity (comes from net force)
  8348. * - `temperature(n)`: current temperature
  8349. *
  8350. * Known issues:
  8351. * Oscillations when force vector has the same magnitude but opposite
  8352. * direction in the next step. Potentially solved by decreasing force by
  8353. * `v * (1 / node.degree)`
  8354. *
  8355. * Note:
  8356. * Actually `min(v(n), temperature(n))` replaces simulated annealing.
  8357. *
  8358. * @private
  8359. * @param {Highcharts.NetworkgraphLayout} layout
  8360. * Layout object
  8361. * @param {Highcharts.Point} node
  8362. * Node that should be translated
  8363. * @return {void}
  8364. */
  8365. integrate: function (layout, node) {
  8366. var distanceR;
  8367. node.dispX +=
  8368. node.dispX * layout.options.friction;
  8369. node.dispY +=
  8370. node.dispY * layout.options.friction;
  8371. distanceR = node.temperature = layout.vectorLength({
  8372. x: node.dispX,
  8373. y: node.dispY
  8374. });
  8375. if (distanceR !== 0) {
  8376. node.plotX += (node.dispX / distanceR *
  8377. Math.min(Math.abs(node.dispX), layout.temperature));
  8378. node.plotY += (node.dispY / distanceR *
  8379. Math.min(Math.abs(node.dispY), layout.temperature));
  8380. }
  8381. },
  8382. /**
  8383. * Estiamte the best possible distance between two nodes, making graph
  8384. * readable.
  8385. *
  8386. * @private
  8387. * @param {object} layout layout object
  8388. * @return {number}
  8389. */
  8390. getK: function (layout) {
  8391. return Math.pow(layout.box.width * layout.box.height / layout.nodes.length, 0.3);
  8392. }
  8393. }
  8394. };
  8395. });
  8396. _registerModule(_modules, 'Series/Networkgraph/QuadTree.js', [_modules['Core/Globals.js'], _modules['Core/Utilities.js']], function (H, U) {
  8397. /* *
  8398. *
  8399. * Networkgraph series
  8400. *
  8401. * (c) 2010-2021 Paweł Fus
  8402. *
  8403. * License: www.highcharts.com/license
  8404. *
  8405. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  8406. *
  8407. * */
  8408. var extend = U.extend;
  8409. /* eslint-disable no-invalid-this, valid-jsdoc */
  8410. /**
  8411. * The QuadTree node class. Used in Networkgraph chart as a base for Barnes-Hut
  8412. * approximation.
  8413. *
  8414. * @private
  8415. * @class
  8416. * @name Highcharts.QuadTreeNode
  8417. *
  8418. * @param {Highcharts.Dictionary<number>} box Available space for the node
  8419. */
  8420. var QuadTreeNode = H.QuadTreeNode = function (box) {
  8421. /**
  8422. * Read only. The available space for node.
  8423. *
  8424. * @name Highcharts.QuadTreeNode#box
  8425. * @type {Highcharts.Dictionary<number>}
  8426. */
  8427. this.box = box;
  8428. /**
  8429. * Read only. The minium of width and height values.
  8430. *
  8431. * @name Highcharts.QuadTreeNode#boxSize
  8432. * @type {number}
  8433. */
  8434. this.boxSize = Math.min(box.width, box.height);
  8435. /**
  8436. * Read only. Array of subnodes. Empty if QuadTreeNode has just one Point.
  8437. * When added another Point to this QuadTreeNode, array is filled with four
  8438. * subnodes.
  8439. *
  8440. * @name Highcharts.QuadTreeNode#nodes
  8441. * @type {Array<Highcharts.QuadTreeNode>}
  8442. */
  8443. this.nodes = [];
  8444. /**
  8445. * Read only. Flag to determine if QuadTreeNode is internal (and has
  8446. * subnodes with mass and central position) or external (bound to Point).
  8447. *
  8448. * @name Highcharts.QuadTreeNode#isInternal
  8449. * @type {boolean}
  8450. */
  8451. this.isInternal = false;
  8452. /**
  8453. * Read only. If QuadTreeNode is an external node, Point is stored in
  8454. * `this.body`.
  8455. *
  8456. * @name Highcharts.QuadTreeNode#body
  8457. * @type {boolean|Highcharts.Point}
  8458. */
  8459. this.body = false;
  8460. /**
  8461. * Read only. Internal nodes when created are empty to reserve the space. If
  8462. * Point is added to this QuadTreeNode, QuadTreeNode is no longer empty.
  8463. *
  8464. * @name Highcharts.QuadTreeNode#isEmpty
  8465. * @type {boolean}
  8466. */
  8467. this.isEmpty = true;
  8468. };
  8469. extend(QuadTreeNode.prototype,
  8470. /** @lends Highcharts.QuadTreeNode.prototype */
  8471. {
  8472. /**
  8473. * Insert recursively point(node) into the QuadTree. If the given
  8474. * quadrant is already occupied, divide it into smaller quadrants.
  8475. *
  8476. * @param {Highcharts.Point} point
  8477. * Point/node to be inserted
  8478. * @param {number} depth
  8479. * Max depth of the QuadTree
  8480. */
  8481. insert: function (point, depth) {
  8482. var newQuadTreeNode;
  8483. if (this.isInternal) {
  8484. // Internal node:
  8485. this.nodes[this.getBoxPosition(point)].insert(point, depth - 1);
  8486. }
  8487. else {
  8488. this.isEmpty = false;
  8489. if (!this.body) {
  8490. // First body in a quadrant:
  8491. this.isInternal = false;
  8492. this.body = point;
  8493. }
  8494. else {
  8495. if (depth) {
  8496. // Every other body in a quadrant:
  8497. this.isInternal = true;
  8498. this.divideBox();
  8499. // Reinsert main body only once:
  8500. if (this.body !== true) {
  8501. this.nodes[this.getBoxPosition(this.body)]
  8502. .insert(this.body, depth - 1);
  8503. this.body = true;
  8504. }
  8505. // Add second body:
  8506. this.nodes[this.getBoxPosition(point)]
  8507. .insert(point, depth - 1);
  8508. }
  8509. else {
  8510. // We are below max allowed depth. That means either:
  8511. // - really huge number of points
  8512. // - falling two points into exactly the same position
  8513. // In this case, create another node in the QuadTree.
  8514. //
  8515. // Alternatively we could add some noise to the
  8516. // position, but that could result in different
  8517. // rendered chart in exporting.
  8518. newQuadTreeNode = new QuadTreeNode({
  8519. top: point.plotX,
  8520. left: point.plotY,
  8521. // Width/height below 1px
  8522. width: 0.1,
  8523. height: 0.1
  8524. });
  8525. newQuadTreeNode.body = point;
  8526. newQuadTreeNode.isInternal = false;
  8527. this.nodes.push(newQuadTreeNode);
  8528. }
  8529. }
  8530. }
  8531. },
  8532. /**
  8533. * Each quad node requires it's mass and center position. That mass and
  8534. * position is used to imitate real node in the layout by approximation.
  8535. */
  8536. updateMassAndCenter: function () {
  8537. var mass = 0,
  8538. plotX = 0,
  8539. plotY = 0;
  8540. if (this.isInternal) {
  8541. // Calcualte weightened mass of the quad node:
  8542. this.nodes.forEach(function (pointMass) {
  8543. if (!pointMass.isEmpty) {
  8544. mass += pointMass.mass;
  8545. plotX +=
  8546. pointMass.plotX * pointMass.mass;
  8547. plotY +=
  8548. pointMass.plotY * pointMass.mass;
  8549. }
  8550. });
  8551. plotX /= mass;
  8552. plotY /= mass;
  8553. }
  8554. else if (this.body) {
  8555. // Just one node, use coordinates directly:
  8556. mass = this.body.mass;
  8557. plotX = this.body.plotX;
  8558. plotY = this.body.plotY;
  8559. }
  8560. // Store details:
  8561. this.mass = mass;
  8562. this.plotX = plotX;
  8563. this.plotY = plotY;
  8564. },
  8565. /**
  8566. * When inserting another node into the box, that already hove one node,
  8567. * divide the available space into another four quadrants.
  8568. *
  8569. * Indexes of quadrants are:
  8570. * ```
  8571. * ------------- -------------
  8572. * | | | | |
  8573. * | | | 0 | 1 |
  8574. * | | divide() | | |
  8575. * | 1 | -----------> -------------
  8576. * | | | | |
  8577. * | | | 3 | 2 |
  8578. * | | | | |
  8579. * ------------- -------------
  8580. * ```
  8581. */
  8582. divideBox: function () {
  8583. var halfWidth = this.box.width / 2,
  8584. halfHeight = this.box.height / 2;
  8585. // Top left
  8586. this.nodes[0] = new QuadTreeNode({
  8587. left: this.box.left,
  8588. top: this.box.top,
  8589. width: halfWidth,
  8590. height: halfHeight
  8591. });
  8592. // Top right
  8593. this.nodes[1] = new QuadTreeNode({
  8594. left: this.box.left + halfWidth,
  8595. top: this.box.top,
  8596. width: halfWidth,
  8597. height: halfHeight
  8598. });
  8599. // Bottom right
  8600. this.nodes[2] = new QuadTreeNode({
  8601. left: this.box.left + halfWidth,
  8602. top: this.box.top + halfHeight,
  8603. width: halfWidth,
  8604. height: halfHeight
  8605. });
  8606. // Bottom left
  8607. this.nodes[3] = new QuadTreeNode({
  8608. left: this.box.left,
  8609. top: this.box.top + halfHeight,
  8610. width: halfWidth,
  8611. height: halfHeight
  8612. });
  8613. },
  8614. /**
  8615. * Determine which of the quadrants should be used when placing node in
  8616. * the QuadTree. Returned index is always in range `< 0 , 3 >`.
  8617. *
  8618. * @param {Highcharts.Point} point
  8619. * @return {number}
  8620. */
  8621. getBoxPosition: function (point) {
  8622. var left = point.plotX < this.box.left + this.box.width / 2,
  8623. top = point.plotY < this.box.top + this.box.height / 2,
  8624. index;
  8625. if (left) {
  8626. if (top) {
  8627. // Top left
  8628. index = 0;
  8629. }
  8630. else {
  8631. // Bottom left
  8632. index = 3;
  8633. }
  8634. }
  8635. else {
  8636. if (top) {
  8637. // Top right
  8638. index = 1;
  8639. }
  8640. else {
  8641. // Bottom right
  8642. index = 2;
  8643. }
  8644. }
  8645. return index;
  8646. }
  8647. });
  8648. /**
  8649. * The QuadTree class. Used in Networkgraph chart as a base for Barnes-Hut
  8650. * approximation.
  8651. *
  8652. * @private
  8653. * @class
  8654. * @name Highcharts.QuadTree
  8655. *
  8656. * @param {number} x left position of the plotting area
  8657. * @param {number} y top position of the plotting area
  8658. * @param {number} width width of the plotting area
  8659. * @param {number} height height of the plotting area
  8660. */
  8661. var QuadTree = H.QuadTree = function (x,
  8662. y,
  8663. width,
  8664. height) {
  8665. // Boundary rectangle:
  8666. this.box = {
  8667. left: x,
  8668. top: y,
  8669. width: width,
  8670. height: height
  8671. };
  8672. this.maxDepth = 25;
  8673. this.root = new QuadTreeNode(this.box, '0');
  8674. this.root.isInternal = true;
  8675. this.root.isRoot = true;
  8676. this.root.divideBox();
  8677. };
  8678. extend(QuadTree.prototype,
  8679. /** @lends Highcharts.QuadTree.prototype */
  8680. {
  8681. /**
  8682. * Insert nodes into the QuadTree
  8683. *
  8684. * @param {Array<Highcharts.Point>} points
  8685. */
  8686. insertNodes: function (points) {
  8687. points.forEach(function (point) {
  8688. this.root.insert(point, this.maxDepth);
  8689. }, this);
  8690. },
  8691. /**
  8692. * Depfth first treversal (DFS). Using `before` and `after` callbacks,
  8693. * we can get two results: preorder and postorder traversals, reminder:
  8694. *
  8695. * ```
  8696. * (a)
  8697. * / \
  8698. * (b) (c)
  8699. * / \
  8700. * (d) (e)
  8701. * ```
  8702. *
  8703. * DFS (preorder): `a -> b -> d -> e -> c`
  8704. *
  8705. * DFS (postorder): `d -> e -> b -> c -> a`
  8706. *
  8707. * @param {Highcharts.QuadTreeNode|null} node
  8708. * @param {Function} [beforeCallback] function to be called before
  8709. * visiting children nodes
  8710. * @param {Function} [afterCallback] function to be called after
  8711. * visiting children nodes
  8712. */
  8713. visitNodeRecursive: function (node, beforeCallback, afterCallback) {
  8714. var goFurther;
  8715. if (!node) {
  8716. node = this.root;
  8717. }
  8718. if (node === this.root && beforeCallback) {
  8719. goFurther = beforeCallback(node);
  8720. }
  8721. if (goFurther === false) {
  8722. return;
  8723. }
  8724. node.nodes.forEach(function (qtNode) {
  8725. if (qtNode.isInternal) {
  8726. if (beforeCallback) {
  8727. goFurther = beforeCallback(qtNode);
  8728. }
  8729. if (goFurther === false) {
  8730. return;
  8731. }
  8732. this.visitNodeRecursive(qtNode, beforeCallback, afterCallback);
  8733. }
  8734. else if (qtNode.body) {
  8735. if (beforeCallback) {
  8736. beforeCallback(qtNode.body);
  8737. }
  8738. }
  8739. if (afterCallback) {
  8740. afterCallback(qtNode);
  8741. }
  8742. }, this);
  8743. if (node === this.root && afterCallback) {
  8744. afterCallback(node);
  8745. }
  8746. },
  8747. /**
  8748. * Calculate mass of the each QuadNode in the tree.
  8749. */
  8750. calculateMassAndCenter: function () {
  8751. this.visitNodeRecursive(null, null, function (node) {
  8752. node.updateMassAndCenter();
  8753. });
  8754. }
  8755. });
  8756. });
  8757. _registerModule(_modules, 'Series/Networkgraph/Layouts.js', [_modules['Core/Chart/Chart.js'], _modules['Core/Animation/AnimationUtilities.js'], _modules['Core/Globals.js'], _modules['Core/Utilities.js']], function (Chart, A, H, U) {
  8758. /* *
  8759. *
  8760. * Networkgraph series
  8761. *
  8762. * (c) 2010-2021 Paweł Fus
  8763. *
  8764. * License: www.highcharts.com/license
  8765. *
  8766. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  8767. *
  8768. * */
  8769. var setAnimation = A.setAnimation;
  8770. var addEvent = U.addEvent,
  8771. clamp = U.clamp,
  8772. defined = U.defined,
  8773. extend = U.extend,
  8774. isFunction = U.isFunction,
  8775. pick = U.pick;
  8776. /* eslint-disable no-invalid-this, valid-jsdoc */
  8777. H.layouts = {
  8778. 'reingold-fruchterman': function () {
  8779. }
  8780. };
  8781. extend(
  8782. /**
  8783. * Reingold-Fruchterman algorithm from
  8784. * "Graph Drawing by Force-directed Placement" paper.
  8785. * @private
  8786. */
  8787. H.layouts['reingold-fruchterman'].prototype, {
  8788. init: function (options) {
  8789. this.options = options;
  8790. this.nodes = [];
  8791. this.links = [];
  8792. this.series = [];
  8793. this.box = {
  8794. x: 0,
  8795. y: 0,
  8796. width: 0,
  8797. height: 0
  8798. };
  8799. this.setInitialRendering(true);
  8800. this.integration =
  8801. H.networkgraphIntegrations[options.integration];
  8802. this.enableSimulation = options.enableSimulation;
  8803. this.attractiveForce = pick(options.attractiveForce, this.integration.attractiveForceFunction);
  8804. this.repulsiveForce = pick(options.repulsiveForce, this.integration.repulsiveForceFunction);
  8805. this.approximation = options.approximation;
  8806. },
  8807. updateSimulation: function (enable) {
  8808. this.enableSimulation = pick(enable, this.options.enableSimulation);
  8809. },
  8810. start: function () {
  8811. var layout = this,
  8812. series = this.series,
  8813. options = this.options;
  8814. layout.currentStep = 0;
  8815. layout.forces = series[0] && series[0].forces || [];
  8816. layout.chart = series[0] && series[0].chart;
  8817. if (layout.initialRendering) {
  8818. layout.initPositions();
  8819. // Render elements in initial positions:
  8820. series.forEach(function (s) {
  8821. s.finishedAnimating = true; // #13169
  8822. s.render();
  8823. });
  8824. }
  8825. layout.setK();
  8826. layout.resetSimulation(options);
  8827. if (layout.enableSimulation) {
  8828. layout.step();
  8829. }
  8830. },
  8831. step: function () {
  8832. var layout = this,
  8833. series = this.series,
  8834. options = this.options;
  8835. // Algorithm:
  8836. layout.currentStep++;
  8837. if (layout.approximation === 'barnes-hut') {
  8838. layout.createQuadTree();
  8839. layout.quadTree.calculateMassAndCenter();
  8840. }
  8841. layout.forces.forEach(function (forceName) {
  8842. layout[forceName + 'Forces'](layout.temperature);
  8843. });
  8844. // Limit to the plotting area and cool down:
  8845. layout.applyLimits(layout.temperature);
  8846. // Cool down the system:
  8847. layout.temperature = layout.coolDown(layout.startTemperature, layout.diffTemperature, layout.currentStep);
  8848. layout.prevSystemTemperature = layout.systemTemperature;
  8849. layout.systemTemperature = layout.getSystemTemperature();
  8850. if (layout.enableSimulation) {
  8851. series.forEach(function (s) {
  8852. // Chart could be destroyed during the simulation
  8853. if (s.chart) {
  8854. s.render();
  8855. }
  8856. });
  8857. if (layout.maxIterations-- &&
  8858. isFinite(layout.temperature) &&
  8859. !layout.isStable()) {
  8860. if (layout.simulation) {
  8861. H.win.cancelAnimationFrame(layout.simulation);
  8862. }
  8863. layout.simulation = H.win.requestAnimationFrame(function () {
  8864. layout.step();
  8865. });
  8866. }
  8867. else {
  8868. layout.simulation = false;
  8869. }
  8870. }
  8871. },
  8872. stop: function () {
  8873. if (this.simulation) {
  8874. H.win.cancelAnimationFrame(this.simulation);
  8875. }
  8876. },
  8877. setArea: function (x, y, w, h) {
  8878. this.box = {
  8879. left: x,
  8880. top: y,
  8881. width: w,
  8882. height: h
  8883. };
  8884. },
  8885. setK: function () {
  8886. // Optimal distance between nodes,
  8887. // available space around the node:
  8888. this.k = this.options.linkLength || this.integration.getK(this);
  8889. },
  8890. addElementsToCollection: function (elements, collection) {
  8891. elements.forEach(function (elem) {
  8892. if (collection.indexOf(elem) === -1) {
  8893. collection.push(elem);
  8894. }
  8895. });
  8896. },
  8897. removeElementFromCollection: function (element, collection) {
  8898. var index = collection.indexOf(element);
  8899. if (index !== -1) {
  8900. collection.splice(index, 1);
  8901. }
  8902. },
  8903. clear: function () {
  8904. this.nodes.length = 0;
  8905. this.links.length = 0;
  8906. this.series.length = 0;
  8907. this.resetSimulation();
  8908. },
  8909. resetSimulation: function () {
  8910. this.forcedStop = false;
  8911. this.systemTemperature = 0;
  8912. this.setMaxIterations();
  8913. this.setTemperature();
  8914. this.setDiffTemperature();
  8915. },
  8916. restartSimulation: function () {
  8917. if (!this.simulation) {
  8918. // When dragging nodes, we don't need to calculate
  8919. // initial positions and rendering nodes:
  8920. this.setInitialRendering(false);
  8921. // Start new simulation:
  8922. if (!this.enableSimulation) {
  8923. // Run only one iteration to speed things up:
  8924. this.setMaxIterations(1);
  8925. }
  8926. else {
  8927. this.start();
  8928. }
  8929. if (this.chart) {
  8930. this.chart.redraw();
  8931. }
  8932. // Restore defaults:
  8933. this.setInitialRendering(true);
  8934. }
  8935. else {
  8936. // Extend current simulation:
  8937. this.resetSimulation();
  8938. }
  8939. },
  8940. setMaxIterations: function (maxIterations) {
  8941. this.maxIterations = pick(maxIterations, this.options.maxIterations);
  8942. },
  8943. setTemperature: function () {
  8944. this.temperature = this.startTemperature =
  8945. Math.sqrt(this.nodes.length);
  8946. },
  8947. setDiffTemperature: function () {
  8948. this.diffTemperature = this.startTemperature /
  8949. (this.options.maxIterations + 1);
  8950. },
  8951. setInitialRendering: function (enable) {
  8952. this.initialRendering = enable;
  8953. },
  8954. createQuadTree: function () {
  8955. this.quadTree = new H.QuadTree(this.box.left, this.box.top, this.box.width, this.box.height);
  8956. this.quadTree.insertNodes(this.nodes);
  8957. },
  8958. initPositions: function () {
  8959. var initialPositions = this.options.initialPositions;
  8960. if (isFunction(initialPositions)) {
  8961. initialPositions.call(this);
  8962. this.nodes.forEach(function (node) {
  8963. if (!defined(node.prevX)) {
  8964. node.prevX = node.plotX;
  8965. }
  8966. if (!defined(node.prevY)) {
  8967. node.prevY = node.plotY;
  8968. }
  8969. node.dispX = 0;
  8970. node.dispY = 0;
  8971. });
  8972. }
  8973. else if (initialPositions === 'circle') {
  8974. this.setCircularPositions();
  8975. }
  8976. else {
  8977. this.setRandomPositions();
  8978. }
  8979. },
  8980. setCircularPositions: function () {
  8981. var box = this.box,
  8982. nodes = this.nodes,
  8983. nodesLength = nodes.length + 1,
  8984. angle = 2 * Math.PI / nodesLength,
  8985. rootNodes = nodes.filter(function (node) {
  8986. return node.linksTo.length === 0;
  8987. }), sortedNodes = [], visitedNodes = {}, radius = this.options.initialPositionRadius;
  8988. /**
  8989. * @private
  8990. */
  8991. function addToNodes(node) {
  8992. node.linksFrom.forEach(function (link) {
  8993. if (!visitedNodes[link.toNode.id]) {
  8994. visitedNodes[link.toNode.id] = true;
  8995. sortedNodes.push(link.toNode);
  8996. addToNodes(link.toNode);
  8997. }
  8998. });
  8999. }
  9000. // Start with identified root nodes an sort the nodes by their
  9001. // hierarchy. In trees, this ensures that branches don't cross
  9002. // eachother.
  9003. rootNodes.forEach(function (rootNode) {
  9004. sortedNodes.push(rootNode);
  9005. addToNodes(rootNode);
  9006. });
  9007. // Cyclic tree, no root node found
  9008. if (!sortedNodes.length) {
  9009. sortedNodes = nodes;
  9010. // Dangling, cyclic trees
  9011. }
  9012. else {
  9013. nodes.forEach(function (node) {
  9014. if (sortedNodes.indexOf(node) === -1) {
  9015. sortedNodes.push(node);
  9016. }
  9017. });
  9018. }
  9019. // Initial positions are laid out along a small circle, appearing
  9020. // as a cluster in the middle
  9021. sortedNodes.forEach(function (node, index) {
  9022. node.plotX = node.prevX = pick(node.plotX, box.width / 2 + radius * Math.cos(index * angle));
  9023. node.plotY = node.prevY = pick(node.plotY, box.height / 2 + radius * Math.sin(index * angle));
  9024. node.dispX = 0;
  9025. node.dispY = 0;
  9026. });
  9027. },
  9028. setRandomPositions: function () {
  9029. var box = this.box,
  9030. nodes = this.nodes,
  9031. nodesLength = nodes.length + 1;
  9032. /**
  9033. * Return a repeatable, quasi-random number based on an integer
  9034. * input. For the initial positions
  9035. * @private
  9036. */
  9037. function unrandom(n) {
  9038. var rand = n * n / Math.PI;
  9039. rand = rand - Math.floor(rand);
  9040. return rand;
  9041. }
  9042. // Initial positions:
  9043. nodes.forEach(function (node, index) {
  9044. node.plotX = node.prevX = pick(node.plotX, box.width * unrandom(index));
  9045. node.plotY = node.prevY = pick(node.plotY, box.height * unrandom(nodesLength + index));
  9046. node.dispX = 0;
  9047. node.dispY = 0;
  9048. });
  9049. },
  9050. force: function (name) {
  9051. this.integration[name].apply(this, Array.prototype.slice.call(arguments, 1));
  9052. },
  9053. barycenterForces: function () {
  9054. this.getBarycenter();
  9055. this.force('barycenter');
  9056. },
  9057. getBarycenter: function () {
  9058. var systemMass = 0,
  9059. cx = 0,
  9060. cy = 0;
  9061. this.nodes.forEach(function (node) {
  9062. cx += node.plotX * node.mass;
  9063. cy += node.plotY * node.mass;
  9064. systemMass += node.mass;
  9065. });
  9066. this.barycenter = {
  9067. x: cx,
  9068. y: cy,
  9069. xFactor: cx / systemMass,
  9070. yFactor: cy / systemMass
  9071. };
  9072. return this.barycenter;
  9073. },
  9074. barnesHutApproximation: function (node, quadNode) {
  9075. var layout = this,
  9076. distanceXY = layout.getDistXY(node,
  9077. quadNode),
  9078. distanceR = layout.vectorLength(distanceXY),
  9079. goDeeper,
  9080. force;
  9081. if (node !== quadNode && distanceR !== 0) {
  9082. if (quadNode.isInternal) {
  9083. // Internal node:
  9084. if (quadNode.boxSize / distanceR <
  9085. layout.options.theta &&
  9086. distanceR !== 0) {
  9087. // Treat as an external node:
  9088. force = layout.repulsiveForce(distanceR, layout.k);
  9089. layout.force('repulsive', node, force * quadNode.mass, distanceXY, distanceR);
  9090. goDeeper = false;
  9091. }
  9092. else {
  9093. // Go deeper:
  9094. goDeeper = true;
  9095. }
  9096. }
  9097. else {
  9098. // External node, direct force:
  9099. force = layout.repulsiveForce(distanceR, layout.k);
  9100. layout.force('repulsive', node, force * quadNode.mass, distanceXY, distanceR);
  9101. }
  9102. }
  9103. return goDeeper;
  9104. },
  9105. repulsiveForces: function () {
  9106. var layout = this;
  9107. if (layout.approximation === 'barnes-hut') {
  9108. layout.nodes.forEach(function (node) {
  9109. layout.quadTree.visitNodeRecursive(null, function (quadNode) {
  9110. return layout.barnesHutApproximation(node, quadNode);
  9111. });
  9112. });
  9113. }
  9114. else {
  9115. layout.nodes.forEach(function (node) {
  9116. layout.nodes.forEach(function (repNode) {
  9117. var force,
  9118. distanceR,
  9119. distanceXY;
  9120. if (
  9121. // Node can not repulse itself:
  9122. node !== repNode &&
  9123. // Only close nodes affect each other:
  9124. // layout.getDistR(node, repNode) < 2 * k &&
  9125. // Not dragged:
  9126. !node.fixedPosition) {
  9127. distanceXY = layout.getDistXY(node, repNode);
  9128. distanceR = layout.vectorLength(distanceXY);
  9129. if (distanceR !== 0) {
  9130. force = layout.repulsiveForce(distanceR, layout.k);
  9131. layout.force('repulsive', node, force * repNode.mass, distanceXY, distanceR);
  9132. }
  9133. }
  9134. });
  9135. });
  9136. }
  9137. },
  9138. attractiveForces: function () {
  9139. var layout = this,
  9140. distanceXY,
  9141. distanceR,
  9142. force;
  9143. layout.links.forEach(function (link) {
  9144. if (link.fromNode && link.toNode) {
  9145. distanceXY = layout.getDistXY(link.fromNode, link.toNode);
  9146. distanceR = layout.vectorLength(distanceXY);
  9147. if (distanceR !== 0) {
  9148. force = layout.attractiveForce(distanceR, layout.k);
  9149. layout.force('attractive', link, force, distanceXY, distanceR);
  9150. }
  9151. }
  9152. });
  9153. },
  9154. applyLimits: function () {
  9155. var layout = this,
  9156. nodes = layout.nodes;
  9157. nodes.forEach(function (node) {
  9158. if (node.fixedPosition) {
  9159. return;
  9160. }
  9161. layout.integration.integrate(layout, node);
  9162. layout.applyLimitBox(node, layout.box);
  9163. // Reset displacement:
  9164. node.dispX = 0;
  9165. node.dispY = 0;
  9166. });
  9167. },
  9168. /**
  9169. * External box that nodes should fall. When hitting an edge, node
  9170. * should stop or bounce.
  9171. * @private
  9172. */
  9173. applyLimitBox: function (node, box) {
  9174. var radius = node.radius;
  9175. /*
  9176. TO DO: Consider elastic collision instead of stopping.
  9177. o' means end position when hitting plotting area edge:
  9178. - "inelastic":
  9179. o
  9180. \
  9181. ______
  9182. | o'
  9183. | \
  9184. | \
  9185. - "elastic"/"bounced":
  9186. o
  9187. \
  9188. ______
  9189. | ^
  9190. | / \
  9191. |o' \
  9192. Euler sample:
  9193. if (plotX < 0) {
  9194. plotX = 0;
  9195. dispX *= -1;
  9196. }
  9197. if (plotX > box.width) {
  9198. plotX = box.width;
  9199. dispX *= -1;
  9200. }
  9201. */
  9202. // Limit X-coordinates:
  9203. node.plotX = clamp(node.plotX, box.left + radius, box.width - radius);
  9204. // Limit Y-coordinates:
  9205. node.plotY = clamp(node.plotY, box.top + radius, box.height - radius);
  9206. },
  9207. /**
  9208. * From "A comparison of simulated annealing cooling strategies" by
  9209. * Nourani and Andresen work.
  9210. * @private
  9211. */
  9212. coolDown: function (temperature, temperatureStep, currentStep) {
  9213. // Logarithmic:
  9214. /*
  9215. return Math.sqrt(this.nodes.length) -
  9216. Math.log(
  9217. currentStep * layout.diffTemperature
  9218. );
  9219. */
  9220. // Exponential:
  9221. /*
  9222. let alpha = 0.1;
  9223. layout.temperature = Math.sqrt(layout.nodes.length) *
  9224. Math.pow(alpha, layout.diffTemperature);
  9225. */
  9226. // Linear:
  9227. return temperature - temperatureStep * currentStep;
  9228. },
  9229. isStable: function () {
  9230. return Math.abs(this.systemTemperature -
  9231. this.prevSystemTemperature) < 0.00001 || this.temperature <= 0;
  9232. },
  9233. getSystemTemperature: function () {
  9234. return this.nodes.reduce(function (value, node) {
  9235. return value + node.temperature;
  9236. }, 0);
  9237. },
  9238. vectorLength: function (vector) {
  9239. return Math.sqrt(vector.x * vector.x + vector.y * vector.y);
  9240. },
  9241. getDistR: function (nodeA, nodeB) {
  9242. var distance = this.getDistXY(nodeA,
  9243. nodeB);
  9244. return this.vectorLength(distance);
  9245. },
  9246. getDistXY: function (nodeA, nodeB) {
  9247. var xDist = nodeA.plotX - nodeB.plotX,
  9248. yDist = nodeA.plotY - nodeB.plotY;
  9249. return {
  9250. x: xDist,
  9251. y: yDist,
  9252. absX: Math.abs(xDist),
  9253. absY: Math.abs(yDist)
  9254. };
  9255. }
  9256. });
  9257. /* ************************************************************************** *
  9258. * Multiple series support:
  9259. * ************************************************************************** */
  9260. // Clear previous layouts
  9261. addEvent(Chart, 'predraw', function () {
  9262. if (this.graphLayoutsLookup) {
  9263. this.graphLayoutsLookup.forEach(function (layout) {
  9264. layout.stop();
  9265. });
  9266. }
  9267. });
  9268. addEvent(Chart, 'render', function () {
  9269. var systemsStable,
  9270. afterRender = false;
  9271. /**
  9272. * @private
  9273. */
  9274. function layoutStep(layout) {
  9275. if (layout.maxIterations-- &&
  9276. isFinite(layout.temperature) &&
  9277. !layout.isStable() &&
  9278. !layout.enableSimulation) {
  9279. // Hook similar to build-in addEvent, but instead of
  9280. // creating whole events logic, use just a function.
  9281. // It's faster which is important for rAF code.
  9282. // Used e.g. in packed-bubble series for bubble radius
  9283. // calculations
  9284. if (layout.beforeStep) {
  9285. layout.beforeStep();
  9286. }
  9287. layout.step();
  9288. systemsStable = false;
  9289. afterRender = true;
  9290. }
  9291. }
  9292. if (this.graphLayoutsLookup) {
  9293. setAnimation(false, this);
  9294. // Start simulation
  9295. this.graphLayoutsLookup.forEach(function (layout) {
  9296. layout.start();
  9297. });
  9298. // Just one sync step, to run different layouts similar to
  9299. // async mode.
  9300. while (!systemsStable) {
  9301. systemsStable = true;
  9302. this.graphLayoutsLookup.forEach(layoutStep);
  9303. }
  9304. if (afterRender) {
  9305. this.series.forEach(function (s) {
  9306. if (s && s.layout) {
  9307. s.render();
  9308. }
  9309. });
  9310. }
  9311. }
  9312. });
  9313. // disable simulation before print if enabled
  9314. addEvent(Chart, 'beforePrint', function () {
  9315. if (this.graphLayoutsLookup) {
  9316. this.graphLayoutsLookup.forEach(function (layout) {
  9317. layout.updateSimulation(false);
  9318. });
  9319. this.redraw();
  9320. }
  9321. });
  9322. // re-enable simulation after print
  9323. addEvent(Chart, 'afterPrint', function () {
  9324. if (this.graphLayoutsLookup) {
  9325. this.graphLayoutsLookup.forEach(function (layout) {
  9326. // return to default simulation
  9327. layout.updateSimulation();
  9328. });
  9329. }
  9330. this.redraw();
  9331. });
  9332. });
  9333. _registerModule(_modules, 'Series/PackedBubble/PackedBubbleComposition.js', [_modules['Core/Chart/Chart.js'], _modules['Core/Globals.js'], _modules['Core/Utilities.js']], function (Chart, H, U) {
  9334. /* *
  9335. *
  9336. * (c) 2010-2021 Grzegorz Blachlinski, Sebastian Bochan
  9337. *
  9338. * License: www.highcharts.com/license
  9339. *
  9340. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  9341. *
  9342. * */
  9343. var Reingold = H.layouts['reingold-fruchterman'];
  9344. var addEvent = U.addEvent,
  9345. extendClass = U.extendClass,
  9346. pick = U.pick;
  9347. /* *
  9348. *
  9349. * Composition
  9350. *
  9351. * */
  9352. Chart.prototype.getSelectedParentNodes = function () {
  9353. var chart = this,
  9354. series = chart.series,
  9355. selectedParentsNodes = [];
  9356. series.forEach(function (series) {
  9357. if (series.parentNode && series.parentNode.selected) {
  9358. selectedParentsNodes.push(series.parentNode);
  9359. }
  9360. });
  9361. return selectedParentsNodes;
  9362. };
  9363. H.networkgraphIntegrations.packedbubble = {
  9364. repulsiveForceFunction: function (d, k, node, repNode) {
  9365. return Math.min(d, (node.marker.radius + repNode.marker.radius) / 2);
  9366. },
  9367. barycenter: function () {
  9368. var layout = this,
  9369. gravitationalConstant = layout.options.gravitationalConstant,
  9370. box = layout.box,
  9371. nodes = layout.nodes,
  9372. centerX,
  9373. centerY;
  9374. nodes.forEach(function (node) {
  9375. if (layout.options.splitSeries && !node.isParentNode) {
  9376. centerX = node.series.parentNode.plotX;
  9377. centerY = node.series.parentNode.plotY;
  9378. }
  9379. else {
  9380. centerX = box.width / 2;
  9381. centerY = box.height / 2;
  9382. }
  9383. if (!node.fixedPosition) {
  9384. node.plotX -=
  9385. (node.plotX - centerX) *
  9386. gravitationalConstant /
  9387. (node.mass * Math.sqrt(nodes.length));
  9388. node.plotY -=
  9389. (node.plotY - centerY) *
  9390. gravitationalConstant /
  9391. (node.mass * Math.sqrt(nodes.length));
  9392. }
  9393. });
  9394. },
  9395. repulsive: function (node, force, distanceXY, repNode) {
  9396. var factor = (force * this.diffTemperature / node.mass /
  9397. node.degree),
  9398. x = distanceXY.x * factor,
  9399. y = distanceXY.y * factor;
  9400. if (!node.fixedPosition) {
  9401. node.plotX += x;
  9402. node.plotY += y;
  9403. }
  9404. if (!repNode.fixedPosition) {
  9405. repNode.plotX -= x;
  9406. repNode.plotY -= y;
  9407. }
  9408. },
  9409. integrate: H.networkgraphIntegrations.verlet.integrate,
  9410. getK: H.noop
  9411. };
  9412. H.layouts.packedbubble = extendClass(Reingold, {
  9413. beforeStep: function () {
  9414. if (this.options.marker) {
  9415. this.series.forEach(function (series) {
  9416. if (series) {
  9417. series.calculateParentRadius();
  9418. }
  9419. });
  9420. }
  9421. },
  9422. isStable: function () {
  9423. var tempDiff = Math.abs(this.prevSystemTemperature -
  9424. this.systemTemperature);
  9425. var upScaledTemperature = 10 * this.systemTemperature /
  9426. Math.sqrt(this.nodes.length);
  9427. return Math.abs(upScaledTemperature) < 1 &&
  9428. tempDiff < 0.00001 ||
  9429. this.temperature <= 0;
  9430. },
  9431. setCircularPositions: function () {
  9432. var layout = this,
  9433. box = layout.box,
  9434. nodes = layout.nodes,
  9435. nodesLength = nodes.length + 1,
  9436. angle = 2 * Math.PI / nodesLength,
  9437. centerX,
  9438. centerY,
  9439. radius = layout.options.initialPositionRadius;
  9440. nodes.forEach(function (node, index) {
  9441. if (layout.options.splitSeries &&
  9442. !node.isParentNode) {
  9443. centerX = node.series.parentNode.plotX;
  9444. centerY = node.series.parentNode.plotY;
  9445. }
  9446. else {
  9447. centerX = box.width / 2;
  9448. centerY = box.height / 2;
  9449. }
  9450. node.plotX = node.prevX = pick(node.plotX, centerX +
  9451. radius * Math.cos(node.index || index * angle));
  9452. node.plotY = node.prevY = pick(node.plotY, centerY +
  9453. radius * Math.sin(node.index || index * angle));
  9454. node.dispX = 0;
  9455. node.dispY = 0;
  9456. });
  9457. },
  9458. repulsiveForces: function () {
  9459. var layout = this,
  9460. force,
  9461. distanceR,
  9462. distanceXY,
  9463. bubblePadding = layout.options.bubblePadding;
  9464. layout.nodes.forEach(function (node) {
  9465. node.degree = node.mass;
  9466. node.neighbours = 0;
  9467. layout.nodes.forEach(function (repNode) {
  9468. force = 0;
  9469. if (
  9470. // Node can not repulse itself:
  9471. node !== repNode &&
  9472. // Only close nodes affect each other:
  9473. // Not dragged:
  9474. !node.fixedPosition &&
  9475. (layout.options.seriesInteraction ||
  9476. node.series === repNode.series)) {
  9477. distanceXY = layout.getDistXY(node, repNode);
  9478. distanceR = (layout.vectorLength(distanceXY) -
  9479. (node.marker.radius +
  9480. repNode.marker.radius +
  9481. bubblePadding));
  9482. // TODO padding configurable
  9483. if (distanceR < 0) {
  9484. node.degree += 0.01;
  9485. node.neighbours++;
  9486. force = layout.repulsiveForce(-distanceR / Math.sqrt(node.neighbours), layout.k, node, repNode);
  9487. }
  9488. layout.force('repulsive', node, force * repNode.mass, distanceXY, repNode, distanceR);
  9489. }
  9490. });
  9491. });
  9492. },
  9493. applyLimitBox: function (node) {
  9494. var layout = this,
  9495. distanceXY,
  9496. distanceR,
  9497. factor = 0.01;
  9498. // parentNodeLimit should be used together
  9499. // with seriesInteraction: false
  9500. if (layout.options.splitSeries &&
  9501. !node.isParentNode &&
  9502. layout.options.parentNodeLimit) {
  9503. distanceXY = layout.getDistXY(node, node.series.parentNode);
  9504. distanceR = (node.series.parentNodeRadius -
  9505. node.marker.radius -
  9506. layout.vectorLength(distanceXY));
  9507. if (distanceR < 0 &&
  9508. distanceR > -2 * node.marker.radius) {
  9509. node.plotX -= distanceXY.x * factor;
  9510. node.plotY -= distanceXY.y * factor;
  9511. }
  9512. }
  9513. Reingold.prototype.applyLimitBox.apply(this, arguments);
  9514. }
  9515. });
  9516. // Remove accumulated data points to redistribute all of them again
  9517. // (i.e after hiding series by legend)
  9518. addEvent(Chart, 'beforeRedraw', function () {
  9519. // eslint-disable-next-line no-invalid-this
  9520. if (this.allDataPoints) {
  9521. // eslint-disable-next-line no-invalid-this
  9522. delete this.allDataPoints;
  9523. }
  9524. });
  9525. });
  9526. _registerModule(_modules, 'Series/PackedBubble/PackedBubbleSeries.js', [_modules['Core/Color/Color.js'], _modules['Core/Globals.js'], _modules['Series/PackedBubble/PackedBubblePoint.js'], _modules['Core/Series/SeriesRegistry.js'], _modules['Core/Utilities.js']], function (Color, H, PackedBubblePoint, SeriesRegistry, U) {
  9527. /* *
  9528. *
  9529. * (c) 2010-2021 Grzegorz Blachlinski, Sebastian Bochan
  9530. *
  9531. * License: www.highcharts.com/license
  9532. *
  9533. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  9534. *
  9535. * */
  9536. var __extends = (this && this.__extends) || (function () {
  9537. var extendStatics = function (d,
  9538. b) {
  9539. extendStatics = Object.setPrototypeOf ||
  9540. ({ __proto__: [] } instanceof Array && function (d,
  9541. b) { d.__proto__ = b; }) ||
  9542. function (d,
  9543. b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  9544. return extendStatics(d, b);
  9545. };
  9546. return function (d, b) {
  9547. extendStatics(d, b);
  9548. function __() { this.constructor = d; }
  9549. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  9550. };
  9551. })();
  9552. var color = Color.parse;
  9553. var Series = SeriesRegistry.series,
  9554. BubbleSeries = SeriesRegistry.seriesTypes.bubble;
  9555. var addEvent = U.addEvent,
  9556. clamp = U.clamp,
  9557. defined = U.defined,
  9558. extend = U.extend,
  9559. fireEvent = U.fireEvent,
  9560. isArray = U.isArray,
  9561. isNumber = U.isNumber,
  9562. merge = U.merge,
  9563. pick = U.pick;
  9564. var dragNodesMixin = H.dragNodesMixin;
  9565. /* *
  9566. *
  9567. * Class
  9568. *
  9569. * */
  9570. /**
  9571. * @private
  9572. * @class
  9573. * @name Highcharts.seriesTypes.packedbubble
  9574. *
  9575. * @extends Highcharts.Series
  9576. */
  9577. var PackedBubbleSeries = /** @class */ (function (_super) {
  9578. __extends(PackedBubbleSeries, _super);
  9579. function PackedBubbleSeries() {
  9580. /* *
  9581. *
  9582. * Static Properties
  9583. *
  9584. * */
  9585. var _this = _super !== null && _super.apply(this,
  9586. arguments) || this;
  9587. /* *
  9588. *
  9589. * Properties
  9590. *
  9591. * */
  9592. _this.chart = void 0;
  9593. _this.data = void 0;
  9594. _this.layout = void 0;
  9595. _this.options = void 0;
  9596. _this.points = void 0;
  9597. _this.xData = void 0;
  9598. return _this;
  9599. /* eslint-enable valid-jsdoc */
  9600. }
  9601. /* *
  9602. *
  9603. * Functions
  9604. *
  9605. * */
  9606. /* eslint-disable valid-jsdoc */
  9607. /**
  9608. * Create a single array of all points from all series
  9609. * @private
  9610. */
  9611. PackedBubbleSeries.prototype.accumulateAllPoints = function (series) {
  9612. var chart = series.chart,
  9613. allDataPoints = [],
  9614. i,
  9615. j;
  9616. for (i = 0; i < chart.series.length; i++) {
  9617. series = chart.series[i];
  9618. if (series.is('packedbubble') && // #13574
  9619. series.visible ||
  9620. !chart.options.chart.ignoreHiddenSeries) {
  9621. // add data to array only if series is visible
  9622. for (j = 0; j < series.yData.length; j++) {
  9623. allDataPoints.push([
  9624. null, null,
  9625. series.yData[j],
  9626. series.index,
  9627. j,
  9628. {
  9629. id: j,
  9630. marker: {
  9631. radius: 0
  9632. }
  9633. }
  9634. ]);
  9635. }
  9636. }
  9637. }
  9638. return allDataPoints;
  9639. };
  9640. /**
  9641. * Adding the basic layout to series points.
  9642. * @private
  9643. */
  9644. PackedBubbleSeries.prototype.addLayout = function () {
  9645. var series = this,
  9646. layoutOptions = series.options.layoutAlgorithm,
  9647. graphLayoutsStorage = series.chart.graphLayoutsStorage,
  9648. graphLayoutsLookup = series.chart.graphLayoutsLookup,
  9649. chartOptions = series.chart.options.chart,
  9650. layout;
  9651. if (!graphLayoutsStorage) {
  9652. series.chart.graphLayoutsStorage = graphLayoutsStorage = {};
  9653. series.chart.graphLayoutsLookup = graphLayoutsLookup = [];
  9654. }
  9655. layout = graphLayoutsStorage[layoutOptions.type];
  9656. if (!layout) {
  9657. layoutOptions.enableSimulation =
  9658. !defined(chartOptions.forExport) ?
  9659. layoutOptions.enableSimulation :
  9660. !chartOptions.forExport;
  9661. graphLayoutsStorage[layoutOptions.type] = layout =
  9662. new H.layouts[layoutOptions.type]();
  9663. layout.init(layoutOptions);
  9664. graphLayoutsLookup.splice(layout.index, 0, layout);
  9665. }
  9666. series.layout = layout;
  9667. series.points.forEach(function (node) {
  9668. node.mass = 2;
  9669. node.degree = 1;
  9670. node.collisionNmb = 1;
  9671. });
  9672. layout.setArea(0, 0, series.chart.plotWidth, series.chart.plotHeight);
  9673. layout.addElementsToCollection([series], layout.series);
  9674. layout.addElementsToCollection(series.points, layout.nodes);
  9675. };
  9676. /**
  9677. * Function responsible for adding series layout, used for parent nodes.
  9678. * @private
  9679. */
  9680. PackedBubbleSeries.prototype.addSeriesLayout = function () {
  9681. var series = this,
  9682. layoutOptions = series.options.layoutAlgorithm,
  9683. graphLayoutsStorage = series.chart.graphLayoutsStorage,
  9684. graphLayoutsLookup = series.chart.graphLayoutsLookup,
  9685. parentNodeOptions = merge(layoutOptions,
  9686. layoutOptions.parentNodeOptions, {
  9687. enableSimulation: series.layout.options.enableSimulation
  9688. }),
  9689. parentNodeLayout;
  9690. parentNodeLayout = graphLayoutsStorage[layoutOptions.type + '-series'];
  9691. if (!parentNodeLayout) {
  9692. graphLayoutsStorage[layoutOptions.type + '-series'] =
  9693. parentNodeLayout =
  9694. new H.layouts[layoutOptions.type]();
  9695. parentNodeLayout.init(parentNodeOptions);
  9696. graphLayoutsLookup.splice(parentNodeLayout.index, 0, parentNodeLayout);
  9697. }
  9698. series.parentNodeLayout = parentNodeLayout;
  9699. this.createParentNodes();
  9700. };
  9701. /**
  9702. * The function responsible for calculating the parent node radius
  9703. * based on the total surface of iniside-bubbles and the group BBox
  9704. * @private
  9705. */
  9706. PackedBubbleSeries.prototype.calculateParentRadius = function () {
  9707. var series = this,
  9708. bBox,
  9709. parentPadding = 20,
  9710. minParentRadius = 20;
  9711. bBox = series.seriesBox();
  9712. series.parentNodeRadius = clamp(Math.sqrt(2 * series.parentNodeMass / Math.PI) + parentPadding, minParentRadius, bBox ?
  9713. Math.max(Math.sqrt(Math.pow(bBox.width, 2) +
  9714. Math.pow(bBox.height, 2)) / 2 + parentPadding, minParentRadius) :
  9715. Math.sqrt(2 * series.parentNodeMass / Math.PI) + parentPadding);
  9716. if (series.parentNode) {
  9717. series.parentNode.marker.radius =
  9718. series.parentNode.radius = series.parentNodeRadius;
  9719. }
  9720. };
  9721. /**
  9722. * Calculate min and max bubble value for radius calculation.
  9723. * @private
  9724. */
  9725. PackedBubbleSeries.prototype.calculateZExtremes = function () {
  9726. var chart = this.chart,
  9727. zMin = this.options.zMin,
  9728. zMax = this.options.zMax,
  9729. valMin = Infinity,
  9730. valMax = -Infinity;
  9731. if (zMin && zMax) {
  9732. return [zMin, zMax];
  9733. }
  9734. // it is needed to deal with null
  9735. // and undefined values
  9736. chart.series.forEach(function (s) {
  9737. s.yData.forEach(function (p) {
  9738. if (defined(p)) {
  9739. if (p > valMax) {
  9740. valMax = p;
  9741. }
  9742. if (p < valMin) {
  9743. valMin = p;
  9744. }
  9745. }
  9746. });
  9747. });
  9748. zMin = pick(zMin, valMin);
  9749. zMax = pick(zMax, valMax);
  9750. return [zMin, zMax];
  9751. };
  9752. /**
  9753. * Check if two bubbles overlaps.
  9754. * @private
  9755. * @param {Array} first bubble
  9756. * @param {Array} second bubble
  9757. * @return {Boolean} overlap or not
  9758. */
  9759. PackedBubbleSeries.prototype.checkOverlap = function (bubble1, bubble2) {
  9760. var diffX = bubble1[0] - bubble2[0], // diff of X center values
  9761. diffY = bubble1[1] - bubble2[1], // diff of Y center values
  9762. sumRad = bubble1[2] + bubble2[2]; // sum of bubble radius
  9763. return (Math.sqrt(diffX * diffX + diffY * diffY) -
  9764. Math.abs(sumRad)) < -0.001;
  9765. };
  9766. /**
  9767. * Creating parent nodes for split series, in which all the bubbles
  9768. * are rendered.
  9769. * @private
  9770. */
  9771. PackedBubbleSeries.prototype.createParentNodes = function () {
  9772. var series = this,
  9773. chart = series.chart,
  9774. parentNodeLayout = series.parentNodeLayout,
  9775. nodeAdded,
  9776. parentNode = series.parentNode,
  9777. PackedBubblePoint = series.pointClass;
  9778. series.parentNodeMass = 0;
  9779. series.points.forEach(function (p) {
  9780. series.parentNodeMass +=
  9781. Math.PI * Math.pow(p.marker.radius, 2);
  9782. });
  9783. series.calculateParentRadius();
  9784. parentNodeLayout.nodes.forEach(function (node) {
  9785. if (node.seriesIndex === series.index) {
  9786. nodeAdded = true;
  9787. }
  9788. });
  9789. parentNodeLayout.setArea(0, 0, chart.plotWidth, chart.plotHeight);
  9790. if (!nodeAdded) {
  9791. if (!parentNode) {
  9792. parentNode = (new PackedBubblePoint()).init(this, {
  9793. mass: series.parentNodeRadius / 2,
  9794. marker: {
  9795. radius: series.parentNodeRadius
  9796. },
  9797. dataLabels: {
  9798. inside: false
  9799. },
  9800. dataLabelOnNull: true,
  9801. degree: series.parentNodeRadius,
  9802. isParentNode: true,
  9803. seriesIndex: series.index
  9804. });
  9805. }
  9806. if (series.parentNode) {
  9807. parentNode.plotX = series.parentNode.plotX;
  9808. parentNode.plotY = series.parentNode.plotY;
  9809. }
  9810. series.parentNode = parentNode;
  9811. parentNodeLayout.addElementsToCollection([series], parentNodeLayout.series);
  9812. parentNodeLayout.addElementsToCollection([parentNode], parentNodeLayout.nodes);
  9813. }
  9814. };
  9815. /**
  9816. * Function responsible for adding all the layouts to the chart.
  9817. * @private
  9818. */
  9819. PackedBubbleSeries.prototype.deferLayout = function () {
  9820. // TODO split layouts to independent methods
  9821. var series = this,
  9822. layoutOptions = series.options.layoutAlgorithm;
  9823. if (!series.visible) {
  9824. return;
  9825. }
  9826. // layout is using nodes for position calculation
  9827. series.addLayout();
  9828. if (layoutOptions.splitSeries) {
  9829. series.addSeriesLayout();
  9830. }
  9831. };
  9832. PackedBubbleSeries.prototype.destroy = function () {
  9833. // Remove the series from all layouts series collections #11469
  9834. if (this.chart.graphLayoutsLookup) {
  9835. this.chart.graphLayoutsLookup.forEach(function (layout) {
  9836. layout.removeElementFromCollection(this, layout.series);
  9837. }, this);
  9838. }
  9839. if (this.parentNode &&
  9840. this.parentNodeLayout) {
  9841. this.parentNodeLayout.removeElementFromCollection(this.parentNode, this.parentNodeLayout.nodes);
  9842. if (this.parentNode.dataLabel) {
  9843. this.parentNode.dataLabel =
  9844. this.parentNode.dataLabel.destroy();
  9845. }
  9846. }
  9847. Series.prototype.destroy.apply(this, arguments);
  9848. };
  9849. /**
  9850. * Packedbubble has two separate collecions of nodes if split, render
  9851. * dataLabels for both sets:
  9852. * @private
  9853. */
  9854. PackedBubbleSeries.prototype.drawDataLabels = function () {
  9855. var textPath = this.options.dataLabels.textPath,
  9856. points = this.points;
  9857. // Render node labels:
  9858. Series.prototype.drawDataLabels.apply(this, arguments);
  9859. // Render parentNode labels:
  9860. if (this.parentNode) {
  9861. this.parentNode.formatPrefix = 'parentNode';
  9862. this.points = [this.parentNode];
  9863. this.options.dataLabels.textPath =
  9864. this.options.dataLabels.parentNodeTextPath;
  9865. Series.prototype.drawDataLabels.apply(this, arguments);
  9866. // Restore nodes
  9867. this.points = points;
  9868. this.options.dataLabels.textPath = textPath;
  9869. }
  9870. };
  9871. /**
  9872. * Create Background/Parent Nodes for split series.
  9873. * @private
  9874. */
  9875. PackedBubbleSeries.prototype.drawGraph = function () {
  9876. // if the series is not using layout, don't add parent nodes
  9877. if (!this.layout || !this.layout.options.splitSeries) {
  9878. return;
  9879. }
  9880. var series = this,
  9881. chart = series.chart,
  9882. parentAttribs = {},
  9883. nodeMarker = this.layout.options.parentNodeOptions.marker,
  9884. parentOptions = {
  9885. fill: nodeMarker.fillColor || color(series.color).brighten(0.4).get(),
  9886. opacity: nodeMarker.fillOpacity,
  9887. stroke: nodeMarker.lineColor || series.color,
  9888. 'stroke-width': nodeMarker.lineWidth
  9889. };
  9890. // create the group for parent Nodes if doesn't exist
  9891. if (!this.parentNodesGroup) {
  9892. series.parentNodesGroup = series.plotGroup('parentNodesGroup', 'parentNode', series.visible ? 'inherit' : 'hidden', 0.1, chart.seriesGroup);
  9893. series.group.attr({
  9894. zIndex: 2
  9895. });
  9896. }
  9897. this.calculateParentRadius();
  9898. parentAttribs = merge({
  9899. x: series.parentNode.plotX -
  9900. series.parentNodeRadius,
  9901. y: series.parentNode.plotY -
  9902. series.parentNodeRadius,
  9903. width: series.parentNodeRadius * 2,
  9904. height: series.parentNodeRadius * 2
  9905. }, parentOptions);
  9906. if (!series.parentNode.graphic) {
  9907. series.graph = series.parentNode.graphic =
  9908. chart.renderer.symbol(parentOptions.symbol)
  9909. .add(series.parentNodesGroup);
  9910. }
  9911. series.parentNode.graphic.attr(parentAttribs);
  9912. };
  9913. PackedBubbleSeries.prototype.drawTracker = function () {
  9914. var series = this,
  9915. /* chart = series.chart,
  9916. pointer = chart.pointer,
  9917. onMouseOver = function (e: PointerEvent): void {
  9918. const point = pointer.getPointFromEvent(e);
  9919. // undefined on graph in scatterchart
  9920. if (typeof point !== 'undefined') {
  9921. pointer.isDirectTouch = true;
  9922. point.onMouseOver(e);
  9923. }
  9924. }, */
  9925. parentNode = series.parentNode;
  9926. var dataLabels;
  9927. _super.prototype.drawTracker.call(this);
  9928. // Add reference to the point
  9929. if (parentNode) {
  9930. dataLabels = (isArray(parentNode.dataLabels) ?
  9931. parentNode.dataLabels :
  9932. (parentNode.dataLabel ? [parentNode.dataLabel] : []));
  9933. if (parentNode.graphic) {
  9934. parentNode.graphic.element.point = parentNode;
  9935. }
  9936. dataLabels.forEach(function (dataLabel) {
  9937. if (dataLabel.div) {
  9938. dataLabel.div.point = parentNode;
  9939. }
  9940. else {
  9941. dataLabel.element.point = parentNode;
  9942. }
  9943. });
  9944. }
  9945. };
  9946. /**
  9947. * Calculate radius of bubbles in series.
  9948. * @private
  9949. */
  9950. PackedBubbleSeries.prototype.getPointRadius = function () {
  9951. var series = this,
  9952. chart = series.chart,
  9953. plotWidth = chart.plotWidth,
  9954. plotHeight = chart.plotHeight,
  9955. seriesOptions = series.options,
  9956. useSimulation = seriesOptions.useSimulation,
  9957. smallestSize = Math.min(plotWidth,
  9958. plotHeight),
  9959. extremes = {},
  9960. radii = [],
  9961. allDataPoints = chart.allDataPoints,
  9962. minSize,
  9963. maxSize,
  9964. value,
  9965. radius,
  9966. zExtremes;
  9967. ['minSize', 'maxSize'].forEach(function (prop) {
  9968. var length = parseInt(seriesOptions[prop], 10),
  9969. isPercent = /%$/.test(seriesOptions[prop]);
  9970. extremes[prop] = isPercent ?
  9971. smallestSize * length / 100 :
  9972. length * Math.sqrt(allDataPoints.length);
  9973. });
  9974. chart.minRadius = minSize = extremes.minSize /
  9975. Math.sqrt(allDataPoints.length);
  9976. chart.maxRadius = maxSize = extremes.maxSize /
  9977. Math.sqrt(allDataPoints.length);
  9978. zExtremes = useSimulation ?
  9979. series.calculateZExtremes() :
  9980. [minSize, maxSize];
  9981. (allDataPoints || []).forEach(function (point, i) {
  9982. value = useSimulation ?
  9983. clamp(point[2], zExtremes[0], zExtremes[1]) :
  9984. point[2];
  9985. radius = series.getRadius(zExtremes[0], zExtremes[1], minSize, maxSize, value);
  9986. if (radius === 0) {
  9987. radius = null;
  9988. }
  9989. allDataPoints[i][2] = radius;
  9990. radii.push(radius);
  9991. });
  9992. series.radii = radii;
  9993. };
  9994. PackedBubbleSeries.prototype.init = function () {
  9995. Series.prototype.init.apply(this, arguments);
  9996. /* eslint-disable no-invalid-this */
  9997. // When one series is modified, the others need to be recomputed
  9998. this.eventsToUnbind.push(addEvent(this, 'updatedData', function () {
  9999. this.chart.series.forEach(function (s) {
  10000. if (s.type === this.type) {
  10001. s.isDirty = true;
  10002. }
  10003. }, this);
  10004. }));
  10005. /* eslint-enable no-invalid-this */
  10006. return this;
  10007. };
  10008. /**
  10009. * Mouse up action, finalizing drag&drop.
  10010. * @private
  10011. * @param {Highcharts.Point} point The point that event occured.
  10012. */
  10013. PackedBubbleSeries.prototype.onMouseUp = function (point) {
  10014. if (point.fixedPosition && !point.removed) {
  10015. var distanceXY_1,
  10016. distanceR_1,
  10017. layout_1 = this.layout,
  10018. parentNodeLayout = this.parentNodeLayout;
  10019. if (parentNodeLayout && layout_1.options.dragBetweenSeries) {
  10020. parentNodeLayout.nodes.forEach(function (node) {
  10021. if (point && point.marker &&
  10022. node !== point.series.parentNode) {
  10023. distanceXY_1 = layout_1.getDistXY(point, node);
  10024. distanceR_1 = (layout_1.vectorLength(distanceXY_1) -
  10025. node.marker.radius -
  10026. point.marker.radius);
  10027. if (distanceR_1 < 0) {
  10028. node.series.addPoint(merge(point.options, {
  10029. plotX: point.plotX,
  10030. plotY: point.plotY
  10031. }), false);
  10032. layout_1.removeElementFromCollection(point, layout_1.nodes);
  10033. point.remove();
  10034. }
  10035. }
  10036. });
  10037. }
  10038. dragNodesMixin.onMouseUp.apply(this, arguments);
  10039. }
  10040. };
  10041. /**
  10042. * This is the main function responsible
  10043. * for positioning all of the bubbles
  10044. * allDataPoints - bubble array, in format [pixel x value,
  10045. * pixel y value, radius,
  10046. * related series index, related point index]
  10047. * @private
  10048. * @param {Array<Highcharts.PackedBubbleData>} allDataPoints All points from all series
  10049. * @return {Array<Highcharts.PackedBubbleData>} Positions of all bubbles
  10050. */
  10051. PackedBubbleSeries.prototype.placeBubbles = function (allDataPoints) {
  10052. var series = this,
  10053. checkOverlap = series.checkOverlap,
  10054. positionBubble = series.positionBubble,
  10055. bubblePos = [],
  10056. stage = 1,
  10057. j = 0,
  10058. k = 0,
  10059. calculatedBubble,
  10060. sortedArr,
  10061. arr = [],
  10062. i;
  10063. // sort all points
  10064. sortedArr = allDataPoints.sort(function (a, b) {
  10065. return b[2] - a[2];
  10066. });
  10067. if (sortedArr.length) {
  10068. // create first bubble in the middle of the chart
  10069. bubblePos.push([
  10070. [
  10071. 0,
  10072. 0,
  10073. sortedArr[0][2],
  10074. sortedArr[0][3],
  10075. sortedArr[0][4]
  10076. ] // point index
  10077. ]); // 0 level bubble
  10078. if (sortedArr.length > 1) {
  10079. bubblePos.push([
  10080. [
  10081. 0,
  10082. (0 - sortedArr[1][2] -
  10083. sortedArr[0][2]),
  10084. // move bubble above first one
  10085. sortedArr[1][2],
  10086. sortedArr[1][3],
  10087. sortedArr[1][4]
  10088. ]
  10089. ]); // 1 level 1st bubble
  10090. // first two already positioned so starting from 2
  10091. for (i = 2; i < sortedArr.length; i++) {
  10092. sortedArr[i][2] = sortedArr[i][2] || 1;
  10093. // in case if radius is calculated as 0.
  10094. calculatedBubble = positionBubble(bubblePos[stage][j], bubblePos[stage - 1][k], sortedArr[i]); // calculate initial bubble position
  10095. if (checkOverlap(calculatedBubble, bubblePos[stage][0])) {
  10096. /* if new bubble is overlapping with first bubble
  10097. * in current level (stage)
  10098. */
  10099. bubblePos.push([]);
  10100. k = 0;
  10101. /* reset index of bubble, used for
  10102. * positioning the bubbles around it,
  10103. * we are starting from first bubble in next
  10104. * stage because we are changing level to higher
  10105. */
  10106. bubblePos[stage + 1].push(positionBubble(bubblePos[stage][j], bubblePos[stage][0], sortedArr[i]));
  10107. // (last bubble, 1. from curr stage, new bubble)
  10108. stage++; // the new level is created, above current
  10109. j = 0; // set the index of bubble in curr level to 0
  10110. }
  10111. else if (stage > 1 &&
  10112. bubblePos[stage - 1][k + 1] &&
  10113. checkOverlap(calculatedBubble, bubblePos[stage - 1][k + 1])) {
  10114. /* if new bubble is overlapping with one of the prev
  10115. * stage bubbles, it means that - bubble, used for
  10116. * positioning the bubbles around it has changed
  10117. * so we need to recalculate it
  10118. */
  10119. k++;
  10120. bubblePos[stage].push(positionBubble(bubblePos[stage][j], bubblePos[stage - 1][k], sortedArr[i]));
  10121. // (last bubble, prev stage bubble, new bubble)
  10122. j++;
  10123. }
  10124. else { // simply add calculated bubble
  10125. j++;
  10126. bubblePos[stage].push(calculatedBubble);
  10127. }
  10128. }
  10129. }
  10130. series.chart.stages = bubblePos;
  10131. // it may not be necessary but adding it just in case -
  10132. // it is containing all of the bubble levels
  10133. series.chart.rawPositions =
  10134. []
  10135. .concat.apply([], bubblePos);
  10136. // bubble positions merged into one array
  10137. series.resizeRadius();
  10138. arr = series.chart.rawPositions;
  10139. }
  10140. return arr;
  10141. };
  10142. /**
  10143. * Function that is adding one bubble based on positions and sizes of
  10144. * two other bubbles, lastBubble is the last added bubble, newOrigin is
  10145. * the bubble for positioning new bubbles. nextBubble is the curently
  10146. * added bubble for which we are calculating positions
  10147. * @private
  10148. * @param {Array<number>} lastBubble The closest last bubble
  10149. * @param {Array<number>} newOrigin New bubble
  10150. * @param {Array<number>} nextBubble The closest next bubble
  10151. * @return {Array<number>} Bubble with correct positions
  10152. */
  10153. PackedBubbleSeries.prototype.positionBubble = function (lastBubble, newOrigin, nextBubble) {
  10154. var sqrt = Math.sqrt,
  10155. asin = Math.asin,
  10156. acos = Math.acos,
  10157. pow = Math.pow,
  10158. abs = Math.abs,
  10159. distance = sqrt(// dist between lastBubble and newOrigin
  10160. pow((lastBubble[0] - newOrigin[0]), 2) +
  10161. pow((lastBubble[1] - newOrigin[1]), 2)),
  10162. alfa = acos(
  10163. // from cosinus theorem: alfa is an angle used for
  10164. // calculating correct position
  10165. (pow(distance, 2) +
  10166. pow(nextBubble[2] + newOrigin[2], 2) -
  10167. pow(nextBubble[2] + lastBubble[2], 2)) / (2 * (nextBubble[2] + newOrigin[2]) * distance)),
  10168. beta = asin(// from sinus theorem.
  10169. abs(lastBubble[0] - newOrigin[0]) /
  10170. distance),
  10171. // providing helping variables, related to angle between
  10172. // lastBubble and newOrigin
  10173. gamma = (lastBubble[1] - newOrigin[1]) < 0 ? 0 : Math.PI,
  10174. // if new origin y is smaller than last bubble y value
  10175. // (2 and 3 quarter),
  10176. // add Math.PI to final angle
  10177. delta = (lastBubble[0] - newOrigin[0]) *
  10178. (lastBubble[1] - newOrigin[1]) < 0 ?
  10179. 1 : -1, // (1st and 3rd quarter)
  10180. finalAngle = gamma + alfa + beta * delta,
  10181. cosA = Math.cos(finalAngle),
  10182. sinA = Math.sin(finalAngle),
  10183. posX = newOrigin[0] + (newOrigin[2] + nextBubble[2]) * sinA,
  10184. // center of new origin + (radius1 + radius2) * sinus A
  10185. posY = newOrigin[1] - (newOrigin[2] + nextBubble[2]) * cosA;
  10186. return [
  10187. posX,
  10188. posY,
  10189. nextBubble[2],
  10190. nextBubble[3],
  10191. nextBubble[4]
  10192. ]; // the same as described before
  10193. };
  10194. PackedBubbleSeries.prototype.render = function () {
  10195. var series = this,
  10196. dataLabels = [];
  10197. Series.prototype.render.apply(this, arguments);
  10198. // #10823 - dataLabels should stay visible
  10199. // when enabled allowOverlap.
  10200. if (!series.options.dataLabels.allowOverlap) {
  10201. series.data.forEach(function (point) {
  10202. if (isArray(point.dataLabels)) {
  10203. point.dataLabels.forEach(function (dataLabel) {
  10204. dataLabels.push(dataLabel);
  10205. });
  10206. }
  10207. });
  10208. // Only hide overlapping dataLabels for layouts that
  10209. // use simulation. Spiral packedbubble don't need
  10210. // additional dataLabel hiding on every simulation step
  10211. if (series.options.useSimulation) {
  10212. series.chart.hideOverlappingLabels(dataLabels);
  10213. }
  10214. }
  10215. };
  10216. /**
  10217. * The function responsible for resizing the bubble radius.
  10218. * In shortcut: it is taking the initially
  10219. * calculated positions of bubbles. Then it is calculating the min max
  10220. * of both dimensions, creating something in shape of bBox.
  10221. * The comparison of bBox and the size of plotArea
  10222. * (later it may be also the size set by customer) is giving the
  10223. * value how to recalculate the radius so it will match the size
  10224. * @private
  10225. */
  10226. PackedBubbleSeries.prototype.resizeRadius = function () {
  10227. var chart = this.chart,
  10228. positions = chart.rawPositions,
  10229. min = Math.min,
  10230. max = Math.max,
  10231. plotLeft = chart.plotLeft,
  10232. plotTop = chart.plotTop,
  10233. chartHeight = chart.plotHeight,
  10234. chartWidth = chart.plotWidth,
  10235. minX,
  10236. maxX,
  10237. minY,
  10238. maxY,
  10239. radius,
  10240. bBox,
  10241. spaceRatio,
  10242. smallerDimension,
  10243. i;
  10244. minX = minY = Number.POSITIVE_INFINITY; // set initial values
  10245. maxX = maxY = Number.NEGATIVE_INFINITY;
  10246. for (i = 0; i < positions.length; i++) {
  10247. radius = positions[i][2];
  10248. minX = min(minX, positions[i][0] - radius);
  10249. // (x center-radius) is the min x value used by specific bubble
  10250. maxX = max(maxX, positions[i][0] + radius);
  10251. minY = min(minY, positions[i][1] - radius);
  10252. maxY = max(maxY, positions[i][1] + radius);
  10253. }
  10254. bBox = [maxX - minX, maxY - minY];
  10255. spaceRatio = [
  10256. (chartWidth - plotLeft) / bBox[0],
  10257. (chartHeight - plotTop) / bBox[1]
  10258. ];
  10259. smallerDimension = min.apply([], spaceRatio);
  10260. if (Math.abs(smallerDimension - 1) > 1e-10) {
  10261. // if bBox is considered not the same width as possible size
  10262. for (i = 0; i < positions.length; i++) {
  10263. positions[i][2] *= smallerDimension;
  10264. }
  10265. this.placeBubbles(positions);
  10266. }
  10267. else {
  10268. /** if no radius recalculation is needed, we need to position
  10269. * the whole bubbles in center of chart plotarea
  10270. * for this, we are adding two parameters,
  10271. * diffY and diffX, that are related to differences
  10272. * between the initial center and the bounding box
  10273. */
  10274. chart.diffY = chartHeight / 2 +
  10275. plotTop - minY - (maxY - minY) / 2;
  10276. chart.diffX = chartWidth / 2 +
  10277. plotLeft - minX - (maxX - minX) / 2;
  10278. }
  10279. };
  10280. /**
  10281. * The function responsible for calculating series bubble' s bBox.
  10282. * Needed because of exporting failure when useSimulation
  10283. * is set to false
  10284. * @private
  10285. */
  10286. PackedBubbleSeries.prototype.seriesBox = function () {
  10287. var series = this,
  10288. chart = series.chart,
  10289. data = series.data,
  10290. max = Math.max,
  10291. min = Math.min,
  10292. radius,
  10293. // bBox = [xMin, xMax, yMin, yMax]
  10294. bBox = [
  10295. chart.plotLeft,
  10296. chart.plotLeft + chart.plotWidth,
  10297. chart.plotTop,
  10298. chart.plotTop + chart.plotHeight
  10299. ];
  10300. data.forEach(function (p) {
  10301. if (defined(p.plotX) &&
  10302. defined(p.plotY) &&
  10303. p.marker.radius) {
  10304. radius = p.marker.radius;
  10305. bBox[0] = min(bBox[0], p.plotX - radius);
  10306. bBox[1] = max(bBox[1], p.plotX + radius);
  10307. bBox[2] = min(bBox[2], p.plotY - radius);
  10308. bBox[3] = max(bBox[3], p.plotY + radius);
  10309. }
  10310. });
  10311. return isNumber(bBox.width / bBox.height) ?
  10312. bBox :
  10313. null;
  10314. };
  10315. /**
  10316. * Needed because of z-indexing issue if point is added in series.group
  10317. * @private
  10318. */
  10319. PackedBubbleSeries.prototype.setVisible = function () {
  10320. var series = this;
  10321. Series.prototype.setVisible.apply(series, arguments);
  10322. if (series.parentNodeLayout && series.graph) {
  10323. if (series.visible) {
  10324. series.graph.show();
  10325. if (series.parentNode.dataLabel) {
  10326. series.parentNode.dataLabel.show();
  10327. }
  10328. }
  10329. else {
  10330. series.graph.hide();
  10331. series.parentNodeLayout
  10332. .removeElementFromCollection(series.parentNode, series.parentNodeLayout.nodes);
  10333. if (series.parentNode.dataLabel) {
  10334. series.parentNode.dataLabel.hide();
  10335. }
  10336. }
  10337. }
  10338. else if (series.layout) {
  10339. if (series.visible) {
  10340. series.layout.addElementsToCollection(series.points, series.layout.nodes);
  10341. }
  10342. else {
  10343. series.points.forEach(function (node) {
  10344. series.layout.removeElementFromCollection(node, series.layout.nodes);
  10345. });
  10346. }
  10347. }
  10348. };
  10349. /**
  10350. * Extend the base translate method to handle bubble size,
  10351. * and correct positioning them.
  10352. * @private
  10353. */
  10354. PackedBubbleSeries.prototype.translate = function () {
  10355. var series = this,
  10356. chart = series.chart,
  10357. data = series.data,
  10358. index = series.index,
  10359. point,
  10360. radius,
  10361. positions,
  10362. i,
  10363. useSimulation = series.options.useSimulation;
  10364. series.processedXData = series.xData;
  10365. series.generatePoints();
  10366. // merged data is an array with all of the data from all series
  10367. if (!defined(chart.allDataPoints)) {
  10368. chart.allDataPoints = series.accumulateAllPoints(series);
  10369. // calculate radius for all added data
  10370. series.getPointRadius();
  10371. }
  10372. // after getting initial radius, calculate bubble positions
  10373. if (useSimulation) {
  10374. positions = chart.allDataPoints;
  10375. }
  10376. else {
  10377. positions = series.placeBubbles(chart.allDataPoints);
  10378. series.options.draggable = false;
  10379. }
  10380. // Set the shape and arguments to be picked up in drawPoints
  10381. for (i = 0; i < positions.length; i++) {
  10382. if (positions[i][3] === index) {
  10383. // update the series points with the val from positions
  10384. // array
  10385. point = data[positions[i][4]];
  10386. radius = pick(positions[i][2], void 0);
  10387. if (!useSimulation) {
  10388. point.plotX = (positions[i][0] - chart.plotLeft +
  10389. chart.diffX);
  10390. point.plotY = (positions[i][1] - chart.plotTop +
  10391. chart.diffY);
  10392. }
  10393. if (isNumber(radius)) {
  10394. point.marker = extend(point.marker, {
  10395. radius: radius,
  10396. width: 2 * radius,
  10397. height: 2 * radius
  10398. });
  10399. point.radius = radius;
  10400. }
  10401. }
  10402. }
  10403. if (useSimulation) {
  10404. series.deferLayout();
  10405. }
  10406. fireEvent(series, 'afterTranslate');
  10407. };
  10408. /**
  10409. * A packed bubble series is a two dimensional series type, where each point
  10410. * renders a value in X, Y position. Each point is drawn as a bubble
  10411. * where the bubbles don't overlap with each other and the radius
  10412. * of the bubble relates to the value.
  10413. *
  10414. * @sample highcharts/demo/packed-bubble/
  10415. * Packed bubble chart
  10416. * @sample highcharts/demo/packed-bubble-split/
  10417. * Split packed bubble chart
  10418. * @extends plotOptions.bubble
  10419. * @excluding connectEnds, connectNulls, cropThreshold, dragDrop, jitter,
  10420. * keys, pointPlacement, sizeByAbsoluteValue, step, xAxis,
  10421. * yAxis, zMax, zMin, dataSorting, boostThreshold,
  10422. * boostBlending
  10423. * @product highcharts
  10424. * @since 7.0.0
  10425. * @requires highcharts-more
  10426. * @optionparent plotOptions.packedbubble
  10427. */
  10428. PackedBubbleSeries.defaultOptions = merge(BubbleSeries.defaultOptions, {
  10429. /**
  10430. * Minimum bubble size. Bubbles will automatically size between the
  10431. * `minSize` and `maxSize` to reflect the value of each bubble.
  10432. * Can be either pixels (when no unit is given), or a percentage of
  10433. * the smallest one of the plot width and height, divided by the square
  10434. * root of total number of points.
  10435. *
  10436. * @sample highcharts/plotoptions/bubble-size/
  10437. * Bubble size
  10438. *
  10439. * @type {number|string}
  10440. *
  10441. * @private
  10442. */
  10443. minSize: '10%',
  10444. /**
  10445. * Maximum bubble size. Bubbles will automatically size between the
  10446. * `minSize` and `maxSize` to reflect the value of each bubble.
  10447. * Can be either pixels (when no unit is given), or a percentage of
  10448. * the smallest one of the plot width and height, divided by the square
  10449. * root of total number of points.
  10450. *
  10451. * @sample highcharts/plotoptions/bubble-size/
  10452. * Bubble size
  10453. *
  10454. * @type {number|string}
  10455. *
  10456. * @private
  10457. */
  10458. maxSize: '50%',
  10459. sizeBy: 'area',
  10460. zoneAxis: 'y',
  10461. crisp: false,
  10462. tooltip: {
  10463. pointFormat: 'Value: {point.value}'
  10464. },
  10465. /**
  10466. * Flag to determine if nodes are draggable or not. Available for
  10467. * graph with useSimulation set to true only.
  10468. *
  10469. * @since 7.1.0
  10470. *
  10471. * @private
  10472. */
  10473. draggable: true,
  10474. /**
  10475. * An option is giving a possibility to choose between using simulation
  10476. * for calculating bubble positions. These reflects in both animation
  10477. * and final position of bubbles. Simulation is also adding options to
  10478. * the series graph based on used layout. In case of big data sets, with
  10479. * any performance issues, it is possible to disable animation and pack
  10480. * bubble in a simple circular way.
  10481. *
  10482. * @sample highcharts/series-packedbubble/spiral/
  10483. * useSimulation set to false
  10484. *
  10485. * @since 7.1.0
  10486. *
  10487. * @private
  10488. */
  10489. useSimulation: true,
  10490. /**
  10491. * Series options for parent nodes.
  10492. *
  10493. * @since 8.1.1
  10494. *
  10495. * @private
  10496. */
  10497. parentNode: {
  10498. /**
  10499. * Allow this series' parent nodes to be selected
  10500. * by clicking on the graph.
  10501. *
  10502. * @since 8.1.1
  10503. */
  10504. allowPointSelect: false
  10505. },
  10506. /**
  10507. /**
  10508. *
  10509. * @declare Highcharts.SeriesPackedBubbleDataLabelsOptionsObject
  10510. *
  10511. * @private
  10512. */
  10513. dataLabels: {
  10514. /**
  10515. * The
  10516. * [format string](https://www.highcharts.com/docs/chart-concepts/labels-and-string-formatting)
  10517. * specifying what to show for _node_ in the networkgraph. In v7.0
  10518. * defaults to `{key}`, since v7.1 defaults to `undefined` and
  10519. * `formatter` is used instead.
  10520. *
  10521. * @type {string}
  10522. * @since 7.0.0
  10523. * @apioption plotOptions.packedbubble.dataLabels.format
  10524. */
  10525. // eslint-disable-next-line valid-jsdoc
  10526. /**
  10527. * Callback JavaScript function to format the data label for a node.
  10528. * Note that if a `format` is defined, the format takes precedence
  10529. * and the formatter is ignored.
  10530. *
  10531. * @type {Highcharts.SeriesPackedBubbleDataLabelsFormatterCallbackFunction}
  10532. * @since 7.0.0
  10533. */
  10534. formatter: function () {
  10535. return this.point.value;
  10536. },
  10537. /**
  10538. * @type {string}
  10539. * @since 7.1.0
  10540. * @apioption plotOptions.packedbubble.dataLabels.parentNodeFormat
  10541. */
  10542. // eslint-disable-next-line valid-jsdoc
  10543. /**
  10544. * @type {Highcharts.SeriesPackedBubbleDataLabelsFormatterCallbackFunction}
  10545. * @since 7.1.0
  10546. */
  10547. parentNodeFormatter: function () {
  10548. return this.name;
  10549. },
  10550. /**
  10551. * @sample {highcharts} highcharts/series-packedbubble/packed-dashboard
  10552. * Dashboard with dataLabels on parentNodes
  10553. *
  10554. * @declare Highcharts.SeriesPackedBubbleDataLabelsTextPathOptionsObject
  10555. * @since 7.1.0
  10556. */
  10557. parentNodeTextPath: {
  10558. /**
  10559. * Presentation attributes for the text path.
  10560. *
  10561. * @type {Highcharts.SVGAttributes}
  10562. * @since 7.1.0
  10563. * @apioption plotOptions.packedbubble.dataLabels.attributes
  10564. */
  10565. /**
  10566. * Enable or disable `textPath` option for link's or marker's
  10567. * data labels.
  10568. *
  10569. * @since 7.1.0
  10570. */
  10571. enabled: true
  10572. },
  10573. /**
  10574. * Options for a _node_ label text which should follow marker's
  10575. * shape.
  10576. *
  10577. * **Note:** Only SVG-based renderer supports this option.
  10578. *
  10579. * @extends plotOptions.series.dataLabels.textPath
  10580. * @apioption plotOptions.packedbubble.dataLabels.textPath
  10581. */
  10582. padding: 0,
  10583. style: {
  10584. transition: 'opacity 2000ms'
  10585. }
  10586. },
  10587. /**
  10588. * Options for layout algorithm when simulation is enabled. Inside there
  10589. * are options to change the speed, padding, initial bubbles positions
  10590. * and more.
  10591. *
  10592. * @extends plotOptions.networkgraph.layoutAlgorithm
  10593. * @excluding approximation, attractiveForce, repulsiveForce, theta
  10594. * @since 7.1.0
  10595. *
  10596. * @private
  10597. */
  10598. layoutAlgorithm: {
  10599. /**
  10600. * Initial layout algorithm for positioning nodes. Can be one of
  10601. * the built-in options ("circle", "random") or a function where
  10602. * positions should be set on each node (`this.nodes`) as
  10603. * `node.plotX` and `node.plotY`.
  10604. *
  10605. * @sample highcharts/series-networkgraph/initial-positions/
  10606. * Initial positions with callback
  10607. *
  10608. * @type {"circle"|"random"|Function}
  10609. */
  10610. initialPositions: 'circle',
  10611. /**
  10612. * @sample highcharts/series-packedbubble/initial-radius/
  10613. * Initial radius set to 200
  10614. *
  10615. * @extends plotOptions.networkgraph.layoutAlgorithm.initialPositionRadius
  10616. * @excluding states
  10617. */
  10618. initialPositionRadius: 20,
  10619. /**
  10620. * The distance between two bubbles, when the algorithm starts to
  10621. * treat two bubbles as overlapping. The `bubblePadding` is also the
  10622. * expected distance between all the bubbles on simulation end.
  10623. */
  10624. bubblePadding: 5,
  10625. /**
  10626. * Whether bubbles should interact with their parentNode to keep
  10627. * them inside.
  10628. */
  10629. parentNodeLimit: false,
  10630. /**
  10631. * Whether series should interact with each other or not. When
  10632. * `parentNodeLimit` is set to true, thi option should be set to
  10633. * false to avoid sticking points in wrong series parentNode.
  10634. */
  10635. seriesInteraction: true,
  10636. /**
  10637. * In case of split series, this option allows user to drag and
  10638. * drop points between series, for changing point related series.
  10639. *
  10640. * @sample highcharts/series-packedbubble/packed-dashboard/
  10641. * Example of drag'n drop bubbles for bubble kanban
  10642. */
  10643. dragBetweenSeries: false,
  10644. /**
  10645. * Layout algorithm options for parent nodes.
  10646. *
  10647. * @extends plotOptions.networkgraph.layoutAlgorithm
  10648. * @excluding approximation, attractiveForce, enableSimulation,
  10649. * repulsiveForce, theta
  10650. */
  10651. parentNodeOptions: {
  10652. maxIterations: 400,
  10653. gravitationalConstant: 0.03,
  10654. maxSpeed: 50,
  10655. initialPositionRadius: 100,
  10656. seriesInteraction: true,
  10657. /**
  10658. * Styling options for parentNodes markers. Similar to
  10659. * line.marker options.
  10660. *
  10661. * @sample highcharts/series-packedbubble/parentnode-style/
  10662. * Bubble size
  10663. *
  10664. * @extends plotOptions.series.marker
  10665. * @excluding states
  10666. */
  10667. marker: {
  10668. fillColor: null,
  10669. fillOpacity: 1,
  10670. lineWidth: 1,
  10671. lineColor: null,
  10672. symbol: 'circle'
  10673. }
  10674. },
  10675. enableSimulation: true,
  10676. /**
  10677. * Type of the algorithm used when positioning bubbles.
  10678. * @ignore-option
  10679. */
  10680. type: 'packedbubble',
  10681. /**
  10682. * Integration type. Integration determines how forces are applied
  10683. * on particles. The `packedbubble` integration is based on
  10684. * the networkgraph `verlet` integration, where the new position
  10685. * is based on a previous position without velocity:
  10686. * `newPosition += previousPosition - newPosition`.
  10687. *
  10688. * @sample highcharts/series-networkgraph/forces/
  10689. *
  10690. * @ignore-option
  10691. */
  10692. integration: 'packedbubble',
  10693. maxIterations: 1000,
  10694. /**
  10695. * Whether to split series into individual groups or to mix all
  10696. * series together.
  10697. *
  10698. * @since 7.1.0
  10699. * @default false
  10700. */
  10701. splitSeries: false,
  10702. /**
  10703. * Max speed that node can get in one iteration. In terms of
  10704. * simulation, it's a maximum translation (in pixels) that a node
  10705. * can move (in both, x and y, dimensions). While `friction` is
  10706. * applied on all nodes, max speed is applied only for nodes that
  10707. * move very fast, for example small or disconnected ones.
  10708. *
  10709. * @see [layoutAlgorithm.integration](#series.networkgraph.layoutAlgorithm.integration)
  10710. *
  10711. * @see [layoutAlgorithm.friction](#series.networkgraph.layoutAlgorithm.friction)
  10712. */
  10713. maxSpeed: 5,
  10714. gravitationalConstant: 0.01,
  10715. friction: -0.981
  10716. }
  10717. });
  10718. return PackedBubbleSeries;
  10719. }(BubbleSeries));
  10720. extend(PackedBubbleSeries.prototype, {
  10721. alignDataLabel: Series.prototype.alignDataLabel,
  10722. axisTypes: [],
  10723. directTouch: true,
  10724. /**
  10725. * Array of internal forces. Each force should be later defined in
  10726. * integrations.js.
  10727. * @private
  10728. */
  10729. forces: ['barycenter', 'repulsive'],
  10730. /**
  10731. * An internal option used for allowing nodes dragging.
  10732. * @private
  10733. */
  10734. hasDraggableNodes: true,
  10735. isCartesian: false,
  10736. noSharedTooltip: true,
  10737. /**
  10738. * Mouse down action, initializing drag&drop mode.
  10739. * @private
  10740. * @param {global.Event} event Browser event, before normalization.
  10741. * @param {Highcharts.Point} point The point that event occured.
  10742. */
  10743. onMouseDown: dragNodesMixin.onMouseDown,
  10744. /**
  10745. * Mouse move action during drag&drop.
  10746. * @private
  10747. * @param {global.Event} event Browser event, before normalization.
  10748. * @param {Highcharts.Point} point The point that event occured.
  10749. */
  10750. onMouseMove: dragNodesMixin.onMouseMove,
  10751. pointArrayMap: ['value'],
  10752. pointClass: PackedBubblePoint,
  10753. pointValKey: 'value',
  10754. /**
  10755. * Redraw halo on mousemove during the drag&drop action.
  10756. * @private
  10757. * @param {Highcharts.Point} point The point that should show halo.
  10758. */
  10759. redrawHalo: dragNodesMixin.redrawHalo,
  10760. requireSorting: false,
  10761. // solving #12287
  10762. searchPoint: H.noop,
  10763. trackerGroups: ['group', 'dataLabelsGroup', 'parentNodesGroup']
  10764. });
  10765. SeriesRegistry.registerSeriesType('packedbubble', PackedBubbleSeries);
  10766. /* *
  10767. *
  10768. * Default Export
  10769. *
  10770. * */
  10771. /* *
  10772. *
  10773. * API Declarations
  10774. *
  10775. * */
  10776. /**
  10777. * Formatter callback function.
  10778. *
  10779. * @callback Highcharts.SeriesPackedBubbleDataLabelsFormatterCallbackFunction
  10780. *
  10781. * @param {Highcharts.SeriesPackedBubbleDataLabelsFormatterContextObject} this
  10782. * Data label context to format
  10783. *
  10784. * @return {string}
  10785. * Formatted data label text
  10786. */
  10787. /**
  10788. * Context for the formatter function.
  10789. *
  10790. * @interface Highcharts.SeriesPackedBubbleDataLabelsFormatterContextObject
  10791. * @extends Highcharts.PointLabelObject
  10792. * @since 7.0.0
  10793. */ /**
  10794. * The color of the node.
  10795. * @name Highcharts.SeriesPackedBubbleDataLabelsFormatterContextObject#color
  10796. * @type {Highcharts.ColorString}
  10797. * @since 7.0.0
  10798. */ /**
  10799. * The point (node) object. The node name, if defined, is available through
  10800. * `this.point.name`. Arrays: `this.point.linksFrom` and `this.point.linksTo`
  10801. * contains all nodes connected to this point.
  10802. * @name Highcharts.SeriesPackedBubbleDataLabelsFormatterContextObject#point
  10803. * @type {Highcharts.Point}
  10804. * @since 7.0.0
  10805. */ /**
  10806. * The ID of the node.
  10807. * @name Highcharts.SeriesPackedBubbleDataLabelsFormatterContextObject#key
  10808. * @type {string}
  10809. * @since 7.0.0
  10810. */
  10811. ''; // detach doclets above
  10812. /* *
  10813. *
  10814. * API Options
  10815. *
  10816. * */
  10817. /**
  10818. * A `packedbubble` series. If the [type](#series.packedbubble.type) option is
  10819. * not specified, it is inherited from [chart.type](#chart.type).
  10820. *
  10821. * @type {Object}
  10822. * @extends series,plotOptions.packedbubble
  10823. * @excluding cropThreshold, dataParser, dataSorting, dataURL, dragDrop, stack,
  10824. * boostThreshold, boostBlending
  10825. * @product highcharts
  10826. * @requires highcharts-more
  10827. * @apioption series.packedbubble
  10828. */
  10829. /**
  10830. * An array of data points for the series. For the `packedbubble` series type,
  10831. * points can be given in the following ways:
  10832. *
  10833. * 1. An array of `values`.
  10834. *
  10835. * ```js
  10836. * data: [5, 1, 20]
  10837. * ```
  10838. *
  10839. * 2. An array of objects with named values. The objects are point
  10840. * configuration objects as seen below. If the total number of data points
  10841. * exceeds the series' [turboThreshold](#series.packedbubble.turboThreshold),
  10842. * this option is not available.
  10843. *
  10844. * ```js
  10845. * data: [{
  10846. * value: 1,
  10847. * name: "Point2",
  10848. * color: "#00FF00"
  10849. * }, {
  10850. * value: 5,
  10851. * name: "Point1",
  10852. * color: "#FF00FF"
  10853. * }]
  10854. * ```
  10855. *
  10856. * @type {Array<Object|Array>}
  10857. * @extends series.line.data
  10858. * @excluding marker, x, y
  10859. * @sample {highcharts} highcharts/series/data-array-of-objects/
  10860. * Config objects
  10861. * @product highcharts
  10862. * @apioption series.packedbubble.data
  10863. */
  10864. /**
  10865. * @type {Highcharts.SeriesPackedBubbleDataLabelsOptionsObject|Array<Highcharts.SeriesPackedBubbleDataLabelsOptionsObject>}
  10866. * @product highcharts
  10867. * @apioption series.packedbubble.data.dataLabels
  10868. */
  10869. /**
  10870. * @excluding enabled,enabledThreshold,height,radius,width
  10871. * @product highcharts
  10872. * @apioption series.packedbubble.marker
  10873. */
  10874. ''; // adds doclets above to transpiled file
  10875. return PackedBubbleSeries;
  10876. });
  10877. _registerModule(_modules, 'Extensions/Polar.js', [_modules['Core/Animation/AnimationUtilities.js'], _modules['Core/Chart/Chart.js'], _modules['Core/Globals.js'], _modules['Extensions/Pane.js'], _modules['Core/Pointer.js'], _modules['Core/Series/Series.js'], _modules['Core/Series/SeriesRegistry.js'], _modules['Core/Renderer/SVG/SVGRenderer.js'], _modules['Core/Utilities.js']], function (A, Chart, H, Pane, Pointer, Series, SeriesRegistry, SVGRenderer, U) {
  10878. /* *
  10879. *
  10880. * (c) 2010-2021 Torstein Honsi
  10881. *
  10882. * License: www.highcharts.com/license
  10883. *
  10884. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  10885. *
  10886. * */
  10887. var animObject = A.animObject;
  10888. var seriesTypes = SeriesRegistry.seriesTypes;
  10889. var addEvent = U.addEvent,
  10890. defined = U.defined,
  10891. find = U.find,
  10892. isNumber = U.isNumber,
  10893. pick = U.pick,
  10894. splat = U.splat,
  10895. uniqueKey = U.uniqueKey,
  10896. wrap = U.wrap;
  10897. // Extensions for polar charts. Additionally, much of the geometry required for
  10898. // polar charts is gathered in RadialAxes.js.
  10899. var seriesProto = Series.prototype,
  10900. pointerProto = Pointer.prototype,
  10901. columnProto,
  10902. arearangeProto;
  10903. /* eslint-disable no-invalid-this, valid-jsdoc */
  10904. /**
  10905. * Search a k-d tree by the point angle, used for shared tooltips in polar
  10906. * charts
  10907. * @private
  10908. */
  10909. seriesProto.searchPointByAngle = function (e) {
  10910. var series = this,
  10911. chart = series.chart,
  10912. xAxis = series.xAxis,
  10913. center = xAxis.pane.center,
  10914. plotX = e.chartX - center[0] - chart.plotLeft,
  10915. plotY = e.chartY - center[1] - chart.plotTop;
  10916. return this.searchKDTree({
  10917. clientX: 180 + (Math.atan2(plotX, plotY) * (-180 / Math.PI))
  10918. });
  10919. };
  10920. /**
  10921. * #6212 Calculate connectors for spline series in polar chart.
  10922. * @private
  10923. * @param {boolean} calculateNeighbours
  10924. * Check if connectors should be calculated for neighbour points as
  10925. * well allows short recurence
  10926. */
  10927. seriesProto.getConnectors = function (segment, index, calculateNeighbours, connectEnds) {
  10928. var i,
  10929. prevPointInd,
  10930. nextPointInd,
  10931. previousPoint,
  10932. nextPoint,
  10933. previousX,
  10934. previousY,
  10935. nextX,
  10936. nextY,
  10937. plotX,
  10938. plotY,
  10939. ret,
  10940. // 1 means control points midway between points, 2 means 1/3 from
  10941. // the point, 3 is 1/4 etc;
  10942. smoothing = 1.5, denom = smoothing + 1, leftContX, leftContY, rightContX, rightContY, dLControlPoint, // distance left control point
  10943. dRControlPoint, leftContAngle, rightContAngle, jointAngle, addedNumber = connectEnds ? 1 : 0;
  10944. // Calculate final index of points depending on the initial index value.
  10945. // Because of calculating neighbours, index may be outisde segment
  10946. // array.
  10947. if (index >= 0 && index <= segment.length - 1) {
  10948. i = index;
  10949. }
  10950. else if (index < 0) {
  10951. i = segment.length - 1 + index;
  10952. }
  10953. else {
  10954. i = 0;
  10955. }
  10956. prevPointInd = (i - 1 < 0) ? segment.length - (1 + addedNumber) : i - 1;
  10957. nextPointInd = (i + 1 > segment.length - 1) ? addedNumber : i + 1;
  10958. previousPoint = segment[prevPointInd];
  10959. nextPoint = segment[nextPointInd];
  10960. previousX = previousPoint.plotX;
  10961. previousY = previousPoint.plotY;
  10962. nextX = nextPoint.plotX;
  10963. nextY = nextPoint.plotY;
  10964. plotX = segment[i].plotX; // actual point
  10965. plotY = segment[i].plotY;
  10966. leftContX = (smoothing * plotX + previousX) / denom;
  10967. leftContY = (smoothing * plotY + previousY) / denom;
  10968. rightContX = (smoothing * plotX + nextX) / denom;
  10969. rightContY = (smoothing * plotY + nextY) / denom;
  10970. dLControlPoint = Math.sqrt(Math.pow(leftContX - plotX, 2) + Math.pow(leftContY - plotY, 2));
  10971. dRControlPoint = Math.sqrt(Math.pow(rightContX - plotX, 2) + Math.pow(rightContY - plotY, 2));
  10972. leftContAngle = Math.atan2(leftContY - plotY, leftContX - plotX);
  10973. rightContAngle = Math.atan2(rightContY - plotY, rightContX - plotX);
  10974. jointAngle = (Math.PI / 2) + ((leftContAngle + rightContAngle) / 2);
  10975. // Ensure the right direction, jointAngle should be in the same quadrant
  10976. // as leftContAngle
  10977. if (Math.abs(leftContAngle - jointAngle) > Math.PI / 2) {
  10978. jointAngle -= Math.PI;
  10979. }
  10980. // Find the corrected control points for a spline straight through the
  10981. // point
  10982. leftContX = plotX + Math.cos(jointAngle) * dLControlPoint;
  10983. leftContY = plotY + Math.sin(jointAngle) * dLControlPoint;
  10984. rightContX = plotX + Math.cos(Math.PI + jointAngle) * dRControlPoint;
  10985. rightContY = plotY + Math.sin(Math.PI + jointAngle) * dRControlPoint;
  10986. // push current point's connectors into returned object
  10987. ret = {
  10988. rightContX: rightContX,
  10989. rightContY: rightContY,
  10990. leftContX: leftContX,
  10991. leftContY: leftContY,
  10992. plotX: plotX,
  10993. plotY: plotY
  10994. };
  10995. // calculate connectors for previous and next point and push them inside
  10996. // returned object
  10997. if (calculateNeighbours) {
  10998. ret.prevPointCont = this.getConnectors(segment, prevPointInd, false, connectEnds);
  10999. }
  11000. return ret;
  11001. };
  11002. /**
  11003. * Translate a point's plotX and plotY from the internal angle and radius
  11004. * measures to true plotX, plotY coordinates
  11005. * @private
  11006. */
  11007. seriesProto.toXY = function (point) {
  11008. var chart = this.chart,
  11009. xAxis = this.xAxis,
  11010. yAxis = this.yAxis,
  11011. plotX = point.plotX,
  11012. plotY = point.plotY,
  11013. series = point.series,
  11014. inverted = chart.inverted,
  11015. pointY = point.y,
  11016. radius = inverted ? plotX : yAxis.len - plotY,
  11017. clientX;
  11018. // Corrected y position of inverted series other than column
  11019. if (inverted && series && !series.isRadialBar) {
  11020. point.plotY = plotY =
  11021. typeof pointY === 'number' ? (yAxis.translate(pointY) || 0) : 0;
  11022. }
  11023. // Save rectangular plotX, plotY for later computation
  11024. point.rectPlotX = plotX;
  11025. point.rectPlotY = plotY;
  11026. if (yAxis.center) {
  11027. radius += yAxis.center[3] / 2;
  11028. }
  11029. // Find the polar plotX and plotY. Avoid setting plotX and plotY to NaN when
  11030. // plotY is undefined (#15438)
  11031. if (isNumber(plotY)) {
  11032. var xy = inverted ? yAxis.postTranslate(plotY,
  11033. radius) :
  11034. xAxis.postTranslate(plotX,
  11035. radius);
  11036. point.plotX = point.polarPlotX = xy.x - chart.plotLeft;
  11037. point.plotY = point.polarPlotY = xy.y - chart.plotTop;
  11038. }
  11039. // If shared tooltip, record the angle in degrees in order to align X
  11040. // points. Otherwise, use a standard k-d tree to get the nearest point
  11041. // in two dimensions.
  11042. if (this.kdByAngle) {
  11043. clientX = ((plotX / Math.PI * 180) +
  11044. xAxis.pane.options.startAngle) % 360;
  11045. if (clientX < 0) { // #2665
  11046. clientX += 360;
  11047. }
  11048. point.clientX = clientX;
  11049. }
  11050. else {
  11051. point.clientX = point.plotX;
  11052. }
  11053. };
  11054. if (seriesTypes.spline) {
  11055. /**
  11056. * Overridden method for calculating a spline from one point to the next
  11057. * @private
  11058. */
  11059. wrap(seriesTypes.spline.prototype, 'getPointSpline', function (proceed, segment, point, i) {
  11060. var ret,
  11061. connectors;
  11062. if (this.chart.polar) {
  11063. // moveTo or lineTo
  11064. if (!i) {
  11065. ret = ['M', point.plotX, point.plotY];
  11066. }
  11067. else { // curve from last point to this
  11068. connectors = this.getConnectors(segment, i, true, this.connectEnds);
  11069. var rightContX = connectors.prevPointCont && connectors.prevPointCont.rightContX;
  11070. var rightContY = connectors.prevPointCont && connectors.prevPointCont.rightContY;
  11071. ret = [
  11072. 'C',
  11073. isNumber(rightContX) ? rightContX : connectors.plotX,
  11074. isNumber(rightContY) ? rightContY : connectors.plotY,
  11075. isNumber(connectors.leftContX) ?
  11076. connectors.leftContX :
  11077. connectors.plotX,
  11078. isNumber(connectors.leftContY) ?
  11079. connectors.leftContY :
  11080. connectors.plotY,
  11081. connectors.plotX,
  11082. connectors.plotY
  11083. ];
  11084. }
  11085. }
  11086. else {
  11087. ret = proceed.call(this, segment, point, i);
  11088. }
  11089. return ret;
  11090. });
  11091. // #6430 Areasplinerange series use unwrapped getPointSpline method, so
  11092. // we need to set this method again.
  11093. if (seriesTypes.areasplinerange) {
  11094. seriesTypes.areasplinerange.prototype.getPointSpline = seriesTypes.spline.prototype.getPointSpline;
  11095. }
  11096. }
  11097. /**
  11098. * Extend translate. The plotX and plotY values are computed as if the polar
  11099. * chart were a cartesian plane, where plotX denotes the angle in radians
  11100. * and (yAxis.len - plotY) is the pixel distance from center.
  11101. * @private
  11102. */
  11103. addEvent(Series, 'afterTranslate', function () {
  11104. var series = this;
  11105. var chart = series.chart;
  11106. if (chart.polar && series.xAxis) {
  11107. // Prepare k-d-tree handling. It searches by angle (clientX) in
  11108. // case of shared tooltip, and by two dimensional distance in case
  11109. // of non-shared.
  11110. series.kdByAngle = chart.tooltip && chart.tooltip.shared;
  11111. if (series.kdByAngle) {
  11112. series.searchPoint = series.searchPointByAngle;
  11113. }
  11114. else {
  11115. series.options.findNearestPointBy = 'xy';
  11116. }
  11117. // Postprocess plot coordinates
  11118. if (!series.preventPostTranslate) {
  11119. var points = series.points;
  11120. var i = points.length;
  11121. while (i--) {
  11122. // Translate plotX, plotY from angle and radius to true plot
  11123. // coordinates
  11124. series.toXY(points[i]);
  11125. // Treat points below Y axis min as null (#10082)
  11126. if (!chart.hasParallelCoordinates &&
  11127. !series.yAxis.reversed &&
  11128. points[i].y < series.yAxis.min) {
  11129. points[i].isNull = true;
  11130. }
  11131. }
  11132. }
  11133. // Perform clip after render
  11134. if (!this.hasClipCircleSetter) {
  11135. this.hasClipCircleSetter = !!series.eventsToUnbind.push(addEvent(series, 'afterRender', function () {
  11136. var circ;
  11137. if (chart.polar) {
  11138. // For clipping purposes there is a need for
  11139. // coordinates from the absolute center
  11140. circ = this.yAxis.pane.center;
  11141. if (!this.clipCircle) {
  11142. this.clipCircle = chart.renderer.clipCircle(circ[0], circ[1], circ[2] / 2, circ[3] / 2);
  11143. }
  11144. else {
  11145. this.clipCircle.animate({
  11146. x: circ[0],
  11147. y: circ[1],
  11148. r: circ[2] / 2,
  11149. innerR: circ[3] / 2
  11150. });
  11151. }
  11152. this.group.clip(this.clipCircle);
  11153. this.setClip = H.noop;
  11154. }
  11155. }));
  11156. }
  11157. }
  11158. }, { order: 2 }); // Run after translation of ||-coords
  11159. /**
  11160. * Extend getSegmentPath to allow connecting ends across 0 to provide a
  11161. * closed circle in line-like series.
  11162. * @private
  11163. */
  11164. wrap(seriesTypes.line.prototype, 'getGraphPath', function (proceed, points) {
  11165. var series = this,
  11166. i,
  11167. firstValid,
  11168. popLastPoint;
  11169. // Connect the path
  11170. if (this.chart.polar) {
  11171. points = points || this.points;
  11172. // Append first valid point in order to connect the ends
  11173. for (i = 0; i < points.length; i++) {
  11174. if (!points[i].isNull) {
  11175. firstValid = i;
  11176. break;
  11177. }
  11178. }
  11179. /**
  11180. * Polar charts only. Whether to connect the ends of a line series
  11181. * plot across the extremes.
  11182. *
  11183. * @sample {highcharts} highcharts/plotoptions/line-connectends-false/
  11184. * Do not connect
  11185. *
  11186. * @type {boolean}
  11187. * @since 2.3.0
  11188. * @product highcharts
  11189. * @apioption plotOptions.series.connectEnds
  11190. */
  11191. if (this.options.connectEnds !== false &&
  11192. typeof firstValid !== 'undefined') {
  11193. this.connectEnds = true; // re-used in splines
  11194. points.splice(points.length, 0, points[firstValid]);
  11195. popLastPoint = true;
  11196. }
  11197. // For area charts, pseudo points are added to the graph, now we
  11198. // need to translate these
  11199. points.forEach(function (point) {
  11200. if (typeof point.polarPlotY === 'undefined') {
  11201. series.toXY(point);
  11202. }
  11203. });
  11204. }
  11205. // Run uber method
  11206. var ret = proceed.apply(this,
  11207. [].slice.call(arguments, 1));
  11208. // #6212 points.splice method is adding points to an array. In case of
  11209. // areaspline getGraphPath method is used two times and in both times
  11210. // points are added to an array. That is why points.pop is used, to get
  11211. // unmodified points.
  11212. if (popLastPoint) {
  11213. points.pop();
  11214. }
  11215. return ret;
  11216. });
  11217. var polarAnimate = function (proceed,
  11218. init) {
  11219. var series = this,
  11220. chart = this.chart,
  11221. animation = this.options.animation,
  11222. group = this.group,
  11223. markerGroup = this.markerGroup,
  11224. center = this.xAxis.center,
  11225. plotLeft = chart.plotLeft,
  11226. plotTop = chart.plotTop,
  11227. attribs,
  11228. paneInnerR,
  11229. graphic,
  11230. shapeArgs,
  11231. r,
  11232. innerR;
  11233. // Specific animation for polar charts
  11234. if (chart.polar) {
  11235. if (series.isRadialBar) {
  11236. if (!init) {
  11237. // Run the pie animation for radial bars
  11238. series.startAngleRad = pick(series.translatedThreshold, series.xAxis.startAngleRad);
  11239. H.seriesTypes.pie.prototype.animate.call(series, init);
  11240. }
  11241. }
  11242. else {
  11243. // Enable animation on polar charts only in SVG. In VML, the scaling
  11244. // is different, plus animation would be so slow it would't matter.
  11245. if (chart.renderer.isSVG) {
  11246. animation = animObject(animation);
  11247. // A different animation needed for column like series
  11248. if (series.is('column')) {
  11249. if (!init) {
  11250. paneInnerR = center[3] / 2;
  11251. series.points.forEach(function (point) {
  11252. graphic = point.graphic;
  11253. shapeArgs = point.shapeArgs;
  11254. r = shapeArgs && shapeArgs.r;
  11255. innerR = shapeArgs && shapeArgs.innerR;
  11256. if (graphic && shapeArgs) {
  11257. // start values
  11258. graphic.attr({
  11259. r: paneInnerR,
  11260. innerR: paneInnerR
  11261. });
  11262. // animate
  11263. graphic.animate({
  11264. r: r,
  11265. innerR: innerR
  11266. }, series.options.animation);
  11267. }
  11268. });
  11269. }
  11270. }
  11271. else {
  11272. // Initialize the animation
  11273. if (init) {
  11274. // Scale down the group and place it in the center
  11275. attribs = {
  11276. translateX: center[0] + plotLeft,
  11277. translateY: center[1] + plotTop,
  11278. scaleX: 0.001,
  11279. scaleY: 0.001
  11280. };
  11281. group.attr(attribs);
  11282. if (markerGroup) {
  11283. markerGroup.attr(attribs);
  11284. }
  11285. // Run the animation
  11286. }
  11287. else {
  11288. attribs = {
  11289. translateX: plotLeft,
  11290. translateY: plotTop,
  11291. scaleX: 1,
  11292. scaleY: 1
  11293. };
  11294. group.animate(attribs, animation);
  11295. if (markerGroup) {
  11296. markerGroup.animate(attribs, animation);
  11297. }
  11298. }
  11299. }
  11300. }
  11301. }
  11302. // For non-polar charts, revert to the basic animation
  11303. }
  11304. else {
  11305. proceed.call(this, init);
  11306. }
  11307. };
  11308. // Define the animate method for regular series
  11309. wrap(seriesProto, 'animate', polarAnimate);
  11310. if (seriesTypes.column) {
  11311. arearangeProto = seriesTypes.arearange.prototype;
  11312. columnProto = seriesTypes.column.prototype;
  11313. columnProto.polarArc = function (low, high, start, end) {
  11314. var center = this.xAxis.center,
  11315. len = this.yAxis.len,
  11316. paneInnerR = center[3] / 2,
  11317. r = len - high + paneInnerR,
  11318. innerR = len - pick(low,
  11319. len) + paneInnerR;
  11320. // Prevent columns from shooting through the pane's center
  11321. if (this.yAxis.reversed) {
  11322. if (r < 0) {
  11323. r = paneInnerR;
  11324. }
  11325. if (innerR < 0) {
  11326. innerR = paneInnerR;
  11327. }
  11328. }
  11329. // Return a new shapeArgs
  11330. return {
  11331. x: center[0],
  11332. y: center[1],
  11333. r: r,
  11334. innerR: innerR,
  11335. start: start,
  11336. end: end
  11337. };
  11338. };
  11339. /**
  11340. * Define the animate method for columnseries
  11341. * @private
  11342. */
  11343. wrap(columnProto, 'animate', polarAnimate);
  11344. /**
  11345. * Extend the column prototype's translate method
  11346. * @private
  11347. */
  11348. wrap(columnProto, 'translate', function (proceed) {
  11349. var series = this,
  11350. options = series.options,
  11351. threshold = options.threshold,
  11352. stacking = options.stacking,
  11353. chart = series.chart,
  11354. xAxis = series.xAxis,
  11355. yAxis = series.yAxis,
  11356. reversed = yAxis.reversed,
  11357. center = yAxis.center,
  11358. startAngleRad = xAxis.startAngleRad,
  11359. endAngleRad = xAxis.endAngleRad,
  11360. visibleRange = endAngleRad - startAngleRad,
  11361. thresholdAngleRad,
  11362. points,
  11363. point,
  11364. i,
  11365. yMin,
  11366. yMax,
  11367. start,
  11368. end,
  11369. tooltipPos,
  11370. pointX,
  11371. pointY,
  11372. stackValues,
  11373. stack,
  11374. barX,
  11375. innerR,
  11376. r;
  11377. series.preventPostTranslate = true;
  11378. // Run uber method
  11379. proceed.call(series);
  11380. // Postprocess plot coordinates
  11381. if (xAxis.isRadial) {
  11382. points = series.points;
  11383. i = points.length;
  11384. yMin = yAxis.translate(yAxis.min);
  11385. yMax = yAxis.translate(yAxis.max);
  11386. threshold = options.threshold || 0;
  11387. if (chart.inverted) {
  11388. // Finding a correct threshold
  11389. if (isNumber(threshold)) {
  11390. thresholdAngleRad = yAxis.translate(threshold);
  11391. // Checks if threshold is outside the visible range
  11392. if (defined(thresholdAngleRad)) {
  11393. if (thresholdAngleRad < 0) {
  11394. thresholdAngleRad = 0;
  11395. }
  11396. else if (thresholdAngleRad > visibleRange) {
  11397. thresholdAngleRad = visibleRange;
  11398. }
  11399. // Adding start angle offset
  11400. series.translatedThreshold =
  11401. thresholdAngleRad + startAngleRad;
  11402. }
  11403. }
  11404. }
  11405. while (i--) {
  11406. point = points[i];
  11407. barX = point.barX;
  11408. pointX = point.x;
  11409. pointY = point.y;
  11410. point.shapeType = 'arc';
  11411. if (chart.inverted) {
  11412. point.plotY = yAxis.translate(pointY);
  11413. if (stacking && yAxis.stacking) {
  11414. stack = yAxis.stacking.stacks[(pointY < 0 ? '-' : '') +
  11415. series.stackKey];
  11416. if (series.visible && stack && stack[pointX]) {
  11417. if (!point.isNull) {
  11418. stackValues = stack[pointX].points[series.getStackIndicator(void 0, pointX, series.index).key];
  11419. // Translating to radial values
  11420. start = yAxis.translate(stackValues[0]);
  11421. end = yAxis.translate(stackValues[1]);
  11422. // If starting point is beyond the
  11423. // range, set it to 0
  11424. if (defined(start)) {
  11425. start = U.clamp(start, 0, visibleRange);
  11426. }
  11427. }
  11428. }
  11429. }
  11430. else {
  11431. // Initial start and end angles for radial bar
  11432. start = thresholdAngleRad;
  11433. end = point.plotY;
  11434. }
  11435. if (start > end) {
  11436. // Swapping start and end
  11437. end = [start, start = end][0];
  11438. }
  11439. // Prevent from rendering point outside the
  11440. // acceptable circular range
  11441. if (!reversed) {
  11442. if (start < yMin) {
  11443. start = yMin;
  11444. }
  11445. else if (end > yMax) {
  11446. end = yMax;
  11447. }
  11448. else if (end < yMin || start > yMax) {
  11449. start = end = 0;
  11450. }
  11451. }
  11452. else {
  11453. if (end > yMin) {
  11454. end = yMin;
  11455. }
  11456. else if (start < yMax) {
  11457. start = yMax;
  11458. }
  11459. else if (start > yMin || end < yMax) {
  11460. start = end = visibleRange;
  11461. }
  11462. }
  11463. if (yAxis.min > yAxis.max) {
  11464. start = end = reversed ? visibleRange : 0;
  11465. }
  11466. start += startAngleRad;
  11467. end += startAngleRad;
  11468. if (center) {
  11469. point.barX = barX += center[3] / 2;
  11470. }
  11471. // In case when radius, inner radius or both are
  11472. // negative, a point is rendered but partially or as
  11473. // a center point
  11474. innerR = Math.max(barX, 0);
  11475. r = Math.max(barX + point.pointWidth, 0);
  11476. point.shapeArgs = {
  11477. x: center && center[0],
  11478. y: center && center[1],
  11479. r: r,
  11480. innerR: innerR,
  11481. start: start,
  11482. end: end
  11483. };
  11484. // Fade out the points if not inside the polar "plot area"
  11485. point.opacity = start === end ? 0 : void 0;
  11486. // A correct value for stacked or not fully visible
  11487. // point
  11488. point.plotY = (defined(series.translatedThreshold) &&
  11489. (start < series.translatedThreshold ? start : end)) -
  11490. startAngleRad;
  11491. }
  11492. else {
  11493. start = barX + startAngleRad;
  11494. // Changed the way polar columns are drawn in order to make
  11495. // it more consistent with the drawing of inverted columns
  11496. // (they are using the same function now). Also, it was
  11497. // essential to make the animation work correctly (the
  11498. // scaling of the group) is replaced by animating each
  11499. // element separately.
  11500. point.shapeArgs = series.polarArc(point.yBottom, point.plotY, start, start + point.pointWidth);
  11501. }
  11502. // Provided a correct coordinates for the tooltip
  11503. series.toXY(point);
  11504. if (chart.inverted) {
  11505. tooltipPos = yAxis.postTranslate(point.rectPlotY, barX + point.pointWidth / 2);
  11506. point.tooltipPos = [
  11507. tooltipPos.x - chart.plotLeft,
  11508. tooltipPos.y - chart.plotTop
  11509. ];
  11510. }
  11511. else {
  11512. point.tooltipPos = [point.plotX, point.plotY];
  11513. }
  11514. if (center) {
  11515. point.ttBelow = point.plotY > center[1];
  11516. }
  11517. }
  11518. }
  11519. });
  11520. /**
  11521. * Find correct align and vertical align based on an angle in polar chart
  11522. * @private
  11523. */
  11524. columnProto.findAlignments = function (angle, options) {
  11525. var align,
  11526. verticalAlign;
  11527. if (options.align === null) {
  11528. if (angle > 20 && angle < 160) {
  11529. align = 'left'; // right hemisphere
  11530. }
  11531. else if (angle > 200 && angle < 340) {
  11532. align = 'right'; // left hemisphere
  11533. }
  11534. else {
  11535. align = 'center'; // top or bottom
  11536. }
  11537. options.align = align;
  11538. }
  11539. if (options.verticalAlign === null) {
  11540. if (angle < 45 || angle > 315) {
  11541. verticalAlign = 'bottom'; // top part
  11542. }
  11543. else if (angle > 135 && angle < 225) {
  11544. verticalAlign = 'top'; // bottom part
  11545. }
  11546. else {
  11547. verticalAlign = 'middle'; // left or right
  11548. }
  11549. options.verticalAlign = verticalAlign;
  11550. }
  11551. return options;
  11552. };
  11553. if (arearangeProto) {
  11554. arearangeProto.findAlignments = columnProto.findAlignments;
  11555. }
  11556. /**
  11557. * Align column data labels outside the columns. #1199.
  11558. * @private
  11559. */
  11560. wrap(columnProto, 'alignDataLabel', function (proceed, point, dataLabel, options, alignTo, isNew) {
  11561. var chart = this.chart,
  11562. inside = pick(options.inside, !!this.options.stacking),
  11563. angle,
  11564. shapeArgs,
  11565. labelPos;
  11566. if (chart.polar) {
  11567. angle = point.rectPlotX / Math.PI * 180;
  11568. if (!chart.inverted) {
  11569. // Align nicely outside the perimeter of the columns
  11570. if (this.findAlignments) {
  11571. options = this.findAlignments(angle, options);
  11572. }
  11573. }
  11574. else { // Required corrections for data labels of inverted bars
  11575. // The plotX and plotY are correctly set therefore they
  11576. // don't need to be swapped (inverted argument is false)
  11577. this.forceDL = chart.isInsidePlot(point.plotX, Math.round(point.plotY));
  11578. // Checks if labels should be positioned inside
  11579. if (inside && point.shapeArgs) {
  11580. shapeArgs = point.shapeArgs;
  11581. // Calculates pixel positions for a data label to be
  11582. // inside
  11583. labelPos =
  11584. this.yAxis.postTranslate(
  11585. // angle
  11586. ((shapeArgs.start || 0) + (shapeArgs.end || 0)) / 2 -
  11587. this
  11588. .xAxis.startAngleRad,
  11589. // radius
  11590. point.barX +
  11591. point.pointWidth / 2);
  11592. alignTo = {
  11593. x: labelPos.x - chart.plotLeft,
  11594. y: labelPos.y - chart.plotTop
  11595. };
  11596. }
  11597. else if (point.tooltipPos) {
  11598. alignTo = {
  11599. x: point.tooltipPos[0],
  11600. y: point.tooltipPos[1]
  11601. };
  11602. }
  11603. options.align = pick(options.align, 'center');
  11604. options.verticalAlign =
  11605. pick(options.verticalAlign, 'middle');
  11606. }
  11607. seriesProto.alignDataLabel.call(this, point, dataLabel, options, alignTo, isNew);
  11608. // Hide label of a point (only inverted) that is outside the
  11609. // visible y range
  11610. if (this.isRadialBar && point.shapeArgs &&
  11611. point.shapeArgs.start === point.shapeArgs.end) {
  11612. dataLabel.hide(true);
  11613. }
  11614. }
  11615. else {
  11616. proceed.call(this, point, dataLabel, options, alignTo, isNew);
  11617. }
  11618. });
  11619. }
  11620. /**
  11621. * Extend getCoordinates to prepare for polar axis values
  11622. * @private
  11623. */
  11624. wrap(pointerProto, 'getCoordinates', function (proceed, e) {
  11625. var chart = this.chart,
  11626. ret = {
  11627. xAxis: [],
  11628. yAxis: []
  11629. };
  11630. if (chart.polar) {
  11631. chart.axes.forEach(function (axis) {
  11632. var isXAxis = axis.isXAxis,
  11633. center = axis.center,
  11634. x,
  11635. y;
  11636. // Skip colorAxis
  11637. if (axis.coll === 'colorAxis') {
  11638. return;
  11639. }
  11640. x = e.chartX - center[0] - chart.plotLeft;
  11641. y = e.chartY - center[1] - chart.plotTop;
  11642. ret[isXAxis ? 'xAxis' : 'yAxis'].push({
  11643. axis: axis,
  11644. value: axis.translate(isXAxis ?
  11645. Math.PI - Math.atan2(x, y) : // angle
  11646. // distance from center
  11647. Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)), true)
  11648. });
  11649. });
  11650. }
  11651. else {
  11652. ret = proceed.call(this, e);
  11653. }
  11654. return ret;
  11655. });
  11656. SVGRenderer.prototype.clipCircle = function (x, y, r, innerR) {
  11657. var wrapper,
  11658. id = uniqueKey(),
  11659. clipPath = this.createElement('clipPath').attr({
  11660. id: id
  11661. }).add(this.defs);
  11662. wrapper = innerR ?
  11663. this.arc(x, y, r, innerR, 0, 2 * Math.PI).add(clipPath) :
  11664. this.circle(x, y, r).add(clipPath);
  11665. wrapper.id = id;
  11666. wrapper.clipPath = clipPath;
  11667. return wrapper;
  11668. };
  11669. addEvent(Chart, 'getAxes', function () {
  11670. if (!this.pane) {
  11671. this.pane = [];
  11672. }
  11673. splat(this.options.pane).forEach(function (paneOptions) {
  11674. new Pane(// eslint-disable-line no-new
  11675. paneOptions, this);
  11676. }, this);
  11677. });
  11678. addEvent(Chart, 'afterDrawChartBox', function () {
  11679. this.pane.forEach(function (pane) {
  11680. pane.render();
  11681. });
  11682. });
  11683. addEvent(Series, 'afterInit', function () {
  11684. var chart = this.chart;
  11685. // Add flags that identifies radial inverted series
  11686. if (chart.inverted && chart.polar) {
  11687. this.isRadialSeries = true;
  11688. if (this.is('column')) {
  11689. this.isRadialBar = true;
  11690. }
  11691. }
  11692. });
  11693. /**
  11694. * Extend chart.get to also search in panes. Used internally in
  11695. * responsiveness and chart.update.
  11696. * @private
  11697. */
  11698. wrap(Chart.prototype, 'get', function (proceed, id) {
  11699. return find(this.pane || [], function (pane) {
  11700. return pane.options.id === id;
  11701. }) || proceed.call(this, id);
  11702. });
  11703. });
  11704. _registerModule(_modules, 'masters/highcharts-more.src.js', [], function () {
  11705. });
  11706. }));