highcharts-more.src.js 501 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470847184728473847484758476847784788479848084818482848384848485848684878488848984908491849284938494849584968497849884998500850185028503850485058506850785088509851085118512851385148515851685178518851985208521852285238524852585268527852885298530853185328533853485358536853785388539854085418542854385448545854685478548854985508551855285538554855585568557855885598560856185628563856485658566856785688569857085718572857385748575857685778578857985808581858285838584858585868587858885898590859185928593859485958596859785988599860086018602860386048605860686078608860986108611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668866986708671867286738674867586768677867886798680868186828683868486858686868786888689869086918692869386948695869686978698869987008701870287038704870587068707870887098710871187128713871487158716871787188719872087218722872387248725872687278728872987308731873287338734873587368737873887398740874187428743874487458746874787488749875087518752875387548755875687578758875987608761876287638764876587668767876887698770877187728773877487758776877787788779878087818782878387848785878687878788878987908791879287938794879587968797879887998800880188028803880488058806880788088809881088118812881388148815881688178818881988208821882288238824882588268827882888298830883188328833883488358836883788388839884088418842884388448845884688478848884988508851885288538854885588568857885888598860886188628863886488658866886788688869887088718872887388748875887688778878887988808881888288838884888588868887888888898890889188928893889488958896889788988899890089018902890389048905890689078908890989108911891289138914891589168917891889198920892189228923892489258926892789288929893089318932893389348935893689378938893989408941894289438944894589468947894889498950895189528953895489558956895789588959896089618962896389648965896689678968896989708971897289738974897589768977897889798980898189828983898489858986898789888989899089918992899389948995899689978998899990009001900290039004900590069007900890099010901190129013901490159016901790189019902090219022902390249025902690279028902990309031903290339034903590369037903890399040904190429043904490459046904790489049905090519052905390549055905690579058905990609061906290639064906590669067906890699070907190729073907490759076907790789079908090819082908390849085908690879088908990909091909290939094909590969097909890999100910191029103910491059106910791089109911091119112911391149115911691179118911991209121912291239124912591269127912891299130913191329133913491359136913791389139914091419142914391449145914691479148914991509151915291539154915591569157915891599160916191629163916491659166916791689169917091719172917391749175917691779178917991809181918291839184918591869187918891899190919191929193919491959196919791989199920092019202920392049205920692079208920992109211921292139214921592169217921892199220922192229223922492259226922792289229923092319232923392349235923692379238923992409241924292439244924592469247924892499250925192529253925492559256925792589259926092619262926392649265926692679268926992709271927292739274927592769277927892799280928192829283928492859286928792889289929092919292929392949295929692979298929993009301930293039304930593069307930893099310931193129313931493159316931793189319932093219322932393249325932693279328932993309331933293339334933593369337933893399340934193429343934493459346934793489349935093519352935393549355935693579358935993609361936293639364936593669367936893699370937193729373937493759376937793789379938093819382938393849385938693879388938993909391939293939394939593969397939893999400940194029403940494059406940794089409941094119412941394149415941694179418941994209421942294239424942594269427942894299430943194329433943494359436943794389439944094419442944394449445944694479448944994509451945294539454945594569457945894599460946194629463946494659466946794689469947094719472947394749475947694779478947994809481948294839484948594869487948894899490949194929493949494959496949794989499950095019502950395049505950695079508950995109511951295139514951595169517951895199520952195229523952495259526952795289529953095319532953395349535953695379538953995409541954295439544954595469547954895499550955195529553955495559556955795589559956095619562956395649565956695679568956995709571957295739574957595769577957895799580958195829583958495859586958795889589959095919592959395949595959695979598959996009601960296039604960596069607960896099610961196129613961496159616961796189619962096219622962396249625962696279628962996309631963296339634963596369637963896399640964196429643964496459646964796489649965096519652965396549655965696579658965996609661966296639664966596669667966896699670967196729673967496759676967796789679968096819682968396849685968696879688968996909691969296939694969596969697969896999700970197029703970497059706970797089709971097119712971397149715971697179718971997209721972297239724972597269727972897299730973197329733973497359736973797389739974097419742974397449745974697479748974997509751975297539754975597569757975897599760976197629763976497659766976797689769977097719772977397749775977697779778977997809781978297839784978597869787978897899790979197929793979497959796979797989799980098019802980398049805980698079808980998109811981298139814981598169817981898199820982198229823982498259826982798289829983098319832983398349835983698379838983998409841984298439844984598469847984898499850985198529853985498559856985798589859986098619862986398649865986698679868986998709871987298739874987598769877987898799880988198829883988498859886988798889889989098919892989398949895989698979898989999009901990299039904990599069907990899099910991199129913991499159916991799189919992099219922992399249925992699279928992999309931993299339934993599369937993899399940994199429943994499459946994799489949995099519952995399549955995699579958995999609961996299639964996599669967996899699970997199729973997499759976997799789979998099819982998399849985998699879988998999909991999299939994999599969997999899991000010001100021000310004100051000610007100081000910010100111001210013100141001510016100171001810019100201002110022100231002410025100261002710028100291003010031100321003310034100351003610037100381003910040100411004210043100441004510046100471004810049100501005110052100531005410055100561005710058100591006010061100621006310064100651006610067100681006910070100711007210073100741007510076100771007810079100801008110082100831008410085100861008710088100891009010091100921009310094100951009610097100981009910100101011010210103101041010510106101071010810109101101011110112101131011410115101161011710118101191012010121101221012310124101251012610127101281012910130101311013210133101341013510136101371013810139101401014110142101431014410145101461014710148101491015010151101521015310154101551015610157101581015910160101611016210163101641016510166101671016810169101701017110172101731017410175101761017710178101791018010181101821018310184101851018610187101881018910190101911019210193101941019510196101971019810199102001020110202102031020410205102061020710208102091021010211102121021310214102151021610217102181021910220102211022210223102241022510226102271022810229102301023110232102331023410235102361023710238102391024010241102421024310244102451024610247102481024910250102511025210253102541025510256102571025810259102601026110262102631026410265102661026710268102691027010271102721027310274102751027610277102781027910280102811028210283102841028510286102871028810289102901029110292102931029410295102961029710298102991030010301103021030310304103051030610307103081030910310103111031210313103141031510316103171031810319103201032110322103231032410325103261032710328103291033010331103321033310334103351033610337103381033910340103411034210343103441034510346103471034810349103501035110352103531035410355103561035710358103591036010361103621036310364103651036610367103681036910370103711037210373103741037510376103771037810379103801038110382103831038410385103861038710388103891039010391103921039310394103951039610397103981039910400104011040210403104041040510406104071040810409104101041110412104131041410415104161041710418104191042010421104221042310424104251042610427104281042910430104311043210433104341043510436104371043810439104401044110442104431044410445104461044710448104491045010451104521045310454104551045610457104581045910460104611046210463104641046510466104671046810469104701047110472104731047410475104761047710478104791048010481104821048310484104851048610487104881048910490104911049210493104941049510496104971049810499105001050110502105031050410505105061050710508105091051010511105121051310514105151051610517105181051910520105211052210523105241052510526105271052810529105301053110532105331053410535105361053710538105391054010541105421054310544105451054610547105481054910550105511055210553105541055510556105571055810559105601056110562105631056410565105661056710568105691057010571105721057310574105751057610577105781057910580105811058210583105841058510586105871058810589105901059110592105931059410595105961059710598105991060010601106021060310604106051060610607106081060910610106111061210613106141061510616106171061810619106201062110622106231062410625106261062710628106291063010631106321063310634106351063610637106381063910640106411064210643106441064510646106471064810649106501065110652106531065410655106561065710658106591066010661106621066310664106651066610667106681066910670106711067210673106741067510676106771067810679106801068110682106831068410685106861068710688106891069010691106921069310694106951069610697106981069910700107011070210703107041070510706107071070810709107101071110712107131071410715107161071710718107191072010721107221072310724107251072610727107281072910730107311073210733107341073510736107371073810739107401074110742107431074410745107461074710748107491075010751107521075310754107551075610757107581075910760107611076210763107641076510766107671076810769107701077110772107731077410775107761077710778107791078010781107821078310784107851078610787107881078910790107911079210793107941079510796107971079810799108001080110802108031080410805108061080710808108091081010811108121081310814108151081610817108181081910820108211082210823108241082510826108271082810829108301083110832108331083410835108361083710838108391084010841108421084310844108451084610847108481084910850108511085210853108541085510856108571085810859108601086110862108631086410865108661086710868108691087010871108721087310874108751087610877108781087910880108811088210883108841088510886108871088810889108901089110892108931089410895108961089710898108991090010901109021090310904109051090610907109081090910910109111091210913109141091510916109171091810919109201092110922109231092410925109261092710928109291093010931109321093310934109351093610937109381093910940109411094210943109441094510946109471094810949109501095110952109531095410955109561095710958109591096010961109621096310964109651096610967109681096910970109711097210973109741097510976109771097810979109801098110982109831098410985109861098710988109891099010991109921099310994109951099610997109981099911000110011100211003110041100511006110071100811009110101101111012110131101411015110161101711018110191102011021110221102311024110251102611027110281102911030110311103211033110341103511036110371103811039110401104111042110431104411045110461104711048110491105011051110521105311054110551105611057110581105911060110611106211063110641106511066110671106811069110701107111072110731107411075110761107711078110791108011081110821108311084110851108611087110881108911090110911109211093110941109511096110971109811099111001110111102111031110411105111061110711108111091111011111111121111311114111151111611117111181111911120111211112211123111241112511126111271112811129111301113111132111331113411135111361113711138111391114011141111421114311144111451114611147111481114911150111511115211153111541115511156111571115811159111601116111162111631116411165111661116711168111691117011171111721117311174111751117611177111781117911180111811118211183111841118511186111871118811189111901119111192111931119411195111961119711198111991120011201112021120311204112051120611207112081120911210112111121211213112141121511216112171121811219112201122111222112231122411225112261122711228112291123011231112321123311234112351123611237112381123911240112411124211243112441124511246112471124811249112501125111252112531125411255112561125711258112591126011261112621126311264112651126611267112681126911270112711127211273112741127511276112771127811279112801128111282112831128411285112861128711288112891129011291112921129311294112951129611297112981129911300113011130211303113041130511306113071130811309113101131111312113131131411315113161131711318113191132011321113221132311324113251132611327113281132911330113311133211333113341133511336113371133811339113401134111342113431134411345113461134711348113491135011351113521135311354113551135611357113581135911360113611136211363113641136511366113671136811369113701137111372113731137411375113761137711378113791138011381113821138311384113851138611387113881138911390113911139211393113941139511396113971139811399114001140111402114031140411405114061140711408114091141011411114121141311414114151141611417114181141911420114211142211423114241142511426114271142811429114301143111432114331143411435114361143711438114391144011441114421144311444114451144611447114481144911450114511145211453114541145511456114571145811459114601146111462114631146411465114661146711468114691147011471114721147311474114751147611477114781147911480114811148211483114841148511486114871148811489114901149111492114931149411495114961149711498114991150011501115021150311504115051150611507115081150911510115111151211513115141151511516115171151811519115201152111522115231152411525115261152711528115291153011531115321153311534115351153611537115381153911540115411154211543115441154511546115471154811549115501155111552115531155411555115561155711558115591156011561115621156311564115651156611567115681156911570115711157211573115741157511576115771157811579115801158111582115831158411585115861158711588115891159011591115921159311594115951159611597115981159911600116011160211603116041160511606116071160811609116101161111612116131161411615116161161711618116191162011621116221162311624116251162611627116281162911630116311163211633116341163511636116371163811639116401164111642116431164411645116461164711648116491165011651116521165311654116551165611657116581165911660116611166211663116641166511666116671166811669116701167111672116731167411675116761167711678116791168011681116821168311684116851168611687116881168911690116911169211693116941169511696116971169811699117001170111702117031170411705117061170711708117091171011711117121171311714117151171611717117181171911720117211172211723117241172511726117271172811729
  1. /**
  2. * @license Highcharts JS v9.0.1 (2021-02-16)
  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 Highstock.
  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 = extend([], this.pane.center);
  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. }
  1080. }
  1081. // Disable certain features on angular and polar axes
  1082. if (angular || polar) {
  1083. axis.isRadial = true;
  1084. chartOptions.chart.zoomType = null;
  1085. if (!axis.labelCollector) {
  1086. axis.labelCollector = axis.createLabelCollector();
  1087. }
  1088. if (axis.labelCollector) {
  1089. // Prevent overlapping axis labels (#9761)
  1090. chart.labelCollectors.push(axis.labelCollector);
  1091. }
  1092. }
  1093. else {
  1094. this.isRadial = false;
  1095. }
  1096. // A pointer back to this axis to borrow geometry
  1097. if (pane && isCircular) {
  1098. pane.axis = axis;
  1099. }
  1100. axis.isCircular = isCircular;
  1101. });
  1102. addEvent(AxisClass, 'afterInit', function () {
  1103. var axis = this;
  1104. var chart = axis.chart,
  1105. options = axis.options,
  1106. isHidden = chart.angular && axis.isXAxis,
  1107. pane = axis.pane,
  1108. paneOptions = pane && pane.options;
  1109. if (!isHidden && pane && (chart.angular || chart.polar)) {
  1110. // Start and end angle options are given in degrees relative to
  1111. // top, while internal computations are in radians relative to
  1112. // right (like SVG).
  1113. // Y axis in polar charts
  1114. axis.angleRad = (options.angle || 0) * Math.PI / 180;
  1115. // Gauges
  1116. axis.startAngleRad =
  1117. (paneOptions.startAngle - 90) * Math.PI / 180;
  1118. axis.endAngleRad = (pick(paneOptions.endAngle, paneOptions.startAngle + 360) - 90) * Math.PI / 180; // Gauges
  1119. axis.offset = options.offset || 0;
  1120. }
  1121. });
  1122. // Wrap auto label align to avoid setting axis-wide rotation on radial
  1123. // axes. (#4920)
  1124. addEvent(AxisClass, 'autoLabelAlign', function (e) {
  1125. if (this.isRadial) {
  1126. e.align = void 0;
  1127. e.preventDefault();
  1128. }
  1129. });
  1130. // Remove label collector function on axis remove/update
  1131. addEvent(AxisClass, 'destroy', function () {
  1132. var axis = this;
  1133. if (axis.chart &&
  1134. axis.chart.labelCollectors) {
  1135. var index = (axis.labelCollector ?
  1136. axis.chart.labelCollectors.indexOf(axis.labelCollector) :
  1137. -1);
  1138. if (index >= 0) {
  1139. axis.chart.labelCollectors.splice(index, 1);
  1140. }
  1141. }
  1142. });
  1143. addEvent(AxisClass, 'initialAxisTranslation', function () {
  1144. var axis = this;
  1145. if (axis.isRadial) {
  1146. axis.beforeSetTickPositions();
  1147. }
  1148. });
  1149. // Add special cases within the Tick class' methods for radial axes.
  1150. addEvent(TickClass, 'afterGetPosition', function (e) {
  1151. var tick = this;
  1152. if (tick.axis.getPosition) {
  1153. extend(e.pos, tick.axis.getPosition(this.pos));
  1154. }
  1155. });
  1156. // Find the center position of the label based on the distance option.
  1157. addEvent(TickClass, 'afterGetLabelPosition', function (e) {
  1158. var tick = this;
  1159. var axis = tick.axis;
  1160. var label = tick.label;
  1161. if (!label) {
  1162. return;
  1163. }
  1164. var labelBBox = label.getBBox(), labelOptions = axis.options.labels, optionsY = labelOptions.y, ret, centerSlot = 20, // 20 degrees to each side at the top and bottom
  1165. align = labelOptions.align, angle = ((axis.translate(this.pos) + axis.startAngleRad +
  1166. Math.PI / 2) / Math.PI * 180) % 360, correctAngle = Math.round(angle), labelDir = 'end', // Direction of the label 'start' or 'end'
  1167. reducedAngle1 = correctAngle < 0 ?
  1168. correctAngle + 360 : correctAngle, reducedAngle2 = reducedAngle1, translateY = 0, translateX = 0, labelYPosCorrection = labelOptions.y === null ? -labelBBox.height * 0.3 : 0;
  1169. if (axis.isRadial) { // Both X and Y axes in a polar chart
  1170. ret = axis.getPosition(this.pos, (axis.center[2] / 2) +
  1171. relativeLength(pick(labelOptions.distance, -25), axis.center[2] / 2, -axis.center[2] / 2));
  1172. // Automatically rotated
  1173. if (labelOptions.rotation === 'auto') {
  1174. label.attr({
  1175. rotation: angle
  1176. });
  1177. // Vertically centered
  1178. }
  1179. else if (optionsY === null) {
  1180. optionsY = (axis.chart.renderer
  1181. .fontMetrics(label.styles && label.styles.fontSize).b -
  1182. labelBBox.height / 2);
  1183. }
  1184. // Automatic alignment
  1185. if (align === null) {
  1186. if (axis.isCircular) { // Y axis
  1187. if (labelBBox.width >
  1188. axis.len * axis.tickInterval / (axis.max - axis.min)) { // #3506
  1189. centerSlot = 0;
  1190. }
  1191. if (angle > centerSlot && angle < 180 - centerSlot) {
  1192. align = 'left'; // right hemisphere
  1193. }
  1194. else if (angle > 180 + centerSlot &&
  1195. angle < 360 - centerSlot) {
  1196. align = 'right'; // left hemisphere
  1197. }
  1198. else {
  1199. align = 'center'; // top or bottom
  1200. }
  1201. }
  1202. else {
  1203. align = 'center';
  1204. }
  1205. label.attr({
  1206. align: align
  1207. });
  1208. }
  1209. // Auto alignment for solid-gauges with two labels (#10635)
  1210. if (align === 'auto' &&
  1211. axis.tickPositions.length === 2 &&
  1212. axis.isCircular) {
  1213. // Angles reduced to 0 - 90 or 180 - 270
  1214. if (reducedAngle1 > 90 && reducedAngle1 < 180) {
  1215. reducedAngle1 = 180 - reducedAngle1;
  1216. }
  1217. else if (reducedAngle1 > 270 && reducedAngle1 <= 360) {
  1218. reducedAngle1 = 540 - reducedAngle1;
  1219. }
  1220. // Angles reduced to 0 - 180
  1221. if (reducedAngle2 > 180 && reducedAngle2 <= 360) {
  1222. reducedAngle2 = 360 - reducedAngle2;
  1223. }
  1224. if ((axis.pane.options.startAngle === correctAngle) ||
  1225. (axis.pane.options.startAngle === correctAngle + 360) ||
  1226. (axis.pane.options.startAngle === correctAngle - 360)) {
  1227. labelDir = 'start';
  1228. }
  1229. if ((correctAngle >= -90 && correctAngle <= 90) ||
  1230. (correctAngle >= -360 && correctAngle <= -270) ||
  1231. (correctAngle >= 270 && correctAngle <= 360)) {
  1232. align = (labelDir === 'start') ? 'right' : 'left';
  1233. }
  1234. else {
  1235. align = (labelDir === 'start') ? 'left' : 'right';
  1236. }
  1237. // For angles beetwen (90 + n * 180) +- 20
  1238. if (reducedAngle2 > 70 && reducedAngle2 < 110) {
  1239. align = 'center';
  1240. }
  1241. // auto Y translation
  1242. if (reducedAngle1 < 15 ||
  1243. (reducedAngle1 >= 180 && reducedAngle1 < 195)) {
  1244. translateY = labelBBox.height * 0.3;
  1245. }
  1246. else if (reducedAngle1 >= 15 && reducedAngle1 <= 35) {
  1247. translateY = labelDir === 'start' ?
  1248. 0 : labelBBox.height * 0.75;
  1249. }
  1250. else if (reducedAngle1 >= 195 && reducedAngle1 <= 215) {
  1251. translateY = labelDir === 'start' ?
  1252. labelBBox.height * 0.75 : 0;
  1253. }
  1254. else if (reducedAngle1 > 35 && reducedAngle1 <= 90) {
  1255. translateY = labelDir === 'start' ?
  1256. -labelBBox.height * 0.25 : labelBBox.height;
  1257. }
  1258. else if (reducedAngle1 > 215 && reducedAngle1 <= 270) {
  1259. translateY = labelDir === 'start' ?
  1260. labelBBox.height : -labelBBox.height * 0.25;
  1261. }
  1262. // auto X translation
  1263. if (reducedAngle2 < 15) {
  1264. translateX = labelDir === 'start' ?
  1265. -labelBBox.height * 0.15 : labelBBox.height * 0.15;
  1266. }
  1267. else if (reducedAngle2 > 165 && reducedAngle2 <= 180) {
  1268. translateX = labelDir === 'start' ?
  1269. labelBBox.height * 0.15 : -labelBBox.height * 0.15;
  1270. }
  1271. label.attr({ align: align });
  1272. label.translate(translateX, translateY + labelYPosCorrection);
  1273. }
  1274. e.pos.x = ret.x + labelOptions.x;
  1275. e.pos.y = ret.y + optionsY;
  1276. }
  1277. });
  1278. // Wrap the getMarkPath function to return the path of the radial marker
  1279. wrap(TickClass.prototype, 'getMarkPath', function (proceed, x, y, tickLength, tickWidth, horiz, renderer) {
  1280. var tick = this;
  1281. var axis = tick.axis;
  1282. var endPoint,
  1283. ret;
  1284. if (axis.isRadial) {
  1285. endPoint = axis.getPosition(this.pos, axis.center[2] / 2 + tickLength);
  1286. ret = [
  1287. 'M',
  1288. x,
  1289. y,
  1290. 'L',
  1291. endPoint.x,
  1292. endPoint.y
  1293. ];
  1294. }
  1295. else {
  1296. ret = proceed.call(this, x, y, tickLength, tickWidth, horiz, renderer);
  1297. }
  1298. return ret;
  1299. });
  1300. };
  1301. /* *
  1302. *
  1303. * Static Properties
  1304. *
  1305. * */
  1306. /**
  1307. * Circular axis around the perimeter of a polar chart.
  1308. * @private
  1309. */
  1310. RadialAxis.defaultCircularOptions = {
  1311. gridLineWidth: 1,
  1312. labels: {
  1313. align: null,
  1314. distance: 15,
  1315. x: 0,
  1316. y: null,
  1317. style: {
  1318. textOverflow: 'none' // wrap lines by default (#7248)
  1319. }
  1320. },
  1321. maxPadding: 0,
  1322. minPadding: 0,
  1323. showLastLabel: false,
  1324. tickLength: 0
  1325. };
  1326. /**
  1327. * The default options extend defaultYAxisOptions.
  1328. * @private
  1329. */
  1330. RadialAxis.defaultRadialGaugeOptions = {
  1331. labels: {
  1332. align: 'center',
  1333. x: 0,
  1334. y: null // auto
  1335. },
  1336. minorGridLineWidth: 0,
  1337. minorTickInterval: 'auto',
  1338. minorTickLength: 10,
  1339. minorTickPosition: 'inside',
  1340. minorTickWidth: 1,
  1341. tickLength: 10,
  1342. tickPosition: 'inside',
  1343. tickWidth: 2,
  1344. title: {
  1345. rotation: 0
  1346. },
  1347. zIndex: 2 // behind dials, points in the series group
  1348. };
  1349. /**
  1350. * Radial axis, like a spoke in a polar chart.
  1351. * @private
  1352. */
  1353. RadialAxis.defaultRadialOptions = {
  1354. /**
  1355. * In a polar chart, this is the angle of the Y axis in degrees, where
  1356. * 0 is up and 90 is right. The angle determines the position of the
  1357. * axis line and the labels, though the coordinate system is unaffected.
  1358. * Since v8.0.0 this option is also applicable for X axis (inverted
  1359. * polar).
  1360. *
  1361. * @sample {highcharts} highcharts/xaxis/angle/
  1362. * Custom X axis' angle on inverted polar chart
  1363. * @sample {highcharts} highcharts/yaxis/angle/
  1364. * Dual axis polar chart
  1365. *
  1366. * @type {number}
  1367. * @default 0
  1368. * @since 4.2.7
  1369. * @product highcharts
  1370. * @apioption xAxis.angle
  1371. */
  1372. /**
  1373. * Polar charts only. Whether the grid lines should draw as a polygon
  1374. * with straight lines between categories, or as circles. Can be either
  1375. * `circle` or `polygon`. Since v8.0.0 this option is also applicable
  1376. * for X axis (inverted polar).
  1377. *
  1378. * @sample {highcharts} highcharts/demo/polar-spider/
  1379. * Polygon grid lines
  1380. * @sample {highcharts} highcharts/xaxis/gridlineinterpolation/
  1381. * Circle and polygon on inverted polar
  1382. * @sample {highcharts} highcharts/yaxis/gridlineinterpolation/
  1383. * Circle and polygon
  1384. *
  1385. * @type {string}
  1386. * @product highcharts
  1387. * @validvalue ["circle", "polygon"]
  1388. * @apioption xAxis.gridLineInterpolation
  1389. */
  1390. gridLineInterpolation: 'circle',
  1391. gridLineWidth: 1,
  1392. labels: {
  1393. align: 'right',
  1394. x: -3,
  1395. y: -2
  1396. },
  1397. showLastLabel: false,
  1398. title: {
  1399. x: 4,
  1400. text: null,
  1401. rotation: 90
  1402. }
  1403. };
  1404. return RadialAxis;
  1405. }());
  1406. RadialAxis.compose(Axis, Tick); // @todo move outside
  1407. return RadialAxis;
  1408. });
  1409. _registerModule(_modules, 'Series/AreaRange/AreaRangePoint.js', [_modules['Series/Area/AreaSeries.js'], _modules['Core/Series/Point.js'], _modules['Core/Utilities.js']], function (AreaSeries, Point, U) {
  1410. /* *
  1411. *
  1412. * (c) 2010-2021 Torstein Honsi
  1413. *
  1414. * License: www.highcharts.com/license
  1415. *
  1416. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  1417. *
  1418. * */
  1419. var __extends = (this && this.__extends) || (function () {
  1420. var extendStatics = function (d,
  1421. b) {
  1422. extendStatics = Object.setPrototypeOf ||
  1423. ({ __proto__: [] } instanceof Array && function (d,
  1424. b) { d.__proto__ = b; }) ||
  1425. function (d,
  1426. b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  1427. return extendStatics(d, b);
  1428. };
  1429. return function (d, b) {
  1430. extendStatics(d, b);
  1431. function __() { this.constructor = d; }
  1432. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  1433. };
  1434. })();
  1435. var pointProto = Point.prototype;
  1436. var defined = U.defined,
  1437. isNumber = U.isNumber;
  1438. /* *
  1439. *
  1440. * Class
  1441. *
  1442. * */
  1443. var AreaRangePoint = /** @class */ (function (_super) {
  1444. __extends(AreaRangePoint, _super);
  1445. function AreaRangePoint() {
  1446. /* *
  1447. *
  1448. * Properties
  1449. *
  1450. * */
  1451. var _this = _super !== null && _super.apply(this,
  1452. arguments) || this;
  1453. _this.high = void 0;
  1454. _this.low = void 0;
  1455. _this.options = void 0;
  1456. _this.plotHigh = void 0;
  1457. _this.plotLow = void 0;
  1458. _this.plotHighX = void 0;
  1459. _this.plotLowX = void 0;
  1460. _this.plotX = void 0;
  1461. _this.series = void 0;
  1462. return _this;
  1463. }
  1464. /* *
  1465. *
  1466. * Functions
  1467. *
  1468. * */
  1469. /**
  1470. * @private
  1471. */
  1472. AreaRangePoint.prototype.setState = function () {
  1473. var prevState = this.state,
  1474. series = this.series,
  1475. isPolar = series.chart.polar;
  1476. if (!defined(this.plotHigh)) {
  1477. // Boost doesn't calculate plotHigh
  1478. this.plotHigh = series.yAxis.toPixels(this.high, true);
  1479. }
  1480. if (!defined(this.plotLow)) {
  1481. // Boost doesn't calculate plotLow
  1482. this.plotLow = this.plotY = series.yAxis.toPixels(this.low, true);
  1483. }
  1484. if (series.stateMarkerGraphic) {
  1485. series.lowerStateMarkerGraphic = series.stateMarkerGraphic;
  1486. series.stateMarkerGraphic = series.upperStateMarkerGraphic;
  1487. }
  1488. // Change state also for the top marker
  1489. this.graphic = this.upperGraphic;
  1490. this.plotY = this.plotHigh;
  1491. if (isPolar) {
  1492. this.plotX = this.plotHighX;
  1493. }
  1494. // Top state:
  1495. pointProto.setState.apply(this, arguments);
  1496. this.state = prevState;
  1497. // Now restore defaults
  1498. this.plotY = this.plotLow;
  1499. this.graphic = this.lowerGraphic;
  1500. if (isPolar) {
  1501. this.plotX = this.plotLowX;
  1502. }
  1503. if (series.stateMarkerGraphic) {
  1504. series.upperStateMarkerGraphic = series.stateMarkerGraphic;
  1505. series.stateMarkerGraphic = series.lowerStateMarkerGraphic;
  1506. // Lower marker is stored at stateMarkerGraphic
  1507. // to avoid reference duplication (#7021)
  1508. series.lowerStateMarkerGraphic = void 0;
  1509. }
  1510. pointProto.setState.apply(this, arguments);
  1511. };
  1512. AreaRangePoint.prototype.haloPath = function () {
  1513. var isPolar = this.series.chart.polar,
  1514. path = [];
  1515. // Bottom halo
  1516. this.plotY = this.plotLow;
  1517. if (isPolar) {
  1518. this.plotX = this.plotLowX;
  1519. }
  1520. if (this.isInside) {
  1521. path = pointProto.haloPath.apply(this, arguments);
  1522. }
  1523. // Top halo
  1524. this.plotY = this.plotHigh;
  1525. if (isPolar) {
  1526. this.plotX = this.plotHighX;
  1527. }
  1528. if (this.isTopInside) {
  1529. path = path.concat(pointProto.haloPath.apply(this, arguments));
  1530. }
  1531. return path;
  1532. };
  1533. AreaRangePoint.prototype.isValid = function () {
  1534. return isNumber(this.low) && isNumber(this.high);
  1535. };
  1536. return AreaRangePoint;
  1537. }(AreaSeries.prototype.pointClass));
  1538. /* *
  1539. *
  1540. * Default export
  1541. *
  1542. * */
  1543. return AreaRangePoint;
  1544. });
  1545. _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) {
  1546. /* *
  1547. *
  1548. * (c) 2010-2021 Torstein Honsi
  1549. *
  1550. * License: www.highcharts.com/license
  1551. *
  1552. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  1553. *
  1554. * */
  1555. var __extends = (this && this.__extends) || (function () {
  1556. var extendStatics = function (d,
  1557. b) {
  1558. extendStatics = Object.setPrototypeOf ||
  1559. ({ __proto__: [] } instanceof Array && function (d,
  1560. b) { d.__proto__ = b; }) ||
  1561. function (d,
  1562. b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  1563. return extendStatics(d, b);
  1564. };
  1565. return function (d, b) {
  1566. extendStatics(d, b);
  1567. function __() { this.constructor = d; }
  1568. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  1569. };
  1570. })();
  1571. var areaProto = AreaSeries.prototype;
  1572. var columnProto = ColumnSeries.prototype;
  1573. var noop = H.noop;
  1574. var seriesProto = Series.prototype;
  1575. var defined = U.defined,
  1576. extend = U.extend,
  1577. isArray = U.isArray,
  1578. pick = U.pick,
  1579. merge = U.merge;
  1580. /* *
  1581. *
  1582. * Class
  1583. *
  1584. * */
  1585. /**
  1586. * The AreaRange series type.
  1587. *
  1588. * @private
  1589. * @class
  1590. * @name Highcharts.seriesTypes.arearange
  1591. *
  1592. * @augments Highcharts.Series
  1593. */
  1594. var AreaRangeSeries = /** @class */ (function (_super) {
  1595. __extends(AreaRangeSeries, _super);
  1596. function AreaRangeSeries() {
  1597. /**
  1598. *
  1599. * Static properties
  1600. *
  1601. */
  1602. var _this = _super !== null && _super.apply(this,
  1603. arguments) || this;
  1604. /* *
  1605. *
  1606. * Properties
  1607. *
  1608. * */
  1609. _this.data = void 0;
  1610. _this.options = void 0;
  1611. _this.points = void 0;
  1612. _this.lowerStateMarkerGraphic = void 0;
  1613. _this.xAxis = void 0;
  1614. _this.setStackedPoints = noop;
  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,
  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. // Split into upper and lower options. If data labels is an array, the
  1791. // first element is the upper label, the second is the lower.
  1792. //
  1793. // TODO: We want to change this and allow multiple labels for both upper
  1794. // and lower values in the future - introducing some options for which
  1795. // point value to use as Y for the dataLabel, so that this could be
  1796. // handled in Series.drawDataLabels. This would also improve performance
  1797. // since we now have to loop over all the points multiple times to work
  1798. // around the data label logic.
  1799. if (isArray(dataLabelOptions)) {
  1800. upperDataLabelOptions = dataLabelOptions[0] || { enabled: false };
  1801. lowerDataLabelOptions = dataLabelOptions[1] || { enabled: false };
  1802. }
  1803. else {
  1804. // Make copies
  1805. upperDataLabelOptions = extend({}, dataLabelOptions);
  1806. upperDataLabelOptions.x = dataLabelOptions.xHigh;
  1807. upperDataLabelOptions.y = dataLabelOptions.yHigh;
  1808. lowerDataLabelOptions = extend({}, dataLabelOptions);
  1809. lowerDataLabelOptions.x = dataLabelOptions.xLow;
  1810. lowerDataLabelOptions.y = dataLabelOptions.yLow;
  1811. }
  1812. // Draw upper labels
  1813. if (upperDataLabelOptions.enabled || this._hasPointLabels) {
  1814. // Set preliminary values for plotY and dataLabel
  1815. // and draw the upper labels
  1816. i = length;
  1817. while (i--) {
  1818. point = data[i];
  1819. if (point) {
  1820. up = upperDataLabelOptions.inside ?
  1821. point.plotHigh < point.plotLow :
  1822. point.plotHigh > point.plotLow;
  1823. point.y = point.high;
  1824. point._plotY = point.plotY;
  1825. point.plotY = point.plotHigh;
  1826. // Store original data labels and set preliminary label
  1827. // objects to be picked up in the uber method
  1828. originalDataLabels[i] = point.dataLabel;
  1829. point.dataLabel = point.dataLabelUpper;
  1830. // Set the default offset
  1831. point.below = up;
  1832. if (inverted) {
  1833. if (!upperDataLabelOptions.align) {
  1834. upperDataLabelOptions.align = up ? 'right' : 'left';
  1835. }
  1836. }
  1837. else {
  1838. if (!upperDataLabelOptions.verticalAlign) {
  1839. upperDataLabelOptions.verticalAlign = up ?
  1840. 'top' :
  1841. 'bottom';
  1842. }
  1843. }
  1844. }
  1845. }
  1846. this.options.dataLabels = upperDataLabelOptions;
  1847. if (seriesProto.drawDataLabels) {
  1848. // #1209:
  1849. seriesProto.drawDataLabels.apply(this, arguments);
  1850. }
  1851. // Reset state after the upper labels were created. Move
  1852. // it to point.dataLabelUpper and reassign the originals.
  1853. // We do this here to support not drawing a lower label.
  1854. i = length;
  1855. while (i--) {
  1856. point = data[i];
  1857. if (point) {
  1858. point.dataLabelUpper = point.dataLabel;
  1859. point.dataLabel = originalDataLabels[i];
  1860. delete point.dataLabels;
  1861. point.y = point.low;
  1862. point.plotY = point._plotY;
  1863. }
  1864. }
  1865. }
  1866. // Draw lower labels
  1867. if (lowerDataLabelOptions.enabled || this._hasPointLabels) {
  1868. i = length;
  1869. while (i--) {
  1870. point = data[i];
  1871. if (point) {
  1872. up = lowerDataLabelOptions.inside ?
  1873. point.plotHigh < point.plotLow :
  1874. point.plotHigh > point.plotLow;
  1875. // Set the default offset
  1876. point.below = !up;
  1877. if (inverted) {
  1878. if (!lowerDataLabelOptions.align) {
  1879. lowerDataLabelOptions.align = up ? 'left' : 'right';
  1880. }
  1881. }
  1882. else {
  1883. if (!lowerDataLabelOptions.verticalAlign) {
  1884. lowerDataLabelOptions.verticalAlign = up ?
  1885. 'bottom' :
  1886. 'top';
  1887. }
  1888. }
  1889. }
  1890. }
  1891. this.options.dataLabels = lowerDataLabelOptions;
  1892. if (seriesProto.drawDataLabels) {
  1893. seriesProto.drawDataLabels.apply(this, arguments);
  1894. }
  1895. }
  1896. // Merge upper and lower into point.dataLabels for later destroying
  1897. if (upperDataLabelOptions.enabled) {
  1898. i = length;
  1899. while (i--) {
  1900. point = data[i];
  1901. if (point) {
  1902. point.dataLabels = [
  1903. point.dataLabelUpper,
  1904. point.dataLabel
  1905. ].filter(function (label) {
  1906. return !!label;
  1907. });
  1908. }
  1909. }
  1910. }
  1911. // Reset options
  1912. this.options.dataLabels = dataLabelOptions;
  1913. };
  1914. AreaRangeSeries.prototype.alignDataLabel = function () {
  1915. columnProto.alignDataLabel.apply(this, arguments);
  1916. };
  1917. AreaRangeSeries.prototype.drawPoints = function () {
  1918. var series = this,
  1919. pointLength = series.points.length,
  1920. point,
  1921. i;
  1922. // Draw bottom points
  1923. seriesProto.drawPoints
  1924. .apply(series, arguments);
  1925. // Prepare drawing top points
  1926. i = 0;
  1927. while (i < pointLength) {
  1928. point = series.points[i];
  1929. // Save original props to be overridden by temporary props for top
  1930. // points
  1931. point.origProps = {
  1932. plotY: point.plotY,
  1933. plotX: point.plotX,
  1934. isInside: point.isInside,
  1935. negative: point.negative,
  1936. zone: point.zone,
  1937. y: point.y
  1938. };
  1939. point.lowerGraphic = point.graphic;
  1940. point.graphic = point.upperGraphic;
  1941. point.plotY = point.plotHigh;
  1942. if (defined(point.plotHighX)) {
  1943. point.plotX = point.plotHighX;
  1944. }
  1945. point.y = point.high;
  1946. point.negative = point.high < (series.options.threshold || 0);
  1947. point.zone = (series.zones.length && point.getZone());
  1948. if (!series.chart.polar) {
  1949. point.isInside = point.isTopInside = (typeof point.plotY !== 'undefined' &&
  1950. point.plotY >= 0 &&
  1951. point.plotY <= series.yAxis.len && // #3519
  1952. point.plotX >= 0 &&
  1953. point.plotX <= series.xAxis.len);
  1954. }
  1955. i++;
  1956. }
  1957. // Draw top points
  1958. seriesProto.drawPoints.apply(series, arguments);
  1959. // Reset top points preliminary modifications
  1960. i = 0;
  1961. while (i < pointLength) {
  1962. point = series.points[i];
  1963. point.upperGraphic = point.graphic;
  1964. point.graphic = point.lowerGraphic;
  1965. extend(point, point.origProps);
  1966. delete point.origProps;
  1967. i++;
  1968. }
  1969. };
  1970. /**
  1971. * The area range series is a carteseian series with higher and lower
  1972. * values for each point along an X axis, where the area between the
  1973. * values is shaded.
  1974. *
  1975. * @sample {highcharts} highcharts/demo/arearange/
  1976. * Area range chart
  1977. * @sample {highstock} stock/demo/arearange/
  1978. * Area range chart
  1979. *
  1980. * @extends plotOptions.area
  1981. * @product highcharts highstock
  1982. * @excluding stack, stacking
  1983. * @requires highcharts-more
  1984. * @optionparent plotOptions.arearange
  1985. */
  1986. AreaRangeSeries.defaultOptions = merge(AreaSeries.defaultOptions, {
  1987. /**
  1988. * @see [fillColor](#plotOptions.arearange.fillColor)
  1989. * @see [fillOpacity](#plotOptions.arearange.fillOpacity)
  1990. *
  1991. * @apioption plotOptions.arearange.color
  1992. */
  1993. /**
  1994. * @default low
  1995. * @apioption plotOptions.arearange.colorKey
  1996. */
  1997. /**
  1998. * @see [color](#plotOptions.arearange.color)
  1999. * @see [fillOpacity](#plotOptions.arearange.fillOpacity)
  2000. *
  2001. * @apioption plotOptions.arearange.fillColor
  2002. */
  2003. /**
  2004. * @see [color](#plotOptions.arearange.color)
  2005. * @see [fillColor](#plotOptions.arearange.fillColor)
  2006. *
  2007. * @default {highcharts} 0.75
  2008. * @default {highstock} 0.75
  2009. * @apioption plotOptions.arearange.fillOpacity
  2010. */
  2011. /**
  2012. * Whether to apply a drop shadow to the graph line. Since 2.3 the
  2013. * shadow can be an object configuration containing `color`, `offsetX`,
  2014. * `offsetY`, `opacity` and `width`.
  2015. *
  2016. * @type {boolean|Highcharts.ShadowOptionsObject}
  2017. * @product highcharts
  2018. * @apioption plotOptions.arearange.shadow
  2019. */
  2020. /**
  2021. * Pixel width of the arearange graph line.
  2022. *
  2023. * @since 2.3.0
  2024. *
  2025. * @private
  2026. */
  2027. lineWidth: 1,
  2028. threshold: null,
  2029. tooltip: {
  2030. pointFormat: '<span style="color:{series.color}">\u25CF</span> ' +
  2031. '{series.name}: <b>{point.low}</b> - <b>{point.high}</b><br/>'
  2032. },
  2033. /**
  2034. * Whether the whole area or just the line should respond to mouseover
  2035. * tooltips and other mouse or touch events.
  2036. *
  2037. * @since 2.3.0
  2038. *
  2039. * @private
  2040. */
  2041. trackByArea: true,
  2042. /**
  2043. * Extended data labels for range series types. Range series data
  2044. * labels use no `x` and `y` options. Instead, they have `xLow`,
  2045. * `xHigh`, `yLow` and `yHigh` options to allow the higher and lower
  2046. * data label sets individually.
  2047. *
  2048. * @declare Highcharts.SeriesAreaRangeDataLabelsOptionsObject
  2049. * @exclude x, y
  2050. * @since 2.3.0
  2051. * @product highcharts highstock
  2052. *
  2053. * @private
  2054. */
  2055. dataLabels: {
  2056. align: void 0,
  2057. verticalAlign: void 0,
  2058. /**
  2059. * X offset of the lower data labels relative to the point value.
  2060. *
  2061. * @sample highcharts/plotoptions/arearange-datalabels/
  2062. * Data labels on range series
  2063. * @sample highcharts/plotoptions/arearange-datalabels/
  2064. * Data labels on range series
  2065. */
  2066. xLow: 0,
  2067. /**
  2068. * X offset of the higher data labels relative to the point value.
  2069. *
  2070. * @sample highcharts/plotoptions/arearange-datalabels/
  2071. * Data labels on range series
  2072. */
  2073. xHigh: 0,
  2074. /**
  2075. * Y offset of the lower data labels relative to the point value.
  2076. *
  2077. * @sample highcharts/plotoptions/arearange-datalabels/
  2078. * Data labels on range series
  2079. */
  2080. yLow: 0,
  2081. /**
  2082. * Y offset of the higher data labels relative to the point value.
  2083. *
  2084. * @sample highcharts/plotoptions/arearange-datalabels/
  2085. * Data labels on range series
  2086. */
  2087. yHigh: 0
  2088. }
  2089. });
  2090. return AreaRangeSeries;
  2091. }(AreaSeries));
  2092. extend(AreaRangeSeries.prototype, {
  2093. pointArrayMap: ['low', 'high'],
  2094. pointValKey: 'low',
  2095. deferTranslatePolar: true,
  2096. pointClass: AreaRangePoint
  2097. });
  2098. SeriesRegistry.registerSeriesType('arearange', AreaRangeSeries);
  2099. /* *
  2100. *
  2101. * Default export
  2102. *
  2103. * */
  2104. /**
  2105. * A `arearange` series. If the [type](#series.arearange.type) option is not
  2106. * specified, it is inherited from [chart.type](#chart.type).
  2107. *
  2108. *
  2109. * @extends series,plotOptions.arearange
  2110. * @excluding dataParser, dataURL, stack, stacking
  2111. * @product highcharts highstock
  2112. * @requires highcharts-more
  2113. * @apioption series.arearange
  2114. */
  2115. /**
  2116. * @see [fillColor](#series.arearange.fillColor)
  2117. * @see [fillOpacity](#series.arearange.fillOpacity)
  2118. *
  2119. * @apioption series.arearange.color
  2120. */
  2121. /**
  2122. * An array of data points for the series. For the `arearange` series type,
  2123. * points can be given in the following ways:
  2124. *
  2125. * 1. An array of arrays with 3 or 2 values. In this case, the values
  2126. * correspond to `x,low,high`. If the first value is a string, it is
  2127. * applied as the name of the point, and the `x` value is inferred.
  2128. * The `x` value can also be omitted, in which case the inner arrays
  2129. * should be of length 2\. Then the `x` value is automatically calculated,
  2130. * either starting at 0 and incremented by 1, or from `pointStart`
  2131. * and `pointInterval` given in the series options.
  2132. * ```js
  2133. * data: [
  2134. * [0, 8, 3],
  2135. * [1, 1, 1],
  2136. * [2, 6, 8]
  2137. * ]
  2138. * ```
  2139. *
  2140. * 2. An array of objects with named values. The following snippet shows only a
  2141. * few settings, see the complete options set below. If the total number of
  2142. * data points exceeds the series'
  2143. * [turboThreshold](#series.arearange.turboThreshold),
  2144. * this option is not available.
  2145. * ```js
  2146. * data: [{
  2147. * x: 1,
  2148. * low: 9,
  2149. * high: 0,
  2150. * name: "Point2",
  2151. * color: "#00FF00"
  2152. * }, {
  2153. * x: 1,
  2154. * low: 3,
  2155. * high: 4,
  2156. * name: "Point1",
  2157. * color: "#FF00FF"
  2158. * }]
  2159. * ```
  2160. *
  2161. * @sample {highcharts} highcharts/series/data-array-of-arrays/
  2162. * Arrays of numeric x and y
  2163. * @sample {highcharts} highcharts/series/data-array-of-arrays-datetime/
  2164. * Arrays of datetime x and y
  2165. * @sample {highcharts} highcharts/series/data-array-of-name-value/
  2166. * Arrays of point.name and y
  2167. * @sample {highcharts} highcharts/series/data-array-of-objects/
  2168. * Config objects
  2169. *
  2170. * @type {Array<Array<(number|string),number>|Array<(number|string),number,number>|*>}
  2171. * @extends series.line.data
  2172. * @excluding marker, y
  2173. * @product highcharts highstock
  2174. * @apioption series.arearange.data
  2175. */
  2176. /**
  2177. * @extends series.arearange.dataLabels
  2178. * @product highcharts highstock
  2179. * @apioption series.arearange.data.dataLabels
  2180. */
  2181. /**
  2182. * @see [color](#series.arearange.color)
  2183. * @see [fillOpacity](#series.arearange.fillOpacity)
  2184. *
  2185. * @apioption series.arearange.fillColor
  2186. */
  2187. /**
  2188. * @see [color](#series.arearange.color)
  2189. * @see [fillColor](#series.arearange.fillColor)
  2190. *
  2191. * @default {highcharts} 0.75
  2192. * @default {highstock} 0.75
  2193. * @apioption series.arearange.fillOpacity
  2194. */
  2195. /**
  2196. * The high or maximum value for each data point.
  2197. *
  2198. * @type {number}
  2199. * @product highcharts highstock
  2200. * @apioption series.arearange.data.high
  2201. */
  2202. /**
  2203. * The low or minimum value for each data point.
  2204. *
  2205. * @type {number}
  2206. * @product highcharts highstock
  2207. * @apioption series.arearange.data.low
  2208. */
  2209. ''; // adds doclets above to tranpiled file
  2210. return AreaRangeSeries;
  2211. });
  2212. _registerModule(_modules, 'Series/AreaSplineRange/AreaSplineRangeSeries.js', [_modules['Series/AreaRange/AreaRangeSeries.js'], _modules['Core/Series/SeriesRegistry.js'], _modules['Core/Utilities.js']], function (AreaRangeSeries, SeriesRegistry, U) {
  2213. /* *
  2214. *
  2215. * (c) 2010-2021 Torstein Honsi
  2216. *
  2217. * License: www.highcharts.com/license
  2218. *
  2219. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  2220. *
  2221. * */
  2222. var __extends = (this && this.__extends) || (function () {
  2223. var extendStatics = function (d,
  2224. b) {
  2225. extendStatics = Object.setPrototypeOf ||
  2226. ({ __proto__: [] } instanceof Array && function (d,
  2227. b) { d.__proto__ = b; }) ||
  2228. function (d,
  2229. b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  2230. return extendStatics(d, b);
  2231. };
  2232. return function (d, b) {
  2233. extendStatics(d, b);
  2234. function __() { this.constructor = d; }
  2235. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  2236. };
  2237. })();
  2238. var SplineSeries = SeriesRegistry.seriesTypes.spline;
  2239. var merge = U.merge,
  2240. extend = U.extend;
  2241. /* *
  2242. *
  2243. * Class
  2244. *
  2245. * */
  2246. /**
  2247. * The areasplinerange series type.
  2248. *
  2249. * @private
  2250. * @class
  2251. * @name Highcharts.seriesTypes.areasplinerange
  2252. *
  2253. * @augments Highcharts.Series
  2254. */
  2255. var AreaSplineRangeSeries = /** @class */ (function (_super) {
  2256. __extends(AreaSplineRangeSeries, _super);
  2257. function AreaSplineRangeSeries() {
  2258. /* *
  2259. *
  2260. * Static properties
  2261. *
  2262. * */
  2263. var _this = _super !== null && _super.apply(this,
  2264. arguments) || this;
  2265. /* *
  2266. *
  2267. * Properties
  2268. *
  2269. * */
  2270. _this.options = void 0;
  2271. _this.data = void 0;
  2272. _this.points = void 0;
  2273. return _this;
  2274. }
  2275. /**
  2276. * The area spline range is a cartesian series type with higher and
  2277. * lower Y values along an X axis. The area inside the range is colored, and
  2278. * the graph outlining the area is a smoothed spline.
  2279. *
  2280. * @sample {highstock|highstock} stock/demo/areasplinerange/
  2281. * Area spline range
  2282. *
  2283. * @extends plotOptions.arearange
  2284. * @since 2.3.0
  2285. * @excluding step, boostThreshold, boostBlending
  2286. * @product highcharts highstock
  2287. * @requires highcharts-more
  2288. * @apioption plotOptions.areasplinerange
  2289. */
  2290. /**
  2291. * @see [fillColor](#plotOptions.areasplinerange.fillColor)
  2292. * @see [fillOpacity](#plotOptions.areasplinerange.fillOpacity)
  2293. *
  2294. * @apioption plotOptions.areasplinerange.color
  2295. */
  2296. /**
  2297. * @see [color](#plotOptions.areasplinerange.color)
  2298. * @see [fillOpacity](#plotOptions.areasplinerange.fillOpacity)
  2299. *
  2300. * @apioption plotOptions.areasplinerange.fillColor
  2301. */
  2302. /**
  2303. * @see [color](#plotOptions.areasplinerange.color)
  2304. * @see [fillColor](#plotOptions.areasplinerange.fillColor)
  2305. *
  2306. * @default {highcharts} 0.75
  2307. * @default {highstock} 0.75
  2308. * @apioption plotOptions.areasplinerange.fillOpacity
  2309. */
  2310. AreaSplineRangeSeries.defaultOptions = merge(AreaRangeSeries.defaultOptions);
  2311. return AreaSplineRangeSeries;
  2312. }(AreaRangeSeries));
  2313. extend(AreaSplineRangeSeries.prototype, {
  2314. getPointSpline: SplineSeries.prototype.getPointSpline
  2315. });
  2316. SeriesRegistry.registerSeriesType('areasplinerange', AreaSplineRangeSeries);
  2317. /* *
  2318. *
  2319. * Default export
  2320. *
  2321. * */
  2322. /* *
  2323. *
  2324. * API options
  2325. *
  2326. * */
  2327. /**
  2328. * A `areasplinerange` series. If the [type](#series.areasplinerange.type)
  2329. * option is not specified, it is inherited from [chart.type](#chart.type).
  2330. *
  2331. * @extends series,plotOptions.areasplinerange
  2332. * @excluding dataParser, dataURL, stack, step, boostThreshold, boostBlending
  2333. * @product highcharts highstock
  2334. * @requires highcharts-more
  2335. * @apioption series.areasplinerange
  2336. */
  2337. /**
  2338. * @see [fillColor](#series.areasplinerange.fillColor)
  2339. * @see [fillOpacity](#series.areasplinerange.fillOpacity)
  2340. *
  2341. * @apioption series.areasplinerange.color
  2342. */
  2343. /**
  2344. * An array of data points for the series. For the `areasplinerange`
  2345. * series type, points can be given in the following ways:
  2346. *
  2347. * 1. An array of arrays with 3 or 2 values. In this case, the values correspond
  2348. * to `x,low,high`. If the first value is a string, it is applied as the name
  2349. * of the point, and the `x` value is inferred. The `x` value can also be
  2350. * omitted, in which case the inner arrays should be of length 2\. Then the
  2351. * `x` value is automatically calculated, either starting at 0 and
  2352. * incremented by 1, or from `pointStart` and `pointInterval` given in the
  2353. * series options.
  2354. * ```js
  2355. * data: [
  2356. * [0, 0, 5],
  2357. * [1, 9, 1],
  2358. * [2, 5, 2]
  2359. * ]
  2360. * ```
  2361. *
  2362. * 2. An array of objects with named values. The following snippet shows only a
  2363. * few settings, see the complete options set below. If the total number of
  2364. * data points exceeds the series'
  2365. * [turboThreshold](#series.areasplinerange.turboThreshold), this option is
  2366. * not available.
  2367. * ```js
  2368. * data: [{
  2369. * x: 1,
  2370. * low: 5,
  2371. * high: 0,
  2372. * name: "Point2",
  2373. * color: "#00FF00"
  2374. * }, {
  2375. * x: 1,
  2376. * low: 4,
  2377. * high: 1,
  2378. * name: "Point1",
  2379. * color: "#FF00FF"
  2380. * }]
  2381. * ```
  2382. *
  2383. * @sample {highcharts} highcharts/series/data-array-of-arrays/
  2384. * Arrays of numeric x and y
  2385. * @sample {highcharts} highcharts/series/data-array-of-arrays-datetime/
  2386. * Arrays of datetime x and y
  2387. * @sample {highcharts} highcharts/series/data-array-of-name-value/
  2388. * Arrays of point.name and y
  2389. * @sample {highcharts} highcharts/series/data-array-of-objects/
  2390. * Config objects
  2391. *
  2392. * @type {Array<Array<(number|string),number>|Array<(number|string),number,number>|*>}
  2393. * @extends series.arearange.data
  2394. * @product highcharts highstock
  2395. * @apioption series.areasplinerange.data
  2396. */
  2397. /**
  2398. * @see [color](#series.areasplinerange.color)
  2399. * @see [fillOpacity](#series.areasplinerange.fillOpacity)
  2400. *
  2401. * @apioption series.areasplinerange.fillColor
  2402. */
  2403. /**
  2404. * @see [color](#series.areasplinerange.color)
  2405. * @see [fillColor](#series.areasplinerange.fillColor)
  2406. *
  2407. * @default {highcharts} 0.75
  2408. * @default {highstock} 0.75
  2409. * @apioption series.areasplinerange.fillOpacity
  2410. */
  2411. ''; // adds doclets above to transpiled file
  2412. return AreaSplineRangeSeries;
  2413. });
  2414. _registerModule(_modules, 'Series/ColumnRange/ColumnRangePoint.js', [_modules['Core/Series/SeriesRegistry.js'], _modules['Core/Utilities.js']], function (SeriesRegistry, U) {
  2415. /* *
  2416. *
  2417. * (c) 2010-2021 Torstein Honsi
  2418. *
  2419. * License: www.highcharts.com/license
  2420. *
  2421. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  2422. *
  2423. * */
  2424. var __extends = (this && this.__extends) || (function () {
  2425. var extendStatics = function (d,
  2426. b) {
  2427. extendStatics = Object.setPrototypeOf ||
  2428. ({ __proto__: [] } instanceof Array && function (d,
  2429. b) { d.__proto__ = b; }) ||
  2430. function (d,
  2431. b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  2432. return extendStatics(d, b);
  2433. };
  2434. return function (d, b) {
  2435. extendStatics(d, b);
  2436. function __() { this.constructor = d; }
  2437. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  2438. };
  2439. })();
  2440. var _a = SeriesRegistry.seriesTypes,
  2441. ColumnPoint = _a.column.prototype.pointClass,
  2442. AreaRangePoint = _a.arearange.prototype.pointClass;
  2443. var extend = U.extend,
  2444. isNumber = U.isNumber;
  2445. /* *
  2446. *
  2447. * Class
  2448. *
  2449. * */
  2450. var ColumnRangePoint = /** @class */ (function (_super) {
  2451. __extends(ColumnRangePoint, _super);
  2452. function ColumnRangePoint() {
  2453. var _this = _super !== null && _super.apply(this,
  2454. arguments) || this;
  2455. _this.series = void 0;
  2456. _this.options = void 0;
  2457. _this.barX = void 0;
  2458. _this.pointWidth = void 0;
  2459. _this.shapeArgs = void 0;
  2460. _this.shapeType = void 0;
  2461. return _this;
  2462. }
  2463. ColumnRangePoint.prototype.isValid = function () {
  2464. return isNumber(this.low);
  2465. };
  2466. return ColumnRangePoint;
  2467. }(AreaRangePoint));
  2468. /* *
  2469. *
  2470. * Prototype properties
  2471. *
  2472. * */
  2473. extend(ColumnRangePoint.prototype, {
  2474. setState: ColumnPoint.prototype.setState
  2475. });
  2476. /* *
  2477. *
  2478. * Default export
  2479. *
  2480. * */
  2481. return ColumnRangePoint;
  2482. });
  2483. _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) {
  2484. /* *
  2485. *
  2486. * (c) 2010-2021 Torstein Honsi
  2487. *
  2488. * License: www.highcharts.com/license
  2489. *
  2490. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  2491. *
  2492. * */
  2493. var __extends = (this && this.__extends) || (function () {
  2494. var extendStatics = function (d,
  2495. b) {
  2496. extendStatics = Object.setPrototypeOf ||
  2497. ({ __proto__: [] } instanceof Array && function (d,
  2498. b) { d.__proto__ = b; }) ||
  2499. function (d,
  2500. b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  2501. return extendStatics(d, b);
  2502. };
  2503. return function (d, b) {
  2504. extendStatics(d, b);
  2505. function __() { this.constructor = d; }
  2506. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  2507. };
  2508. })();
  2509. var noop = H.noop;
  2510. var _a = SeriesRegistry.seriesTypes,
  2511. AreaRangeSeries = _a.arearange,
  2512. ColumnSeries = _a.column;
  2513. var columnProto = ColumnSeries.prototype;
  2514. var arearangeProto = AreaRangeSeries.prototype;
  2515. var clamp = U.clamp,
  2516. merge = U.merge,
  2517. pick = U.pick,
  2518. extend = U.extend;
  2519. /**
  2520. * The column range is a cartesian series type with higher and lower
  2521. * Y values along an X axis. To display horizontal bars, set
  2522. * [chart.inverted](#chart.inverted) to `true`.
  2523. *
  2524. * @sample {highcharts|highstock} highcharts/demo/columnrange/
  2525. * Inverted column range
  2526. *
  2527. * @extends plotOptions.column
  2528. * @since 2.3.0
  2529. * @excluding negativeColor, stacking, softThreshold, threshold
  2530. * @product highcharts highstock
  2531. * @requires highcharts-more
  2532. * @optionparent plotOptions.columnrange
  2533. */
  2534. var columnRangeOptions = {
  2535. /**
  2536. * Extended data labels for range series types. Range series data labels
  2537. * have no `x` and `y` options. Instead,
  2538. they have `xLow`,
  2539. `xHigh`,
  2540. * `yLow` and `yHigh` options to allow the higher and lower data label
  2541. * sets individually.
  2542. *
  2543. * @declare Highcharts.SeriesAreaRangeDataLabelsOptionsObject
  2544. * @extends plotOptions.arearange.dataLabels
  2545. * @since 2.3.0
  2546. * @product highcharts highstock
  2547. * @apioption plotOptions.columnrange.dataLabels
  2548. */
  2549. pointRange: null,
  2550. /** @ignore-option */
  2551. marker: null,
  2552. states: {
  2553. hover: {
  2554. /** @ignore-option */
  2555. halo: false
  2556. }
  2557. }
  2558. };
  2559. /* *
  2560. *
  2561. * Class
  2562. *
  2563. * */
  2564. /**
  2565. * The ColumnRangeSeries class
  2566. *
  2567. * @private
  2568. * @class
  2569. * @name Highcharts.seriesTypes.columnrange
  2570. *
  2571. * @augments Highcharts.Series
  2572. */
  2573. var ColumnRangeSeries = /** @class */ (function (_super) {
  2574. __extends(ColumnRangeSeries, _super);
  2575. function ColumnRangeSeries() {
  2576. /* *
  2577. *
  2578. * Static properties
  2579. *
  2580. * */
  2581. var _this = _super !== null && _super.apply(this,
  2582. arguments) || this;
  2583. /* *
  2584. *
  2585. * Properties
  2586. *
  2587. * */
  2588. _this.data = void 0;
  2589. _this.points = void 0;
  2590. _this.options = void 0;
  2591. return _this;
  2592. }
  2593. /* *
  2594. *
  2595. * Functions
  2596. *
  2597. * */
  2598. ColumnRangeSeries.prototype.setOptions = function () {
  2599. merge(true, arguments[0], { stacking: void 0 }); // #14359 Prevent side-effect from stacking.
  2600. return arearangeProto.setOptions.apply(this, arguments);
  2601. };
  2602. // eslint-disable-next-line valid-jsdoc
  2603. /**
  2604. * Translate data points from raw values x and y to plotX and plotY
  2605. * @private
  2606. */
  2607. ColumnRangeSeries.prototype.translate = function () {
  2608. var series = this,
  2609. yAxis = series.yAxis,
  2610. xAxis = series.xAxis,
  2611. startAngleRad = xAxis.startAngleRad,
  2612. start,
  2613. chart = series.chart,
  2614. isRadial = series.xAxis.isRadial,
  2615. safeDistance = Math.max(chart.chartWidth,
  2616. chart.chartHeight) + 999,
  2617. plotHigh;
  2618. // eslint-disable-next-line valid-jsdoc
  2619. /**
  2620. * Don't draw too far outside plot area (#6835)
  2621. * @private
  2622. */
  2623. function safeBounds(pixelPos) {
  2624. return clamp(pixelPos, -safeDistance, safeDistance);
  2625. }
  2626. columnProto.translate.apply(series);
  2627. // Set plotLow and plotHigh
  2628. series.points.forEach(function (point) {
  2629. var shapeArgs = point.shapeArgs,
  2630. minPointLength = series.options.minPointLength,
  2631. heightDifference,
  2632. height,
  2633. y;
  2634. point.plotHigh = plotHigh = safeBounds(yAxis.translate(point.high, 0, 1, 0, 1));
  2635. point.plotLow = safeBounds(point.plotY);
  2636. // adjust shape
  2637. y = plotHigh;
  2638. height = pick(point.rectPlotY, point.plotY) - plotHigh;
  2639. // Adjust for minPointLength
  2640. if (Math.abs(height) < minPointLength) {
  2641. heightDifference = (minPointLength - height);
  2642. height += heightDifference;
  2643. y -= heightDifference / 2;
  2644. // Adjust for negative ranges or reversed Y axis (#1457)
  2645. }
  2646. else if (height < 0) {
  2647. height *= -1;
  2648. y -= height;
  2649. }
  2650. if (isRadial) {
  2651. start = point.barX + startAngleRad;
  2652. point.shapeType = 'arc';
  2653. point.shapeArgs = series.polarArc(y + height, y, start, start + point.pointWidth);
  2654. }
  2655. else {
  2656. shapeArgs.height = height;
  2657. shapeArgs.y = y;
  2658. point.tooltipPos = chart.inverted ?
  2659. [
  2660. yAxis.len + yAxis.pos - chart.plotLeft - y -
  2661. height / 2,
  2662. xAxis.len + xAxis.pos - chart.plotTop -
  2663. shapeArgs.x - shapeArgs.width / 2,
  2664. height
  2665. ] : [
  2666. xAxis.left - chart.plotLeft + shapeArgs.x +
  2667. shapeArgs.width / 2,
  2668. yAxis.pos - chart.plotTop + y + height / 2,
  2669. height
  2670. ]; // don't inherit from column tooltip position - #3372
  2671. }
  2672. });
  2673. };
  2674. // Overrides from modules that may be loaded after this module
  2675. ColumnRangeSeries.prototype.crispCol = function () {
  2676. return columnProto.crispCol.apply(this, arguments);
  2677. };
  2678. ColumnRangeSeries.prototype.drawPoints = function () {
  2679. return columnProto.drawPoints.apply(this, arguments);
  2680. };
  2681. ColumnRangeSeries.prototype.drawTracker = function () {
  2682. return columnProto.drawTracker.apply(this, arguments);
  2683. };
  2684. ColumnRangeSeries.prototype.getColumnMetrics = function () {
  2685. return columnProto.getColumnMetrics.apply(this, arguments);
  2686. };
  2687. ColumnRangeSeries.prototype.pointAttribs = function () {
  2688. return columnProto.pointAttribs.apply(this, arguments);
  2689. };
  2690. ColumnRangeSeries.prototype.adjustForMissingColumns = function () {
  2691. return columnProto.adjustForMissingColumns.apply(this, arguments);
  2692. };
  2693. ColumnRangeSeries.prototype.animate = function () {
  2694. return columnProto.animate.apply(this, arguments);
  2695. };
  2696. ColumnRangeSeries.prototype.translate3dPoints = function () {
  2697. return columnProto.translate3dPoints.apply(this, arguments);
  2698. };
  2699. ColumnRangeSeries.prototype.translate3dShapes = function () {
  2700. return columnProto.translate3dShapes.apply(this, arguments);
  2701. };
  2702. ColumnRangeSeries.defaultOptions = merge(ColumnSeries.defaultOptions, AreaRangeSeries.defaultOptions, columnRangeOptions);
  2703. return ColumnRangeSeries;
  2704. }(AreaRangeSeries));
  2705. extend(ColumnRangeSeries.prototype, {
  2706. directTouch: true,
  2707. trackerGroups: ['group', 'dataLabelsGroup'],
  2708. drawGraph: noop,
  2709. getSymbol: noop,
  2710. polarArc: function () {
  2711. return columnProto.polarArc.apply(this, arguments);
  2712. },
  2713. pointClass: ColumnRangePoint
  2714. });
  2715. SeriesRegistry.registerSeriesType('columnrange', ColumnRangeSeries);
  2716. /* *
  2717. *
  2718. * Default export
  2719. *
  2720. * */
  2721. /* *
  2722. *
  2723. * API options
  2724. *
  2725. * */
  2726. /**
  2727. * A `columnrange` series. If the [type](#series.columnrange.type)
  2728. * option is not specified, it is inherited from
  2729. * [chart.type](#chart.type).
  2730. *
  2731. * @extends series,plotOptions.columnrange
  2732. * @excluding dataParser, dataURL, stack, stacking
  2733. * @product highcharts highstock
  2734. * @requires highcharts-more
  2735. * @apioption series.columnrange
  2736. */
  2737. /**
  2738. * An array of data points for the series. For the `columnrange` series
  2739. * type, points can be given in the following ways:
  2740. *
  2741. * 1. An array of arrays with 3 or 2 values. In this case, the values correspond
  2742. * to `x,low,high`. If the first value is a string, it is applied as the name
  2743. * of the point, and the `x` value is inferred. The `x` value can also be
  2744. * omitted, in which case the inner arrays should be of length 2\. Then the
  2745. * `x` value is automatically calculated, either starting at 0 and
  2746. * incremented by 1, or from `pointStart` and `pointInterval` given in the
  2747. * series options.
  2748. * ```js
  2749. * data: [
  2750. * [0, 4, 2],
  2751. * [1, 2, 1],
  2752. * [2, 9, 10]
  2753. * ]
  2754. * ```
  2755. *
  2756. * 2. An array of objects with named values. The following snippet shows only a
  2757. * few settings, see the complete options set below. If the total number of
  2758. * data points exceeds the series'
  2759. * [turboThreshold](#series.columnrange.turboThreshold), this option is not
  2760. * available.
  2761. * ```js
  2762. * data: [{
  2763. * x: 1,
  2764. * low: 0,
  2765. * high: 4,
  2766. * name: "Point2",
  2767. * color: "#00FF00"
  2768. * }, {
  2769. * x: 1,
  2770. * low: 5,
  2771. * high: 3,
  2772. * name: "Point1",
  2773. * color: "#FF00FF"
  2774. * }]
  2775. * ```
  2776. *
  2777. * @sample {highcharts} highcharts/series/data-array-of-arrays/
  2778. * Arrays of numeric x and y
  2779. * @sample {highcharts} highcharts/series/data-array-of-arrays-datetime/
  2780. * Arrays of datetime x and y
  2781. * @sample {highcharts} highcharts/series/data-array-of-name-value/
  2782. * Arrays of point.name and y
  2783. * @sample {highcharts} highcharts/series/data-array-of-objects/
  2784. * Config objects
  2785. *
  2786. * @type {Array<Array<(number|string),number>|Array<(number|string),number,number>|*>}
  2787. * @extends series.arearange.data
  2788. * @excluding marker
  2789. * @product highcharts highstock
  2790. * @apioption series.columnrange.data
  2791. */
  2792. /**
  2793. * @extends series.columnrange.dataLabels
  2794. * @product highcharts highstock
  2795. * @apioption series.columnrange.data.dataLabels
  2796. */
  2797. /**
  2798. * @excluding halo, lineWidth, lineWidthPlus, marker
  2799. * @product highcharts highstock
  2800. * @apioption series.columnrange.states.hover
  2801. */
  2802. /**
  2803. * @excluding halo, lineWidth, lineWidthPlus, marker
  2804. * @product highcharts highstock
  2805. * @apioption series.columnrange.states.select
  2806. */
  2807. ''; // adds doclets above into transpiled
  2808. return ColumnRangeSeries;
  2809. });
  2810. _registerModule(_modules, 'Series/ColumnPyramid/ColumnPyramidSeries.js', [_modules['Series/Column/ColumnSeries.js'], _modules['Core/Series/SeriesRegistry.js'], _modules['Core/Utilities.js']], function (ColumnSeries, SeriesRegistry, U) {
  2811. /* *
  2812. *
  2813. * (c) 2010-2021 Sebastian Bochan
  2814. *
  2815. * License: www.highcharts.com/license
  2816. *
  2817. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  2818. *
  2819. * */
  2820. var __extends = (this && this.__extends) || (function () {
  2821. var extendStatics = function (d,
  2822. b) {
  2823. extendStatics = Object.setPrototypeOf ||
  2824. ({ __proto__: [] } instanceof Array && function (d,
  2825. b) { d.__proto__ = b; }) ||
  2826. function (d,
  2827. b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  2828. return extendStatics(d, b);
  2829. };
  2830. return function (d, b) {
  2831. extendStatics(d, b);
  2832. function __() { this.constructor = d; }
  2833. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  2834. };
  2835. })();
  2836. var colProto = ColumnSeries.prototype;
  2837. var clamp = U.clamp,
  2838. extend = U.extend,
  2839. merge = U.merge,
  2840. pick = U.pick;
  2841. /**
  2842. * The ColumnPyramidSeries class
  2843. *
  2844. * @private
  2845. * @class
  2846. * @name Highcharts.seriesTypes.columnpyramid
  2847. *
  2848. * @augments Highcharts.Series
  2849. */
  2850. var ColumnPyramidSeries = /** @class */ (function (_super) {
  2851. __extends(ColumnPyramidSeries, _super);
  2852. function ColumnPyramidSeries() {
  2853. /* *
  2854. *
  2855. * Static properties
  2856. *
  2857. * */
  2858. var _this = _super !== null && _super.apply(this,
  2859. arguments) || this;
  2860. /* *
  2861. *
  2862. * Properties
  2863. *
  2864. * */
  2865. _this.data = void 0;
  2866. _this.options = void 0;
  2867. _this.points = void 0;
  2868. return _this;
  2869. }
  2870. /* *
  2871. *
  2872. * Functions
  2873. *
  2874. * */
  2875. /* eslint-disable-next-line valid-jsdoc */
  2876. /**
  2877. * Overrides the column translate method
  2878. * @private
  2879. */
  2880. ColumnPyramidSeries.prototype.translate = function () {
  2881. var series = this,
  2882. chart = series.chart,
  2883. options = series.options,
  2884. dense = series.dense =
  2885. series.closestPointRange * series.xAxis.transA < 2,
  2886. borderWidth = series.borderWidth = pick(options.borderWidth,
  2887. dense ? 0 : 1 // #3635
  2888. ),
  2889. yAxis = series.yAxis,
  2890. threshold = options.threshold,
  2891. translatedThreshold = series.translatedThreshold =
  2892. yAxis.getThreshold(threshold),
  2893. minPointLength = pick(options.minPointLength, 5),
  2894. metrics = series.getColumnMetrics(),
  2895. pointWidth = metrics.width,
  2896. // postprocessed for border width
  2897. seriesBarW = series.barW =
  2898. Math.max(pointWidth, 1 + 2 * borderWidth),
  2899. pointXOffset = series.pointXOffset = metrics.offset;
  2900. if (chart.inverted) {
  2901. translatedThreshold -= 0.5; // #3355
  2902. }
  2903. // When the pointPadding is 0,
  2904. // we want the pyramids to be packed tightly,
  2905. // so we allow individual pyramids to have individual sizes.
  2906. // When pointPadding is greater,
  2907. // we strive for equal-width columns (#2694).
  2908. if (options.pointPadding) {
  2909. seriesBarW = Math.ceil(seriesBarW);
  2910. }
  2911. colProto.translate.apply(series);
  2912. // Record the new values
  2913. series.points.forEach(function (point) {
  2914. var yBottom = pick(point.yBottom,
  2915. translatedThreshold),
  2916. safeDistance = 999 + Math.abs(yBottom),
  2917. plotY = clamp(point.plotY, -safeDistance,
  2918. yAxis.len + safeDistance),
  2919. // Don't draw too far outside plot area
  2920. // (#1303, #2241, #4264)
  2921. barX = point.plotX + pointXOffset,
  2922. barW = seriesBarW / 2,
  2923. barY = Math.min(plotY,
  2924. yBottom),
  2925. barH = Math.max(plotY,
  2926. yBottom) - barY,
  2927. stackTotal,
  2928. stackHeight,
  2929. topPointY,
  2930. topXwidth,
  2931. bottomXwidth,
  2932. invBarPos,
  2933. x1,
  2934. x2,
  2935. x3,
  2936. x4,
  2937. y1,
  2938. y2;
  2939. point.barX = barX;
  2940. point.pointWidth = pointWidth;
  2941. // Fix the tooltip on center of grouped pyramids
  2942. // (#1216, #424, #3648)
  2943. point.tooltipPos = chart.inverted ?
  2944. [
  2945. yAxis.len + yAxis.pos - chart.plotLeft - plotY,
  2946. series.xAxis.len - barX - barW,
  2947. barH
  2948. ] :
  2949. [
  2950. barX + barW,
  2951. plotY + yAxis.pos - chart.plotTop,
  2952. barH
  2953. ];
  2954. stackTotal =
  2955. threshold + (point.total || point.y);
  2956. // overwrite stacktotal (always 100 / -100)
  2957. if (options.stacking === 'percent') {
  2958. stackTotal =
  2959. threshold + (point.y < 0) ?
  2960. -100 :
  2961. 100;
  2962. }
  2963. // get the highest point (if stack, extract from total)
  2964. topPointY = yAxis.toPixels((stackTotal), true);
  2965. // calculate height of stack (in pixels)
  2966. stackHeight =
  2967. chart.plotHeight - topPointY -
  2968. (chart.plotHeight - translatedThreshold);
  2969. // topXwidth and bottomXwidth = width of lines from the center
  2970. // calculated from tanges proportion.
  2971. // Can not be a NaN #12514
  2972. topXwidth = stackHeight ? (barW * (barY - topPointY)) / stackHeight : 0;
  2973. // like topXwidth, but with height of point
  2974. bottomXwidth = stackHeight ? (barW * (barY + barH - topPointY)) / stackHeight : 0;
  2975. /*
  2976. /\
  2977. / \
  2978. x1,y1,------ x2,y1
  2979. / \
  2980. ----------
  2981. x4,y2 x3,y2
  2982. */
  2983. x1 = barX - topXwidth + barW;
  2984. x2 = barX + topXwidth + barW;
  2985. x3 = barX + bottomXwidth + barW;
  2986. x4 = barX - bottomXwidth + barW;
  2987. y1 = barY - minPointLength;
  2988. y2 = barY + barH;
  2989. if (point.y < 0) {
  2990. y1 = barY;
  2991. y2 = barY + barH + minPointLength;
  2992. }
  2993. // inverted chart
  2994. if (chart.inverted) {
  2995. invBarPos = chart.plotWidth - barY;
  2996. stackHeight = (topPointY -
  2997. (chart.plotWidth - translatedThreshold));
  2998. // proportion tanges
  2999. topXwidth = (barW *
  3000. (topPointY - invBarPos)) / stackHeight;
  3001. bottomXwidth = (barW *
  3002. (topPointY - (invBarPos - barH))) / stackHeight;
  3003. x1 = barX + barW + topXwidth; // top bottom
  3004. x2 = x1 - 2 * topXwidth; // top top
  3005. x3 = barX - bottomXwidth + barW; // bottom top
  3006. x4 = barX + bottomXwidth + barW; // bottom bottom
  3007. y1 = barY;
  3008. y2 = barY + barH - minPointLength;
  3009. if (point.y < 0) {
  3010. y2 = barY + barH + minPointLength;
  3011. }
  3012. }
  3013. // Register shape type and arguments to be used in drawPoints
  3014. point.shapeType = 'path';
  3015. point.shapeArgs = {
  3016. // args for datalabels positioning
  3017. x: x1,
  3018. y: y1,
  3019. width: x2 - x1,
  3020. height: barH,
  3021. // path of pyramid
  3022. d: [
  3023. ['M', x1, y1],
  3024. ['L', x2, y1],
  3025. ['L', x3, y2],
  3026. ['L', x4, y2],
  3027. ['Z']
  3028. ]
  3029. };
  3030. });
  3031. };
  3032. /**
  3033. * Column pyramid series display one pyramid per value along an X axis.
  3034. * To display horizontal pyramids, set [chart.inverted](#chart.inverted) to
  3035. * `true`.
  3036. *
  3037. * @sample {highcharts|highstock} highcharts/demo/column-pyramid/
  3038. * Column pyramid
  3039. * @sample {highcharts|highstock} highcharts/plotoptions/columnpyramid-stacked/
  3040. * Column pyramid stacked
  3041. * @sample {highcharts|highstock} highcharts/plotoptions/columnpyramid-inverted/
  3042. * Column pyramid inverted
  3043. *
  3044. * @extends plotOptions.column
  3045. * @since 7.0.0
  3046. * @product highcharts highstock
  3047. * @excluding boostThreshold, borderRadius, crisp, depth, edgeColor,
  3048. * edgeWidth, groupZPadding, negativeColor, softThreshold,
  3049. * threshold, zoneAxis, zones, boostBlending
  3050. * @requires highcharts-more
  3051. * @optionparent plotOptions.columnpyramid
  3052. */
  3053. ColumnPyramidSeries.defaultOptions = merge(ColumnSeries.defaultOptions, {
  3054. // Nothing here
  3055. });
  3056. return ColumnPyramidSeries;
  3057. }(ColumnSeries));
  3058. SeriesRegistry.registerSeriesType('columnpyramid', ColumnPyramidSeries);
  3059. /* *
  3060. *
  3061. * Default export
  3062. *
  3063. * */
  3064. /* *
  3065. *
  3066. * API Options
  3067. *
  3068. * */
  3069. /**
  3070. * A `columnpyramid` series. If the [type](#series.columnpyramid.type) option is
  3071. * not specified, it is inherited from [chart.type](#chart.type).
  3072. *
  3073. * @extends series,plotOptions.columnpyramid
  3074. * @excluding connectEnds, connectNulls, dashStyle, dataParser, dataURL,
  3075. * gapSize, gapUnit, linecap, lineWidth, marker, step,
  3076. * boostThreshold, boostBlending
  3077. * @product highcharts highstock
  3078. * @requires highcharts-more
  3079. * @apioption series.columnpyramid
  3080. */
  3081. /**
  3082. * @excluding halo, lineWidth, lineWidthPlus, marker
  3083. * @product highcharts highstock
  3084. * @apioption series.columnpyramid.states.hover
  3085. */
  3086. /**
  3087. * @excluding halo, lineWidth, lineWidthPlus, marker
  3088. * @product highcharts highstock
  3089. * @apioption series.columnpyramid.states.select
  3090. */
  3091. /**
  3092. * An array of data points for the series. For the `columnpyramid` series type,
  3093. * points can be given in the following ways:
  3094. *
  3095. * 1. An array of numerical values. In this case, the numerical values will be
  3096. * interpreted as `y` options. The `x` values will be automatically
  3097. * calculated, either starting at 0 and incremented by 1, or from
  3098. * `pointStart` and `pointInterval` given in the series options. If the axis
  3099. * has categories, these will be used. Example:
  3100. * ```js
  3101. * data: [0, 5, 3, 5]
  3102. * ```
  3103. *
  3104. * 2. An array of arrays with 2 values. In this case, the values correspond to
  3105. * `x,y`. If the first value is a string, it is applied as the name of the
  3106. * point, and the `x` value is inferred.
  3107. * ```js
  3108. * data: [
  3109. * [0, 6],
  3110. * [1, 2],
  3111. * [2, 6]
  3112. * ]
  3113. * ```
  3114. *
  3115. * 3. An array of objects with named values. The objects are point configuration
  3116. * objects as seen below. If the total number of data points exceeds the
  3117. * series' [turboThreshold](#series.columnpyramid.turboThreshold), this
  3118. * option is not available.
  3119. * ```js
  3120. * data: [{
  3121. * x: 1,
  3122. * y: 9,
  3123. * name: "Point2",
  3124. * color: "#00FF00"
  3125. * }, {
  3126. * x: 1,
  3127. * y: 6,
  3128. * name: "Point1",
  3129. * color: "#FF00FF"
  3130. * }]
  3131. * ```
  3132. *
  3133. * @sample {highcharts} highcharts/chart/reflow-true/
  3134. * Numerical values
  3135. * @sample {highcharts} highcharts/series/data-array-of-arrays/
  3136. * Arrays of numeric x and y
  3137. * @sample {highcharts} highcharts/series/data-array-of-arrays-datetime/
  3138. * Arrays of datetime x and y
  3139. * @sample {highcharts} highcharts/series/data-array-of-name-value/
  3140. * Arrays of point.name and y
  3141. * @sample {highcharts} highcharts/series/data-array-of-objects/
  3142. * Config objects
  3143. *
  3144. * @type {Array<number|Array<(number|string),(number|null)>|null|*>}
  3145. * @extends series.line.data
  3146. * @excluding marker
  3147. * @product highcharts highstock
  3148. * @apioption series.columnpyramid.data
  3149. */
  3150. ''; // adds doclets above to transpiled file;
  3151. return ColumnPyramidSeries;
  3152. });
  3153. _registerModule(_modules, 'Series/Gauge/GaugePoint.js', [_modules['Core/Series/SeriesRegistry.js']], function (SeriesRegistry) {
  3154. /* *
  3155. *
  3156. * (c) 2010-2021 Torstein Honsi
  3157. *
  3158. * License: www.highcharts.com/license
  3159. *
  3160. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  3161. *
  3162. * */
  3163. var __extends = (this && this.__extends) || (function () {
  3164. var extendStatics = function (d,
  3165. b) {
  3166. extendStatics = Object.setPrototypeOf ||
  3167. ({ __proto__: [] } instanceof Array && function (d,
  3168. b) { d.__proto__ = b; }) ||
  3169. function (d,
  3170. b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  3171. return extendStatics(d, b);
  3172. };
  3173. return function (d, b) {
  3174. extendStatics(d, b);
  3175. function __() { this.constructor = d; }
  3176. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  3177. };
  3178. })();
  3179. var Point = SeriesRegistry.series.prototype.pointClass;
  3180. /* *
  3181. *
  3182. * Class
  3183. *
  3184. * */
  3185. var GaugePoint = /** @class */ (function (_super) {
  3186. __extends(GaugePoint, _super);
  3187. function GaugePoint() {
  3188. /* *
  3189. *
  3190. * Properties
  3191. *
  3192. * */
  3193. var _this = _super !== null && _super.apply(this,
  3194. arguments) || this;
  3195. _this.options = void 0;
  3196. _this.series = void 0;
  3197. _this.shapeArgs = void 0;
  3198. return _this;
  3199. /* eslint-enable valid-jsdoc */
  3200. }
  3201. /* *
  3202. *
  3203. * Functions
  3204. *
  3205. * */
  3206. /* eslint-disable valid-jsdoc */
  3207. /**
  3208. * Don't do any hover colors or anything
  3209. * @private
  3210. */
  3211. GaugePoint.prototype.setState = function (state) {
  3212. this.state = state;
  3213. };
  3214. return GaugePoint;
  3215. }(Point));
  3216. /* *
  3217. *
  3218. * Default export
  3219. *
  3220. * */
  3221. return GaugePoint;
  3222. });
  3223. _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) {
  3224. /* *
  3225. *
  3226. * (c) 2010-2021 Torstein Honsi
  3227. *
  3228. * License: www.highcharts.com/license
  3229. *
  3230. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  3231. *
  3232. * */
  3233. var __extends = (this && this.__extends) || (function () {
  3234. var extendStatics = function (d,
  3235. b) {
  3236. extendStatics = Object.setPrototypeOf ||
  3237. ({ __proto__: [] } instanceof Array && function (d,
  3238. b) { d.__proto__ = b; }) ||
  3239. function (d,
  3240. b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  3241. return extendStatics(d, b);
  3242. };
  3243. return function (d, b) {
  3244. extendStatics(d, b);
  3245. function __() { this.constructor = d; }
  3246. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  3247. };
  3248. })();
  3249. var noop = H.noop;
  3250. var Series = SeriesRegistry.series,
  3251. ColumnSeries = SeriesRegistry.seriesTypes.column;
  3252. var clamp = U.clamp,
  3253. isNumber = U.isNumber,
  3254. extend = U.extend,
  3255. merge = U.merge,
  3256. pick = U.pick,
  3257. pInt = U.pInt;
  3258. /* *
  3259. *
  3260. * Class
  3261. *
  3262. * */
  3263. /**
  3264. *
  3265. * The `gauge` series type
  3266. *
  3267. * @private
  3268. * @class
  3269. * @name Highcharts.seriesTypes.map
  3270. *
  3271. * @augments Highcharts.Series
  3272. */
  3273. var GaugeSeries = /** @class */ (function (_super) {
  3274. __extends(GaugeSeries, _super);
  3275. function GaugeSeries() {
  3276. /* *
  3277. *
  3278. * Static properties
  3279. *
  3280. * */
  3281. var _this = _super !== null && _super.apply(this,
  3282. arguments) || this;
  3283. /* *
  3284. *
  3285. * Properties
  3286. *
  3287. * */
  3288. _this.data = void 0;
  3289. _this.points = void 0;
  3290. _this.options = void 0;
  3291. _this.yAxis = void 0;
  3292. return _this;
  3293. /* eslint-enable valid-jsdoc */
  3294. }
  3295. /* *
  3296. *
  3297. * Functions
  3298. *
  3299. * */
  3300. /* eslint-disable valid-jsdoc */
  3301. /**
  3302. * Calculate paths etc
  3303. * @private
  3304. */
  3305. GaugeSeries.prototype.translate = function () {
  3306. var series = this,
  3307. yAxis = series.yAxis,
  3308. options = series.options,
  3309. center = yAxis.center;
  3310. series.generatePoints();
  3311. series.points.forEach(function (point) {
  3312. var dialOptions = merge(options.dial,
  3313. point.dial),
  3314. radius = ((pInt(pick(dialOptions.radius, '80%')) * center[2]) /
  3315. 200),
  3316. baseLength = ((pInt(pick(dialOptions.baseLength, '70%')) * radius) /
  3317. 100),
  3318. rearLength = ((pInt(pick(dialOptions.rearLength, '10%')) * radius) /
  3319. 100),
  3320. baseWidth = dialOptions.baseWidth || 3,
  3321. topWidth = dialOptions.topWidth || 1,
  3322. overshoot = options.overshoot,
  3323. rotation = yAxis.startAngleRad + yAxis.translate(point.y,
  3324. null,
  3325. null,
  3326. null,
  3327. true);
  3328. // Handle the wrap and overshoot options
  3329. if (isNumber(overshoot) || options.wrap === false) {
  3330. overshoot = isNumber(overshoot) ?
  3331. (overshoot / 180 * Math.PI) : 0;
  3332. rotation = clamp(rotation, yAxis.startAngleRad - overshoot, yAxis.endAngleRad + overshoot);
  3333. }
  3334. rotation = rotation * 180 / Math.PI;
  3335. point.shapeType = 'path';
  3336. var d = dialOptions.path || [
  3337. ['M', -rearLength, -baseWidth / 2],
  3338. ['L',
  3339. baseLength, -baseWidth / 2],
  3340. ['L',
  3341. radius, -topWidth / 2],
  3342. ['L',
  3343. radius,
  3344. topWidth / 2],
  3345. ['L',
  3346. baseLength,
  3347. baseWidth / 2],
  3348. ['L', -rearLength,
  3349. baseWidth / 2],
  3350. ['Z']
  3351. ];
  3352. point.shapeArgs = {
  3353. d: d,
  3354. translateX: center[0],
  3355. translateY: center[1],
  3356. rotation: rotation
  3357. };
  3358. // Positions for data label
  3359. point.plotX = center[0];
  3360. point.plotY = center[1];
  3361. });
  3362. };
  3363. /**
  3364. * Draw the points where each point is one needle
  3365. * @private
  3366. */
  3367. GaugeSeries.prototype.drawPoints = function () {
  3368. var series = this,
  3369. chart = series.chart,
  3370. center = series.yAxis.center,
  3371. pivot = series.pivot,
  3372. options = series.options,
  3373. pivotOptions = options.pivot,
  3374. renderer = chart.renderer;
  3375. series.points.forEach(function (point) {
  3376. var graphic = point.graphic,
  3377. shapeArgs = point.shapeArgs,
  3378. d = shapeArgs.d,
  3379. dialOptions = merge(options.dial,
  3380. point.dial); // #1233
  3381. if (graphic) {
  3382. graphic.animate(shapeArgs);
  3383. shapeArgs.d = d; // animate alters it
  3384. }
  3385. else {
  3386. point.graphic =
  3387. renderer[point.shapeType](shapeArgs)
  3388. .attr({
  3389. // required by VML when animation is false
  3390. rotation: shapeArgs.rotation,
  3391. zIndex: 1
  3392. })
  3393. .addClass('highcharts-dial')
  3394. .add(series.group);
  3395. }
  3396. // Presentational attributes
  3397. if (!chart.styledMode) {
  3398. point.graphic[graphic ? 'animate' : 'attr']({
  3399. stroke: dialOptions.borderColor || 'none',
  3400. 'stroke-width': dialOptions.borderWidth || 0,
  3401. fill: dialOptions.backgroundColor ||
  3402. palette.neutralColor100
  3403. });
  3404. }
  3405. });
  3406. // Add or move the pivot
  3407. if (pivot) {
  3408. pivot.animate({
  3409. translateX: center[0],
  3410. translateY: center[1]
  3411. });
  3412. }
  3413. else {
  3414. series.pivot =
  3415. renderer.circle(0, 0, pick(pivotOptions.radius, 5))
  3416. .attr({
  3417. zIndex: 2
  3418. })
  3419. .addClass('highcharts-pivot')
  3420. .translate(center[0], center[1])
  3421. .add(series.group);
  3422. // Presentational attributes
  3423. if (!chart.styledMode) {
  3424. series.pivot.attr({
  3425. 'stroke-width': pivotOptions.borderWidth || 0,
  3426. stroke: pivotOptions.borderColor ||
  3427. palette.neutralColor20,
  3428. fill: pivotOptions.backgroundColor ||
  3429. palette.neutralColor100
  3430. });
  3431. }
  3432. }
  3433. };
  3434. /**
  3435. * Animate the arrow up from startAngle
  3436. * @private
  3437. */
  3438. GaugeSeries.prototype.animate = function (init) {
  3439. var series = this;
  3440. if (!init) {
  3441. series.points.forEach(function (point) {
  3442. var graphic = point.graphic;
  3443. if (graphic) {
  3444. // start value
  3445. graphic.attr({
  3446. rotation: series.yAxis.startAngleRad * 180 / Math.PI
  3447. });
  3448. // animate
  3449. graphic.animate({
  3450. rotation: point.shapeArgs.rotation
  3451. }, series.options.animation);
  3452. }
  3453. });
  3454. }
  3455. };
  3456. /**
  3457. * @private
  3458. */
  3459. GaugeSeries.prototype.render = function () {
  3460. this.group = this.plotGroup('group', 'series', this.visible ? 'visible' : 'hidden', this.options.zIndex, this.chart.seriesGroup);
  3461. Series.prototype.render.call(this);
  3462. this.group.clip(this.chart.clipRect);
  3463. };
  3464. /**
  3465. * Extend the basic setData method by running processData and generatePoints
  3466. * immediately, in order to access the points from the legend.
  3467. * @private
  3468. */
  3469. GaugeSeries.prototype.setData = function (data, redraw) {
  3470. Series.prototype.setData.call(this, data, false);
  3471. this.processData();
  3472. this.generatePoints();
  3473. if (pick(redraw, true)) {
  3474. this.chart.redraw();
  3475. }
  3476. };
  3477. /**
  3478. * Define hasData function for non-cartesian series.
  3479. * Returns true if the series has points at all.
  3480. * @private
  3481. */
  3482. GaugeSeries.prototype.hasData = function () {
  3483. return !!this.points.length; // != 0
  3484. };
  3485. /**
  3486. * Gauges are circular plots displaying one or more values with a dial
  3487. * pointing to values along the perimeter.
  3488. *
  3489. * @sample highcharts/demo/gauge-speedometer/
  3490. * Gauge chart
  3491. *
  3492. * @extends plotOptions.line
  3493. * @excluding animationLimit, boostThreshold, colorAxis, colorKey,
  3494. * connectEnds, connectNulls, cropThreshold, dashStyle,
  3495. * dragDrop, findNearestPointBy, getExtremesFromAll, marker,
  3496. * negativeColor, pointPlacement, shadow, softThreshold,
  3497. * stacking, states, step, threshold, turboThreshold, xAxis,
  3498. * zoneAxis, zones, dataSorting, boostBlending
  3499. * @product highcharts
  3500. * @requires highcharts-more
  3501. * @optionparent plotOptions.gauge
  3502. */
  3503. GaugeSeries.defaultOptions = merge(Series.defaultOptions, {
  3504. /**
  3505. * When this option is `true`, the dial will wrap around the axes.
  3506. * For instance, in a full-range gauge going from 0 to 360, a value
  3507. * of 400 will point to 40\. When `wrap` is `false`, the dial stops
  3508. * at 360.
  3509. *
  3510. * @see [overshoot](#plotOptions.gauge.overshoot)
  3511. *
  3512. * @type {boolean}
  3513. * @default true
  3514. * @since 3.0
  3515. * @product highcharts
  3516. * @apioption plotOptions.gauge.wrap
  3517. */
  3518. /**
  3519. * Data labels for the gauge. For gauges, the data labels are
  3520. * enabled by default and shown in a bordered box below the point.
  3521. *
  3522. * @since 2.3.0
  3523. * @product highcharts
  3524. */
  3525. dataLabels: {
  3526. borderColor: palette.neutralColor20,
  3527. borderRadius: 3,
  3528. borderWidth: 1,
  3529. crop: false,
  3530. defer: false,
  3531. enabled: true,
  3532. verticalAlign: 'top',
  3533. y: 15,
  3534. zIndex: 2
  3535. },
  3536. /**
  3537. * Options for the dial or arrow pointer of the gauge.
  3538. *
  3539. * In styled mode, the dial is styled with the
  3540. * `.highcharts-gauge-series .highcharts-dial` rule.
  3541. *
  3542. * @sample {highcharts} highcharts/css/gauge/
  3543. * Styled mode
  3544. *
  3545. * @type {*}
  3546. * @since 2.3.0
  3547. * @product highcharts
  3548. */
  3549. dial: {},
  3550. /**
  3551. * The length of the dial's base part, relative to the total radius
  3552. * or length of the dial.
  3553. *
  3554. * @sample {highcharts} highcharts/plotoptions/gauge-dial/
  3555. * Dial options demonstrated
  3556. *
  3557. * @type {string}
  3558. * @default 70%
  3559. * @since 2.3.0
  3560. * @product highcharts
  3561. * @apioption plotOptions.gauge.dial.baseLength
  3562. */
  3563. /**
  3564. * The pixel width of the base of the gauge dial. The base is the
  3565. * part closest to the pivot, defined by baseLength.
  3566. *
  3567. * @sample {highcharts} highcharts/plotoptions/gauge-dial/
  3568. * Dial options demonstrated
  3569. *
  3570. * @type {number}
  3571. * @default 3
  3572. * @since 2.3.0
  3573. * @product highcharts
  3574. * @apioption plotOptions.gauge.dial.baseWidth
  3575. */
  3576. /**
  3577. * The radius or length of the dial, in percentages relative to the
  3578. * radius of the gauge itself.
  3579. *
  3580. * @sample {highcharts} highcharts/plotoptions/gauge-dial/
  3581. * Dial options demonstrated
  3582. *
  3583. * @type {string}
  3584. * @default 80%
  3585. * @since 2.3.0
  3586. * @product highcharts
  3587. * @apioption plotOptions.gauge.dial.radius
  3588. */
  3589. /**
  3590. * The length of the dial's rear end, the part that extends out on
  3591. * the other side of the pivot. Relative to the dial's length.
  3592. *
  3593. * @sample {highcharts} highcharts/plotoptions/gauge-dial/
  3594. * Dial options demonstrated
  3595. *
  3596. * @type {string}
  3597. * @default 10%
  3598. * @since 2.3.0
  3599. * @product highcharts
  3600. * @apioption plotOptions.gauge.dial.rearLength
  3601. */
  3602. /**
  3603. * The width of the top of the dial, closest to the perimeter. The
  3604. * pivot narrows in from the base to the top.
  3605. *
  3606. * @sample {highcharts} highcharts/plotoptions/gauge-dial/
  3607. * Dial options demonstrated
  3608. *
  3609. * @type {number}
  3610. * @default 1
  3611. * @since 2.3.0
  3612. * @product highcharts
  3613. * @apioption plotOptions.gauge.dial.topWidth
  3614. */
  3615. /**
  3616. * The background or fill color of the gauge's dial.
  3617. *
  3618. * @sample {highcharts} highcharts/plotoptions/gauge-dial/
  3619. * Dial options demonstrated
  3620. *
  3621. * @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
  3622. * @default #000000
  3623. * @since 2.3.0
  3624. * @product highcharts
  3625. * @apioption plotOptions.gauge.dial.backgroundColor
  3626. */
  3627. /**
  3628. * The border color or stroke of the gauge's dial. By default, the
  3629. * borderWidth is 0, so this must be set in addition to a custom
  3630. * border color.
  3631. *
  3632. * @sample {highcharts} highcharts/plotoptions/gauge-dial/
  3633. * Dial options demonstrated
  3634. *
  3635. * @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
  3636. * @default #cccccc
  3637. * @since 2.3.0
  3638. * @product highcharts
  3639. * @apioption plotOptions.gauge.dial.borderColor
  3640. */
  3641. /**
  3642. * The width of the gauge dial border in pixels.
  3643. *
  3644. * @sample {highcharts} highcharts/plotoptions/gauge-dial/
  3645. * Dial options demonstrated
  3646. *
  3647. * @type {number}
  3648. * @default 0
  3649. * @since 2.3.0
  3650. * @product highcharts
  3651. * @apioption plotOptions.gauge.dial.borderWidth
  3652. */
  3653. /**
  3654. * Allow the dial to overshoot the end of the perimeter axis by
  3655. * this many degrees. Say if the gauge axis goes from 0 to 60, a
  3656. * value of 100, or 1000, will show 5 degrees beyond the end of the
  3657. * axis when this option is set to 5.
  3658. *
  3659. * @see [wrap](#plotOptions.gauge.wrap)
  3660. *
  3661. * @sample {highcharts} highcharts/plotoptions/gauge-overshoot/
  3662. * Allow 5 degrees overshoot
  3663. *
  3664. * @type {number}
  3665. * @since 3.0.10
  3666. * @product highcharts
  3667. * @apioption plotOptions.gauge.overshoot
  3668. */
  3669. /**
  3670. * Options for the pivot or the center point of the gauge.
  3671. *
  3672. * In styled mode, the pivot is styled with the
  3673. * `.highcharts-gauge-series .highcharts-pivot` rule.
  3674. *
  3675. * @sample {highcharts} highcharts/css/gauge/
  3676. * Styled mode
  3677. *
  3678. * @type {*}
  3679. * @since 2.3.0
  3680. * @product highcharts
  3681. */
  3682. pivot: {},
  3683. /**
  3684. * The pixel radius of the pivot.
  3685. *
  3686. * @sample {highcharts} highcharts/plotoptions/gauge-pivot/
  3687. * Pivot options demonstrated
  3688. *
  3689. * @type {number}
  3690. * @default 5
  3691. * @since 2.3.0
  3692. * @product highcharts
  3693. * @apioption plotOptions.gauge.pivot.radius
  3694. */
  3695. /**
  3696. * The border or stroke width of the pivot.
  3697. *
  3698. * @sample {highcharts} highcharts/plotoptions/gauge-pivot/
  3699. * Pivot options demonstrated
  3700. *
  3701. * @type {number}
  3702. * @default 0
  3703. * @since 2.3.0
  3704. * @product highcharts
  3705. * @apioption plotOptions.gauge.pivot.borderWidth
  3706. */
  3707. /**
  3708. * The border or stroke color of the pivot. In able to change this,
  3709. * the borderWidth must also be set to something other than the
  3710. * default 0.
  3711. *
  3712. * @sample {highcharts} highcharts/plotoptions/gauge-pivot/
  3713. * Pivot options demonstrated
  3714. *
  3715. * @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
  3716. * @default #cccccc
  3717. * @since 2.3.0
  3718. * @product highcharts
  3719. * @apioption plotOptions.gauge.pivot.borderColor
  3720. */
  3721. /**
  3722. * The background color or fill of the pivot.
  3723. *
  3724. * @sample {highcharts} highcharts/plotoptions/gauge-pivot/
  3725. * Pivot options demonstrated
  3726. *
  3727. * @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
  3728. * @default #000000
  3729. * @since 2.3.0
  3730. * @product highcharts
  3731. * @apioption plotOptions.gauge.pivot.backgroundColor
  3732. */
  3733. tooltip: {
  3734. headerFormat: ''
  3735. },
  3736. /**
  3737. * Whether to display this particular series or series type in the
  3738. * legend. Defaults to false for gauge series.
  3739. *
  3740. * @since 2.3.0
  3741. * @product highcharts
  3742. */
  3743. showInLegend: false
  3744. // Prototype members
  3745. });
  3746. return GaugeSeries;
  3747. }(Series));
  3748. extend(GaugeSeries.prototype, {
  3749. // chart.angular will be set to true when a gauge series is present,
  3750. // and this will be used on the axes
  3751. angular: true,
  3752. directTouch: true,
  3753. drawGraph: noop,
  3754. drawTracker: ColumnSeries.prototype.drawTracker,
  3755. fixedBox: true,
  3756. forceDL: true,
  3757. noSharedTooltip: true,
  3758. pointClass: GaugePoint,
  3759. trackerGroups: ['group', 'dataLabelsGroup']
  3760. });
  3761. SeriesRegistry.registerSeriesType('gauge', GaugeSeries);
  3762. /* *
  3763. *
  3764. * Default export
  3765. *
  3766. * */
  3767. /* *
  3768. *
  3769. * API options
  3770. *
  3771. * */
  3772. /**
  3773. * A `gauge` series. If the [type](#series.gauge.type) option is not
  3774. * specified, it is inherited from [chart.type](#chart.type).
  3775. *
  3776. * @extends series,plotOptions.gauge
  3777. * @excluding animationLimit, boostThreshold, connectEnds, connectNulls,
  3778. * cropThreshold, dashStyle, dataParser, dataURL, findNearestPointBy,
  3779. * getExtremesFromAll, marker, negativeColor, pointPlacement, shadow,
  3780. * softThreshold, stack, stacking, states, step, threshold,
  3781. * turboThreshold, zoneAxis, zones, dataSorting, boostBlending
  3782. * @product highcharts
  3783. * @requires highcharts-more
  3784. * @apioption series.gauge
  3785. */
  3786. /**
  3787. * An array of data points for the series. For the `gauge` series type,
  3788. * points can be given in the following ways:
  3789. *
  3790. * 1. An array of numerical values. In this case, the numerical values will be
  3791. * interpreted as `y` options. Example:
  3792. * ```js
  3793. * data: [0, 5, 3, 5]
  3794. * ```
  3795. *
  3796. * 2. An array of objects with named values. The following snippet shows only a
  3797. * few settings, see the complete options set below. If the total number of
  3798. * data points exceeds the series'
  3799. * [turboThreshold](#series.gauge.turboThreshold), this option is not
  3800. * available.
  3801. * ```js
  3802. * data: [{
  3803. * y: 6,
  3804. * name: "Point2",
  3805. * color: "#00FF00"
  3806. * }, {
  3807. * y: 8,
  3808. * name: "Point1",
  3809. * color: "#FF00FF"
  3810. * }]
  3811. * ```
  3812. *
  3813. * The typical gauge only contains a single data value.
  3814. *
  3815. * @sample {highcharts} highcharts/chart/reflow-true/
  3816. * Numerical values
  3817. * @sample {highcharts} highcharts/series/data-array-of-objects/
  3818. * Config objects
  3819. *
  3820. * @type {Array<number|null|*>}
  3821. * @extends series.line.data
  3822. * @excluding drilldown, marker, x
  3823. * @product highcharts
  3824. * @apioption series.gauge.data
  3825. */
  3826. ''; // adds the doclets above in the transpiled file
  3827. return GaugeSeries;
  3828. });
  3829. _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) {
  3830. /* *
  3831. *
  3832. * (c) 2010-2021 Torstein Honsi
  3833. *
  3834. * License: www.highcharts.com/license
  3835. *
  3836. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  3837. *
  3838. * */
  3839. var __extends = (this && this.__extends) || (function () {
  3840. var extendStatics = function (d,
  3841. b) {
  3842. extendStatics = Object.setPrototypeOf ||
  3843. ({ __proto__: [] } instanceof Array && function (d,
  3844. b) { d.__proto__ = b; }) ||
  3845. function (d,
  3846. b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  3847. return extendStatics(d, b);
  3848. };
  3849. return function (d, b) {
  3850. extendStatics(d, b);
  3851. function __() { this.constructor = d; }
  3852. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  3853. };
  3854. })();
  3855. var noop = H.noop;
  3856. var extend = U.extend,
  3857. merge = U.merge,
  3858. pick = U.pick;
  3859. /**
  3860. * The boxplot series type.
  3861. *
  3862. * @private
  3863. * @class
  3864. * @name Highcharts.seriesTypes#boxplot
  3865. *
  3866. * @augments Highcharts.Series
  3867. */
  3868. /* *
  3869. *
  3870. * Class
  3871. *
  3872. * */
  3873. var BoxPlotSeries = /** @class */ (function (_super) {
  3874. __extends(BoxPlotSeries, _super);
  3875. function BoxPlotSeries() {
  3876. /* *
  3877. *
  3878. * Static Properties
  3879. *
  3880. * */
  3881. var _this = _super !== null && _super.apply(this,
  3882. arguments) || this;
  3883. /* *
  3884. *
  3885. * Properties
  3886. *
  3887. * */
  3888. _this.data = void 0;
  3889. _this.options = void 0;
  3890. _this.points = void 0;
  3891. return _this;
  3892. }
  3893. /* *
  3894. *
  3895. * Functions
  3896. *
  3897. * */
  3898. // Get presentational attributes
  3899. BoxPlotSeries.prototype.pointAttribs = function () {
  3900. // No attributes should be set on point.graphic which is the group
  3901. return {};
  3902. };
  3903. // Translate data points from raw values x and y to plotX and plotY
  3904. BoxPlotSeries.prototype.translate = function () {
  3905. var series = this,
  3906. yAxis = series.yAxis,
  3907. pointArrayMap = series.pointArrayMap;
  3908. _super.prototype.translate.apply(series);
  3909. // do the translation on each point dimension
  3910. series.points.forEach(function (point) {
  3911. pointArrayMap.forEach(function (key) {
  3912. if (point[key] !== null) {
  3913. point[key + 'Plot'] = yAxis.translate(point[key], 0, 1, 0, 1);
  3914. }
  3915. });
  3916. point.plotHigh = point.highPlot; // For data label validation
  3917. });
  3918. };
  3919. // eslint-disable-next-line valid-jsdoc
  3920. /**
  3921. * Draw the data points
  3922. * @private
  3923. */
  3924. BoxPlotSeries.prototype.drawPoints = function () {
  3925. var series = this,
  3926. points = series.points,
  3927. options = series.options,
  3928. chart = series.chart,
  3929. renderer = chart.renderer,
  3930. q1Plot,
  3931. q3Plot,
  3932. highPlot,
  3933. lowPlot,
  3934. medianPlot,
  3935. medianPath,
  3936. crispCorr,
  3937. crispX = 0,
  3938. boxPath,
  3939. width,
  3940. left,
  3941. right,
  3942. halfWidth,
  3943. // error bar inherits this series type but doesn't do quartiles
  3944. doQuartiles = series.doQuartiles !== false,
  3945. pointWiskerLength,
  3946. whiskerLength = series.options.whiskerLength;
  3947. points.forEach(function (point) {
  3948. var graphic = point.graphic,
  3949. verb = graphic ? 'animate' : 'attr',
  3950. shapeArgs = point.shapeArgs,
  3951. boxAttr = {},
  3952. stemAttr = {},
  3953. whiskersAttr = {},
  3954. medianAttr = {},
  3955. color = point.color || series.color;
  3956. if (typeof point.plotY !== 'undefined') {
  3957. // crisp vector coordinates
  3958. width = Math.round(shapeArgs.width);
  3959. left = Math.floor(shapeArgs.x);
  3960. right = left + width;
  3961. halfWidth = Math.round(width / 2);
  3962. q1Plot = Math.floor(doQuartiles ? point.q1Plot : point.lowPlot);
  3963. q3Plot = Math.floor(doQuartiles ? point.q3Plot : point.lowPlot);
  3964. highPlot = Math.floor(point.highPlot);
  3965. lowPlot = Math.floor(point.lowPlot);
  3966. if (!graphic) {
  3967. point.graphic = graphic = renderer.g('point')
  3968. .add(series.group);
  3969. point.stem = renderer.path()
  3970. .addClass('highcharts-boxplot-stem')
  3971. .add(graphic);
  3972. if (whiskerLength) {
  3973. point.whiskers = renderer.path()
  3974. .addClass('highcharts-boxplot-whisker')
  3975. .add(graphic);
  3976. }
  3977. if (doQuartiles) {
  3978. point.box = renderer.path(boxPath)
  3979. .addClass('highcharts-boxplot-box')
  3980. .add(graphic);
  3981. }
  3982. point.medianShape = renderer.path(medianPath)
  3983. .addClass('highcharts-boxplot-median')
  3984. .add(graphic);
  3985. }
  3986. if (!chart.styledMode) {
  3987. // Stem attributes
  3988. stemAttr.stroke =
  3989. point.stemColor || options.stemColor || color;
  3990. stemAttr['stroke-width'] = pick(point.stemWidth, options.stemWidth, options.lineWidth);
  3991. stemAttr.dashstyle = (point.stemDashStyle ||
  3992. options.stemDashStyle ||
  3993. options.dashStyle);
  3994. point.stem.attr(stemAttr);
  3995. // Whiskers attributes
  3996. if (whiskerLength) {
  3997. whiskersAttr.stroke = (point.whiskerColor ||
  3998. options.whiskerColor ||
  3999. color);
  4000. whiskersAttr['stroke-width'] = pick(point.whiskerWidth, options.whiskerWidth, options.lineWidth);
  4001. whiskersAttr.dashstyle = (point.whiskerDashStyle ||
  4002. options.whiskerDashStyle ||
  4003. options.dashStyle);
  4004. point.whiskers.attr(whiskersAttr);
  4005. }
  4006. if (doQuartiles) {
  4007. boxAttr.fill = (point.fillColor ||
  4008. options.fillColor ||
  4009. color);
  4010. boxAttr.stroke = options.lineColor || color;
  4011. boxAttr['stroke-width'] = options.lineWidth || 0;
  4012. boxAttr.dashstyle = (point.boxDashStyle ||
  4013. options.boxDashStyle ||
  4014. options.dashStyle);
  4015. point.box.attr(boxAttr);
  4016. }
  4017. // Median attributes
  4018. medianAttr.stroke = (point.medianColor ||
  4019. options.medianColor ||
  4020. color);
  4021. medianAttr['stroke-width'] = pick(point.medianWidth, options.medianWidth, options.lineWidth);
  4022. medianAttr.dashstyle = (point.medianDashStyle ||
  4023. options.medianDashStyle ||
  4024. options.dashStyle);
  4025. point.medianShape.attr(medianAttr);
  4026. }
  4027. var d = void 0;
  4028. // The stem
  4029. crispCorr = (point.stem.strokeWidth() % 2) / 2;
  4030. crispX = left + halfWidth + crispCorr;
  4031. d = [
  4032. // stem up
  4033. ['M', crispX, q3Plot],
  4034. ['L', crispX, highPlot],
  4035. // stem down
  4036. ['M', crispX, q1Plot],
  4037. ['L', crispX, lowPlot]
  4038. ];
  4039. point.stem[verb]({ d: d });
  4040. // The box
  4041. if (doQuartiles) {
  4042. crispCorr = (point.box.strokeWidth() % 2) / 2;
  4043. q1Plot = Math.floor(q1Plot) + crispCorr;
  4044. q3Plot = Math.floor(q3Plot) + crispCorr;
  4045. left += crispCorr;
  4046. right += crispCorr;
  4047. d = [
  4048. ['M', left, q3Plot],
  4049. ['L', left, q1Plot],
  4050. ['L', right, q1Plot],
  4051. ['L', right, q3Plot],
  4052. ['L', left, q3Plot],
  4053. ['Z']
  4054. ];
  4055. point.box[verb]({ d: d });
  4056. }
  4057. // The whiskers
  4058. if (whiskerLength) {
  4059. crispCorr = (point.whiskers.strokeWidth() % 2) / 2;
  4060. highPlot = highPlot + crispCorr;
  4061. lowPlot = lowPlot + crispCorr;
  4062. pointWiskerLength = (/%$/).test(whiskerLength) ?
  4063. halfWidth * parseFloat(whiskerLength) / 100 :
  4064. whiskerLength / 2;
  4065. d = [
  4066. // High whisker
  4067. ['M', crispX - pointWiskerLength, highPlot],
  4068. ['L', crispX + pointWiskerLength, highPlot],
  4069. // Low whisker
  4070. ['M', crispX - pointWiskerLength, lowPlot],
  4071. ['L', crispX + pointWiskerLength, lowPlot]
  4072. ];
  4073. point.whiskers[verb]({ d: d });
  4074. }
  4075. // The median
  4076. medianPlot = Math.round(point.medianPlot);
  4077. crispCorr = (point.medianShape.strokeWidth() % 2) / 2;
  4078. medianPlot = medianPlot + crispCorr;
  4079. d = [
  4080. ['M', left, medianPlot],
  4081. ['L', right, medianPlot]
  4082. ];
  4083. point.medianShape[verb]({ d: d });
  4084. }
  4085. });
  4086. };
  4087. // return a plain array for speedy calculation
  4088. BoxPlotSeries.prototype.toYData = function (point) {
  4089. return [point.low, point.q1, point.median, point.q3, point.high];
  4090. };
  4091. /**
  4092. * A box plot is a convenient way of depicting groups of data through their
  4093. * five-number summaries: the smallest observation (sample minimum), lower
  4094. * quartile (Q1), median (Q2), upper quartile (Q3), and largest observation
  4095. * (sample maximum).
  4096. *
  4097. * @sample highcharts/demo/box-plot/
  4098. * Box plot
  4099. *
  4100. * @extends plotOptions.column
  4101. * @excluding borderColor, borderRadius, borderWidth, groupZPadding,
  4102. * states, boostThreshold, boostBlending
  4103. * @product highcharts
  4104. * @requires highcharts-more
  4105. * @optionparent plotOptions.boxplot
  4106. */
  4107. BoxPlotSeries.defaultOptions = merge(ColumnSeries.defaultOptions, {
  4108. threshold: null,
  4109. tooltip: {
  4110. pointFormat: '<span style="color:{point.color}">\u25CF</span> <b> ' +
  4111. '{series.name}</b><br/>' +
  4112. 'Maximum: {point.high}<br/>' +
  4113. 'Upper quartile: {point.q3}<br/>' +
  4114. 'Median: {point.median}<br/>' +
  4115. 'Lower quartile: {point.q1}<br/>' +
  4116. 'Minimum: {point.low}<br/>'
  4117. },
  4118. /**
  4119. * The length of the whiskers, the horizontal lines marking low and
  4120. * high values. It can be a numerical pixel value, or a percentage
  4121. * value of the box width. Set `0` to disable whiskers.
  4122. *
  4123. * @sample {highcharts} highcharts/plotoptions/box-plot-styling/
  4124. * True by default
  4125. *
  4126. * @type {number|string}
  4127. * @since 3.0
  4128. * @product highcharts
  4129. */
  4130. whiskerLength: '50%',
  4131. /**
  4132. * The fill color of the box.
  4133. *
  4134. * In styled mode, the fill color can be set with the
  4135. * `.highcharts-boxplot-box` class.
  4136. *
  4137. * @sample {highcharts} highcharts/plotoptions/box-plot-styling/
  4138. * Box plot styling
  4139. *
  4140. * @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
  4141. * @default #ffffff
  4142. * @since 3.0
  4143. * @product highcharts
  4144. */
  4145. fillColor: palette.backgroundColor,
  4146. /**
  4147. * The width of the line surrounding the box. If any of
  4148. * [stemWidth](#plotOptions.boxplot.stemWidth),
  4149. * [medianWidth](#plotOptions.boxplot.medianWidth)
  4150. * or [whiskerWidth](#plotOptions.boxplot.whiskerWidth) are `null`,
  4151. * the lineWidth also applies to these lines.
  4152. *
  4153. * @sample {highcharts} highcharts/plotoptions/box-plot-styling/
  4154. * Box plot styling
  4155. * @sample {highcharts} highcharts/plotoptions/error-bar-styling/
  4156. * Error bar styling
  4157. *
  4158. * @since 3.0
  4159. * @product highcharts
  4160. */
  4161. lineWidth: 1,
  4162. /**
  4163. * The color of the median line. If `undefined`, the general series
  4164. * color applies.
  4165. *
  4166. * In styled mode, the median stroke width can be set with the
  4167. * `.highcharts-boxplot-median` class.
  4168. *
  4169. * @sample {highcharts} highcharts/plotoptions/box-plot-styling/
  4170. * Box plot styling
  4171. * @sample {highcharts} highcharts/css/boxplot/
  4172. * Box plot in styled mode
  4173. * @sample {highcharts} highcharts/plotoptions/error-bar-styling/
  4174. * Error bar styling
  4175. *
  4176. * @type {Highcharts.ColorString|Highcharts.GradientColorObject}
  4177. * @since 3.0
  4178. * @product highcharts
  4179. * @apioption plotOptions.boxplot.medianColor
  4180. */
  4181. /**
  4182. * The pixel width of the median line. If `null`, the
  4183. * [lineWidth](#plotOptions.boxplot.lineWidth) is used.
  4184. *
  4185. * In styled mode, the median stroke width can be set with the
  4186. * `.highcharts-boxplot-median` class.
  4187. *
  4188. * @sample {highcharts} highcharts/plotoptions/box-plot-styling/
  4189. * Box plot styling
  4190. * @sample {highcharts} highcharts/css/boxplot/
  4191. * Box plot in styled mode
  4192. *
  4193. * @type {number|null}
  4194. * @since 3.0
  4195. * @product highcharts
  4196. */
  4197. medianWidth: 2,
  4198. /*
  4199. // States are not working and are removed from docs.
  4200. // Refer to: #2340
  4201. states: {
  4202. hover: {
  4203. brightness: -0.3
  4204. }
  4205. },
  4206. /**
  4207. * The color of the stem, the vertical line extending from the box to
  4208. * the whiskers. If `undefined`, the series color is used.
  4209. *
  4210. * In styled mode, the stem stroke can be set with the
  4211. * `.highcharts-boxplot-stem` class.
  4212. *
  4213. * @sample {highcharts} highcharts/plotoptions/box-plot-styling/
  4214. * Box plot styling
  4215. * @sample {highcharts} highcharts/css/boxplot/
  4216. * Box plot in styled mode
  4217. * @sample {highcharts} highcharts/plotoptions/error-bar-styling/
  4218. * Error bar styling
  4219. *
  4220. * @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
  4221. * @since 3.0
  4222. * @product highcharts
  4223. * @apioption plotOptions.boxplot.stemColor
  4224. */
  4225. /**
  4226. * The dash style of the box.
  4227. *
  4228. * @sample {highcharts} highcharts/plotoptions/box-plot-styling/
  4229. * Box plot styling
  4230. * @sample {highcharts} highcharts/css/boxplot/
  4231. * Box plot in styled mode
  4232. *
  4233. * @type {Highcharts.DashStyleValue}
  4234. * @default Solid
  4235. * @since 8.1.0
  4236. * @product highcharts
  4237. * @apioption plotOptions.boxplot.boxDashStyle
  4238. */
  4239. /**
  4240. * The dash style of the median.
  4241. *
  4242. * @sample {highcharts} highcharts/plotoptions/box-plot-styling/
  4243. * Box plot styling
  4244. * @sample {highcharts} highcharts/css/boxplot/
  4245. * Box plot in styled mode
  4246. *
  4247. * @type {Highcharts.DashStyleValue}
  4248. * @default Solid
  4249. * @since 8.1.0
  4250. * @product highcharts
  4251. * @apioption plotOptions.boxplot.medianDashStyle
  4252. */
  4253. /**
  4254. * The dash style of the stem, the vertical line extending from the
  4255. * box to the whiskers.
  4256. *
  4257. * @sample {highcharts} highcharts/plotoptions/box-plot-styling/
  4258. * Box plot styling
  4259. * @sample {highcharts} highcharts/css/boxplot/
  4260. * Box plot in styled mode
  4261. * @sample {highcharts} highcharts/plotoptions/error-bar-styling/
  4262. * Error bar styling
  4263. *
  4264. * @type {Highcharts.DashStyleValue}
  4265. * @default Solid
  4266. * @since 3.0
  4267. * @product highcharts
  4268. * @apioption plotOptions.boxplot.stemDashStyle
  4269. */
  4270. /**
  4271. * The dash style of the whiskers.
  4272. *
  4273. * @sample {highcharts} highcharts/plotoptions/box-plot-styling/
  4274. * Box plot styling
  4275. * @sample {highcharts} highcharts/css/boxplot/
  4276. * Box plot in styled mode
  4277. *
  4278. * @type {Highcharts.DashStyleValue}
  4279. * @default Solid
  4280. * @since 8.1.0
  4281. * @product highcharts
  4282. * @apioption plotOptions.boxplot.whiskerDashStyle
  4283. */
  4284. /**
  4285. * The width of the stem, the vertical line extending from the box to
  4286. * the whiskers. If `undefined`, the width is inherited from the
  4287. * [lineWidth](#plotOptions.boxplot.lineWidth) option.
  4288. *
  4289. * In styled mode, the stem stroke width can be set with the
  4290. * `.highcharts-boxplot-stem` class.
  4291. *
  4292. * @sample {highcharts} highcharts/plotoptions/box-plot-styling/
  4293. * Box plot styling
  4294. * @sample {highcharts} highcharts/css/boxplot/
  4295. * Box plot in styled mode
  4296. * @sample {highcharts} highcharts/plotoptions/error-bar-styling/
  4297. * Error bar styling
  4298. *
  4299. * @type {number}
  4300. * @since 3.0
  4301. * @product highcharts
  4302. * @apioption plotOptions.boxplot.stemWidth
  4303. */
  4304. /**
  4305. * @default high
  4306. * @apioption plotOptions.boxplot.colorKey
  4307. */
  4308. /**
  4309. * The color of the whiskers, the horizontal lines marking low and high
  4310. * values. When `undefined`, the general series color is used.
  4311. *
  4312. * In styled mode, the whisker stroke can be set with the
  4313. * `.highcharts-boxplot-whisker` class .
  4314. *
  4315. * @sample {highcharts} highcharts/plotoptions/box-plot-styling/
  4316. * Box plot styling
  4317. * @sample {highcharts} highcharts/css/boxplot/
  4318. * Box plot in styled mode
  4319. *
  4320. * @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
  4321. * @since 3.0
  4322. * @product highcharts
  4323. * @apioption plotOptions.boxplot.whiskerColor
  4324. */
  4325. /**
  4326. * The line width of the whiskers, the horizontal lines marking low and
  4327. * high values. When `undefined`, the general
  4328. * [lineWidth](#plotOptions.boxplot.lineWidth) applies.
  4329. *
  4330. * In styled mode, the whisker stroke width can be set with the
  4331. * `.highcharts-boxplot-whisker` class.
  4332. *
  4333. * @sample {highcharts} highcharts/plotoptions/box-plot-styling/
  4334. * Box plot styling
  4335. * @sample {highcharts} highcharts/css/boxplot/
  4336. * Box plot in styled mode
  4337. *
  4338. * @since 3.0
  4339. * @product highcharts
  4340. */
  4341. whiskerWidth: 2
  4342. });
  4343. return BoxPlotSeries;
  4344. }(ColumnSeries));
  4345. extend(BoxPlotSeries.prototype, {
  4346. // array point configs are mapped to this
  4347. pointArrayMap: ['low', 'q1', 'median', 'q3', 'high'],
  4348. // defines the top of the tracker
  4349. pointValKey: 'high',
  4350. // Disable data labels for box plot
  4351. drawDataLabels: noop,
  4352. setStackedPoints: noop // #3890
  4353. });
  4354. /* *
  4355. *
  4356. * Registry
  4357. *
  4358. * */
  4359. SeriesRegistry.registerSeriesType('boxplot', BoxPlotSeries);
  4360. /* *
  4361. *
  4362. * Default Export
  4363. *
  4364. * */
  4365. /* *
  4366. *
  4367. * API Options
  4368. *
  4369. * */
  4370. /**
  4371. * A `boxplot` series. If the [type](#series.boxplot.type) option is
  4372. * not specified, it is inherited from [chart.type](#chart.type).
  4373. *
  4374. * @extends series,plotOptions.boxplot
  4375. * @excluding dataParser, dataURL, marker, stack, stacking, states,
  4376. * boostThreshold, boostBlending
  4377. * @product highcharts
  4378. * @requires highcharts-more
  4379. * @apioption series.boxplot
  4380. */
  4381. /**
  4382. * An array of data points for the series. For the `boxplot` series
  4383. * type, points can be given in the following ways:
  4384. *
  4385. * 1. An array of arrays with 6 or 5 values. In this case, the values correspond
  4386. * to `x,low,q1,median,q3,high`. If the first value is a string, it is
  4387. * applied as the name of the point, and the `x` value is inferred. The `x`
  4388. * value can also be omitted, in which case the inner arrays should be of
  4389. * length 5. Then the `x` value is automatically calculated, either starting
  4390. * at 0 and incremented by 1, or from `pointStart` and `pointInterval` given
  4391. * in the series options.
  4392. * ```js
  4393. * data: [
  4394. * [0, 3, 0, 10, 3, 5],
  4395. * [1, 7, 8, 7, 2, 9],
  4396. * [2, 6, 9, 5, 1, 3]
  4397. * ]
  4398. * ```
  4399. *
  4400. * 2. An array of objects with named values. The following snippet shows only a
  4401. * few settings, see the complete options set below. If the total number of
  4402. * data points exceeds the series'
  4403. * [turboThreshold](#series.boxplot.turboThreshold), this option is not
  4404. * available.
  4405. * ```js
  4406. * data: [{
  4407. * x: 1,
  4408. * low: 4,
  4409. * q1: 9,
  4410. * median: 9,
  4411. * q3: 1,
  4412. * high: 10,
  4413. * name: "Point2",
  4414. * color: "#00FF00"
  4415. * }, {
  4416. * x: 1,
  4417. * low: 5,
  4418. * q1: 7,
  4419. * median: 3,
  4420. * q3: 6,
  4421. * high: 2,
  4422. * name: "Point1",
  4423. * color: "#FF00FF"
  4424. * }]
  4425. * ```
  4426. *
  4427. * @sample {highcharts} highcharts/series/data-array-of-arrays/
  4428. * Arrays of numeric x and y
  4429. * @sample {highcharts} highcharts/series/data-array-of-arrays-datetime/
  4430. * Arrays of datetime x and y
  4431. * @sample {highcharts} highcharts/series/data-array-of-name-value/
  4432. * Arrays of point.name and y
  4433. * @sample {highcharts} highcharts/series/data-array-of-objects/
  4434. * Config objects
  4435. *
  4436. * @type {Array<Array<(number|string),number,number,number,number>|Array<(number|string),number,number,number,number,number>|*>}
  4437. * @extends series.line.data
  4438. * @excluding marker
  4439. * @product highcharts
  4440. * @apioption series.boxplot.data
  4441. */
  4442. /**
  4443. * The `high` value for each data point, signifying the highest value
  4444. * in the sample set. The top whisker is drawn here.
  4445. *
  4446. * @type {number}
  4447. * @product highcharts
  4448. * @apioption series.boxplot.data.high
  4449. */
  4450. /**
  4451. * The `low` value for each data point, signifying the lowest value
  4452. * in the sample set. The bottom whisker is drawn here.
  4453. *
  4454. * @type {number}
  4455. * @product highcharts
  4456. * @apioption series.boxplot.data.low
  4457. */
  4458. /**
  4459. * The median for each data point. This is drawn as a line through the
  4460. * middle area of the box.
  4461. *
  4462. * @type {number}
  4463. * @product highcharts
  4464. * @apioption series.boxplot.data.median
  4465. */
  4466. /**
  4467. * The lower quartile for each data point. This is the bottom of the
  4468. * box.
  4469. *
  4470. * @type {number}
  4471. * @product highcharts
  4472. * @apioption series.boxplot.data.q1
  4473. */
  4474. /**
  4475. * The higher quartile for each data point. This is the top of the box.
  4476. *
  4477. * @type {number}
  4478. * @product highcharts
  4479. * @apioption series.boxplot.data.q3
  4480. */
  4481. /**
  4482. * The dash style of the box.
  4483. *
  4484. * @sample {highcharts} highcharts/plotoptions/box-plot-styling/
  4485. * Box plot styling
  4486. * @sample {highcharts} highcharts/css/boxplot/
  4487. * Box plot in styled mode
  4488. *
  4489. * @type {Highcharts.DashStyleValue}
  4490. * @default Solid
  4491. * @since 8.1.0
  4492. * @product highcharts
  4493. * @apioption series.boxplot.data.boxDashStyle
  4494. */
  4495. /**
  4496. * The dash style of the median.
  4497. *
  4498. * @sample {highcharts} highcharts/plotoptions/box-plot-styling/
  4499. * Box plot styling
  4500. * @sample {highcharts} highcharts/css/boxplot/
  4501. * Box plot in styled mode
  4502. *
  4503. * @type {Highcharts.DashStyleValue}
  4504. * @default Solid
  4505. * @since 8.1.0
  4506. * @product highcharts
  4507. * @apioption series.boxplot.data.medianDashStyle
  4508. */
  4509. /**
  4510. * The dash style of the stem.
  4511. *
  4512. * @sample {highcharts} highcharts/plotoptions/box-plot-styling/
  4513. * Box plot styling
  4514. * @sample {highcharts} highcharts/css/boxplot/
  4515. * Box plot in styled mode
  4516. *
  4517. * @type {Highcharts.DashStyleValue}
  4518. * @default Solid
  4519. * @since 8.1.0
  4520. * @product highcharts
  4521. * @apioption series.boxplot.data.stemDashStyle
  4522. */
  4523. /**
  4524. * The dash style of the whiskers.
  4525. *
  4526. * @sample {highcharts} highcharts/plotoptions/box-plot-styling/
  4527. * Box plot styling
  4528. * @sample {highcharts} highcharts/css/boxplot/
  4529. * Box plot in styled mode
  4530. *
  4531. * @type {Highcharts.DashStyleValue}
  4532. * @default Solid
  4533. * @since 8.1.0
  4534. * @product highcharts
  4535. * @apioption series.boxplot.data.whiskerDashStyle
  4536. */
  4537. ''; // adds doclets above to transpiled file
  4538. return BoxPlotSeries;
  4539. });
  4540. _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) {
  4541. /* *
  4542. *
  4543. * (c) 2010-2021 Torstein Honsi
  4544. *
  4545. * License: www.highcharts.com/license
  4546. *
  4547. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  4548. *
  4549. * */
  4550. var __extends = (this && this.__extends) || (function () {
  4551. var extendStatics = function (d,
  4552. b) {
  4553. extendStatics = Object.setPrototypeOf ||
  4554. ({ __proto__: [] } instanceof Array && function (d,
  4555. b) { d.__proto__ = b; }) ||
  4556. function (d,
  4557. b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  4558. return extendStatics(d, b);
  4559. };
  4560. return function (d, b) {
  4561. extendStatics(d, b);
  4562. function __() { this.constructor = d; }
  4563. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  4564. };
  4565. })();
  4566. var AreaRangeSeries = SeriesRegistry.seriesTypes.arearange;
  4567. var merge = U.merge,
  4568. extend = U.extend;
  4569. /**
  4570. * Errorbar series type
  4571. *
  4572. * @private
  4573. * @class
  4574. * @name Highcharts.seriesTypes.errorbar
  4575. *
  4576. * @augments Highcharts.Series
  4577. *
  4578. */
  4579. var ErrorBarSeries = /** @class */ (function (_super) {
  4580. __extends(ErrorBarSeries, _super);
  4581. function ErrorBarSeries() {
  4582. /* *
  4583. *
  4584. * Static properties
  4585. *
  4586. * */
  4587. var _this = _super !== null && _super.apply(this,
  4588. arguments) || this;
  4589. /* *
  4590. *
  4591. * Properties
  4592. *
  4593. * */
  4594. _this.data = void 0;
  4595. _this.options = void 0;
  4596. _this.points = void 0;
  4597. return _this;
  4598. }
  4599. /* *
  4600. *
  4601. * Functions
  4602. *
  4603. * */
  4604. // Get the width and X offset, either on top of the linked series
  4605. // column or standalone
  4606. ErrorBarSeries.prototype.getColumnMetrics = function () {
  4607. return ((this.linkedParent && this.linkedParent.columnMetrics) ||
  4608. ColumnSeries.prototype.getColumnMetrics.call(this));
  4609. };
  4610. ErrorBarSeries.prototype.drawDataLabels = function () {
  4611. var valKey = this.pointValKey;
  4612. if (AreaRangeSeries) {
  4613. AreaRangeSeries.prototype.drawDataLabels.call(this);
  4614. // Arearange drawDataLabels does not reset point.y to high,
  4615. // but to low after drawing (#4133)
  4616. this.data.forEach(function (point) {
  4617. point.y = point[valKey];
  4618. });
  4619. }
  4620. };
  4621. // return a plain array for speedy calculation
  4622. ErrorBarSeries.prototype.toYData = function (point) {
  4623. return [point.low, point.high];
  4624. };
  4625. /**
  4626. * Error bars are a graphical representation of the variability of data and
  4627. * are used on graphs to indicate the error, or uncertainty in a reported
  4628. * measurement.
  4629. *
  4630. * @sample highcharts/demo/error-bar/
  4631. * Error bars on a column series
  4632. * @sample highcharts/series-errorbar/on-scatter/
  4633. * Error bars on a scatter series
  4634. *
  4635. * @extends plotOptions.boxplot
  4636. * @excluding boostBlending, boostThreshold
  4637. * @product highcharts highstock
  4638. * @requires highcharts-more
  4639. * @optionparent plotOptions.errorbar
  4640. */
  4641. ErrorBarSeries.defaultOptions = merge(BoxPlotSeries.defaultOptions, {
  4642. /**
  4643. * The main color of the bars. This can be overridden by
  4644. * [stemColor](#plotOptions.errorbar.stemColor) and
  4645. * [whiskerColor](#plotOptions.errorbar.whiskerColor) individually.
  4646. *
  4647. * @sample {highcharts} highcharts/plotoptions/error-bar-styling/
  4648. * Error bar styling
  4649. *
  4650. * @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
  4651. * @default #000000
  4652. * @since 3.0
  4653. * @product highcharts
  4654. */
  4655. color: palette.neutralColor100,
  4656. grouping: false,
  4657. /**
  4658. * The parent series of the error bar. The default value links it to
  4659. * the previous series. Otherwise, use the id of the parent series.
  4660. *
  4661. * @since 3.0
  4662. * @product highcharts
  4663. */
  4664. linkedTo: ':previous',
  4665. tooltip: {
  4666. pointFormat: '<span style="color:{point.color}">\u25CF</span> {series.name}: <b>{point.low}</b> - <b>{point.high}</b><br/>'
  4667. },
  4668. /**
  4669. * The line width of the whiskers, the horizontal lines marking
  4670. * low and high values. When `null`, the general
  4671. * [lineWidth](#plotOptions.errorbar.lineWidth) applies.
  4672. *
  4673. * @sample {highcharts} highcharts/plotoptions/error-bar-styling/
  4674. * Error bar styling
  4675. *
  4676. * @type {number}
  4677. * @since 3.0
  4678. * @product highcharts
  4679. */
  4680. whiskerWidth: null
  4681. });
  4682. return ErrorBarSeries;
  4683. }(BoxPlotSeries));
  4684. extend(ErrorBarSeries.prototype, {
  4685. // array point configs are mapped to this
  4686. pointArrayMap: ['low', 'high'],
  4687. pointValKey: 'high',
  4688. doQuartiles: false
  4689. });
  4690. SeriesRegistry.registerSeriesType('errorbar', ErrorBarSeries);
  4691. /* *
  4692. *
  4693. * Default export
  4694. *
  4695. * */
  4696. /* *
  4697. *
  4698. * API options
  4699. *
  4700. * */
  4701. /**
  4702. * A `errorbar` series. If the [type](#series.errorbar.type) option
  4703. * is not specified, it is inherited from [chart.type](#chart.type).
  4704. *
  4705. * @extends series,plotOptions.errorbar
  4706. * @excluding dataParser, dataURL, stack, stacking, boostThreshold,
  4707. * boostBlending
  4708. * @product highcharts
  4709. * @requires highcharts-more
  4710. * @apioption series.errorbar
  4711. */
  4712. /**
  4713. * An array of data points for the series. For the `errorbar` series
  4714. * type, points can be given in the following ways:
  4715. *
  4716. * 1. An array of arrays with 3 or 2 values. In this case, the values correspond
  4717. * to `x,low,high`. If the first value is a string, it is applied as the name
  4718. * of the point, and the `x` value is inferred. The `x` value can also be
  4719. * omitted, in which case the inner arrays should be of length 2\. Then the
  4720. * `x` value is automatically calculated, either starting at 0 and
  4721. * incremented by 1, or from `pointStart` and `pointInterval` given in the
  4722. * series options.
  4723. * ```js
  4724. * data: [
  4725. * [0, 10, 2],
  4726. * [1, 1, 8],
  4727. * [2, 4, 5]
  4728. * ]
  4729. * ```
  4730. *
  4731. * 2. An array of objects with named values. The following snippet shows only a
  4732. * few settings, see the complete options set below. If the total number of
  4733. * data points exceeds the series'
  4734. * [turboThreshold](#series.errorbar.turboThreshold), this option is not
  4735. * available.
  4736. * ```js
  4737. * data: [{
  4738. * x: 1,
  4739. * low: 0,
  4740. * high: 0,
  4741. * name: "Point2",
  4742. * color: "#00FF00"
  4743. * }, {
  4744. * x: 1,
  4745. * low: 5,
  4746. * high: 5,
  4747. * name: "Point1",
  4748. * color: "#FF00FF"
  4749. * }]
  4750. * ```
  4751. *
  4752. * @sample {highcharts} highcharts/series/data-array-of-arrays/
  4753. * Arrays of numeric x and y
  4754. * @sample {highcharts} highcharts/series/data-array-of-arrays-datetime/
  4755. * Arrays of datetime x and y
  4756. * @sample {highcharts} highcharts/series/data-array-of-name-value/
  4757. * Arrays of point.name and y
  4758. * @sample {highcharts} highcharts/series/data-array-of-objects/
  4759. * Config objects
  4760. *
  4761. * @type {Array<Array<(number|string),number>|Array<(number|string),number,number>|*>}
  4762. * @extends series.arearange.data
  4763. * @excluding dataLabels, drilldown, marker, states
  4764. * @product highcharts
  4765. * @apioption series.errorbar.data
  4766. */
  4767. ''; // adds doclets above to transpiled file
  4768. return ErrorBarSeries;
  4769. });
  4770. _registerModule(_modules, 'Core/Axis/WaterfallAxis.js', [_modules['Extensions/Stacking.js'], _modules['Core/Utilities.js']], function (StackItem, U) {
  4771. /* *
  4772. *
  4773. * (c) 2010-2021 Torstein Honsi
  4774. *
  4775. * License: www.highcharts.com/license
  4776. *
  4777. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  4778. *
  4779. * */
  4780. var addEvent = U.addEvent,
  4781. objectEach = U.objectEach;
  4782. /**
  4783. * @private
  4784. */
  4785. var WaterfallAxis;
  4786. (function (WaterfallAxis) {
  4787. /* *
  4788. *
  4789. * Interfaces
  4790. *
  4791. * */
  4792. /* *
  4793. *
  4794. * Classes
  4795. *
  4796. * */
  4797. /**
  4798. * @private
  4799. */
  4800. var Composition = /** @class */ (function () {
  4801. /* eslint-disable no-invalid-this, valid-jsdoc */
  4802. /* *
  4803. *
  4804. * Constructors
  4805. *
  4806. * */
  4807. /**
  4808. * @private
  4809. */
  4810. function Composition(axis) {
  4811. this.axis = axis;
  4812. this.stacks = {
  4813. changed: false
  4814. };
  4815. }
  4816. /* *
  4817. *
  4818. * Functions
  4819. *
  4820. * */
  4821. /**
  4822. * Calls StackItem.prototype.render function that creates and renders
  4823. * stack total label for each waterfall stack item.
  4824. *
  4825. * @private
  4826. * @function Highcharts.Axis#renderWaterfallStackTotals
  4827. */
  4828. Composition.prototype.renderStackTotals = function () {
  4829. var yAxis = this.axis,
  4830. waterfallStacks = yAxis.waterfall.stacks,
  4831. stackTotalGroup = yAxis.stacking && yAxis.stacking.stackTotalGroup,
  4832. dummyStackItem = new StackItem(yAxis,
  4833. yAxis.options.stackLabels,
  4834. false, 0,
  4835. void 0);
  4836. this.dummyStackItem = dummyStackItem;
  4837. // Render each waterfall stack total
  4838. objectEach(waterfallStacks, function (type) {
  4839. objectEach(type, function (stackItem) {
  4840. dummyStackItem.total = stackItem.stackTotal;
  4841. if (stackItem.label) {
  4842. dummyStackItem.label = stackItem.label;
  4843. }
  4844. StackItem.prototype.render.call(dummyStackItem, stackTotalGroup);
  4845. stackItem.label = dummyStackItem.label;
  4846. delete dummyStackItem.label;
  4847. });
  4848. });
  4849. dummyStackItem.total = null;
  4850. };
  4851. return Composition;
  4852. }());
  4853. WaterfallAxis.Composition = Composition;
  4854. /* *
  4855. *
  4856. * Functions
  4857. *
  4858. * */
  4859. /* eslint-disable no-invalid-this, valid-jsdoc */
  4860. /**
  4861. * @private
  4862. */
  4863. function compose(AxisClass, ChartClass) {
  4864. addEvent(AxisClass, 'init', onInit);
  4865. addEvent(AxisClass, 'afterBuildStacks', onAfterBuildStacks);
  4866. addEvent(AxisClass, 'afterRender', onAfterRender);
  4867. addEvent(ChartClass, 'beforeRedraw', onBeforeRedraw);
  4868. }
  4869. WaterfallAxis.compose = compose;
  4870. /**
  4871. * @private
  4872. */
  4873. function onAfterBuildStacks() {
  4874. var axis = this;
  4875. var stacks = axis.waterfall.stacks;
  4876. if (stacks) {
  4877. stacks.changed = false;
  4878. delete stacks.alreadyChanged;
  4879. }
  4880. }
  4881. /**
  4882. * @private
  4883. */
  4884. function onAfterRender() {
  4885. var axis = this;
  4886. var stackLabelOptions = axis.options.stackLabels;
  4887. if (stackLabelOptions && stackLabelOptions.enabled &&
  4888. axis.waterfall.stacks) {
  4889. axis.waterfall.renderStackTotals();
  4890. }
  4891. }
  4892. /**
  4893. * @private
  4894. */
  4895. function onBeforeRedraw() {
  4896. var axes = this.axes,
  4897. series = this.series,
  4898. i = series.length;
  4899. while (i--) {
  4900. if (series[i].options.stacking) {
  4901. axes.forEach(function (axis) {
  4902. if (!axis.isXAxis) {
  4903. axis.waterfall.stacks.changed = true;
  4904. }
  4905. });
  4906. i = 0;
  4907. }
  4908. }
  4909. }
  4910. /**
  4911. * @private
  4912. */
  4913. function onInit() {
  4914. var axis = this;
  4915. if (!axis.waterfall) {
  4916. axis.waterfall = new Composition(axis);
  4917. }
  4918. }
  4919. })(WaterfallAxis || (WaterfallAxis = {}));
  4920. /* *
  4921. *
  4922. * Default Export
  4923. *
  4924. * */
  4925. return WaterfallAxis;
  4926. });
  4927. _registerModule(_modules, 'Series/Waterfall/WaterfallPoint.js', [_modules['Series/Column/ColumnSeries.js'], _modules['Core/Series/Point.js'], _modules['Core/Utilities.js']], function (ColumnSeries, Point, U) {
  4928. /* *
  4929. *
  4930. * (c) 2010-2021 Torstein Honsi
  4931. *
  4932. * License: www.highcharts.com/license
  4933. *
  4934. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  4935. *
  4936. * */
  4937. var __extends = (this && this.__extends) || (function () {
  4938. var extendStatics = function (d,
  4939. b) {
  4940. extendStatics = Object.setPrototypeOf ||
  4941. ({ __proto__: [] } instanceof Array && function (d,
  4942. b) { d.__proto__ = b; }) ||
  4943. function (d,
  4944. b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  4945. return extendStatics(d, b);
  4946. };
  4947. return function (d, b) {
  4948. extendStatics(d, b);
  4949. function __() { this.constructor = d; }
  4950. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  4951. };
  4952. })();
  4953. var isNumber = U.isNumber;
  4954. /* *
  4955. *
  4956. * Class
  4957. *
  4958. * */
  4959. var WaterfallPoint = /** @class */ (function (_super) {
  4960. __extends(WaterfallPoint, _super);
  4961. function WaterfallPoint() {
  4962. var _this = _super !== null && _super.apply(this,
  4963. arguments) || this;
  4964. _this.options = void 0;
  4965. _this.series = void 0;
  4966. return _this;
  4967. }
  4968. /* *
  4969. *
  4970. * Functions
  4971. *
  4972. * */
  4973. WaterfallPoint.prototype.getClassName = function () {
  4974. var className = Point.prototype.getClassName.call(this);
  4975. if (this.isSum) {
  4976. className += ' highcharts-sum';
  4977. }
  4978. else if (this.isIntermediateSum) {
  4979. className += ' highcharts-intermediate-sum';
  4980. }
  4981. return className;
  4982. };
  4983. // Pass the null test in ColumnSeries.translate.
  4984. WaterfallPoint.prototype.isValid = function () {
  4985. return (isNumber(this.y) ||
  4986. this.isSum ||
  4987. Boolean(this.isIntermediateSum));
  4988. };
  4989. return WaterfallPoint;
  4990. }(ColumnSeries.prototype.pointClass));
  4991. /* *
  4992. *
  4993. * Export
  4994. *
  4995. * */
  4996. return WaterfallPoint;
  4997. });
  4998. _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) {
  4999. /* *
  5000. *
  5001. * (c) 2010-2021 Torstein Honsi
  5002. *
  5003. * License: www.highcharts.com/license
  5004. *
  5005. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  5006. *
  5007. * */
  5008. var __extends = (this && this.__extends) || (function () {
  5009. var extendStatics = function (d,
  5010. b) {
  5011. extendStatics = Object.setPrototypeOf ||
  5012. ({ __proto__: [] } instanceof Array && function (d,
  5013. b) { d.__proto__ = b; }) ||
  5014. function (d,
  5015. b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  5016. return extendStatics(d, b);
  5017. };
  5018. return function (d, b) {
  5019. extendStatics(d, b);
  5020. function __() { this.constructor = d; }
  5021. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  5022. };
  5023. })();
  5024. var _a = SeriesRegistry.seriesTypes,
  5025. ColumnSeries = _a.column,
  5026. LineSeries = _a.line;
  5027. var arrayMax = U.arrayMax,
  5028. arrayMin = U.arrayMin,
  5029. correctFloat = U.correctFloat,
  5030. extend = U.extend,
  5031. merge = U.merge,
  5032. objectEach = U.objectEach,
  5033. pick = U.pick;
  5034. /**
  5035. * Returns true if the key is a direct property of the object.
  5036. * @private
  5037. * @param {*} obj - Object with property to test
  5038. * @param {string} key - Property key to test
  5039. * @return {boolean} - Whether it is a direct property
  5040. */
  5041. function ownProp(obj, key) {
  5042. return Object.hasOwnProperty.call(obj, key);
  5043. }
  5044. /* eslint-disable no-invalid-this, valid-jsdoc */
  5045. // eslint-disable-next-line valid-jsdoc
  5046. /**
  5047. * Waterfall series type.
  5048. *
  5049. * @private
  5050. */
  5051. var WaterfallSeries = /** @class */ (function (_super) {
  5052. __extends(WaterfallSeries, _super);
  5053. function WaterfallSeries() {
  5054. /* *
  5055. *
  5056. * Static properties
  5057. *
  5058. * */
  5059. var _this = _super !== null && _super.apply(this,
  5060. arguments) || this;
  5061. /* *
  5062. *
  5063. * Properties
  5064. *
  5065. * */
  5066. _this.chart = void 0;
  5067. _this.data = void 0;
  5068. _this.options = void 0;
  5069. _this.points = void 0;
  5070. _this.stackedYNeg = void 0;
  5071. _this.stackedYPos = void 0;
  5072. _this.stackKey = void 0;
  5073. _this.xData = void 0;
  5074. _this.yAxis = void 0;
  5075. _this.yData = void 0;
  5076. return _this;
  5077. }
  5078. /* *
  5079. *
  5080. * Functions
  5081. *
  5082. * */
  5083. // After generating points, set y-values for all sums.
  5084. WaterfallSeries.prototype.generatePoints = function () {
  5085. var point,
  5086. len,
  5087. i,
  5088. y;
  5089. // Parent call:
  5090. ColumnSeries.prototype.generatePoints.apply(this);
  5091. for (i = 0, len = this.points.length; i < len; i++) {
  5092. point = this.points[i];
  5093. y = this.processedYData[i];
  5094. // override point value for sums
  5095. // #3710 Update point does not propagate to sum
  5096. if (point.isIntermediateSum || point.isSum) {
  5097. point.y = correctFloat(y);
  5098. }
  5099. }
  5100. };
  5101. // Translate data points from raw values
  5102. WaterfallSeries.prototype.translate = function () {
  5103. var series = this,
  5104. options = series.options,
  5105. yAxis = series.yAxis,
  5106. len,
  5107. i,
  5108. points,
  5109. point,
  5110. shapeArgs,
  5111. y,
  5112. yValue,
  5113. previousY,
  5114. previousIntermediate,
  5115. range,
  5116. minPointLength = pick(options.minPointLength, 5),
  5117. halfMinPointLength = minPointLength / 2,
  5118. threshold = options.threshold,
  5119. stacking = options.stacking,
  5120. tooltipY,
  5121. actualStack = yAxis.waterfall.stacks[series.stackKey],
  5122. actualStackX,
  5123. dummyStackItem,
  5124. total,
  5125. pointY,
  5126. yPos,
  5127. hPos;
  5128. // run column series translate
  5129. ColumnSeries.prototype.translate.apply(series);
  5130. previousY = previousIntermediate = threshold;
  5131. points = series.points;
  5132. for (i = 0, len = points.length; i < len; i++) {
  5133. // cache current point object
  5134. point = points[i];
  5135. yValue = series.processedYData[i];
  5136. shapeArgs = point.shapeArgs;
  5137. range = [0, yValue];
  5138. pointY = point.y;
  5139. // code responsible for correct positions of stacked points
  5140. // starts here
  5141. if (stacking) {
  5142. if (actualStack) {
  5143. actualStackX = actualStack[i];
  5144. if (stacking === 'overlap') {
  5145. total =
  5146. actualStackX.stackState[actualStackX.stateIndex--];
  5147. y = pointY >= 0 ? total : total - pointY;
  5148. if (ownProp(actualStackX, 'absolutePos')) {
  5149. delete actualStackX.absolutePos;
  5150. }
  5151. if (ownProp(actualStackX, 'absoluteNeg')) {
  5152. delete actualStackX.absoluteNeg;
  5153. }
  5154. }
  5155. else {
  5156. if (pointY >= 0) {
  5157. total = actualStackX.threshold +
  5158. actualStackX.posTotal;
  5159. actualStackX.posTotal -= pointY;
  5160. y = total;
  5161. }
  5162. else {
  5163. total = actualStackX.threshold +
  5164. actualStackX.negTotal;
  5165. actualStackX.negTotal -= pointY;
  5166. y = total - pointY;
  5167. }
  5168. if (!actualStackX.posTotal) {
  5169. if (ownProp(actualStackX, 'absolutePos')) {
  5170. actualStackX.posTotal =
  5171. actualStackX.absolutePos;
  5172. delete actualStackX.absolutePos;
  5173. }
  5174. }
  5175. if (!actualStackX.negTotal) {
  5176. if (ownProp(actualStackX, 'absoluteNeg')) {
  5177. actualStackX.negTotal =
  5178. actualStackX.absoluteNeg;
  5179. delete actualStackX.absoluteNeg;
  5180. }
  5181. }
  5182. }
  5183. if (!point.isSum) {
  5184. // the connectorThreshold property is later used in
  5185. // getCrispPath function to draw a connector line in a
  5186. // correct place
  5187. actualStackX.connectorThreshold =
  5188. actualStackX.threshold + actualStackX.stackTotal;
  5189. }
  5190. if (yAxis.reversed) {
  5191. yPos = (pointY >= 0) ? (y - pointY) : (y + pointY);
  5192. hPos = y;
  5193. }
  5194. else {
  5195. yPos = y;
  5196. hPos = y - pointY;
  5197. }
  5198. point.below = yPos <= pick(threshold, 0);
  5199. shapeArgs.y = yAxis.translate(yPos, 0, 1, 0, 1);
  5200. shapeArgs.height = Math.abs(shapeArgs.y -
  5201. yAxis.translate(hPos, 0, 1, 0, 1));
  5202. dummyStackItem = yAxis.waterfall.dummyStackItem;
  5203. if (dummyStackItem) {
  5204. dummyStackItem.x = i;
  5205. dummyStackItem.label = actualStack[i].label;
  5206. dummyStackItem.setOffset(series.pointXOffset || 0, series.barW || 0, series.stackedYNeg[i], series.stackedYPos[i]);
  5207. }
  5208. }
  5209. }
  5210. else {
  5211. // up points
  5212. y =
  5213. Math.max(previousY, previousY + pointY) + range[0];
  5214. shapeArgs.y =
  5215. yAxis.translate(y, 0, 1, 0, 1);
  5216. // sum points
  5217. if (point.isSum) {
  5218. shapeArgs.y = yAxis.translate(range[1], 0, 1, 0, 1);
  5219. shapeArgs.height = Math.min(yAxis.translate(range[0], 0, 1, 0, 1), yAxis.len) - shapeArgs.y; // #4256
  5220. }
  5221. else if (point.isIntermediateSum) {
  5222. if (pointY >= 0) {
  5223. yPos = range[1] + previousIntermediate;
  5224. hPos = previousIntermediate;
  5225. }
  5226. else {
  5227. yPos = previousIntermediate;
  5228. hPos = range[1] + previousIntermediate;
  5229. }
  5230. if (yAxis.reversed) {
  5231. // swapping values
  5232. yPos ^= hPos;
  5233. hPos ^= yPos;
  5234. yPos ^= hPos;
  5235. }
  5236. shapeArgs.y = yAxis.translate(yPos, 0, 1, 0, 1);
  5237. shapeArgs.height = Math.abs(shapeArgs.y -
  5238. Math.min(yAxis.translate(hPos, 0, 1, 0, 1), yAxis.len));
  5239. previousIntermediate += range[1];
  5240. // If it's not the sum point, update previous stack end position
  5241. // and get shape height (#3886)
  5242. }
  5243. else {
  5244. shapeArgs.height = yValue > 0 ?
  5245. yAxis.translate(previousY, 0, 1, 0, 1) - shapeArgs.y :
  5246. yAxis.translate(previousY, 0, 1, 0, 1) - yAxis.translate(previousY - yValue, 0, 1, 0, 1);
  5247. previousY += yValue;
  5248. point.below = previousY < pick(threshold, 0);
  5249. }
  5250. // #3952 Negative sum or intermediate sum not rendered correctly
  5251. if (shapeArgs.height < 0) {
  5252. shapeArgs.y += shapeArgs.height;
  5253. shapeArgs.height *= -1;
  5254. }
  5255. }
  5256. point.plotY = shapeArgs.y =
  5257. Math.round(shapeArgs.y) - (series.borderWidth % 2) / 2;
  5258. // #3151
  5259. shapeArgs.height =
  5260. Math.max(Math.round(shapeArgs.height), 0.001);
  5261. point.yBottom = shapeArgs.y + shapeArgs.height;
  5262. if (shapeArgs.height <= minPointLength && !point.isNull) {
  5263. shapeArgs.height = minPointLength;
  5264. shapeArgs.y -= halfMinPointLength;
  5265. point.plotY = shapeArgs.y;
  5266. if (point.y < 0) {
  5267. point.minPointLengthOffset = -halfMinPointLength;
  5268. }
  5269. else {
  5270. point.minPointLengthOffset = halfMinPointLength;
  5271. }
  5272. }
  5273. else {
  5274. if (point.isNull) {
  5275. shapeArgs.width = 0;
  5276. }
  5277. point.minPointLengthOffset = 0;
  5278. }
  5279. // Correct tooltip placement (#3014)
  5280. tooltipY =
  5281. point.plotY + (point.negative ? shapeArgs.height : 0);
  5282. if (series.chart.inverted) {
  5283. point.tooltipPos[0] = yAxis.len - tooltipY;
  5284. }
  5285. else {
  5286. point.tooltipPos[1] = tooltipY;
  5287. }
  5288. }
  5289. };
  5290. // Call default processData then override yData to reflect waterfall's
  5291. // extremes on yAxis
  5292. WaterfallSeries.prototype.processData = function (force) {
  5293. var series = this,
  5294. options = series.options,
  5295. yData = series.yData,
  5296. // #3710 Update point does not propagate to sum
  5297. points = options.data,
  5298. point,
  5299. dataLength = yData.length,
  5300. threshold = options.threshold || 0,
  5301. subSum,
  5302. sum,
  5303. dataMin,
  5304. dataMax,
  5305. y,
  5306. i;
  5307. sum = subSum = dataMin = dataMax = 0;
  5308. for (i = 0; i < dataLength; i++) {
  5309. y = yData[i];
  5310. point = points && points[i] ? points[i] : {};
  5311. if (y === 'sum' || point.isSum) {
  5312. yData[i] = correctFloat(sum);
  5313. }
  5314. else if (y === 'intermediateSum' ||
  5315. point.isIntermediateSum) {
  5316. yData[i] = correctFloat(subSum);
  5317. subSum = 0;
  5318. }
  5319. else {
  5320. sum += y;
  5321. subSum += y;
  5322. }
  5323. dataMin = Math.min(sum, dataMin);
  5324. dataMax = Math.max(sum, dataMax);
  5325. }
  5326. _super.prototype.processData.call(this, force);
  5327. // Record extremes only if stacking was not set:
  5328. if (!options.stacking) {
  5329. series.dataMin = dataMin + threshold;
  5330. series.dataMax = dataMax;
  5331. }
  5332. return;
  5333. };
  5334. // Return y value or string if point is sum
  5335. WaterfallSeries.prototype.toYData = function (pt) {
  5336. if (pt.isSum) {
  5337. return 'sum';
  5338. }
  5339. if (pt.isIntermediateSum) {
  5340. return 'intermediateSum';
  5341. }
  5342. return pt.y;
  5343. };
  5344. WaterfallSeries.prototype.updateParallelArrays = function (point, i) {
  5345. _super.prototype.updateParallelArrays.call(this, point, i);
  5346. // Prevent initial sums from triggering an error (#3245, #7559)
  5347. if (this.yData[0] === 'sum' || this.yData[0] === 'intermediateSum') {
  5348. this.yData[0] = null;
  5349. }
  5350. };
  5351. // Postprocess mapping between options and SVG attributes
  5352. WaterfallSeries.prototype.pointAttribs = function (point, state) {
  5353. var upColor = this.options.upColor,
  5354. attr;
  5355. // Set or reset up color (#3710, update to negative)
  5356. if (upColor && !point.options.color) {
  5357. point.color = point.y > 0 ? upColor : null;
  5358. }
  5359. attr = ColumnSeries.prototype.pointAttribs.call(this, point, state);
  5360. // The dashStyle option in waterfall applies to the graph, not
  5361. // the points
  5362. delete attr.dashstyle;
  5363. return attr;
  5364. };
  5365. // Return an empty path initially, because we need to know the stroke-width
  5366. // in order to set the final path.
  5367. WaterfallSeries.prototype.getGraphPath = function () {
  5368. return [['M', 0, 0]];
  5369. };
  5370. // Draw columns' connector lines
  5371. WaterfallSeries.prototype.getCrispPath = function () {
  5372. var data = this.data,
  5373. yAxis = this.yAxis,
  5374. length = data.length,
  5375. graphNormalizer = Math.round(this.graph.strokeWidth()) % 2 / 2,
  5376. borderNormalizer = Math.round(this.borderWidth) % 2 / 2,
  5377. reversedXAxis = this.xAxis.reversed,
  5378. reversedYAxis = this.yAxis.reversed,
  5379. stacking = this.options.stacking,
  5380. path = [],
  5381. connectorThreshold,
  5382. prevStack,
  5383. prevStackX,
  5384. prevPoint,
  5385. yPos,
  5386. isPos,
  5387. prevArgs,
  5388. pointArgs,
  5389. i;
  5390. for (i = 1; i < length; i++) {
  5391. pointArgs = data[i].shapeArgs;
  5392. prevPoint = data[i - 1];
  5393. prevArgs = data[i - 1].shapeArgs;
  5394. prevStack = yAxis.waterfall.stacks[this.stackKey];
  5395. isPos = prevPoint.y > 0 ? -prevArgs.height : 0;
  5396. if (prevStack && prevArgs && pointArgs) {
  5397. prevStackX = prevStack[i - 1];
  5398. // y position of the connector is different when series are
  5399. // stacked, yAxis is reversed and it also depends on point's
  5400. // value
  5401. if (stacking) {
  5402. connectorThreshold = prevStackX.connectorThreshold;
  5403. yPos = Math.round((yAxis.translate(connectorThreshold, 0, 1, 0, 1) +
  5404. (reversedYAxis ? isPos : 0))) - graphNormalizer;
  5405. }
  5406. else {
  5407. yPos =
  5408. prevArgs.y + prevPoint.minPointLengthOffset +
  5409. borderNormalizer - graphNormalizer;
  5410. }
  5411. path.push([
  5412. 'M',
  5413. (prevArgs.x || 0) + (reversedXAxis ?
  5414. 0 :
  5415. (prevArgs.width || 0)),
  5416. yPos
  5417. ], [
  5418. 'L',
  5419. (pointArgs.x || 0) + (reversedXAxis ?
  5420. (pointArgs.width || 0) :
  5421. 0),
  5422. yPos
  5423. ]);
  5424. }
  5425. if (prevArgs &&
  5426. path.length &&
  5427. ((!stacking && prevPoint.y < 0 && !reversedYAxis) ||
  5428. (prevPoint.y > 0 && reversedYAxis))) {
  5429. path[path.length - 2][2] += prevArgs.height;
  5430. path[path.length - 1][2] += prevArgs.height;
  5431. }
  5432. }
  5433. return path;
  5434. };
  5435. // The graph is initially drawn with an empty definition, then updated with
  5436. // crisp rendering.
  5437. WaterfallSeries.prototype.drawGraph = function () {
  5438. LineSeries.prototype.drawGraph.call(this);
  5439. this.graph.attr({
  5440. d: this.getCrispPath()
  5441. });
  5442. };
  5443. // Waterfall has stacking along the x-values too.
  5444. WaterfallSeries.prototype.setStackedPoints = function () {
  5445. var series = this,
  5446. options = series.options,
  5447. waterfallStacks = series.yAxis.waterfall.stacks,
  5448. seriesThreshold = options.threshold,
  5449. stackThreshold = seriesThreshold || 0,
  5450. interSum = stackThreshold,
  5451. stackKey = series.stackKey,
  5452. xData = series.xData,
  5453. xLength = xData.length,
  5454. actualStack,
  5455. actualStackX,
  5456. totalYVal,
  5457. actualSum,
  5458. prevSum,
  5459. statesLen,
  5460. posTotal,
  5461. negTotal,
  5462. xPoint,
  5463. yVal,
  5464. x,
  5465. alreadyChanged,
  5466. changed;
  5467. // function responsible for calculating correct values for stackState
  5468. // array of each stack item. The arguments are: firstS - the value for
  5469. // the first state, nextS - the difference between the previous and the
  5470. // newest state, sInx - counter used in the for that updates each state
  5471. // when necessary, sOff - offset that must be added to each state when
  5472. // they need to be updated (if point isn't a total sum)
  5473. // eslint-disable-next-line require-jsdoc
  5474. function calculateStackState(firstS, nextS, sInx, sOff) {
  5475. if (!statesLen) {
  5476. actualStackX.stackState[0] = firstS;
  5477. statesLen = actualStackX.stackState.length;
  5478. }
  5479. else {
  5480. for (sInx; sInx < statesLen; sInx++) {
  5481. actualStackX.stackState[sInx] += sOff;
  5482. }
  5483. }
  5484. actualStackX.stackState.push(actualStackX.stackState[statesLen - 1] + nextS);
  5485. }
  5486. series.yAxis.stacking.usePercentage = false;
  5487. totalYVal = actualSum = prevSum = stackThreshold;
  5488. // code responsible for creating stacks for waterfall series
  5489. if (series.visible ||
  5490. !series.chart.options.chart.ignoreHiddenSeries) {
  5491. changed = waterfallStacks.changed;
  5492. alreadyChanged = waterfallStacks.alreadyChanged;
  5493. // in case of a redraw, stack for each x value must be
  5494. // emptied (only for the first series in a specific stack)
  5495. // and recalculated once more
  5496. if (alreadyChanged &&
  5497. alreadyChanged.indexOf(stackKey) < 0) {
  5498. changed = true;
  5499. }
  5500. if (!waterfallStacks[stackKey]) {
  5501. waterfallStacks[stackKey] = {};
  5502. }
  5503. actualStack = waterfallStacks[stackKey];
  5504. for (var i = 0; i < xLength; i++) {
  5505. x = xData[i];
  5506. if (!actualStack[x] || changed) {
  5507. actualStack[x] = {
  5508. negTotal: 0,
  5509. posTotal: 0,
  5510. stackTotal: 0,
  5511. threshold: 0,
  5512. stateIndex: 0,
  5513. stackState: [],
  5514. label: ((changed &&
  5515. actualStack[x]) ?
  5516. actualStack[x].label :
  5517. void 0)
  5518. };
  5519. }
  5520. actualStackX = actualStack[x];
  5521. yVal = series.yData[i];
  5522. if (yVal >= 0) {
  5523. actualStackX.posTotal += yVal;
  5524. }
  5525. else {
  5526. actualStackX.negTotal += yVal;
  5527. }
  5528. // points do not exist yet, so raw data is used
  5529. xPoint = options.data[i];
  5530. posTotal = actualStackX.absolutePos =
  5531. actualStackX.posTotal;
  5532. negTotal = actualStackX.absoluteNeg =
  5533. actualStackX.negTotal;
  5534. actualStackX.stackTotal = posTotal + negTotal;
  5535. statesLen = actualStackX.stackState.length;
  5536. if (xPoint && xPoint.isIntermediateSum) {
  5537. calculateStackState(prevSum, actualSum, 0, prevSum);
  5538. prevSum = actualSum;
  5539. actualSum = seriesThreshold;
  5540. // swapping values
  5541. stackThreshold ^= interSum;
  5542. interSum ^= stackThreshold;
  5543. stackThreshold ^= interSum;
  5544. }
  5545. else if (xPoint && xPoint.isSum) {
  5546. calculateStackState(seriesThreshold, totalYVal, statesLen);
  5547. stackThreshold = seriesThreshold;
  5548. }
  5549. else {
  5550. calculateStackState(stackThreshold, yVal, 0, totalYVal);
  5551. if (xPoint) {
  5552. totalYVal += yVal;
  5553. actualSum += yVal;
  5554. }
  5555. }
  5556. actualStackX.stateIndex++;
  5557. actualStackX.threshold = stackThreshold;
  5558. stackThreshold += actualStackX.stackTotal;
  5559. }
  5560. waterfallStacks.changed = false;
  5561. if (!waterfallStacks.alreadyChanged) {
  5562. waterfallStacks.alreadyChanged = [];
  5563. }
  5564. waterfallStacks.alreadyChanged.push(stackKey);
  5565. }
  5566. };
  5567. // Extremes for a non-stacked series are recorded in processData.
  5568. // In case of stacking, use Series.stackedYData to calculate extremes.
  5569. WaterfallSeries.prototype.getExtremes = function () {
  5570. var stacking = this.options.stacking,
  5571. yAxis,
  5572. waterfallStacks,
  5573. stackedYNeg,
  5574. stackedYPos;
  5575. if (stacking) {
  5576. yAxis = this.yAxis;
  5577. waterfallStacks = yAxis.waterfall.stacks;
  5578. stackedYNeg = this.stackedYNeg = [];
  5579. stackedYPos = this.stackedYPos = [];
  5580. // the visible y range can be different when stacking is set to
  5581. // overlap and different when it's set to normal
  5582. if (stacking === 'overlap') {
  5583. objectEach(waterfallStacks[this.stackKey], function (stackX) {
  5584. stackedYNeg.push(arrayMin(stackX.stackState));
  5585. stackedYPos.push(arrayMax(stackX.stackState));
  5586. });
  5587. }
  5588. else {
  5589. objectEach(waterfallStacks[this.stackKey], function (stackX) {
  5590. stackedYNeg.push(stackX.negTotal + stackX.threshold);
  5591. stackedYPos.push(stackX.posTotal + stackX.threshold);
  5592. });
  5593. }
  5594. return {
  5595. dataMin: arrayMin(stackedYNeg),
  5596. dataMax: arrayMax(stackedYPos)
  5597. };
  5598. }
  5599. // When not stacking, data extremes have already been computed in the
  5600. // processData function.
  5601. return {
  5602. dataMin: this.dataMin,
  5603. dataMax: this.dataMax
  5604. };
  5605. };
  5606. /**
  5607. * A waterfall chart displays sequentially introduced positive or negative
  5608. * values in cumulative columns.
  5609. *
  5610. * @sample highcharts/demo/waterfall/
  5611. * Waterfall chart
  5612. * @sample highcharts/plotoptions/waterfall-inverted/
  5613. * Horizontal (inverted) waterfall
  5614. * @sample highcharts/plotoptions/waterfall-stacked/
  5615. * Stacked waterfall chart
  5616. *
  5617. * @extends plotOptions.column
  5618. * @excluding boostThreshold, boostBlending
  5619. * @product highcharts
  5620. * @requires highcharts-more
  5621. * @optionparent plotOptions.waterfall
  5622. */
  5623. WaterfallSeries.defaultOptions = merge(ColumnSeries.defaultOptions, {
  5624. /**
  5625. * @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
  5626. * @apioption plotOptions.waterfall.color
  5627. */
  5628. /**
  5629. * The color used specifically for positive point columns. When not
  5630. * specified, the general series color is used.
  5631. *
  5632. * In styled mode, the waterfall colors can be set with the
  5633. * `.highcharts-point-negative`, `.highcharts-sum` and
  5634. * `.highcharts-intermediate-sum` classes.
  5635. *
  5636. * @sample {highcharts} highcharts/demo/waterfall/
  5637. * Waterfall
  5638. *
  5639. * @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
  5640. * @product highcharts
  5641. * @apioption plotOptions.waterfall.upColor
  5642. */
  5643. dataLabels: {
  5644. inside: true
  5645. },
  5646. /**
  5647. * The width of the line connecting waterfall columns.
  5648. *
  5649. * @product highcharts
  5650. */
  5651. lineWidth: 1,
  5652. /**
  5653. * The color of the line that connects columns in a waterfall series.
  5654. *
  5655. * In styled mode, the stroke can be set with the `.highcharts-graph`
  5656. * class.
  5657. *
  5658. * @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
  5659. * @since 3.0
  5660. * @product highcharts
  5661. */
  5662. lineColor: palette.neutralColor80,
  5663. /**
  5664. * A name for the dash style to use for the line connecting the columns
  5665. * of the waterfall series. Possible values: Dash, DashDot, Dot,
  5666. * LongDash, LongDashDot, LongDashDotDot, ShortDash, ShortDashDot,
  5667. * ShortDashDotDot, ShortDot, Solid
  5668. *
  5669. * In styled mode, the stroke dash-array can be set with the
  5670. * `.highcharts-graph` class.
  5671. *
  5672. * @type {Highcharts.DashStyleValue}
  5673. * @since 3.0
  5674. * @product highcharts
  5675. */
  5676. dashStyle: 'Dot',
  5677. /**
  5678. * The color of the border of each waterfall column.
  5679. *
  5680. * In styled mode, the border stroke can be set with the
  5681. * `.highcharts-point` class.
  5682. *
  5683. * @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
  5684. * @since 3.0
  5685. * @product highcharts
  5686. */
  5687. borderColor: palette.neutralColor80,
  5688. states: {
  5689. hover: {
  5690. lineWidthPlus: 0 // #3126
  5691. }
  5692. }
  5693. });
  5694. return WaterfallSeries;
  5695. }(ColumnSeries));
  5696. extend(WaterfallSeries.prototype, {
  5697. getZonesGraphs: LineSeries.prototype.getZonesGraphs,
  5698. pointValKey: 'y',
  5699. // Property needed to prevent lines between the columns from disappearing
  5700. // when negativeColor is used.
  5701. showLine: true,
  5702. pointClass: WaterfallPoint
  5703. });
  5704. SeriesRegistry.registerSeriesType('waterfall', WaterfallSeries);
  5705. WaterfallAxis.compose(H.Axis, Chart);
  5706. /* *
  5707. *
  5708. * Export
  5709. *
  5710. * */
  5711. /**
  5712. *
  5713. * API Options
  5714. *
  5715. */
  5716. /**
  5717. * A `waterfall` series. If the [type](#series.waterfall.type) option
  5718. * is not specified, it is inherited from [chart.type](#chart.type).
  5719. *
  5720. * @extends series,plotOptions.waterfall
  5721. * @excluding dataParser, dataURL, boostThreshold, boostBlending
  5722. * @product highcharts
  5723. * @requires highcharts-more
  5724. * @apioption series.waterfall
  5725. */
  5726. /**
  5727. * An array of data points for the series. For the `waterfall` series
  5728. * type, points can be given in the following ways:
  5729. *
  5730. * 1. An array of numerical values. In this case, the numerical values will be
  5731. * interpreted as `y` options. The `x` values will be automatically
  5732. * calculated, either starting at 0 and incremented by 1, or from
  5733. * `pointStart` and `pointInterval` given in the series options. If the axis
  5734. * has categories, these will be used. Example:
  5735. * ```js
  5736. * data: [0, 5, 3, 5]
  5737. * ```
  5738. *
  5739. * 2. An array of arrays with 2 values. In this case, the values correspond to
  5740. * `x,y`. If the first value is a string, it is applied as the name of the
  5741. * point, and the `x` value is inferred.
  5742. * ```js
  5743. * data: [
  5744. * [0, 7],
  5745. * [1, 8],
  5746. * [2, 3]
  5747. * ]
  5748. * ```
  5749. *
  5750. * 3. An array of objects with named values. The following snippet shows only a
  5751. * few settings, see the complete options set below. If the total number of
  5752. * data points exceeds the series'
  5753. * [turboThreshold](#series.waterfall.turboThreshold), this option is not
  5754. * available.
  5755. * ```js
  5756. * data: [{
  5757. * x: 1,
  5758. * y: 8,
  5759. * name: "Point2",
  5760. * color: "#00FF00"
  5761. * }, {
  5762. * x: 1,
  5763. * y: 8,
  5764. * name: "Point1",
  5765. * color: "#FF00FF"
  5766. * }]
  5767. * ```
  5768. *
  5769. * @sample {highcharts} highcharts/chart/reflow-true/
  5770. * Numerical values
  5771. * @sample {highcharts} highcharts/series/data-array-of-arrays/
  5772. * Arrays of numeric x and y
  5773. * @sample {highcharts} highcharts/series/data-array-of-arrays-datetime/
  5774. * Arrays of datetime x and y
  5775. * @sample {highcharts} highcharts/series/data-array-of-name-value/
  5776. * Arrays of point.name and y
  5777. * @sample {highcharts} highcharts/series/data-array-of-objects/
  5778. * Config objects
  5779. *
  5780. * @type {Array<number|Array<(number|string),(number|null)>|null|*>}
  5781. * @extends series.line.data
  5782. * @excluding marker
  5783. * @product highcharts
  5784. * @apioption series.waterfall.data
  5785. */
  5786. /**
  5787. * When this property is true, the points acts as a summary column for
  5788. * the values added or substracted since the last intermediate sum,
  5789. * or since the start of the series. The `y` value is ignored.
  5790. *
  5791. * @sample {highcharts} highcharts/demo/waterfall/
  5792. * Waterfall
  5793. *
  5794. * @type {boolean}
  5795. * @default false
  5796. * @product highcharts
  5797. * @apioption series.waterfall.data.isIntermediateSum
  5798. */
  5799. /**
  5800. * When this property is true, the point display the total sum across
  5801. * the entire series. The `y` value is ignored.
  5802. *
  5803. * @sample {highcharts} highcharts/demo/waterfall/
  5804. * Waterfall
  5805. *
  5806. * @type {boolean}
  5807. * @default false
  5808. * @product highcharts
  5809. * @apioption series.waterfall.data.isSum
  5810. */
  5811. ''; // adds doclets above to transpiled file
  5812. return WaterfallSeries;
  5813. });
  5814. _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) {
  5815. /* *
  5816. *
  5817. * (c) 2010-2021 Torstein Honsi
  5818. *
  5819. * License: www.highcharts.com/license
  5820. *
  5821. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  5822. *
  5823. * */
  5824. var __extends = (this && this.__extends) || (function () {
  5825. var extendStatics = function (d,
  5826. b) {
  5827. extendStatics = Object.setPrototypeOf ||
  5828. ({ __proto__: [] } instanceof Array && function (d,
  5829. b) { d.__proto__ = b; }) ||
  5830. function (d,
  5831. b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  5832. return extendStatics(d, b);
  5833. };
  5834. return function (d, b) {
  5835. extendStatics(d, b);
  5836. function __() { this.constructor = d; }
  5837. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  5838. };
  5839. })();
  5840. var noop = H.noop;
  5841. var Series = SeriesRegistry.series,
  5842. _a = SeriesRegistry.seriesTypes,
  5843. AreaSeries = _a.area,
  5844. LineSeries = _a.line,
  5845. ScatterSeries = _a.scatter;
  5846. var extend = U.extend,
  5847. merge = U.merge;
  5848. /* *
  5849. *
  5850. * Class
  5851. *
  5852. * */
  5853. var PolygonSeries = /** @class */ (function (_super) {
  5854. __extends(PolygonSeries, _super);
  5855. function PolygonSeries() {
  5856. /* *
  5857. *
  5858. * Static properties
  5859. *
  5860. * */
  5861. var _this = _super !== null && _super.apply(this,
  5862. arguments) || this;
  5863. _this.data = void 0;
  5864. _this.options = void 0;
  5865. _this.points = void 0;
  5866. return _this;
  5867. }
  5868. /* *
  5869. *
  5870. * Functions
  5871. *
  5872. * */
  5873. PolygonSeries.prototype.getGraphPath = function () {
  5874. var graphPath = LineSeries.prototype.getGraphPath.call(this),
  5875. i = graphPath.length + 1;
  5876. // Close all segments
  5877. while (i--) {
  5878. if ((i === graphPath.length || graphPath[i][0] === 'M') && i > 0) {
  5879. graphPath.splice(i, 0, ['Z']);
  5880. }
  5881. }
  5882. this.areaPath = graphPath;
  5883. return graphPath;
  5884. };
  5885. PolygonSeries.prototype.drawGraph = function () {
  5886. // Hack into the fill logic in area.drawGraph
  5887. this.options.fillColor = this.color;
  5888. AreaSeries.prototype.drawGraph.call(this);
  5889. };
  5890. /**
  5891. * A polygon series can be used to draw any freeform shape in the cartesian
  5892. * coordinate system. A fill is applied with the `color` option, and
  5893. * stroke is applied through `lineWidth` and `lineColor` options.
  5894. *
  5895. * @sample {highcharts} highcharts/demo/polygon/
  5896. * Polygon
  5897. * @sample {highstock} highcharts/demo/polygon/
  5898. * Polygon
  5899. *
  5900. * @extends plotOptions.scatter
  5901. * @since 4.1.0
  5902. * @excluding jitter, softThreshold, threshold, cluster, boostThreshold,
  5903. * boostBlending
  5904. * @product highcharts highstock
  5905. * @requires highcharts-more
  5906. * @optionparent plotOptions.polygon
  5907. */
  5908. PolygonSeries.defaultOptions = merge(ScatterSeries.defaultOptions, {
  5909. marker: {
  5910. enabled: false,
  5911. states: {
  5912. hover: {
  5913. enabled: false
  5914. }
  5915. }
  5916. },
  5917. stickyTracking: false,
  5918. tooltip: {
  5919. followPointer: true,
  5920. pointFormat: ''
  5921. },
  5922. trackByArea: true
  5923. });
  5924. return PolygonSeries;
  5925. }(ScatterSeries));
  5926. extend(PolygonSeries.prototype, {
  5927. type: 'polygon',
  5928. drawLegendSymbol: LegendSymbolMixin.drawRectangle,
  5929. drawTracker: Series.prototype.drawTracker,
  5930. setStackedPoints: noop // No stacking points on polygons (#5310)
  5931. });
  5932. SeriesRegistry.registerSeriesType('polygon', PolygonSeries);
  5933. /* *
  5934. *
  5935. * Export
  5936. *
  5937. * */
  5938. /* *
  5939. *
  5940. * API Options
  5941. *
  5942. * */
  5943. /**
  5944. * A `polygon` series. If the [type](#series.polygon.type) option is
  5945. * not specified, it is inherited from [chart.type](#chart.type).
  5946. *
  5947. * @extends series,plotOptions.polygon
  5948. * @excluding dataParser, dataURL, stack, boostThreshold, boostBlending
  5949. * @product highcharts highstock
  5950. * @requires highcharts-more
  5951. * @apioption series.polygon
  5952. */
  5953. /**
  5954. * An array of data points for the series. For the `polygon` series
  5955. * type, points can be given in the following ways:
  5956. *
  5957. * 1. An array of numerical values. In this case, the numerical values will be
  5958. * interpreted as `y` options. The `x` values will be automatically
  5959. * calculated, either starting at 0 and incremented by 1, or from
  5960. * `pointStart` and `pointInterval` given in the series options. If the axis
  5961. * has categories, these will be used. Example:
  5962. * ```js
  5963. * data: [0, 5, 3, 5]
  5964. * ```
  5965. *
  5966. * 2. An array of arrays with 2 values. In this case, the values correspond to
  5967. * `x,y`. If the first value is a string, it is applied as the name of the
  5968. * point, and the `x` value is inferred.
  5969. * ```js
  5970. * data: [
  5971. * [0, 10],
  5972. * [1, 3],
  5973. * [2, 1]
  5974. * ]
  5975. * ```
  5976. *
  5977. * 3. An array of objects with named values. The following snippet shows only a
  5978. * few settings, see the complete options set below. If the total number of
  5979. * data points exceeds the series'
  5980. * [turboThreshold](#series.polygon.turboThreshold), this option is not
  5981. * available.
  5982. * ```js
  5983. * data: [{
  5984. * x: 1,
  5985. * y: 1,
  5986. * name: "Point2",
  5987. * color: "#00FF00"
  5988. * }, {
  5989. * x: 1,
  5990. * y: 8,
  5991. * name: "Point1",
  5992. * color: "#FF00FF"
  5993. * }]
  5994. * ```
  5995. *
  5996. * @sample {highcharts} highcharts/chart/reflow-true/
  5997. * Numerical values
  5998. * @sample {highcharts} highcharts/series/data-array-of-arrays/
  5999. * Arrays of numeric x and y
  6000. * @sample {highcharts} highcharts/series/data-array-of-arrays-datetime/
  6001. * Arrays of datetime x and y
  6002. * @sample {highcharts} highcharts/series/data-array-of-name-value/
  6003. * Arrays of point.name and y
  6004. * @sample {highcharts} highcharts/series/data-array-of-objects/
  6005. * Config objects
  6006. *
  6007. * @type {Array<number|Array<(number|string),(number|null)>|null|*>}
  6008. * @extends series.line.data
  6009. * @product highcharts highstock
  6010. * @apioption series.polygon.data
  6011. */
  6012. ''; // adds doclets above to transpiled file
  6013. return PolygonSeries;
  6014. });
  6015. _registerModule(_modules, 'Series/Bubble/BubblePoint.js', [_modules['Core/Series/Point.js'], _modules['Core/Series/SeriesRegistry.js'], _modules['Core/Utilities.js']], function (Point, SeriesRegistry, U) {
  6016. /* *
  6017. *
  6018. * (c) 2010-2021 Torstein Honsi
  6019. *
  6020. * License: www.highcharts.com/license
  6021. *
  6022. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  6023. *
  6024. * */
  6025. var __extends = (this && this.__extends) || (function () {
  6026. var extendStatics = function (d,
  6027. b) {
  6028. extendStatics = Object.setPrototypeOf ||
  6029. ({ __proto__: [] } instanceof Array && function (d,
  6030. b) { d.__proto__ = b; }) ||
  6031. function (d,
  6032. b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  6033. return extendStatics(d, b);
  6034. };
  6035. return function (d, b) {
  6036. extendStatics(d, b);
  6037. function __() { this.constructor = d; }
  6038. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  6039. };
  6040. })();
  6041. var ScatterPoint = SeriesRegistry.seriesTypes.scatter.prototype.pointClass;
  6042. var extend = U.extend;
  6043. /* *
  6044. *
  6045. * Class
  6046. *
  6047. * */
  6048. var BubblePoint = /** @class */ (function (_super) {
  6049. __extends(BubblePoint, _super);
  6050. function BubblePoint() {
  6051. /* *
  6052. *
  6053. * Properties
  6054. *
  6055. * */
  6056. var _this = _super !== null && _super.apply(this,
  6057. arguments) || this;
  6058. _this.options = void 0;
  6059. _this.series = void 0;
  6060. return _this;
  6061. /* eslint-enable valid-jsdoc */
  6062. }
  6063. /* *
  6064. *
  6065. * Functions
  6066. *
  6067. * */
  6068. /* eslint-disable valid-jsdoc */
  6069. /**
  6070. * @private
  6071. */
  6072. BubblePoint.prototype.haloPath = function (size) {
  6073. return Point.prototype.haloPath.call(this,
  6074. // #6067
  6075. size === 0 ? 0 : (this.marker ? this.marker.radius || 0 : 0) + size);
  6076. };
  6077. return BubblePoint;
  6078. }(ScatterPoint));
  6079. extend(BubblePoint.prototype, {
  6080. ttBelow: false
  6081. });
  6082. /* *
  6083. *
  6084. * Default Export
  6085. *
  6086. * */
  6087. return BubblePoint;
  6088. });
  6089. _registerModule(_modules, 'Series/Bubble/BubbleLegend.js', [_modules['Core/Chart/Chart.js'], _modules['Core/Color/Color.js'], _modules['Core/Globals.js'], _modules['Core/Legend.js'], _modules['Core/Color/Palette.js'], _modules['Core/Series/Series.js'], _modules['Core/Utilities.js']], function (Chart, Color, H, Legend, palette, Series, U) {
  6090. /* *
  6091. *
  6092. * (c) 2010-2021 Highsoft AS
  6093. *
  6094. * Author: Paweł Potaczek
  6095. *
  6096. * License: www.highcharts.com/license
  6097. *
  6098. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  6099. *
  6100. * */
  6101. var color = Color.parse;
  6102. var noop = H.noop;
  6103. var addEvent = U.addEvent,
  6104. arrayMax = U.arrayMax,
  6105. arrayMin = U.arrayMin,
  6106. isNumber = U.isNumber,
  6107. merge = U.merge,
  6108. objectEach = U.objectEach,
  6109. pick = U.pick,
  6110. setOptions = U.setOptions,
  6111. stableSort = U.stableSort,
  6112. wrap = U.wrap;
  6113. /**
  6114. * @interface Highcharts.BubbleLegendFormatterContextObject
  6115. */ /**
  6116. * The center y position of the range.
  6117. * @name Highcharts.BubbleLegendFormatterContextObject#center
  6118. * @type {number}
  6119. */ /**
  6120. * The radius of the bubble range.
  6121. * @name Highcharts.BubbleLegendFormatterContextObject#radius
  6122. * @type {number}
  6123. */ /**
  6124. * The bubble value.
  6125. * @name Highcharts.BubbleLegendFormatterContextObject#value
  6126. * @type {number}
  6127. */
  6128. ''; // detach doclets above
  6129. setOptions({
  6130. legend: {
  6131. /**
  6132. * The bubble legend is an additional element in legend which
  6133. * presents the scale of the bubble series. Individual bubble ranges
  6134. * can be defined by user or calculated from series. In the case of
  6135. * automatically calculated ranges, a 1px margin of error is
  6136. * permitted.
  6137. *
  6138. * @since 7.0.0
  6139. * @product highcharts highstock highmaps
  6140. * @requires highcharts-more
  6141. * @optionparent legend.bubbleLegend
  6142. */
  6143. bubbleLegend: {
  6144. /**
  6145. * The color of the ranges borders, can be also defined for an
  6146. * individual range.
  6147. *
  6148. * @sample highcharts/bubble-legend/similartoseries/
  6149. * Similar look to the bubble series
  6150. * @sample highcharts/bubble-legend/bordercolor/
  6151. * Individual bubble border color
  6152. *
  6153. * @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
  6154. */
  6155. borderColor: void 0,
  6156. /**
  6157. * The width of the ranges borders in pixels, can be also
  6158. * defined for an individual range.
  6159. */
  6160. borderWidth: 2,
  6161. /**
  6162. * An additional class name to apply to the bubble legend'
  6163. * circle graphical elements. This option does not replace
  6164. * default class names of the graphical element.
  6165. *
  6166. * @sample {highcharts} highcharts/css/bubble-legend/
  6167. * Styling by CSS
  6168. *
  6169. * @type {string}
  6170. */
  6171. className: void 0,
  6172. /**
  6173. * The main color of the bubble legend. Applies to ranges, if
  6174. * individual color is not defined.
  6175. *
  6176. * @sample highcharts/bubble-legend/similartoseries/
  6177. * Similar look to the bubble series
  6178. * @sample highcharts/bubble-legend/color/
  6179. * Individual bubble color
  6180. *
  6181. * @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
  6182. */
  6183. color: void 0,
  6184. /**
  6185. * An additional class name to apply to the bubble legend's
  6186. * connector graphical elements. This option does not replace
  6187. * default class names of the graphical element.
  6188. *
  6189. * @sample {highcharts} highcharts/css/bubble-legend/
  6190. * Styling by CSS
  6191. *
  6192. * @type {string}
  6193. */
  6194. connectorClassName: void 0,
  6195. /**
  6196. * The color of the connector, can be also defined
  6197. * for an individual range.
  6198. *
  6199. * @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
  6200. */
  6201. connectorColor: void 0,
  6202. /**
  6203. * The length of the connectors in pixels. If labels are
  6204. * centered, the distance is reduced to 0.
  6205. *
  6206. * @sample highcharts/bubble-legend/connectorandlabels/
  6207. * Increased connector length
  6208. */
  6209. connectorDistance: 60,
  6210. /**
  6211. * The width of the connectors in pixels.
  6212. *
  6213. * @sample highcharts/bubble-legend/connectorandlabels/
  6214. * Increased connector width
  6215. */
  6216. connectorWidth: 1,
  6217. /**
  6218. * Enable or disable the bubble legend.
  6219. */
  6220. enabled: false,
  6221. /**
  6222. * Options for the bubble legend labels.
  6223. */
  6224. labels: {
  6225. /**
  6226. * An additional class name to apply to the bubble legend
  6227. * label graphical elements. This option does not replace
  6228. * default class names of the graphical element.
  6229. *
  6230. * @sample {highcharts} highcharts/css/bubble-legend/
  6231. * Styling by CSS
  6232. *
  6233. * @type {string}
  6234. */
  6235. className: void 0,
  6236. /**
  6237. * Whether to allow data labels to overlap.
  6238. */
  6239. allowOverlap: false,
  6240. /**
  6241. * A format string for the bubble legend labels. Available
  6242. * variables are the same as for `formatter`.
  6243. *
  6244. * @sample highcharts/bubble-legend/format/
  6245. * Add a unit
  6246. *
  6247. * @type {string}
  6248. */
  6249. format: '',
  6250. /**
  6251. * Available `this` properties are:
  6252. *
  6253. * - `this.value`: The bubble value.
  6254. *
  6255. * - `this.radius`: The radius of the bubble range.
  6256. *
  6257. * - `this.center`: The center y position of the range.
  6258. *
  6259. * @type {Highcharts.FormatterCallbackFunction<Highcharts.BubbleLegendFormatterContextObject>}
  6260. */
  6261. formatter: void 0,
  6262. /**
  6263. * The alignment of the labels compared to the bubble
  6264. * legend. Can be one of `left`, `center` or `right`.
  6265. *
  6266. * @sample highcharts/bubble-legend/connectorandlabels/
  6267. * Labels on left
  6268. *
  6269. * @type {Highcharts.AlignValue}
  6270. */
  6271. align: 'right',
  6272. /**
  6273. * CSS styles for the labels.
  6274. *
  6275. * @type {Highcharts.CSSObject}
  6276. */
  6277. style: {
  6278. /** @ignore-option */
  6279. fontSize: 10,
  6280. /** @ignore-option */
  6281. color: void 0
  6282. },
  6283. /**
  6284. * The x position offset of the label relative to the
  6285. * connector.
  6286. */
  6287. x: 0,
  6288. /**
  6289. * The y position offset of the label relative to the
  6290. * connector.
  6291. */
  6292. y: 0
  6293. },
  6294. /**
  6295. * Miximum bubble legend range size. If values for ranges are
  6296. * not specified, the `minSize` and the `maxSize` are calculated
  6297. * from bubble series.
  6298. */
  6299. maxSize: 60,
  6300. /**
  6301. * Minimum bubble legend range size. If values for ranges are
  6302. * not specified, the `minSize` and the `maxSize` are calculated
  6303. * from bubble series.
  6304. */
  6305. minSize: 10,
  6306. /**
  6307. * The position of the bubble legend in the legend.
  6308. * @sample highcharts/bubble-legend/connectorandlabels/
  6309. * Bubble legend as last item in legend
  6310. */
  6311. legendIndex: 0,
  6312. /**
  6313. * Options for specific range. One range consists of bubble,
  6314. * label and connector.
  6315. *
  6316. * @sample highcharts/bubble-legend/ranges/
  6317. * Manually defined ranges
  6318. * @sample highcharts/bubble-legend/autoranges/
  6319. * Auto calculated ranges
  6320. *
  6321. * @type {Array<*>}
  6322. */
  6323. ranges: {
  6324. /**
  6325. * Range size value, similar to bubble Z data.
  6326. * @type {number}
  6327. */
  6328. value: void 0,
  6329. /**
  6330. * The color of the border for individual range.
  6331. * @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
  6332. */
  6333. borderColor: void 0,
  6334. /**
  6335. * The color of the bubble for individual range.
  6336. * @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
  6337. */
  6338. color: void 0,
  6339. /**
  6340. * The color of the connector for individual range.
  6341. * @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
  6342. */
  6343. connectorColor: void 0
  6344. },
  6345. /**
  6346. * Whether the bubble legend range value should be represented
  6347. * by the area or the width of the bubble. The default, area,
  6348. * corresponds best to the human perception of the size of each
  6349. * bubble.
  6350. *
  6351. * @sample highcharts/bubble-legend/ranges/
  6352. * Size by width
  6353. *
  6354. * @type {Highcharts.BubbleSizeByValue}
  6355. */
  6356. sizeBy: 'area',
  6357. /**
  6358. * When this is true, the absolute value of z determines the
  6359. * size of the bubble. This means that with the default
  6360. * zThreshold of 0, a bubble of value -1 will have the same size
  6361. * as a bubble of value 1, while a bubble of value 0 will have a
  6362. * smaller size according to minSize.
  6363. */
  6364. sizeByAbsoluteValue: false,
  6365. /**
  6366. * Define the visual z index of the bubble legend.
  6367. */
  6368. zIndex: 1,
  6369. /**
  6370. * Ranges with with lower value than zThreshold, are skipped.
  6371. */
  6372. zThreshold: 0
  6373. }
  6374. }
  6375. });
  6376. /* eslint-disable no-invalid-this, valid-jsdoc */
  6377. /**
  6378. * BubbleLegend class.
  6379. *
  6380. * @private
  6381. * @class
  6382. * @name Highcharts.BubbleLegend
  6383. * @param {Highcharts.LegendBubbleLegendOptions} options
  6384. * Bubble legend options
  6385. * @param {Highcharts.Legend} legend
  6386. * Legend
  6387. */
  6388. var BubbleLegend = /** @class */ (function () {
  6389. function BubbleLegend(options, legend) {
  6390. this.chart = void 0;
  6391. this.fontMetrics = void 0;
  6392. this.legend = void 0;
  6393. this.legendGroup = void 0;
  6394. this.legendItem = void 0;
  6395. this.legendItemHeight = void 0;
  6396. this.legendItemWidth = void 0;
  6397. this.legendSymbol = void 0;
  6398. this.maxLabel = void 0;
  6399. this.movementX = void 0;
  6400. this.ranges = void 0;
  6401. this.visible = void 0;
  6402. this.symbols = void 0;
  6403. this.options = void 0;
  6404. this.setState = noop;
  6405. this.init(options, legend);
  6406. }
  6407. /**
  6408. * Create basic bubbleLegend properties similar to item in legend.
  6409. *
  6410. * @private
  6411. * @function Highcharts.BubbleLegend#init
  6412. * @param {Highcharts.LegendBubbleLegendOptions} options
  6413. * Bubble legend options
  6414. * @param {Highcharts.Legend} legend
  6415. * Legend
  6416. * @return {void}
  6417. */
  6418. BubbleLegend.prototype.init = function (options, legend) {
  6419. this.options = options;
  6420. this.visible = true;
  6421. this.chart = legend.chart;
  6422. this.legend = legend;
  6423. };
  6424. /**
  6425. * Depending on the position option, add bubbleLegend to legend items.
  6426. *
  6427. * @private
  6428. * @function Highcharts.BubbleLegend#addToLegend
  6429. * @param {Array<(Highcharts.Point|Highcharts.Series)>}
  6430. * All legend items
  6431. * @return {void}
  6432. */
  6433. BubbleLegend.prototype.addToLegend = function (items) {
  6434. // Insert bubbleLegend into legend items
  6435. items.splice(this.options.legendIndex, 0, this);
  6436. };
  6437. /**
  6438. * Calculate ranges, sizes and call the next steps of bubbleLegend
  6439. * creation.
  6440. *
  6441. * @private
  6442. * @function Highcharts.BubbleLegend#drawLegendSymbol
  6443. * @param {Highcharts.Legend} legend
  6444. * Legend instance
  6445. * @return {void}
  6446. */
  6447. BubbleLegend.prototype.drawLegendSymbol = function (legend) {
  6448. var chart = this.chart,
  6449. options = this.options,
  6450. size,
  6451. itemDistance = pick(legend.options.itemDistance, 20),
  6452. connectorSpace,
  6453. ranges = options.ranges,
  6454. radius,
  6455. maxLabel,
  6456. connectorDistance = options.connectorDistance;
  6457. // Predict label dimensions
  6458. this.fontMetrics = chart.renderer.fontMetrics(options.labels.style.fontSize.toString() + 'px');
  6459. // Do not create bubbleLegend now if ranges or ranges valeus are not
  6460. // specified or if are empty array.
  6461. if (!ranges || !ranges.length || !isNumber(ranges[0].value)) {
  6462. legend.options.bubbleLegend.autoRanges = true;
  6463. return;
  6464. }
  6465. // Sort ranges to right render order
  6466. stableSort(ranges, function (a, b) {
  6467. return b.value - a.value;
  6468. });
  6469. this.ranges = ranges;
  6470. this.setOptions();
  6471. this.render();
  6472. // Get max label size
  6473. maxLabel = this.getMaxLabelSize();
  6474. radius = this.ranges[0].radius;
  6475. size = radius * 2;
  6476. // Space for connectors and labels.
  6477. connectorSpace =
  6478. connectorDistance - radius + maxLabel.width;
  6479. connectorSpace = connectorSpace > 0 ? connectorSpace : 0;
  6480. this.maxLabel = maxLabel;
  6481. this.movementX = options.labels.align === 'left' ?
  6482. connectorSpace : 0;
  6483. this.legendItemWidth = size + connectorSpace + itemDistance;
  6484. this.legendItemHeight = size + this.fontMetrics.h / 2;
  6485. };
  6486. /**
  6487. * Set style options for each bubbleLegend range.
  6488. *
  6489. * @private
  6490. * @function Highcharts.BubbleLegend#setOptions
  6491. * @return {void}
  6492. */
  6493. BubbleLegend.prototype.setOptions = function () {
  6494. var ranges = this.ranges,
  6495. options = this.options,
  6496. series = this.chart.series[options.seriesIndex],
  6497. baseline = this.legend.baseline,
  6498. bubbleStyle = {
  6499. 'z-index': options.zIndex,
  6500. 'stroke-width': options.borderWidth
  6501. },
  6502. connectorStyle = {
  6503. 'z-index': options.zIndex,
  6504. 'stroke-width': options.connectorWidth
  6505. },
  6506. labelStyle = this.getLabelStyles(),
  6507. fillOpacity = series.options.marker.fillOpacity,
  6508. styledMode = this.chart.styledMode;
  6509. // Allow to parts of styles be used individually for range
  6510. ranges.forEach(function (range, i) {
  6511. if (!styledMode) {
  6512. bubbleStyle.stroke = pick(range.borderColor, options.borderColor, series.color);
  6513. bubbleStyle.fill = pick(range.color, options.color, fillOpacity !== 1 ?
  6514. color(series.color).setOpacity(fillOpacity)
  6515. .get('rgba') :
  6516. series.color);
  6517. connectorStyle.stroke = pick(range.connectorColor, options.connectorColor, series.color);
  6518. }
  6519. // Set options needed for rendering each range
  6520. ranges[i].radius = this.getRangeRadius(range.value);
  6521. ranges[i] = merge(ranges[i], {
  6522. center: (ranges[0].radius - ranges[i].radius +
  6523. baseline)
  6524. });
  6525. if (!styledMode) {
  6526. merge(true, ranges[i], {
  6527. bubbleStyle: merge(false, bubbleStyle),
  6528. connectorStyle: merge(false, connectorStyle),
  6529. labelStyle: labelStyle
  6530. });
  6531. }
  6532. }, this);
  6533. };
  6534. /**
  6535. * Merge options for bubbleLegend labels.
  6536. *
  6537. * @private
  6538. * @function Highcharts.BubbleLegend#getLabelStyles
  6539. * @return {Highcharts.CSSObject}
  6540. */
  6541. BubbleLegend.prototype.getLabelStyles = function () {
  6542. var options = this.options,
  6543. additionalLabelsStyle = {},
  6544. labelsOnLeft = options.labels.align === 'left',
  6545. rtl = this.legend.options.rtl;
  6546. // To separate additional style options
  6547. objectEach(options.labels.style, function (value, key) {
  6548. if (key !== 'color' &&
  6549. key !== 'fontSize' &&
  6550. key !== 'z-index') {
  6551. additionalLabelsStyle[key] = value;
  6552. }
  6553. });
  6554. return merge(false, additionalLabelsStyle, {
  6555. 'font-size': options.labels.style.fontSize,
  6556. fill: pick(options.labels.style.color, palette.neutralColor100),
  6557. 'z-index': options.zIndex,
  6558. align: rtl || labelsOnLeft ? 'right' : 'left'
  6559. });
  6560. };
  6561. /**
  6562. * Calculate radius for each bubble range,
  6563. * used code from BubbleSeries.js 'getRadius' method.
  6564. *
  6565. * @private
  6566. * @function Highcharts.BubbleLegend#getRangeRadius
  6567. * @param {number} value
  6568. * Range value
  6569. * @return {number|null}
  6570. * Radius for one range
  6571. */
  6572. BubbleLegend.prototype.getRangeRadius = function (value) {
  6573. var options = this.options,
  6574. seriesIndex = this.options.seriesIndex,
  6575. bubbleSeries = this.chart.series[seriesIndex],
  6576. zMax = options.ranges[0].value,
  6577. zMin = options.ranges[options.ranges.length - 1].value,
  6578. minSize = options.minSize,
  6579. maxSize = options.maxSize;
  6580. return bubbleSeries.getRadius.call(this, zMin, zMax, minSize, maxSize, value);
  6581. };
  6582. /**
  6583. * Render the legendSymbol group.
  6584. *
  6585. * @private
  6586. * @function Highcharts.BubbleLegend#render
  6587. * @return {void}
  6588. */
  6589. BubbleLegend.prototype.render = function () {
  6590. var renderer = this.chart.renderer,
  6591. zThreshold = this.options.zThreshold;
  6592. if (!this.symbols) {
  6593. this.symbols = {
  6594. connectors: [],
  6595. bubbleItems: [],
  6596. labels: []
  6597. };
  6598. }
  6599. // Nesting SVG groups to enable handleOverflow
  6600. this.legendSymbol = renderer.g('bubble-legend');
  6601. this.legendItem = renderer.g('bubble-legend-item');
  6602. // To enable default 'hideOverlappingLabels' method
  6603. this.legendSymbol.translateX = 0;
  6604. this.legendSymbol.translateY = 0;
  6605. this.ranges.forEach(function (range) {
  6606. if (range.value >= zThreshold) {
  6607. this.renderRange(range);
  6608. }
  6609. }, this);
  6610. // To use handleOverflow method
  6611. this.legendSymbol.add(this.legendItem);
  6612. this.legendItem.add(this.legendGroup);
  6613. this.hideOverlappingLabels();
  6614. };
  6615. /**
  6616. * Render one range, consisting of bubble symbol, connector and label.
  6617. *
  6618. * @private
  6619. * @function Highcharts.BubbleLegend#renderRange
  6620. * @param {Highcharts.LegendBubbleLegendRangesOptions} range
  6621. * Range options
  6622. * @return {void}
  6623. */
  6624. BubbleLegend.prototype.renderRange = function (range) {
  6625. var mainRange = this.ranges[0],
  6626. legend = this.legend,
  6627. options = this.options,
  6628. labelsOptions = options.labels,
  6629. chart = this.chart,
  6630. renderer = chart.renderer,
  6631. symbols = this.symbols,
  6632. labels = symbols.labels,
  6633. label,
  6634. elementCenter = range.center,
  6635. absoluteRadius = Math.abs(range.radius),
  6636. connectorDistance = options.connectorDistance || 0,
  6637. labelsAlign = labelsOptions.align,
  6638. rtl = legend.options.rtl,
  6639. fontSize = labelsOptions.style.fontSize,
  6640. connectorLength = rtl || labelsAlign === 'left' ?
  6641. -connectorDistance : connectorDistance,
  6642. borderWidth = options.borderWidth,
  6643. connectorWidth = options.connectorWidth,
  6644. posX = mainRange.radius || 0,
  6645. posY = elementCenter - absoluteRadius -
  6646. borderWidth / 2 + connectorWidth / 2,
  6647. labelY,
  6648. labelX,
  6649. fontMetrics = this.fontMetrics,
  6650. labelMovement = fontSize / 2 - (fontMetrics.h - fontSize) / 2,
  6651. crispMovement = (posY % 1 ? 1 : 0.5) -
  6652. (connectorWidth % 2 ? 0 : 0.5),
  6653. styledMode = renderer.styledMode;
  6654. // Set options for centered labels
  6655. if (labelsAlign === 'center') {
  6656. connectorLength = 0; // do not use connector
  6657. options.connectorDistance = 0;
  6658. range.labelStyle.align = 'center';
  6659. }
  6660. labelY = posY + options.labels.y;
  6661. labelX = posX + connectorLength + options.labels.x;
  6662. // Render bubble symbol
  6663. symbols.bubbleItems.push(renderer
  6664. .circle(posX, elementCenter + crispMovement, absoluteRadius)
  6665. .attr(styledMode ? {} : range.bubbleStyle)
  6666. .addClass((styledMode ?
  6667. 'highcharts-color-' +
  6668. this.options.seriesIndex + ' ' :
  6669. '') +
  6670. 'highcharts-bubble-legend-symbol ' +
  6671. (options.className || '')).add(this.legendSymbol));
  6672. // Render connector
  6673. symbols.connectors.push(renderer
  6674. .path(renderer.crispLine([
  6675. ['M', posX, posY],
  6676. ['L', posX + connectorLength, posY]
  6677. ], options.connectorWidth))
  6678. .attr(styledMode ? {} : range.connectorStyle)
  6679. .addClass((styledMode ?
  6680. 'highcharts-color-' +
  6681. this.options.seriesIndex + ' ' : '') +
  6682. 'highcharts-bubble-legend-connectors ' +
  6683. (options.connectorClassName || '')).add(this.legendSymbol));
  6684. // Render label
  6685. label = renderer
  6686. .text(this.formatLabel(range), labelX, labelY + labelMovement)
  6687. .attr(styledMode ? {} : range.labelStyle)
  6688. .addClass('highcharts-bubble-legend-labels ' +
  6689. (options.labels.className || '')).add(this.legendSymbol);
  6690. labels.push(label);
  6691. // To enable default 'hideOverlappingLabels' method
  6692. label.placed = true;
  6693. label.alignAttr = {
  6694. x: labelX,
  6695. y: labelY + labelMovement
  6696. };
  6697. };
  6698. /**
  6699. * Get the label which takes up the most space.
  6700. *
  6701. * @private
  6702. * @function Highcharts.BubbleLegend#getMaxLabelSize
  6703. * @return {Highcharts.BBoxObject}
  6704. */
  6705. BubbleLegend.prototype.getMaxLabelSize = function () {
  6706. var labels = this.symbols.labels,
  6707. maxLabel,
  6708. labelSize;
  6709. labels.forEach(function (label) {
  6710. labelSize = label.getBBox(true);
  6711. if (maxLabel) {
  6712. maxLabel = labelSize.width > maxLabel.width ?
  6713. labelSize : maxLabel;
  6714. }
  6715. else {
  6716. maxLabel = labelSize;
  6717. }
  6718. });
  6719. return maxLabel || {};
  6720. };
  6721. /**
  6722. * Get formatted label for range.
  6723. *
  6724. * @private
  6725. * @function Highcharts.BubbleLegend#formatLabel
  6726. * @param {Highcharts.LegendBubbleLegendRangesOptions} range
  6727. * Range options
  6728. * @return {string}
  6729. * Range label text
  6730. */
  6731. BubbleLegend.prototype.formatLabel = function (range) {
  6732. var options = this.options,
  6733. formatter = options.labels.formatter,
  6734. format = options.labels.format;
  6735. var numberFormatter = this.chart.numberFormatter;
  6736. return format ? U.format(format, range) :
  6737. formatter ? formatter.call(range) :
  6738. numberFormatter(range.value, 1);
  6739. };
  6740. /**
  6741. * By using default chart 'hideOverlappingLabels' method, hide or show
  6742. * labels and connectors.
  6743. *
  6744. * @private
  6745. * @function Highcharts.BubbleLegend#hideOverlappingLabels
  6746. * @return {void}
  6747. */
  6748. BubbleLegend.prototype.hideOverlappingLabels = function () {
  6749. var chart = this.chart,
  6750. allowOverlap = this.options.labels.allowOverlap,
  6751. symbols = this.symbols;
  6752. if (!allowOverlap && symbols) {
  6753. chart.hideOverlappingLabels(symbols.labels);
  6754. // Hide or show connectors
  6755. symbols.labels.forEach(function (label, index) {
  6756. if (!label.newOpacity) {
  6757. symbols.connectors[index].hide();
  6758. }
  6759. else if (label.newOpacity !== label.oldOpacity) {
  6760. symbols.connectors[index].show();
  6761. }
  6762. });
  6763. }
  6764. };
  6765. /**
  6766. * Calculate ranges from created series.
  6767. *
  6768. * @private
  6769. * @function Highcharts.BubbleLegend#getRanges
  6770. * @return {Array<Highcharts.LegendBubbleLegendRangesOptions>}
  6771. * Array of range objects
  6772. */
  6773. BubbleLegend.prototype.getRanges = function () {
  6774. var bubbleLegend = this.legend.bubbleLegend,
  6775. series = bubbleLegend.chart.series,
  6776. ranges,
  6777. rangesOptions = bubbleLegend.options.ranges,
  6778. zData,
  6779. minZ = Number.MAX_VALUE,
  6780. maxZ = -Number.MAX_VALUE;
  6781. series.forEach(function (s) {
  6782. // Find the min and max Z, like in bubble series
  6783. if (s.isBubble && !s.ignoreSeries) {
  6784. zData = s.zData.filter(isNumber);
  6785. if (zData.length) {
  6786. minZ = pick(s.options.zMin, Math.min(minZ, Math.max(arrayMin(zData), s.options.displayNegative === false ?
  6787. s.options.zThreshold :
  6788. -Number.MAX_VALUE)));
  6789. maxZ = pick(s.options.zMax, Math.max(maxZ, arrayMax(zData)));
  6790. }
  6791. }
  6792. });
  6793. // Set values for ranges
  6794. if (minZ === maxZ) {
  6795. // Only one range if min and max values are the same.
  6796. ranges = [{ value: maxZ }];
  6797. }
  6798. else {
  6799. ranges = [
  6800. { value: minZ },
  6801. { value: (minZ + maxZ) / 2 },
  6802. { value: maxZ, autoRanges: true }
  6803. ];
  6804. }
  6805. // Prevent reverse order of ranges after redraw
  6806. if (rangesOptions.length && rangesOptions[0].radius) {
  6807. ranges.reverse();
  6808. }
  6809. // Merge ranges values with user options
  6810. ranges.forEach(function (range, i) {
  6811. if (rangesOptions && rangesOptions[i]) {
  6812. ranges[i] = merge(false, rangesOptions[i], range);
  6813. }
  6814. });
  6815. return ranges;
  6816. };
  6817. /**
  6818. * Calculate bubble legend sizes from rendered series.
  6819. *
  6820. * @private
  6821. * @function Highcharts.BubbleLegend#predictBubbleSizes
  6822. * @return {Array<number,number>}
  6823. * Calculated min and max bubble sizes
  6824. */
  6825. BubbleLegend.prototype.predictBubbleSizes = function () {
  6826. var chart = this.chart,
  6827. fontMetrics = this.fontMetrics,
  6828. legendOptions = chart.legend.options,
  6829. floating = legendOptions.floating,
  6830. horizontal = legendOptions.layout === 'horizontal',
  6831. lastLineHeight = horizontal ? chart.legend.lastLineHeight : 0,
  6832. plotSizeX = chart.plotSizeX,
  6833. plotSizeY = chart.plotSizeY,
  6834. bubbleSeries = chart.series[this.options.seriesIndex],
  6835. minSize = Math.ceil(bubbleSeries.minPxSize),
  6836. maxPxSize = Math.ceil(bubbleSeries.maxPxSize),
  6837. maxSize = bubbleSeries.options.maxSize,
  6838. plotSize = Math.min(plotSizeY,
  6839. plotSizeX),
  6840. calculatedSize;
  6841. // Calculate prediceted max size of bubble
  6842. if (floating || !(/%$/.test(maxSize))) {
  6843. calculatedSize = maxPxSize;
  6844. }
  6845. else {
  6846. maxSize = parseFloat(maxSize);
  6847. calculatedSize = ((plotSize + lastLineHeight -
  6848. fontMetrics.h / 2) * maxSize / 100) / (maxSize / 100 + 1);
  6849. // Get maxPxSize from bubble series if calculated bubble legend
  6850. // size will not affect to bubbles series.
  6851. if ((horizontal && plotSizeY - calculatedSize >=
  6852. plotSizeX) || (!horizontal && plotSizeX -
  6853. calculatedSize >= plotSizeY)) {
  6854. calculatedSize = maxPxSize;
  6855. }
  6856. }
  6857. return [minSize, Math.ceil(calculatedSize)];
  6858. };
  6859. /**
  6860. * Correct ranges with calculated sizes.
  6861. *
  6862. * @private
  6863. * @function Highcharts.BubbleLegend#updateRanges
  6864. * @param {number} min
  6865. * @param {number} max
  6866. * @return {void}
  6867. */
  6868. BubbleLegend.prototype.updateRanges = function (min, max) {
  6869. var bubbleLegendOptions = this.legend.options.bubbleLegend;
  6870. bubbleLegendOptions.minSize = min;
  6871. bubbleLegendOptions.maxSize = max;
  6872. bubbleLegendOptions.ranges = this.getRanges();
  6873. };
  6874. /**
  6875. * Because of the possibility of creating another legend line, predicted
  6876. * bubble legend sizes may differ by a few pixels, so it is necessary to
  6877. * correct them.
  6878. *
  6879. * @private
  6880. * @function Highcharts.BubbleLegend#correctSizes
  6881. * @return {void}
  6882. */
  6883. BubbleLegend.prototype.correctSizes = function () {
  6884. var legend = this.legend,
  6885. chart = this.chart,
  6886. bubbleSeries = chart.series[this.options.seriesIndex],
  6887. bubbleSeriesSize = bubbleSeries.maxPxSize,
  6888. bubbleLegendSize = this.options.maxSize;
  6889. if (Math.abs(Math.ceil(bubbleSeriesSize) - bubbleLegendSize) >
  6890. 1) {
  6891. this.updateRanges(this.options.minSize, bubbleSeries.maxPxSize);
  6892. legend.render();
  6893. }
  6894. };
  6895. return BubbleLegend;
  6896. }());
  6897. // Start the bubble legend creation process.
  6898. addEvent(Legend, 'afterGetAllItems', function (e) {
  6899. var legend = this,
  6900. bubbleLegend = legend.bubbleLegend,
  6901. legendOptions = legend.options,
  6902. options = legendOptions.bubbleLegend,
  6903. bubbleSeriesIndex = legend.chart.getVisibleBubbleSeriesIndex();
  6904. // Remove unnecessary element
  6905. if (bubbleLegend && bubbleLegend.ranges && bubbleLegend.ranges.length) {
  6906. // Allow change the way of calculating ranges in update
  6907. if (options.ranges.length) {
  6908. options.autoRanges =
  6909. !!options.ranges[0].autoRanges;
  6910. }
  6911. // Update bubbleLegend dimensions in each redraw
  6912. legend.destroyItem(bubbleLegend);
  6913. }
  6914. // Create bubble legend
  6915. if (bubbleSeriesIndex >= 0 &&
  6916. legendOptions.enabled &&
  6917. options.enabled) {
  6918. options.seriesIndex = bubbleSeriesIndex;
  6919. legend.bubbleLegend = new H.BubbleLegend(options, legend);
  6920. legend.bubbleLegend.addToLegend(e.allItems);
  6921. }
  6922. });
  6923. /**
  6924. * Check if there is at least one visible bubble series.
  6925. *
  6926. * @private
  6927. * @function Highcharts.Chart#getVisibleBubbleSeriesIndex
  6928. * @return {number}
  6929. * First visible bubble series index
  6930. */
  6931. Chart.prototype.getVisibleBubbleSeriesIndex = function () {
  6932. var series = this.series,
  6933. i = 0;
  6934. while (i < series.length) {
  6935. if (series[i] &&
  6936. series[i].isBubble &&
  6937. series[i].visible &&
  6938. series[i].zData.length) {
  6939. return i;
  6940. }
  6941. i++;
  6942. }
  6943. return -1;
  6944. };
  6945. /**
  6946. * Calculate height for each row in legend.
  6947. *
  6948. * @private
  6949. * @function Highcharts.Legend#getLinesHeights
  6950. * @return {Array<Highcharts.Dictionary<number>>}
  6951. * Informations about line height and items amount
  6952. */
  6953. Legend.prototype.getLinesHeights = function () {
  6954. var items = this.allItems,
  6955. lines = [],
  6956. lastLine,
  6957. length = items.length,
  6958. i = 0,
  6959. j = 0;
  6960. for (i = 0; i < length; i++) {
  6961. if (items[i].legendItemHeight) {
  6962. // for bubbleLegend
  6963. items[i].itemHeight = items[i].legendItemHeight;
  6964. }
  6965. if ( // Line break
  6966. items[i] === items[length - 1] ||
  6967. items[i + 1] &&
  6968. items[i]._legendItemPos[1] !==
  6969. items[i + 1]._legendItemPos[1]) {
  6970. lines.push({ height: 0 });
  6971. lastLine = lines[lines.length - 1];
  6972. // Find the highest item in line
  6973. for (j; j <= i; j++) {
  6974. if (items[j].itemHeight > lastLine.height) {
  6975. lastLine.height = items[j].itemHeight;
  6976. }
  6977. }
  6978. lastLine.step = i;
  6979. }
  6980. }
  6981. return lines;
  6982. };
  6983. /**
  6984. * Correct legend items translation in case of different elements heights.
  6985. *
  6986. * @private
  6987. * @function Highcharts.Legend#retranslateItems
  6988. * @param {Array<Highcharts.Dictionary<number>>} lines
  6989. * Informations about line height and items amount
  6990. * @return {void}
  6991. */
  6992. Legend.prototype.retranslateItems = function (lines) {
  6993. var items = this.allItems,
  6994. orgTranslateX,
  6995. orgTranslateY,
  6996. movementX,
  6997. rtl = this.options.rtl,
  6998. actualLine = 0;
  6999. items.forEach(function (item, index) {
  7000. orgTranslateX = item.legendGroup.translateX;
  7001. orgTranslateY = item._legendItemPos[1];
  7002. movementX = item.movementX;
  7003. if (movementX || (rtl && item.ranges)) {
  7004. movementX = rtl ?
  7005. orgTranslateX - item.options.maxSize / 2 :
  7006. orgTranslateX + movementX;
  7007. item.legendGroup.attr({ translateX: movementX });
  7008. }
  7009. if (index > lines[actualLine].step) {
  7010. actualLine++;
  7011. }
  7012. item.legendGroup.attr({
  7013. translateY: Math.round(orgTranslateY + lines[actualLine].height / 2)
  7014. });
  7015. item._legendItemPos[1] = orgTranslateY +
  7016. lines[actualLine].height / 2;
  7017. });
  7018. };
  7019. // Toggle bubble legend depending on the visible status of bubble series.
  7020. addEvent(Series, 'legendItemClick', function () {
  7021. var series = this,
  7022. chart = series.chart,
  7023. visible = series.visible,
  7024. legend = series.chart.legend,
  7025. status;
  7026. if (legend && legend.bubbleLegend) {
  7027. // Temporary correct 'visible' property
  7028. series.visible = !visible;
  7029. // Save future status for getRanges method
  7030. series.ignoreSeries = visible;
  7031. // Check if at lest one bubble series is visible
  7032. status = chart.getVisibleBubbleSeriesIndex() >= 0;
  7033. // Hide bubble legend if all bubble series are disabled
  7034. if (legend.bubbleLegend.visible !== status) {
  7035. // Show or hide bubble legend
  7036. legend.update({
  7037. bubbleLegend: { enabled: status }
  7038. });
  7039. legend.bubbleLegend.visible = status; // Restore default status
  7040. }
  7041. series.visible = visible;
  7042. }
  7043. });
  7044. // If ranges are not specified, determine ranges from rendered bubble series
  7045. // and render legend again.
  7046. wrap(Chart.prototype, 'drawChartBox', function (proceed, options, callback) {
  7047. var chart = this,
  7048. legend = chart.legend,
  7049. bubbleSeries = chart.getVisibleBubbleSeriesIndex() >= 0,
  7050. bubbleLegendOptions,
  7051. bubbleSizes;
  7052. if (legend && legend.options.enabled && legend.bubbleLegend &&
  7053. legend.options.bubbleLegend.autoRanges && bubbleSeries) {
  7054. bubbleLegendOptions = legend.bubbleLegend.options;
  7055. bubbleSizes = legend.bubbleLegend.predictBubbleSizes();
  7056. legend.bubbleLegend.updateRanges(bubbleSizes[0], bubbleSizes[1]);
  7057. // Disable animation on init
  7058. if (!bubbleLegendOptions.placed) {
  7059. legend.group.placed = false;
  7060. legend.allItems.forEach(function (item) {
  7061. item.legendGroup.translateY = null;
  7062. });
  7063. }
  7064. // Create legend with bubbleLegend
  7065. legend.render();
  7066. chart.getMargins();
  7067. chart.axes.forEach(function (axis) {
  7068. if (axis.visible) { // #11448
  7069. axis.render();
  7070. }
  7071. if (!bubbleLegendOptions.placed) {
  7072. axis.setScale();
  7073. axis.updateNames();
  7074. // Disable axis animation on init
  7075. objectEach(axis.ticks, function (tick) {
  7076. tick.isNew = true;
  7077. tick.isNewLabel = true;
  7078. });
  7079. }
  7080. });
  7081. bubbleLegendOptions.placed = true;
  7082. // After recalculate axes, calculate margins again.
  7083. chart.getMargins();
  7084. // Call default 'drawChartBox' method.
  7085. proceed.call(chart, options, callback);
  7086. // Check bubble legend sizes and correct them if necessary.
  7087. legend.bubbleLegend.correctSizes();
  7088. // Correct items positions with different dimensions in legend.
  7089. legend.retranslateItems(legend.getLinesHeights());
  7090. }
  7091. else {
  7092. proceed.call(chart, options, callback);
  7093. // Allow color change on static bubble legend after click on legend
  7094. if (legend && legend.options.enabled && legend.bubbleLegend) {
  7095. legend.render();
  7096. legend.retranslateItems(legend.getLinesHeights());
  7097. }
  7098. }
  7099. });
  7100. H.BubbleLegend = BubbleLegend;
  7101. return H.BubbleLegend;
  7102. });
  7103. _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) {
  7104. /* *
  7105. *
  7106. * (c) 2010-2021 Torstein Honsi
  7107. *
  7108. * License: www.highcharts.com/license
  7109. *
  7110. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  7111. *
  7112. * */
  7113. var __extends = (this && this.__extends) || (function () {
  7114. var extendStatics = function (d,
  7115. b) {
  7116. extendStatics = Object.setPrototypeOf ||
  7117. ({ __proto__: [] } instanceof Array && function (d,
  7118. b) { d.__proto__ = b; }) ||
  7119. function (d,
  7120. b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  7121. return extendStatics(d, b);
  7122. };
  7123. return function (d, b) {
  7124. extendStatics(d, b);
  7125. function __() { this.constructor = d; }
  7126. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  7127. };
  7128. })();
  7129. var color = Color.parse;
  7130. var noop = H.noop;
  7131. var _a = SeriesRegistry.seriesTypes,
  7132. ColumnSeries = _a.column,
  7133. ScatterSeries = _a.scatter;
  7134. var arrayMax = U.arrayMax,
  7135. arrayMin = U.arrayMin,
  7136. clamp = U.clamp,
  7137. extend = U.extend,
  7138. isNumber = U.isNumber,
  7139. merge = U.merge,
  7140. pick = U.pick,
  7141. pInt = U.pInt;
  7142. /* *
  7143. *
  7144. * Class
  7145. *
  7146. * */
  7147. var BubbleSeries = /** @class */ (function (_super) {
  7148. __extends(BubbleSeries, _super);
  7149. function BubbleSeries() {
  7150. /* *
  7151. *
  7152. * Static Properties
  7153. *
  7154. * */
  7155. var _this = _super !== null && _super.apply(this,
  7156. arguments) || this;
  7157. /* *
  7158. *
  7159. * Properties
  7160. *
  7161. * */
  7162. _this.data = void 0;
  7163. _this.maxPxSize = void 0;
  7164. _this.minPxSize = void 0;
  7165. _this.options = void 0;
  7166. _this.points = void 0;
  7167. _this.radii = void 0;
  7168. _this.yData = void 0;
  7169. _this.zData = void 0;
  7170. return _this;
  7171. /* eslint-enable valid-jsdoc */
  7172. }
  7173. /* *
  7174. *
  7175. * Functions
  7176. *
  7177. * */
  7178. /* eslint-disable valid-jsdoc */
  7179. /**
  7180. * Perform animation on the bubbles
  7181. * @private
  7182. */
  7183. BubbleSeries.prototype.animate = function (init) {
  7184. if (!init &&
  7185. this.points.length < this.options.animationLimit // #8099
  7186. ) {
  7187. this.points.forEach(function (point) {
  7188. var graphic = point.graphic;
  7189. if (graphic && graphic.width) { // URL symbols don't have width
  7190. // Start values
  7191. if (!this.hasRendered) {
  7192. graphic.attr({
  7193. x: point.plotX,
  7194. y: point.plotY,
  7195. width: 1,
  7196. height: 1
  7197. });
  7198. }
  7199. // Run animation
  7200. graphic.animate(this.markerAttribs(point), this.options.animation);
  7201. }
  7202. }, this);
  7203. }
  7204. };
  7205. /**
  7206. * Get the radius for each point based on the minSize, maxSize and each
  7207. * point's Z value. This must be done prior to Series.translate because
  7208. * the axis needs to add padding in accordance with the point sizes.
  7209. * @private
  7210. */
  7211. BubbleSeries.prototype.getRadii = function (zMin, zMax, series) {
  7212. var len,
  7213. i,
  7214. zData = this.zData,
  7215. yData = this.yData,
  7216. minSize = series.minPxSize,
  7217. maxSize = series.maxPxSize,
  7218. radii = [],
  7219. value;
  7220. // Set the shape type and arguments to be picked up in drawPoints
  7221. for (i = 0, len = zData.length; i < len; i++) {
  7222. value = zData[i];
  7223. // Separate method to get individual radius for bubbleLegend
  7224. radii.push(this.getRadius(zMin, zMax, minSize, maxSize, value, yData[i]));
  7225. }
  7226. this.radii = radii;
  7227. };
  7228. /**
  7229. * Get the individual radius for one point.
  7230. * @private
  7231. */
  7232. BubbleSeries.prototype.getRadius = function (zMin, zMax, minSize, maxSize, value, yValue) {
  7233. var options = this.options,
  7234. sizeByArea = options.sizeBy !== 'width',
  7235. zThreshold = options.zThreshold,
  7236. zRange = zMax - zMin,
  7237. pos = 0.5;
  7238. // #8608 - bubble should be visible when z is undefined
  7239. if (yValue === null || value === null) {
  7240. return null;
  7241. }
  7242. if (isNumber(value)) {
  7243. // When sizing by threshold, the absolute value of z determines
  7244. // the size of the bubble.
  7245. if (options.sizeByAbsoluteValue) {
  7246. value = Math.abs(value - zThreshold);
  7247. zMax = zRange = Math.max(zMax - zThreshold, Math.abs(zMin - zThreshold));
  7248. zMin = 0;
  7249. }
  7250. // Issue #4419 - if value is less than zMin, push a radius that's
  7251. // always smaller than the minimum size
  7252. if (value < zMin) {
  7253. return minSize / 2 - 1;
  7254. }
  7255. // Relative size, a number between 0 and 1
  7256. if (zRange > 0) {
  7257. pos = (value - zMin) / zRange;
  7258. }
  7259. }
  7260. if (sizeByArea && pos >= 0) {
  7261. pos = Math.sqrt(pos);
  7262. }
  7263. return Math.ceil(minSize + pos * (maxSize - minSize)) / 2;
  7264. };
  7265. /**
  7266. * Define hasData function for non-cartesian series.
  7267. * Returns true if the series has points at all.
  7268. * @private
  7269. */
  7270. BubbleSeries.prototype.hasData = function () {
  7271. return !!this.processedXData.length; // != 0
  7272. };
  7273. /**
  7274. * @private
  7275. */
  7276. BubbleSeries.prototype.pointAttribs = function (point, state) {
  7277. var markerOptions = this.options.marker,
  7278. fillOpacity = markerOptions.fillOpacity,
  7279. attr = Series.prototype.pointAttribs.call(this,
  7280. point,
  7281. state);
  7282. if (fillOpacity !== 1) {
  7283. attr.fill = color(attr.fill)
  7284. .setOpacity(fillOpacity)
  7285. .get('rgba');
  7286. }
  7287. return attr;
  7288. };
  7289. /**
  7290. * Extend the base translate method to handle bubble size
  7291. * @private
  7292. */
  7293. BubbleSeries.prototype.translate = function () {
  7294. var i,
  7295. data = this.data,
  7296. point,
  7297. radius,
  7298. radii = this.radii;
  7299. // Run the parent method
  7300. _super.prototype.translate.call(this);
  7301. // Set the shape type and arguments to be picked up in drawPoints
  7302. i = data.length;
  7303. while (i--) {
  7304. point = data[i];
  7305. radius = radii ? radii[i] : 0; // #1737
  7306. if (isNumber(radius) && radius >= this.minPxSize / 2) {
  7307. // Shape arguments
  7308. point.marker = extend(point.marker, {
  7309. radius: radius,
  7310. width: 2 * radius,
  7311. height: 2 * radius
  7312. });
  7313. // Alignment box for the data label
  7314. point.dlBox = {
  7315. x: point.plotX - radius,
  7316. y: point.plotY - radius,
  7317. width: 2 * radius,
  7318. height: 2 * radius
  7319. };
  7320. }
  7321. else { // below zThreshold
  7322. // #1691
  7323. point.shapeArgs = point.plotY = point.dlBox = void 0;
  7324. }
  7325. }
  7326. };
  7327. /**
  7328. * A bubble series is a three dimensional series type where each point
  7329. * renders an X, Y and Z value. Each points is drawn as a bubble where the
  7330. * position along the X and Y axes mark the X and Y values, and the size of
  7331. * the bubble relates to the Z value.
  7332. *
  7333. * @sample {highcharts} highcharts/demo/bubble/
  7334. * Bubble chart
  7335. *
  7336. * @extends plotOptions.scatter
  7337. * @excluding cluster
  7338. * @product highcharts highstock
  7339. * @requires highcharts-more
  7340. * @optionparent plotOptions.bubble
  7341. */
  7342. BubbleSeries.defaultOptions = merge(ScatterSeries.defaultOptions, {
  7343. dataLabels: {
  7344. formatter: function () {
  7345. return this.point.z;
  7346. },
  7347. inside: true,
  7348. verticalAlign: 'middle'
  7349. },
  7350. /**
  7351. * If there are more points in the series than the `animationLimit`, the
  7352. * animation won't run. Animation affects overall performance and
  7353. * doesn't work well with heavy data series.
  7354. *
  7355. * @since 6.1.0
  7356. */
  7357. animationLimit: 250,
  7358. /**
  7359. * Whether to display negative sized bubbles. The threshold is given
  7360. * by the [zThreshold](#plotOptions.bubble.zThreshold) option, and negative
  7361. * bubbles can be visualized by setting
  7362. * [negativeColor](#plotOptions.bubble.negativeColor).
  7363. *
  7364. * @sample {highcharts} highcharts/plotoptions/bubble-negative/
  7365. * Negative bubbles
  7366. *
  7367. * @type {boolean}
  7368. * @default true
  7369. * @since 3.0
  7370. * @apioption plotOptions.bubble.displayNegative
  7371. */
  7372. /**
  7373. * @extends plotOptions.series.marker
  7374. * @excluding enabled, enabledThreshold, height, radius, width
  7375. */
  7376. marker: {
  7377. lineColor: null,
  7378. lineWidth: 1,
  7379. /**
  7380. * The fill opacity of the bubble markers.
  7381. */
  7382. fillOpacity: 0.5,
  7383. /**
  7384. * In bubble charts, the radius is overridden and determined based
  7385. * on the point's data value.
  7386. *
  7387. * @ignore-option
  7388. */
  7389. radius: null,
  7390. states: {
  7391. hover: {
  7392. radiusPlus: 0
  7393. }
  7394. },
  7395. /**
  7396. * A predefined shape or symbol for the marker. Possible values are
  7397. * "circle", "square", "diamond", "triangle" and "triangle-down".
  7398. *
  7399. * Additionally, the URL to a graphic can be given on the form
  7400. * `url(graphic.png)`. Note that for the image to be applied to
  7401. * exported charts, its URL needs to be accessible by the export
  7402. * server.
  7403. *
  7404. * Custom callbacks for symbol path generation can also be added to
  7405. * `Highcharts.SVGRenderer.prototype.symbols`. The callback is then
  7406. * used by its method name, as shown in the demo.
  7407. *
  7408. * @sample {highcharts} highcharts/plotoptions/bubble-symbol/
  7409. * Bubble chart with various symbols
  7410. * @sample {highcharts} highcharts/plotoptions/series-marker-symbol/
  7411. * General chart with predefined, graphic and custom markers
  7412. *
  7413. * @type {Highcharts.SymbolKeyValue|string}
  7414. * @since 5.0.11
  7415. */
  7416. symbol: 'circle'
  7417. },
  7418. /**
  7419. * Minimum bubble size. Bubbles will automatically size between the
  7420. * `minSize` and `maxSize` to reflect the `z` value of each bubble.
  7421. * Can be either pixels (when no unit is given), or a percentage of
  7422. * the smallest one of the plot width and height.
  7423. *
  7424. * @sample {highcharts} highcharts/plotoptions/bubble-size/
  7425. * Bubble size
  7426. *
  7427. * @type {number|string}
  7428. * @since 3.0
  7429. * @product highcharts highstock
  7430. */
  7431. minSize: 8,
  7432. /**
  7433. * Maximum bubble size. Bubbles will automatically size between the
  7434. * `minSize` and `maxSize` to reflect the `z` value of each bubble.
  7435. * Can be either pixels (when no unit is given), or a percentage of
  7436. * the smallest one of the plot width and height.
  7437. *
  7438. * @sample {highcharts} highcharts/plotoptions/bubble-size/
  7439. * Bubble size
  7440. *
  7441. * @type {number|string}
  7442. * @since 3.0
  7443. * @product highcharts highstock
  7444. */
  7445. maxSize: '20%',
  7446. /**
  7447. * When a point's Z value is below the
  7448. * [zThreshold](#plotOptions.bubble.zThreshold)
  7449. * setting, this color is used.
  7450. *
  7451. * @sample {highcharts} highcharts/plotoptions/bubble-negative/
  7452. * Negative bubbles
  7453. *
  7454. * @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
  7455. * @since 3.0
  7456. * @product highcharts
  7457. * @apioption plotOptions.bubble.negativeColor
  7458. */
  7459. /**
  7460. * Whether the bubble's value should be represented by the area or the
  7461. * width of the bubble. The default, `area`, corresponds best to the
  7462. * human perception of the size of each bubble.
  7463. *
  7464. * @sample {highcharts} highcharts/plotoptions/bubble-sizeby/
  7465. * Comparison of area and size
  7466. *
  7467. * @type {Highcharts.BubbleSizeByValue}
  7468. * @default area
  7469. * @since 3.0.7
  7470. * @apioption plotOptions.bubble.sizeBy
  7471. */
  7472. /**
  7473. * When this is true, the absolute value of z determines the size of
  7474. * the bubble. This means that with the default `zThreshold` of 0, a
  7475. * bubble of value -1 will have the same size as a bubble of value 1,
  7476. * while a bubble of value 0 will have a smaller size according to
  7477. * `minSize`.
  7478. *
  7479. * @sample {highcharts} highcharts/plotoptions/bubble-sizebyabsolutevalue/
  7480. * Size by absolute value, various thresholds
  7481. *
  7482. * @type {boolean}
  7483. * @default false
  7484. * @since 4.1.9
  7485. * @product highcharts
  7486. * @apioption plotOptions.bubble.sizeByAbsoluteValue
  7487. */
  7488. /**
  7489. * When this is true, the series will not cause the Y axis to cross
  7490. * the zero plane (or [threshold](#plotOptions.series.threshold) option)
  7491. * unless the data actually crosses the plane.
  7492. *
  7493. * For example, if `softThreshold` is `false`, a series of 0, 1, 2,
  7494. * 3 will make the Y axis show negative values according to the
  7495. * `minPadding` option. If `softThreshold` is `true`, the Y axis starts
  7496. * at 0.
  7497. *
  7498. * @since 4.1.9
  7499. * @product highcharts
  7500. */
  7501. softThreshold: false,
  7502. states: {
  7503. hover: {
  7504. halo: {
  7505. size: 5
  7506. }
  7507. }
  7508. },
  7509. tooltip: {
  7510. pointFormat: '({point.x}, {point.y}), Size: {point.z}'
  7511. },
  7512. turboThreshold: 0,
  7513. /**
  7514. * The minimum for the Z value range. Defaults to the highest Z value
  7515. * in the data.
  7516. *
  7517. * @see [zMin](#plotOptions.bubble.zMin)
  7518. *
  7519. * @sample {highcharts} highcharts/plotoptions/bubble-zmin-zmax/
  7520. * Z has a possible range of 0-100
  7521. *
  7522. * @type {number}
  7523. * @since 4.0.3
  7524. * @product highcharts
  7525. * @apioption plotOptions.bubble.zMax
  7526. */
  7527. /**
  7528. * @default z
  7529. * @apioption plotOptions.bubble.colorKey
  7530. */
  7531. /**
  7532. * The minimum for the Z value range. Defaults to the lowest Z value
  7533. * in the data.
  7534. *
  7535. * @see [zMax](#plotOptions.bubble.zMax)
  7536. *
  7537. * @sample {highcharts} highcharts/plotoptions/bubble-zmin-zmax/
  7538. * Z has a possible range of 0-100
  7539. *
  7540. * @type {number}
  7541. * @since 4.0.3
  7542. * @product highcharts
  7543. * @apioption plotOptions.bubble.zMin
  7544. */
  7545. /**
  7546. * When [displayNegative](#plotOptions.bubble.displayNegative) is `false`,
  7547. * bubbles with lower Z values are skipped. When `displayNegative`
  7548. * is `true` and a [negativeColor](#plotOptions.bubble.negativeColor)
  7549. * is given, points with lower Z is colored.
  7550. *
  7551. * @sample {highcharts} highcharts/plotoptions/bubble-negative/
  7552. * Negative bubbles
  7553. *
  7554. * @since 3.0
  7555. * @product highcharts
  7556. */
  7557. zThreshold: 0,
  7558. zoneAxis: 'z'
  7559. });
  7560. return BubbleSeries;
  7561. }(ScatterSeries));
  7562. extend(BubbleSeries.prototype, {
  7563. alignDataLabel: ColumnSeries.prototype.alignDataLabel,
  7564. applyZones: noop,
  7565. bubblePadding: true,
  7566. buildKDTree: noop,
  7567. directTouch: true,
  7568. isBubble: true,
  7569. pointArrayMap: ['y', 'z'],
  7570. pointClass: BubblePoint,
  7571. parallelArrays: ['x', 'y', 'z'],
  7572. trackerGroups: ['group', 'dataLabelsGroup'],
  7573. specialGroup: 'group',
  7574. zoneAxis: 'z'
  7575. });
  7576. /* *
  7577. *
  7578. * Axis ?
  7579. *
  7580. * */
  7581. // Add logic to pad each axis with the amount of pixels necessary to avoid the
  7582. // bubbles to overflow.
  7583. Axis.prototype.beforePadding = function () {
  7584. var axis = this,
  7585. axisLength = this.len,
  7586. chart = this.chart,
  7587. pxMin = 0,
  7588. pxMax = axisLength,
  7589. isXAxis = this.isXAxis,
  7590. dataKey = isXAxis ? 'xData' : 'yData',
  7591. min = this.min,
  7592. extremes = {},
  7593. smallestSize = Math.min(chart.plotWidth,
  7594. chart.plotHeight),
  7595. zMin = Number.MAX_VALUE,
  7596. zMax = -Number.MAX_VALUE,
  7597. range = this.max - min,
  7598. transA = axisLength / range,
  7599. activeSeries = [];
  7600. // Handle padding on the second pass, or on redraw
  7601. this.series.forEach(function (series) {
  7602. var seriesOptions = series.options,
  7603. zData;
  7604. if (series.bubblePadding &&
  7605. (series.visible || !chart.options.chart.ignoreHiddenSeries)) {
  7606. // Correction for #1673
  7607. axis.allowZoomOutside = true;
  7608. // Cache it
  7609. activeSeries.push(series);
  7610. if (isXAxis) { // because X axis is evaluated first
  7611. // For each series, translate the size extremes to pixel values
  7612. ['minSize', 'maxSize'].forEach(function (prop) {
  7613. var length = seriesOptions[prop],
  7614. isPercent = /%$/.test(length);
  7615. length = pInt(length);
  7616. extremes[prop] = isPercent ?
  7617. smallestSize * length / 100 :
  7618. length;
  7619. });
  7620. series.minPxSize = extremes.minSize;
  7621. // Prioritize min size if conflict to make sure bubbles are
  7622. // always visible. #5873
  7623. series.maxPxSize = Math.max(extremes.maxSize, extremes.minSize);
  7624. // Find the min and max Z
  7625. zData = series.zData.filter(isNumber);
  7626. if (zData.length) { // #1735
  7627. zMin = pick(seriesOptions.zMin, clamp(arrayMin(zData), seriesOptions.displayNegative === false ?
  7628. seriesOptions.zThreshold :
  7629. -Number.MAX_VALUE, zMin));
  7630. zMax = pick(seriesOptions.zMax, Math.max(zMax, arrayMax(zData)));
  7631. }
  7632. }
  7633. }
  7634. });
  7635. activeSeries.forEach(function (series) {
  7636. var data = series[dataKey],
  7637. i = data.length,
  7638. radius;
  7639. if (isXAxis) {
  7640. series.getRadii(zMin, zMax, series);
  7641. }
  7642. if (range > 0) {
  7643. while (i--) {
  7644. if (isNumber(data[i]) &&
  7645. axis.dataMin <= data[i] &&
  7646. data[i] <= axis.max) {
  7647. radius = series.radii ? series.radii[i] : 0;
  7648. pxMin = Math.min(((data[i] - min) * transA) - radius, pxMin);
  7649. pxMax = Math.max(((data[i] - min) * transA) + radius, pxMax);
  7650. }
  7651. }
  7652. }
  7653. });
  7654. // Apply the padding to the min and max properties
  7655. if (activeSeries.length && range > 0 && !this.logarithmic) {
  7656. pxMax -= axisLength;
  7657. transA *= (axisLength +
  7658. Math.max(0, pxMin) - // #8901
  7659. Math.min(pxMax, axisLength)) / axisLength;
  7660. [
  7661. ['min', 'userMin', pxMin],
  7662. ['max', 'userMax', pxMax]
  7663. ].forEach(function (keys) {
  7664. if (typeof pick(axis.options[keys[0]], axis[keys[1]]) === 'undefined') {
  7665. axis[keys[0]] += keys[2] / transA;
  7666. }
  7667. });
  7668. }
  7669. /* eslint-enable valid-jsdoc */
  7670. };
  7671. SeriesRegistry.registerSeriesType('bubble', BubbleSeries);
  7672. /* *
  7673. *
  7674. * Default Export
  7675. *
  7676. * */
  7677. /* *
  7678. *
  7679. * API Declarations
  7680. *
  7681. * */
  7682. /**
  7683. * @typedef {"area"|"width"} Highcharts.BubbleSizeByValue
  7684. */
  7685. ''; // detach doclets above
  7686. /* *
  7687. *
  7688. * API Options
  7689. *
  7690. * */
  7691. /**
  7692. * A `bubble` series. If the [type](#series.bubble.type) option is
  7693. * not specified, it is inherited from [chart.type](#chart.type).
  7694. *
  7695. * @extends series,plotOptions.bubble
  7696. * @excluding dataParser, dataURL, stack
  7697. * @product highcharts highstock
  7698. * @requires highcharts-more
  7699. * @apioption series.bubble
  7700. */
  7701. /**
  7702. * An array of data points for the series. For the `bubble` series type,
  7703. * points can be given in the following ways:
  7704. *
  7705. * 1. An array of arrays with 3 or 2 values. In this case, the values correspond
  7706. * to `x,y,z`. If the first value is a string, it is applied as the name of
  7707. * the point, and the `x` value is inferred. The `x` value can also be
  7708. * omitted, in which case the inner arrays should be of length 2\. Then the
  7709. * `x` value is automatically calculated, either starting at 0 and
  7710. * incremented by 1, or from `pointStart` and `pointInterval` given in the
  7711. * series options.
  7712. * ```js
  7713. * data: [
  7714. * [0, 1, 2],
  7715. * [1, 5, 5],
  7716. * [2, 0, 2]
  7717. * ]
  7718. * ```
  7719. *
  7720. * 2. An array of objects with named values. The following snippet shows only a
  7721. * few settings, see the complete options set below. If the total number of
  7722. * data points exceeds the series'
  7723. * [turboThreshold](#series.bubble.turboThreshold), this option is not
  7724. * available.
  7725. * ```js
  7726. * data: [{
  7727. * x: 1,
  7728. * y: 1,
  7729. * z: 1,
  7730. * name: "Point2",
  7731. * color: "#00FF00"
  7732. * }, {
  7733. * x: 1,
  7734. * y: 5,
  7735. * z: 4,
  7736. * name: "Point1",
  7737. * color: "#FF00FF"
  7738. * }]
  7739. * ```
  7740. *
  7741. * @sample {highcharts} highcharts/series/data-array-of-arrays/
  7742. * Arrays of numeric x and y
  7743. * @sample {highcharts} highcharts/series/data-array-of-arrays-datetime/
  7744. * Arrays of datetime x and y
  7745. * @sample {highcharts} highcharts/series/data-array-of-name-value/
  7746. * Arrays of point.name and y
  7747. * @sample {highcharts} highcharts/series/data-array-of-objects/
  7748. * Config objects
  7749. *
  7750. * @type {Array<Array<(number|string),number>|Array<(number|string),number,number>|*>}
  7751. * @extends series.line.data
  7752. * @product highcharts
  7753. * @apioption series.bubble.data
  7754. */
  7755. /**
  7756. * @extends series.line.data.marker
  7757. * @excluding enabledThreshold, height, radius, width
  7758. * @product highcharts
  7759. * @apioption series.bubble.data.marker
  7760. */
  7761. /**
  7762. * The size value for each bubble. The bubbles' diameters are computed
  7763. * based on the `z`, and controlled by series options like `minSize`,
  7764. * `maxSize`, `sizeBy`, `zMin` and `zMax`.
  7765. *
  7766. * @type {number|null}
  7767. * @product highcharts
  7768. * @apioption series.bubble.data.z
  7769. */
  7770. /**
  7771. * @excluding enabled, enabledThreshold, height, radius, width
  7772. * @apioption series.bubble.marker
  7773. */
  7774. ''; // adds doclets above to transpiled file
  7775. return BubbleSeries;
  7776. });
  7777. _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) {
  7778. /* *
  7779. *
  7780. * (c) 2010-2021 Grzegorz Blachlinski, Sebastian Bochan
  7781. *
  7782. * License: www.highcharts.com/license
  7783. *
  7784. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  7785. *
  7786. * */
  7787. var __extends = (this && this.__extends) || (function () {
  7788. var extendStatics = function (d,
  7789. b) {
  7790. extendStatics = Object.setPrototypeOf ||
  7791. ({ __proto__: [] } instanceof Array && function (d,
  7792. b) { d.__proto__ = b; }) ||
  7793. function (d,
  7794. b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  7795. return extendStatics(d, b);
  7796. };
  7797. return function (d, b) {
  7798. extendStatics(d, b);
  7799. function __() { this.constructor = d; }
  7800. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  7801. };
  7802. })();
  7803. var BubbleSeries = SeriesRegistry.seriesTypes.bubble;
  7804. /* *
  7805. *
  7806. * Class
  7807. *
  7808. * */
  7809. var PackedBubblePoint = /** @class */ (function (_super) {
  7810. __extends(PackedBubblePoint, _super);
  7811. function PackedBubblePoint() {
  7812. /* *
  7813. *
  7814. * Properties
  7815. *
  7816. * */
  7817. var _this = _super !== null && _super.apply(this,
  7818. arguments) || this;
  7819. _this.degree = NaN;
  7820. _this.mass = NaN;
  7821. _this.radius = NaN;
  7822. _this.options = void 0;
  7823. _this.series = void 0;
  7824. _this.value = null;
  7825. return _this;
  7826. /* eslint-enable valid-jsdoc */
  7827. }
  7828. /* *
  7829. *
  7830. * Functions
  7831. *
  7832. * */
  7833. /* eslint-disable valid-jsdoc */
  7834. /**
  7835. * Destroy point.
  7836. * Then remove point from the layout.
  7837. * @private
  7838. */
  7839. PackedBubblePoint.prototype.destroy = function () {
  7840. if (this.series.layout) {
  7841. this.series.layout.removeElementFromCollection(this, this.series.layout.nodes);
  7842. }
  7843. return Point.prototype.destroy.apply(this, arguments);
  7844. };
  7845. PackedBubblePoint.prototype.firePointEvent = function () {
  7846. var point = this,
  7847. series = this.series,
  7848. seriesOptions = series.options;
  7849. if (this.isParentNode && seriesOptions.parentNode) {
  7850. var temp = seriesOptions.allowPointSelect;
  7851. seriesOptions.allowPointSelect = seriesOptions.parentNode.allowPointSelect;
  7852. Point.prototype.firePointEvent.apply(this, arguments);
  7853. seriesOptions.allowPointSelect = temp;
  7854. }
  7855. else {
  7856. Point.prototype.firePointEvent.apply(this, arguments);
  7857. }
  7858. };
  7859. PackedBubblePoint.prototype.select = function () {
  7860. var point = this,
  7861. series = this.series,
  7862. chart = series.chart;
  7863. if (point.isParentNode) {
  7864. chart.getSelectedPoints = chart.getSelectedParentNodes;
  7865. Point.prototype.select.apply(this, arguments);
  7866. chart.getSelectedPoints = Chart.prototype.getSelectedPoints;
  7867. }
  7868. else {
  7869. Point.prototype.select.apply(this, arguments);
  7870. }
  7871. };
  7872. return PackedBubblePoint;
  7873. }(BubbleSeries.prototype.pointClass));
  7874. /* *
  7875. *
  7876. * Default Export
  7877. *
  7878. * */
  7879. return PackedBubblePoint;
  7880. });
  7881. _registerModule(_modules, 'Series/Networkgraph/DraggableNodes.js', [_modules['Core/Chart/Chart.js'], _modules['Core/Globals.js'], _modules['Core/Utilities.js']], function (Chart, H, U) {
  7882. /* *
  7883. *
  7884. * Networkgraph series
  7885. *
  7886. * (c) 2010-2021 Paweł Fus
  7887. *
  7888. * License: www.highcharts.com/license
  7889. *
  7890. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  7891. *
  7892. * */
  7893. var addEvent = U.addEvent;
  7894. /* eslint-disable no-invalid-this, valid-jsdoc */
  7895. H.dragNodesMixin = {
  7896. /**
  7897. * Mouse down action, initializing drag&drop mode.
  7898. *
  7899. * @private
  7900. * @param {Highcharts.Point} point The point that event occured.
  7901. * @param {Highcharts.PointerEventObject} event Browser event, before normalization.
  7902. * @return {void}
  7903. */
  7904. onMouseDown: function (point, event) {
  7905. var normalizedEvent = this.chart.pointer.normalize(event);
  7906. point.fixedPosition = {
  7907. chartX: normalizedEvent.chartX,
  7908. chartY: normalizedEvent.chartY,
  7909. plotX: point.plotX,
  7910. plotY: point.plotY
  7911. };
  7912. point.inDragMode = true;
  7913. },
  7914. /**
  7915. * Mouse move action during drag&drop.
  7916. *
  7917. * @private
  7918. *
  7919. * @param {global.Event} event Browser event, before normalization.
  7920. * @param {Highcharts.Point} point The point that event occured.
  7921. *
  7922. * @return {void}
  7923. */
  7924. onMouseMove: function (point, event) {
  7925. if (point.fixedPosition && point.inDragMode) {
  7926. var series = this,
  7927. chart = series.chart,
  7928. normalizedEvent = chart.pointer.normalize(event),
  7929. diffX = point.fixedPosition.chartX - normalizedEvent.chartX,
  7930. diffY = point.fixedPosition.chartY - normalizedEvent.chartY,
  7931. newPlotX,
  7932. newPlotY,
  7933. graphLayoutsLookup = chart.graphLayoutsLookup;
  7934. // At least 5px to apply change (avoids simple click):
  7935. if (Math.abs(diffX) > 5 || Math.abs(diffY) > 5) {
  7936. newPlotX = point.fixedPosition.plotX - diffX;
  7937. newPlotY = point.fixedPosition.plotY - diffY;
  7938. if (chart.isInsidePlot(newPlotX, newPlotY)) {
  7939. point.plotX = newPlotX;
  7940. point.plotY = newPlotY;
  7941. point.hasDragged = true;
  7942. this.redrawHalo(point);
  7943. graphLayoutsLookup.forEach(function (layout) {
  7944. layout.restartSimulation();
  7945. });
  7946. }
  7947. }
  7948. }
  7949. },
  7950. /**
  7951. * Mouse up action, finalizing drag&drop.
  7952. *
  7953. * @private
  7954. * @param {Highcharts.Point} point The point that event occured.
  7955. * @return {void}
  7956. */
  7957. onMouseUp: function (point, event) {
  7958. if (point.fixedPosition) {
  7959. if (point.hasDragged) {
  7960. if (this.layout.enableSimulation) {
  7961. this.layout.start();
  7962. }
  7963. else {
  7964. this.chart.redraw();
  7965. }
  7966. }
  7967. point.inDragMode = point.hasDragged = false;
  7968. if (!this.options.fixedDraggable) {
  7969. delete point.fixedPosition;
  7970. }
  7971. }
  7972. },
  7973. // Draggable mode:
  7974. /**
  7975. * Redraw halo on mousemove during the drag&drop action.
  7976. *
  7977. * @private
  7978. * @param {Highcharts.Point} point The point that should show halo.
  7979. * @return {void}
  7980. */
  7981. redrawHalo: function (point) {
  7982. if (point && this.halo) {
  7983. this.halo.attr({
  7984. d: point.haloPath(this.options.states.hover.halo.size)
  7985. });
  7986. }
  7987. }
  7988. };
  7989. /*
  7990. * Draggable mode:
  7991. */
  7992. addEvent(Chart, 'load', function () {
  7993. var chart = this,
  7994. mousedownUnbinder,
  7995. mousemoveUnbinder,
  7996. mouseupUnbinder;
  7997. if (chart.container) {
  7998. mousedownUnbinder = addEvent(chart.container, 'mousedown', function (event) {
  7999. var point = chart.hoverPoint;
  8000. if (point &&
  8001. point.series &&
  8002. point.series.hasDraggableNodes &&
  8003. point.series.options.draggable) {
  8004. point.series.onMouseDown(point, event);
  8005. mousemoveUnbinder = addEvent(chart.container, 'mousemove', function (e) {
  8006. return point &&
  8007. point.series &&
  8008. point.series.onMouseMove(point, e);
  8009. });
  8010. mouseupUnbinder = addEvent(chart.container.ownerDocument, 'mouseup', function (e) {
  8011. mousemoveUnbinder();
  8012. mouseupUnbinder();
  8013. return point &&
  8014. point.series &&
  8015. point.series.onMouseUp(point, e);
  8016. });
  8017. }
  8018. });
  8019. }
  8020. addEvent(chart, 'destroy', function () {
  8021. mousedownUnbinder();
  8022. });
  8023. });
  8024. });
  8025. _registerModule(_modules, 'Series/Networkgraph/Integrations.js', [_modules['Core/Globals.js']], function (H) {
  8026. /* *
  8027. *
  8028. * Networkgraph series
  8029. *
  8030. * (c) 2010-2021 Paweł Fus
  8031. *
  8032. * License: www.highcharts.com/license
  8033. *
  8034. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  8035. *
  8036. * */
  8037. /* eslint-disable no-invalid-this, valid-jsdoc */
  8038. H.networkgraphIntegrations = {
  8039. verlet: {
  8040. /**
  8041. * Attractive force funtion. Can be replaced by API's
  8042. * `layoutAlgorithm.attractiveForce`
  8043. *
  8044. * @private
  8045. * @param {number} d current distance between two nodes
  8046. * @param {number} k expected distance between two nodes
  8047. * @return {number} force
  8048. */
  8049. attractiveForceFunction: function (d, k) {
  8050. // Used in API:
  8051. return (k - d) / d;
  8052. },
  8053. /**
  8054. * Repulsive force funtion. Can be replaced by API's
  8055. * `layoutAlgorithm.repulsiveForce`
  8056. *
  8057. * @private
  8058. * @param {number} d current distance between two nodes
  8059. * @param {number} k expected distance between two nodes
  8060. * @return {number} force
  8061. */
  8062. repulsiveForceFunction: function (d, k) {
  8063. // Used in API:
  8064. return (k - d) / d * (k > d ? 1 : 0); // Force only for close nodes
  8065. },
  8066. /**
  8067. * Barycenter force. Calculate and applys barycenter forces on the
  8068. * nodes. Making them closer to the center of their barycenter point.
  8069. *
  8070. * In Verlet integration, force is applied on a node immidatelly to it's
  8071. * `plotX` and `plotY` position.
  8072. *
  8073. * @private
  8074. * @return {void}
  8075. */
  8076. barycenter: function () {
  8077. var gravitationalConstant = this.options.gravitationalConstant,
  8078. xFactor = this.barycenter.xFactor,
  8079. yFactor = this.barycenter.yFactor;
  8080. // To consider:
  8081. xFactor = (xFactor - (this.box.left + this.box.width) / 2) *
  8082. gravitationalConstant;
  8083. yFactor = (yFactor - (this.box.top + this.box.height) / 2) *
  8084. gravitationalConstant;
  8085. this.nodes.forEach(function (node) {
  8086. if (!node.fixedPosition) {
  8087. node.plotX -=
  8088. xFactor / node.mass / node.degree;
  8089. node.plotY -=
  8090. yFactor / node.mass / node.degree;
  8091. }
  8092. });
  8093. },
  8094. /**
  8095. * Repulsive force.
  8096. *
  8097. * In Verlet integration, force is applied on a node immidatelly to it's
  8098. * `plotX` and `plotY` position.
  8099. *
  8100. * @private
  8101. * @param {Highcharts.Point} node
  8102. * Node that should be translated by force.
  8103. * @param {number} force
  8104. * Force calcualated in `repulsiveForceFunction`
  8105. * @param {Highcharts.PositionObject} distance
  8106. * Distance between two nodes e.g. `{x, y}`
  8107. * @return {void}
  8108. */
  8109. repulsive: function (node, force, distanceXY) {
  8110. var factor = force * this.diffTemperature / node.mass / node.degree;
  8111. if (!node.fixedPosition) {
  8112. node.plotX += distanceXY.x * factor;
  8113. node.plotY += distanceXY.y * factor;
  8114. }
  8115. },
  8116. /**
  8117. * Attractive force.
  8118. *
  8119. * In Verlet integration, force is applied on a node immidatelly to it's
  8120. * `plotX` and `plotY` position.
  8121. *
  8122. * @private
  8123. * @param {Highcharts.Point} link
  8124. * Link that connects two nodes
  8125. * @param {number} force
  8126. * Force calcualated in `repulsiveForceFunction`
  8127. * @param {Highcharts.PositionObject} distance
  8128. * Distance between two nodes e.g. `{x, y}`
  8129. * @return {void}
  8130. */
  8131. attractive: function (link, force, distanceXY) {
  8132. var massFactor = link.getMass(),
  8133. translatedX = -distanceXY.x * force * this.diffTemperature,
  8134. translatedY = -distanceXY.y * force * this.diffTemperature;
  8135. if (!link.fromNode.fixedPosition) {
  8136. link.fromNode.plotX -=
  8137. translatedX * massFactor.fromNode / link.fromNode.degree;
  8138. link.fromNode.plotY -=
  8139. translatedY * massFactor.fromNode / link.fromNode.degree;
  8140. }
  8141. if (!link.toNode.fixedPosition) {
  8142. link.toNode.plotX +=
  8143. translatedX * massFactor.toNode / link.toNode.degree;
  8144. link.toNode.plotY +=
  8145. translatedY * massFactor.toNode / link.toNode.degree;
  8146. }
  8147. },
  8148. /**
  8149. * Integration method.
  8150. *
  8151. * In Verlet integration, forces are applied on node immidatelly to it's
  8152. * `plotX` and `plotY` position.
  8153. *
  8154. * Verlet without velocity:
  8155. *
  8156. * x(n+1) = 2 * x(n) - x(n-1) + A(T) * deltaT ^ 2
  8157. *
  8158. * where:
  8159. * - x(n+1) - new position
  8160. * - x(n) - current position
  8161. * - x(n-1) - previous position
  8162. *
  8163. * Assuming A(t) = 0 (no acceleration) and (deltaT = 1) we get:
  8164. *
  8165. * x(n+1) = x(n) + (x(n) - x(n-1))
  8166. *
  8167. * where:
  8168. * - (x(n) - x(n-1)) - position change
  8169. *
  8170. * TO DO:
  8171. * Consider Verlet with velocity to support additional
  8172. * forces. Or even Time-Corrected Verlet by Jonathan
  8173. * "lonesock" Dummer
  8174. *
  8175. * @private
  8176. * @param {Highcharts.NetworkgraphLayout} layout layout object
  8177. * @param {Highcharts.Point} node node that should be translated
  8178. * @return {void}
  8179. */
  8180. integrate: function (layout, node) {
  8181. var friction = -layout.options.friction,
  8182. maxSpeed = layout.options.maxSpeed,
  8183. prevX = node.prevX,
  8184. prevY = node.prevY,
  8185. // Apply friciton:
  8186. diffX = ((node.plotX + node.dispX -
  8187. prevX) * friction),
  8188. diffY = ((node.plotY + node.dispY -
  8189. prevY) * friction),
  8190. abs = Math.abs,
  8191. signX = abs(diffX) / (diffX || 1), // need to deal with 0
  8192. signY = abs(diffY) / (diffY || 1);
  8193. // Apply max speed:
  8194. diffX = signX * Math.min(maxSpeed, Math.abs(diffX));
  8195. diffY = signY * Math.min(maxSpeed, Math.abs(diffY));
  8196. // Store for the next iteration:
  8197. node.prevX = node.plotX + node.dispX;
  8198. node.prevY = node.plotY + node.dispY;
  8199. // Update positions:
  8200. node.plotX += diffX;
  8201. node.plotY += diffY;
  8202. node.temperature = layout.vectorLength({
  8203. x: diffX,
  8204. y: diffY
  8205. });
  8206. },
  8207. /**
  8208. * Estiamte the best possible distance between two nodes, making graph
  8209. * readable.
  8210. *
  8211. * @private
  8212. * @param {Highcharts.NetworkgraphLayout} layout layout object
  8213. * @return {number}
  8214. */
  8215. getK: function (layout) {
  8216. return Math.pow(layout.box.width * layout.box.height / layout.nodes.length, 0.5);
  8217. }
  8218. },
  8219. euler: {
  8220. /**
  8221. * Attractive force funtion. Can be replaced by API's
  8222. * `layoutAlgorithm.attractiveForce`
  8223. *
  8224. * Other forces that can be used:
  8225. *
  8226. * basic, not recommended:
  8227. * `function (d, k) { return d / k }`
  8228. *
  8229. * @private
  8230. * @param {number} d current distance between two nodes
  8231. * @param {number} k expected distance between two nodes
  8232. * @return {number} force
  8233. */
  8234. attractiveForceFunction: function (d, k) {
  8235. return d * d / k;
  8236. },
  8237. /**
  8238. * Repulsive force funtion. Can be replaced by API's
  8239. * `layoutAlgorithm.repulsiveForce`.
  8240. *
  8241. * Other forces that can be used:
  8242. *
  8243. * basic, not recommended:
  8244. * `function (d, k) { return k / d }`
  8245. *
  8246. * standard:
  8247. * `function (d, k) { return k * k / d }`
  8248. *
  8249. * grid-variant:
  8250. * `function (d, k) { return k * k / d * (2 * k - d > 0 ? 1 : 0) }`
  8251. *
  8252. * @private
  8253. * @param {number} d current distance between two nodes
  8254. * @param {number} k expected distance between two nodes
  8255. * @return {number} force
  8256. */
  8257. repulsiveForceFunction: function (d, k) {
  8258. return k * k / d;
  8259. },
  8260. /**
  8261. * Barycenter force. Calculate and applys barycenter forces on the
  8262. * nodes. Making them closer to the center of their barycenter point.
  8263. *
  8264. * In Euler integration, force is stored in a node, not changing it's
  8265. * position. Later, in `integrate()` forces are applied on nodes.
  8266. *
  8267. * @private
  8268. * @return {void}
  8269. */
  8270. barycenter: function () {
  8271. var gravitationalConstant = this.options.gravitationalConstant,
  8272. xFactor = this.barycenter.xFactor,
  8273. yFactor = this.barycenter.yFactor;
  8274. this.nodes.forEach(function (node) {
  8275. if (!node.fixedPosition) {
  8276. var degree = node.getDegree(),
  8277. phi = degree * (1 + degree / 2);
  8278. node.dispX += ((xFactor - node.plotX) *
  8279. gravitationalConstant *
  8280. phi / node.degree);
  8281. node.dispY += ((yFactor - node.plotY) *
  8282. gravitationalConstant *
  8283. phi / node.degree);
  8284. }
  8285. });
  8286. },
  8287. /**
  8288. * Repulsive force.
  8289. *
  8290. * @private
  8291. * @param {Highcharts.Point} node
  8292. * Node that should be translated by force.
  8293. * @param {number} force
  8294. * Force calcualated in `repulsiveForceFunction`
  8295. * @param {Highcharts.PositionObject} distanceXY
  8296. * Distance between two nodes e.g. `{x, y}`
  8297. * @return {void}
  8298. */
  8299. repulsive: function (node, force, distanceXY, distanceR) {
  8300. node.dispX +=
  8301. (distanceXY.x / distanceR) * force / node.degree;
  8302. node.dispY +=
  8303. (distanceXY.y / distanceR) * force / node.degree;
  8304. },
  8305. /**
  8306. * Attractive force.
  8307. *
  8308. * In Euler integration, force is stored in a node, not changing it's
  8309. * position. Later, in `integrate()` forces are applied on nodes.
  8310. *
  8311. * @private
  8312. * @param {Highcharts.Point} link
  8313. * Link that connects two nodes
  8314. * @param {number} force
  8315. * Force calcualated in `repulsiveForceFunction`
  8316. * @param {Highcharts.PositionObject} distanceXY
  8317. * Distance between two nodes e.g. `{x, y}`
  8318. * @param {number} distanceR
  8319. * @return {void}
  8320. */
  8321. attractive: function (link, force, distanceXY, distanceR) {
  8322. var massFactor = link.getMass(),
  8323. translatedX = (distanceXY.x / distanceR) * force,
  8324. translatedY = (distanceXY.y / distanceR) * force;
  8325. if (!link.fromNode.fixedPosition) {
  8326. link.fromNode.dispX -=
  8327. translatedX * massFactor.fromNode / link.fromNode.degree;
  8328. link.fromNode.dispY -=
  8329. translatedY * massFactor.fromNode / link.fromNode.degree;
  8330. }
  8331. if (!link.toNode.fixedPosition) {
  8332. link.toNode.dispX +=
  8333. translatedX * massFactor.toNode / link.toNode.degree;
  8334. link.toNode.dispY +=
  8335. translatedY * massFactor.toNode / link.toNode.degree;
  8336. }
  8337. },
  8338. /**
  8339. * Integration method.
  8340. *
  8341. * In Euler integration, force were stored in a node, not changing it's
  8342. * position. Now, in the integrator method, we apply changes.
  8343. *
  8344. * Euler:
  8345. *
  8346. * Basic form: `x(n+1) = x(n) + v(n)`
  8347. *
  8348. * With Rengoild-Fruchterman we get:
  8349. * `x(n+1) = x(n) + v(n) / length(v(n)) * min(v(n), temperature(n))`
  8350. * where:
  8351. * - `x(n+1)`: next position
  8352. * - `x(n)`: current position
  8353. * - `v(n)`: velocity (comes from net force)
  8354. * - `temperature(n)`: current temperature
  8355. *
  8356. * Known issues:
  8357. * Oscillations when force vector has the same magnitude but opposite
  8358. * direction in the next step. Potentially solved by decreasing force by
  8359. * `v * (1 / node.degree)`
  8360. *
  8361. * Note:
  8362. * Actually `min(v(n), temperature(n))` replaces simulated annealing.
  8363. *
  8364. * @private
  8365. * @param {Highcharts.NetworkgraphLayout} layout
  8366. * Layout object
  8367. * @param {Highcharts.Point} node
  8368. * Node that should be translated
  8369. * @return {void}
  8370. */
  8371. integrate: function (layout, node) {
  8372. var distanceR;
  8373. node.dispX +=
  8374. node.dispX * layout.options.friction;
  8375. node.dispY +=
  8376. node.dispY * layout.options.friction;
  8377. distanceR = node.temperature = layout.vectorLength({
  8378. x: node.dispX,
  8379. y: node.dispY
  8380. });
  8381. if (distanceR !== 0) {
  8382. node.plotX += (node.dispX / distanceR *
  8383. Math.min(Math.abs(node.dispX), layout.temperature));
  8384. node.plotY += (node.dispY / distanceR *
  8385. Math.min(Math.abs(node.dispY), layout.temperature));
  8386. }
  8387. },
  8388. /**
  8389. * Estiamte the best possible distance between two nodes, making graph
  8390. * readable.
  8391. *
  8392. * @private
  8393. * @param {object} layout layout object
  8394. * @return {number}
  8395. */
  8396. getK: function (layout) {
  8397. return Math.pow(layout.box.width * layout.box.height / layout.nodes.length, 0.3);
  8398. }
  8399. }
  8400. };
  8401. });
  8402. _registerModule(_modules, 'Series/Networkgraph/QuadTree.js', [_modules['Core/Globals.js'], _modules['Core/Utilities.js']], function (H, U) {
  8403. /* *
  8404. *
  8405. * Networkgraph series
  8406. *
  8407. * (c) 2010-2021 Paweł Fus
  8408. *
  8409. * License: www.highcharts.com/license
  8410. *
  8411. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  8412. *
  8413. * */
  8414. var extend = U.extend;
  8415. /* eslint-disable no-invalid-this, valid-jsdoc */
  8416. /**
  8417. * The QuadTree node class. Used in Networkgraph chart as a base for Barnes-Hut
  8418. * approximation.
  8419. *
  8420. * @private
  8421. * @class
  8422. * @name Highcharts.QuadTreeNode
  8423. *
  8424. * @param {Highcharts.Dictionary<number>} box Available space for the node
  8425. */
  8426. var QuadTreeNode = H.QuadTreeNode = function (box) {
  8427. /**
  8428. * Read only. The available space for node.
  8429. *
  8430. * @name Highcharts.QuadTreeNode#box
  8431. * @type {Highcharts.Dictionary<number>}
  8432. */
  8433. this.box = box;
  8434. /**
  8435. * Read only. The minium of width and height values.
  8436. *
  8437. * @name Highcharts.QuadTreeNode#boxSize
  8438. * @type {number}
  8439. */
  8440. this.boxSize = Math.min(box.width, box.height);
  8441. /**
  8442. * Read only. Array of subnodes. Empty if QuadTreeNode has just one Point.
  8443. * When added another Point to this QuadTreeNode, array is filled with four
  8444. * subnodes.
  8445. *
  8446. * @name Highcharts.QuadTreeNode#nodes
  8447. * @type {Array<Highcharts.QuadTreeNode>}
  8448. */
  8449. this.nodes = [];
  8450. /**
  8451. * Read only. Flag to determine if QuadTreeNode is internal (and has
  8452. * subnodes with mass and central position) or external (bound to Point).
  8453. *
  8454. * @name Highcharts.QuadTreeNode#isInternal
  8455. * @type {boolean}
  8456. */
  8457. this.isInternal = false;
  8458. /**
  8459. * Read only. If QuadTreeNode is an external node, Point is stored in
  8460. * `this.body`.
  8461. *
  8462. * @name Highcharts.QuadTreeNode#body
  8463. * @type {boolean|Highcharts.Point}
  8464. */
  8465. this.body = false;
  8466. /**
  8467. * Read only. Internal nodes when created are empty to reserve the space. If
  8468. * Point is added to this QuadTreeNode, QuadTreeNode is no longer empty.
  8469. *
  8470. * @name Highcharts.QuadTreeNode#isEmpty
  8471. * @type {boolean}
  8472. */
  8473. this.isEmpty = true;
  8474. };
  8475. extend(QuadTreeNode.prototype,
  8476. /** @lends Highcharts.QuadTreeNode.prototype */
  8477. {
  8478. /**
  8479. * Insert recursively point(node) into the QuadTree. If the given
  8480. * quadrant is already occupied, divide it into smaller quadrants.
  8481. *
  8482. * @param {Highcharts.Point} point
  8483. * Point/node to be inserted
  8484. * @param {number} depth
  8485. * Max depth of the QuadTree
  8486. */
  8487. insert: function (point, depth) {
  8488. var newQuadTreeNode;
  8489. if (this.isInternal) {
  8490. // Internal node:
  8491. this.nodes[this.getBoxPosition(point)].insert(point, depth - 1);
  8492. }
  8493. else {
  8494. this.isEmpty = false;
  8495. if (!this.body) {
  8496. // First body in a quadrant:
  8497. this.isInternal = false;
  8498. this.body = point;
  8499. }
  8500. else {
  8501. if (depth) {
  8502. // Every other body in a quadrant:
  8503. this.isInternal = true;
  8504. this.divideBox();
  8505. // Reinsert main body only once:
  8506. if (this.body !== true) {
  8507. this.nodes[this.getBoxPosition(this.body)]
  8508. .insert(this.body, depth - 1);
  8509. this.body = true;
  8510. }
  8511. // Add second body:
  8512. this.nodes[this.getBoxPosition(point)]
  8513. .insert(point, depth - 1);
  8514. }
  8515. else {
  8516. // We are below max allowed depth. That means either:
  8517. // - really huge number of points
  8518. // - falling two points into exactly the same position
  8519. // In this case, create another node in the QuadTree.
  8520. //
  8521. // Alternatively we could add some noise to the
  8522. // position, but that could result in different
  8523. // rendered chart in exporting.
  8524. newQuadTreeNode = new QuadTreeNode({
  8525. top: point.plotX,
  8526. left: point.plotY,
  8527. // Width/height below 1px
  8528. width: 0.1,
  8529. height: 0.1
  8530. });
  8531. newQuadTreeNode.body = point;
  8532. newQuadTreeNode.isInternal = false;
  8533. this.nodes.push(newQuadTreeNode);
  8534. }
  8535. }
  8536. }
  8537. },
  8538. /**
  8539. * Each quad node requires it's mass and center position. That mass and
  8540. * position is used to imitate real node in the layout by approximation.
  8541. */
  8542. updateMassAndCenter: function () {
  8543. var mass = 0,
  8544. plotX = 0,
  8545. plotY = 0;
  8546. if (this.isInternal) {
  8547. // Calcualte weightened mass of the quad node:
  8548. this.nodes.forEach(function (pointMass) {
  8549. if (!pointMass.isEmpty) {
  8550. mass += pointMass.mass;
  8551. plotX +=
  8552. pointMass.plotX * pointMass.mass;
  8553. plotY +=
  8554. pointMass.plotY * pointMass.mass;
  8555. }
  8556. });
  8557. plotX /= mass;
  8558. plotY /= mass;
  8559. }
  8560. else if (this.body) {
  8561. // Just one node, use coordinates directly:
  8562. mass = this.body.mass;
  8563. plotX = this.body.plotX;
  8564. plotY = this.body.plotY;
  8565. }
  8566. // Store details:
  8567. this.mass = mass;
  8568. this.plotX = plotX;
  8569. this.plotY = plotY;
  8570. },
  8571. /**
  8572. * When inserting another node into the box, that already hove one node,
  8573. * divide the available space into another four quadrants.
  8574. *
  8575. * Indexes of quadrants are:
  8576. * ```
  8577. * ------------- -------------
  8578. * | | | | |
  8579. * | | | 0 | 1 |
  8580. * | | divide() | | |
  8581. * | 1 | -----------> -------------
  8582. * | | | | |
  8583. * | | | 3 | 2 |
  8584. * | | | | |
  8585. * ------------- -------------
  8586. * ```
  8587. */
  8588. divideBox: function () {
  8589. var halfWidth = this.box.width / 2,
  8590. halfHeight = this.box.height / 2;
  8591. // Top left
  8592. this.nodes[0] = new QuadTreeNode({
  8593. left: this.box.left,
  8594. top: this.box.top,
  8595. width: halfWidth,
  8596. height: halfHeight
  8597. });
  8598. // Top right
  8599. this.nodes[1] = new QuadTreeNode({
  8600. left: this.box.left + halfWidth,
  8601. top: this.box.top,
  8602. width: halfWidth,
  8603. height: halfHeight
  8604. });
  8605. // Bottom right
  8606. this.nodes[2] = new QuadTreeNode({
  8607. left: this.box.left + halfWidth,
  8608. top: this.box.top + halfHeight,
  8609. width: halfWidth,
  8610. height: halfHeight
  8611. });
  8612. // Bottom left
  8613. this.nodes[3] = new QuadTreeNode({
  8614. left: this.box.left,
  8615. top: this.box.top + halfHeight,
  8616. width: halfWidth,
  8617. height: halfHeight
  8618. });
  8619. },
  8620. /**
  8621. * Determine which of the quadrants should be used when placing node in
  8622. * the QuadTree. Returned index is always in range `< 0 , 3 >`.
  8623. *
  8624. * @param {Highcharts.Point} point
  8625. * @return {number}
  8626. */
  8627. getBoxPosition: function (point) {
  8628. var left = point.plotX < this.box.left + this.box.width / 2,
  8629. top = point.plotY < this.box.top + this.box.height / 2,
  8630. index;
  8631. if (left) {
  8632. if (top) {
  8633. // Top left
  8634. index = 0;
  8635. }
  8636. else {
  8637. // Bottom left
  8638. index = 3;
  8639. }
  8640. }
  8641. else {
  8642. if (top) {
  8643. // Top right
  8644. index = 1;
  8645. }
  8646. else {
  8647. // Bottom right
  8648. index = 2;
  8649. }
  8650. }
  8651. return index;
  8652. }
  8653. });
  8654. /**
  8655. * The QuadTree class. Used in Networkgraph chart as a base for Barnes-Hut
  8656. * approximation.
  8657. *
  8658. * @private
  8659. * @class
  8660. * @name Highcharts.QuadTree
  8661. *
  8662. * @param {number} x left position of the plotting area
  8663. * @param {number} y top position of the plotting area
  8664. * @param {number} width width of the plotting area
  8665. * @param {number} height height of the plotting area
  8666. */
  8667. var QuadTree = H.QuadTree = function (x,
  8668. y,
  8669. width,
  8670. height) {
  8671. // Boundary rectangle:
  8672. this.box = {
  8673. left: x,
  8674. top: y,
  8675. width: width,
  8676. height: height
  8677. };
  8678. this.maxDepth = 25;
  8679. this.root = new QuadTreeNode(this.box, '0');
  8680. this.root.isInternal = true;
  8681. this.root.isRoot = true;
  8682. this.root.divideBox();
  8683. };
  8684. extend(QuadTree.prototype,
  8685. /** @lends Highcharts.QuadTree.prototype */
  8686. {
  8687. /**
  8688. * Insert nodes into the QuadTree
  8689. *
  8690. * @param {Array<Highcharts.Point>} points
  8691. */
  8692. insertNodes: function (points) {
  8693. points.forEach(function (point) {
  8694. this.root.insert(point, this.maxDepth);
  8695. }, this);
  8696. },
  8697. /**
  8698. * Depfth first treversal (DFS). Using `before` and `after` callbacks,
  8699. * we can get two results: preorder and postorder traversals, reminder:
  8700. *
  8701. * ```
  8702. * (a)
  8703. * / \
  8704. * (b) (c)
  8705. * / \
  8706. * (d) (e)
  8707. * ```
  8708. *
  8709. * DFS (preorder): `a -> b -> d -> e -> c`
  8710. *
  8711. * DFS (postorder): `d -> e -> b -> c -> a`
  8712. *
  8713. * @param {Highcharts.QuadTreeNode|null} node
  8714. * @param {Function} [beforeCallback] function to be called before
  8715. * visiting children nodes
  8716. * @param {Function} [afterCallback] function to be called after
  8717. * visiting children nodes
  8718. */
  8719. visitNodeRecursive: function (node, beforeCallback, afterCallback) {
  8720. var goFurther;
  8721. if (!node) {
  8722. node = this.root;
  8723. }
  8724. if (node === this.root && beforeCallback) {
  8725. goFurther = beforeCallback(node);
  8726. }
  8727. if (goFurther === false) {
  8728. return;
  8729. }
  8730. node.nodes.forEach(function (qtNode) {
  8731. if (qtNode.isInternal) {
  8732. if (beforeCallback) {
  8733. goFurther = beforeCallback(qtNode);
  8734. }
  8735. if (goFurther === false) {
  8736. return;
  8737. }
  8738. this.visitNodeRecursive(qtNode, beforeCallback, afterCallback);
  8739. }
  8740. else if (qtNode.body) {
  8741. if (beforeCallback) {
  8742. beforeCallback(qtNode.body);
  8743. }
  8744. }
  8745. if (afterCallback) {
  8746. afterCallback(qtNode);
  8747. }
  8748. }, this);
  8749. if (node === this.root && afterCallback) {
  8750. afterCallback(node);
  8751. }
  8752. },
  8753. /**
  8754. * Calculate mass of the each QuadNode in the tree.
  8755. */
  8756. calculateMassAndCenter: function () {
  8757. this.visitNodeRecursive(null, null, function (node) {
  8758. node.updateMassAndCenter();
  8759. });
  8760. }
  8761. });
  8762. });
  8763. _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) {
  8764. /* *
  8765. *
  8766. * Networkgraph series
  8767. *
  8768. * (c) 2010-2021 Paweł Fus
  8769. *
  8770. * License: www.highcharts.com/license
  8771. *
  8772. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  8773. *
  8774. * */
  8775. var setAnimation = A.setAnimation;
  8776. var addEvent = U.addEvent,
  8777. clamp = U.clamp,
  8778. defined = U.defined,
  8779. extend = U.extend,
  8780. isFunction = U.isFunction,
  8781. pick = U.pick;
  8782. /* eslint-disable no-invalid-this, valid-jsdoc */
  8783. H.layouts = {
  8784. 'reingold-fruchterman': function () {
  8785. }
  8786. };
  8787. extend(
  8788. /**
  8789. * Reingold-Fruchterman algorithm from
  8790. * "Graph Drawing by Force-directed Placement" paper.
  8791. * @private
  8792. */
  8793. H.layouts['reingold-fruchterman'].prototype, {
  8794. init: function (options) {
  8795. this.options = options;
  8796. this.nodes = [];
  8797. this.links = [];
  8798. this.series = [];
  8799. this.box = {
  8800. x: 0,
  8801. y: 0,
  8802. width: 0,
  8803. height: 0
  8804. };
  8805. this.setInitialRendering(true);
  8806. this.integration =
  8807. H.networkgraphIntegrations[options.integration];
  8808. this.enableSimulation = options.enableSimulation;
  8809. this.attractiveForce = pick(options.attractiveForce, this.integration.attractiveForceFunction);
  8810. this.repulsiveForce = pick(options.repulsiveForce, this.integration.repulsiveForceFunction);
  8811. this.approximation = options.approximation;
  8812. },
  8813. updateSimulation: function (enable) {
  8814. this.enableSimulation = pick(enable, this.options.enableSimulation);
  8815. },
  8816. start: function () {
  8817. var layout = this,
  8818. series = this.series,
  8819. options = this.options;
  8820. layout.currentStep = 0;
  8821. layout.forces = series[0] && series[0].forces || [];
  8822. layout.chart = series[0] && series[0].chart;
  8823. if (layout.initialRendering) {
  8824. layout.initPositions();
  8825. // Render elements in initial positions:
  8826. series.forEach(function (s) {
  8827. s.finishedAnimating = true; // #13169
  8828. s.render();
  8829. });
  8830. }
  8831. layout.setK();
  8832. layout.resetSimulation(options);
  8833. if (layout.enableSimulation) {
  8834. layout.step();
  8835. }
  8836. },
  8837. step: function () {
  8838. var layout = this,
  8839. series = this.series,
  8840. options = this.options;
  8841. // Algorithm:
  8842. layout.currentStep++;
  8843. if (layout.approximation === 'barnes-hut') {
  8844. layout.createQuadTree();
  8845. layout.quadTree.calculateMassAndCenter();
  8846. }
  8847. layout.forces.forEach(function (forceName) {
  8848. layout[forceName + 'Forces'](layout.temperature);
  8849. });
  8850. // Limit to the plotting area and cool down:
  8851. layout.applyLimits(layout.temperature);
  8852. // Cool down the system:
  8853. layout.temperature = layout.coolDown(layout.startTemperature, layout.diffTemperature, layout.currentStep);
  8854. layout.prevSystemTemperature = layout.systemTemperature;
  8855. layout.systemTemperature = layout.getSystemTemperature();
  8856. if (layout.enableSimulation) {
  8857. series.forEach(function (s) {
  8858. // Chart could be destroyed during the simulation
  8859. if (s.chart) {
  8860. s.render();
  8861. }
  8862. });
  8863. if (layout.maxIterations-- &&
  8864. isFinite(layout.temperature) &&
  8865. !layout.isStable()) {
  8866. if (layout.simulation) {
  8867. H.win.cancelAnimationFrame(layout.simulation);
  8868. }
  8869. layout.simulation = H.win.requestAnimationFrame(function () {
  8870. layout.step();
  8871. });
  8872. }
  8873. else {
  8874. layout.simulation = false;
  8875. }
  8876. }
  8877. },
  8878. stop: function () {
  8879. if (this.simulation) {
  8880. H.win.cancelAnimationFrame(this.simulation);
  8881. }
  8882. },
  8883. setArea: function (x, y, w, h) {
  8884. this.box = {
  8885. left: x,
  8886. top: y,
  8887. width: w,
  8888. height: h
  8889. };
  8890. },
  8891. setK: function () {
  8892. // Optimal distance between nodes,
  8893. // available space around the node:
  8894. this.k = this.options.linkLength || this.integration.getK(this);
  8895. },
  8896. addElementsToCollection: function (elements, collection) {
  8897. elements.forEach(function (elem) {
  8898. if (collection.indexOf(elem) === -1) {
  8899. collection.push(elem);
  8900. }
  8901. });
  8902. },
  8903. removeElementFromCollection: function (element, collection) {
  8904. var index = collection.indexOf(element);
  8905. if (index !== -1) {
  8906. collection.splice(index, 1);
  8907. }
  8908. },
  8909. clear: function () {
  8910. this.nodes.length = 0;
  8911. this.links.length = 0;
  8912. this.series.length = 0;
  8913. this.resetSimulation();
  8914. },
  8915. resetSimulation: function () {
  8916. this.forcedStop = false;
  8917. this.systemTemperature = 0;
  8918. this.setMaxIterations();
  8919. this.setTemperature();
  8920. this.setDiffTemperature();
  8921. },
  8922. restartSimulation: function () {
  8923. if (!this.simulation) {
  8924. // When dragging nodes, we don't need to calculate
  8925. // initial positions and rendering nodes:
  8926. this.setInitialRendering(false);
  8927. // Start new simulation:
  8928. if (!this.enableSimulation) {
  8929. // Run only one iteration to speed things up:
  8930. this.setMaxIterations(1);
  8931. }
  8932. else {
  8933. this.start();
  8934. }
  8935. if (this.chart) {
  8936. this.chart.redraw();
  8937. }
  8938. // Restore defaults:
  8939. this.setInitialRendering(true);
  8940. }
  8941. else {
  8942. // Extend current simulation:
  8943. this.resetSimulation();
  8944. }
  8945. },
  8946. setMaxIterations: function (maxIterations) {
  8947. this.maxIterations = pick(maxIterations, this.options.maxIterations);
  8948. },
  8949. setTemperature: function () {
  8950. this.temperature = this.startTemperature =
  8951. Math.sqrt(this.nodes.length);
  8952. },
  8953. setDiffTemperature: function () {
  8954. this.diffTemperature = this.startTemperature /
  8955. (this.options.maxIterations + 1);
  8956. },
  8957. setInitialRendering: function (enable) {
  8958. this.initialRendering = enable;
  8959. },
  8960. createQuadTree: function () {
  8961. this.quadTree = new H.QuadTree(this.box.left, this.box.top, this.box.width, this.box.height);
  8962. this.quadTree.insertNodes(this.nodes);
  8963. },
  8964. initPositions: function () {
  8965. var initialPositions = this.options.initialPositions;
  8966. if (isFunction(initialPositions)) {
  8967. initialPositions.call(this);
  8968. this.nodes.forEach(function (node) {
  8969. if (!defined(node.prevX)) {
  8970. node.prevX = node.plotX;
  8971. }
  8972. if (!defined(node.prevY)) {
  8973. node.prevY = node.plotY;
  8974. }
  8975. node.dispX = 0;
  8976. node.dispY = 0;
  8977. });
  8978. }
  8979. else if (initialPositions === 'circle') {
  8980. this.setCircularPositions();
  8981. }
  8982. else {
  8983. this.setRandomPositions();
  8984. }
  8985. },
  8986. setCircularPositions: function () {
  8987. var box = this.box,
  8988. nodes = this.nodes,
  8989. nodesLength = nodes.length + 1,
  8990. angle = 2 * Math.PI / nodesLength,
  8991. rootNodes = nodes.filter(function (node) {
  8992. return node.linksTo.length === 0;
  8993. }), sortedNodes = [], visitedNodes = {}, radius = this.options.initialPositionRadius;
  8994. /**
  8995. * @private
  8996. */
  8997. function addToNodes(node) {
  8998. node.linksFrom.forEach(function (link) {
  8999. if (!visitedNodes[link.toNode.id]) {
  9000. visitedNodes[link.toNode.id] = true;
  9001. sortedNodes.push(link.toNode);
  9002. addToNodes(link.toNode);
  9003. }
  9004. });
  9005. }
  9006. // Start with identified root nodes an sort the nodes by their
  9007. // hierarchy. In trees, this ensures that branches don't cross
  9008. // eachother.
  9009. rootNodes.forEach(function (rootNode) {
  9010. sortedNodes.push(rootNode);
  9011. addToNodes(rootNode);
  9012. });
  9013. // Cyclic tree, no root node found
  9014. if (!sortedNodes.length) {
  9015. sortedNodes = nodes;
  9016. // Dangling, cyclic trees
  9017. }
  9018. else {
  9019. nodes.forEach(function (node) {
  9020. if (sortedNodes.indexOf(node) === -1) {
  9021. sortedNodes.push(node);
  9022. }
  9023. });
  9024. }
  9025. // Initial positions are laid out along a small circle, appearing
  9026. // as a cluster in the middle
  9027. sortedNodes.forEach(function (node, index) {
  9028. node.plotX = node.prevX = pick(node.plotX, box.width / 2 + radius * Math.cos(index * angle));
  9029. node.plotY = node.prevY = pick(node.plotY, box.height / 2 + radius * Math.sin(index * angle));
  9030. node.dispX = 0;
  9031. node.dispY = 0;
  9032. });
  9033. },
  9034. setRandomPositions: function () {
  9035. var box = this.box,
  9036. nodes = this.nodes,
  9037. nodesLength = nodes.length + 1;
  9038. /**
  9039. * Return a repeatable, quasi-random number based on an integer
  9040. * input. For the initial positions
  9041. * @private
  9042. */
  9043. function unrandom(n) {
  9044. var rand = n * n / Math.PI;
  9045. rand = rand - Math.floor(rand);
  9046. return rand;
  9047. }
  9048. // Initial positions:
  9049. nodes.forEach(function (node, index) {
  9050. node.plotX = node.prevX = pick(node.plotX, box.width * unrandom(index));
  9051. node.plotY = node.prevY = pick(node.plotY, box.height * unrandom(nodesLength + index));
  9052. node.dispX = 0;
  9053. node.dispY = 0;
  9054. });
  9055. },
  9056. force: function (name) {
  9057. this.integration[name].apply(this, Array.prototype.slice.call(arguments, 1));
  9058. },
  9059. barycenterForces: function () {
  9060. this.getBarycenter();
  9061. this.force('barycenter');
  9062. },
  9063. getBarycenter: function () {
  9064. var systemMass = 0,
  9065. cx = 0,
  9066. cy = 0;
  9067. this.nodes.forEach(function (node) {
  9068. cx += node.plotX * node.mass;
  9069. cy += node.plotY * node.mass;
  9070. systemMass += node.mass;
  9071. });
  9072. this.barycenter = {
  9073. x: cx,
  9074. y: cy,
  9075. xFactor: cx / systemMass,
  9076. yFactor: cy / systemMass
  9077. };
  9078. return this.barycenter;
  9079. },
  9080. barnesHutApproximation: function (node, quadNode) {
  9081. var layout = this,
  9082. distanceXY = layout.getDistXY(node,
  9083. quadNode),
  9084. distanceR = layout.vectorLength(distanceXY),
  9085. goDeeper,
  9086. force;
  9087. if (node !== quadNode && distanceR !== 0) {
  9088. if (quadNode.isInternal) {
  9089. // Internal node:
  9090. if (quadNode.boxSize / distanceR <
  9091. layout.options.theta &&
  9092. distanceR !== 0) {
  9093. // Treat as an external node:
  9094. force = layout.repulsiveForce(distanceR, layout.k);
  9095. layout.force('repulsive', node, force * quadNode.mass, distanceXY, distanceR);
  9096. goDeeper = false;
  9097. }
  9098. else {
  9099. // Go deeper:
  9100. goDeeper = true;
  9101. }
  9102. }
  9103. else {
  9104. // External node, direct force:
  9105. force = layout.repulsiveForce(distanceR, layout.k);
  9106. layout.force('repulsive', node, force * quadNode.mass, distanceXY, distanceR);
  9107. }
  9108. }
  9109. return goDeeper;
  9110. },
  9111. repulsiveForces: function () {
  9112. var layout = this;
  9113. if (layout.approximation === 'barnes-hut') {
  9114. layout.nodes.forEach(function (node) {
  9115. layout.quadTree.visitNodeRecursive(null, function (quadNode) {
  9116. return layout.barnesHutApproximation(node, quadNode);
  9117. });
  9118. });
  9119. }
  9120. else {
  9121. layout.nodes.forEach(function (node) {
  9122. layout.nodes.forEach(function (repNode) {
  9123. var force,
  9124. distanceR,
  9125. distanceXY;
  9126. if (
  9127. // Node can not repulse itself:
  9128. node !== repNode &&
  9129. // Only close nodes affect each other:
  9130. // layout.getDistR(node, repNode) < 2 * k &&
  9131. // Not dragged:
  9132. !node.fixedPosition) {
  9133. distanceXY = layout.getDistXY(node, repNode);
  9134. distanceR = layout.vectorLength(distanceXY);
  9135. if (distanceR !== 0) {
  9136. force = layout.repulsiveForce(distanceR, layout.k);
  9137. layout.force('repulsive', node, force * repNode.mass, distanceXY, distanceR);
  9138. }
  9139. }
  9140. });
  9141. });
  9142. }
  9143. },
  9144. attractiveForces: function () {
  9145. var layout = this,
  9146. distanceXY,
  9147. distanceR,
  9148. force;
  9149. layout.links.forEach(function (link) {
  9150. if (link.fromNode && link.toNode) {
  9151. distanceXY = layout.getDistXY(link.fromNode, link.toNode);
  9152. distanceR = layout.vectorLength(distanceXY);
  9153. if (distanceR !== 0) {
  9154. force = layout.attractiveForce(distanceR, layout.k);
  9155. layout.force('attractive', link, force, distanceXY, distanceR);
  9156. }
  9157. }
  9158. });
  9159. },
  9160. applyLimits: function () {
  9161. var layout = this,
  9162. nodes = layout.nodes;
  9163. nodes.forEach(function (node) {
  9164. if (node.fixedPosition) {
  9165. return;
  9166. }
  9167. layout.integration.integrate(layout, node);
  9168. layout.applyLimitBox(node, layout.box);
  9169. // Reset displacement:
  9170. node.dispX = 0;
  9171. node.dispY = 0;
  9172. });
  9173. },
  9174. /**
  9175. * External box that nodes should fall. When hitting an edge, node
  9176. * should stop or bounce.
  9177. * @private
  9178. */
  9179. applyLimitBox: function (node, box) {
  9180. var radius = node.radius;
  9181. /*
  9182. TO DO: Consider elastic collision instead of stopping.
  9183. o' means end position when hitting plotting area edge:
  9184. - "inelastic":
  9185. o
  9186. \
  9187. ______
  9188. | o'
  9189. | \
  9190. | \
  9191. - "elastic"/"bounced":
  9192. o
  9193. \
  9194. ______
  9195. | ^
  9196. | / \
  9197. |o' \
  9198. Euler sample:
  9199. if (plotX < 0) {
  9200. plotX = 0;
  9201. dispX *= -1;
  9202. }
  9203. if (plotX > box.width) {
  9204. plotX = box.width;
  9205. dispX *= -1;
  9206. }
  9207. */
  9208. // Limit X-coordinates:
  9209. node.plotX = clamp(node.plotX, box.left + radius, box.width - radius);
  9210. // Limit Y-coordinates:
  9211. node.plotY = clamp(node.plotY, box.top + radius, box.height - radius);
  9212. },
  9213. /**
  9214. * From "A comparison of simulated annealing cooling strategies" by
  9215. * Nourani and Andresen work.
  9216. * @private
  9217. */
  9218. coolDown: function (temperature, temperatureStep, currentStep) {
  9219. // Logarithmic:
  9220. /*
  9221. return Math.sqrt(this.nodes.length) -
  9222. Math.log(
  9223. currentStep * layout.diffTemperature
  9224. );
  9225. */
  9226. // Exponential:
  9227. /*
  9228. var alpha = 0.1;
  9229. layout.temperature = Math.sqrt(layout.nodes.length) *
  9230. Math.pow(alpha, layout.diffTemperature);
  9231. */
  9232. // Linear:
  9233. return temperature - temperatureStep * currentStep;
  9234. },
  9235. isStable: function () {
  9236. return Math.abs(this.systemTemperature -
  9237. this.prevSystemTemperature) < 0.00001 || this.temperature <= 0;
  9238. },
  9239. getSystemTemperature: function () {
  9240. return this.nodes.reduce(function (value, node) {
  9241. return value + node.temperature;
  9242. }, 0);
  9243. },
  9244. vectorLength: function (vector) {
  9245. return Math.sqrt(vector.x * vector.x + vector.y * vector.y);
  9246. },
  9247. getDistR: function (nodeA, nodeB) {
  9248. var distance = this.getDistXY(nodeA,
  9249. nodeB);
  9250. return this.vectorLength(distance);
  9251. },
  9252. getDistXY: function (nodeA, nodeB) {
  9253. var xDist = nodeA.plotX - nodeB.plotX,
  9254. yDist = nodeA.plotY - nodeB.plotY;
  9255. return {
  9256. x: xDist,
  9257. y: yDist,
  9258. absX: Math.abs(xDist),
  9259. absY: Math.abs(yDist)
  9260. };
  9261. }
  9262. });
  9263. /* ************************************************************************** *
  9264. * Multiple series support:
  9265. * ************************************************************************** */
  9266. // Clear previous layouts
  9267. addEvent(Chart, 'predraw', function () {
  9268. if (this.graphLayoutsLookup) {
  9269. this.graphLayoutsLookup.forEach(function (layout) {
  9270. layout.stop();
  9271. });
  9272. }
  9273. });
  9274. addEvent(Chart, 'render', function () {
  9275. var systemsStable,
  9276. afterRender = false;
  9277. /**
  9278. * @private
  9279. */
  9280. function layoutStep(layout) {
  9281. if (layout.maxIterations-- &&
  9282. isFinite(layout.temperature) &&
  9283. !layout.isStable() &&
  9284. !layout.enableSimulation) {
  9285. // Hook similar to build-in addEvent, but instead of
  9286. // creating whole events logic, use just a function.
  9287. // It's faster which is important for rAF code.
  9288. // Used e.g. in packed-bubble series for bubble radius
  9289. // calculations
  9290. if (layout.beforeStep) {
  9291. layout.beforeStep();
  9292. }
  9293. layout.step();
  9294. systemsStable = false;
  9295. afterRender = true;
  9296. }
  9297. }
  9298. if (this.graphLayoutsLookup) {
  9299. setAnimation(false, this);
  9300. // Start simulation
  9301. this.graphLayoutsLookup.forEach(function (layout) {
  9302. layout.start();
  9303. });
  9304. // Just one sync step, to run different layouts similar to
  9305. // async mode.
  9306. while (!systemsStable) {
  9307. systemsStable = true;
  9308. this.graphLayoutsLookup.forEach(layoutStep);
  9309. }
  9310. if (afterRender) {
  9311. this.series.forEach(function (s) {
  9312. if (s && s.layout) {
  9313. s.render();
  9314. }
  9315. });
  9316. }
  9317. }
  9318. });
  9319. // disable simulation before print if enabled
  9320. addEvent(Chart, 'beforePrint', function () {
  9321. if (this.graphLayoutsLookup) {
  9322. this.graphLayoutsLookup.forEach(function (layout) {
  9323. layout.updateSimulation(false);
  9324. });
  9325. this.redraw();
  9326. }
  9327. });
  9328. // re-enable simulation after print
  9329. addEvent(Chart, 'afterPrint', function () {
  9330. if (this.graphLayoutsLookup) {
  9331. this.graphLayoutsLookup.forEach(function (layout) {
  9332. // return to default simulation
  9333. layout.updateSimulation();
  9334. });
  9335. }
  9336. this.redraw();
  9337. });
  9338. });
  9339. _registerModule(_modules, 'Series/PackedBubble/PackedBubbleComposition.js', [_modules['Core/Chart/Chart.js'], _modules['Core/Globals.js'], _modules['Core/Utilities.js']], function (Chart, H, U) {
  9340. /* *
  9341. *
  9342. * (c) 2010-2021 Grzegorz Blachlinski, Sebastian Bochan
  9343. *
  9344. * License: www.highcharts.com/license
  9345. *
  9346. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  9347. *
  9348. * */
  9349. var Reingold = H.layouts['reingold-fruchterman'];
  9350. var addEvent = U.addEvent,
  9351. extendClass = U.extendClass,
  9352. pick = U.pick;
  9353. /* *
  9354. *
  9355. * Composition
  9356. *
  9357. * */
  9358. Chart.prototype.getSelectedParentNodes = function () {
  9359. var chart = this,
  9360. series = chart.series,
  9361. selectedParentsNodes = [];
  9362. series.forEach(function (series) {
  9363. if (series.parentNode && series.parentNode.selected) {
  9364. selectedParentsNodes.push(series.parentNode);
  9365. }
  9366. });
  9367. return selectedParentsNodes;
  9368. };
  9369. H.networkgraphIntegrations.packedbubble = {
  9370. repulsiveForceFunction: function (d, k, node, repNode) {
  9371. return Math.min(d, (node.marker.radius + repNode.marker.radius) / 2);
  9372. },
  9373. barycenter: function () {
  9374. var layout = this,
  9375. gravitationalConstant = layout.options.gravitationalConstant,
  9376. box = layout.box,
  9377. nodes = layout.nodes,
  9378. centerX,
  9379. centerY;
  9380. nodes.forEach(function (node) {
  9381. if (layout.options.splitSeries && !node.isParentNode) {
  9382. centerX = node.series.parentNode.plotX;
  9383. centerY = node.series.parentNode.plotY;
  9384. }
  9385. else {
  9386. centerX = box.width / 2;
  9387. centerY = box.height / 2;
  9388. }
  9389. if (!node.fixedPosition) {
  9390. node.plotX -=
  9391. (node.plotX - centerX) *
  9392. gravitationalConstant /
  9393. (node.mass * Math.sqrt(nodes.length));
  9394. node.plotY -=
  9395. (node.plotY - centerY) *
  9396. gravitationalConstant /
  9397. (node.mass * Math.sqrt(nodes.length));
  9398. }
  9399. });
  9400. },
  9401. repulsive: function (node, force, distanceXY, repNode) {
  9402. var factor = (force * this.diffTemperature / node.mass /
  9403. node.degree),
  9404. x = distanceXY.x * factor,
  9405. y = distanceXY.y * factor;
  9406. if (!node.fixedPosition) {
  9407. node.plotX += x;
  9408. node.plotY += y;
  9409. }
  9410. if (!repNode.fixedPosition) {
  9411. repNode.plotX -= x;
  9412. repNode.plotY -= y;
  9413. }
  9414. },
  9415. integrate: H.networkgraphIntegrations.verlet.integrate,
  9416. getK: H.noop
  9417. };
  9418. H.layouts.packedbubble = extendClass(Reingold, {
  9419. beforeStep: function () {
  9420. if (this.options.marker) {
  9421. this.series.forEach(function (series) {
  9422. if (series) {
  9423. series.calculateParentRadius();
  9424. }
  9425. });
  9426. }
  9427. },
  9428. setCircularPositions: function () {
  9429. var layout = this,
  9430. box = layout.box,
  9431. nodes = layout.nodes,
  9432. nodesLength = nodes.length + 1,
  9433. angle = 2 * Math.PI / nodesLength,
  9434. centerX,
  9435. centerY,
  9436. radius = layout.options.initialPositionRadius;
  9437. nodes.forEach(function (node, index) {
  9438. if (layout.options.splitSeries &&
  9439. !node.isParentNode) {
  9440. centerX = node.series.parentNode.plotX;
  9441. centerY = node.series.parentNode.plotY;
  9442. }
  9443. else {
  9444. centerX = box.width / 2;
  9445. centerY = box.height / 2;
  9446. }
  9447. node.plotX = node.prevX = pick(node.plotX, centerX +
  9448. radius * Math.cos(node.index || index * angle));
  9449. node.plotY = node.prevY = pick(node.plotY, centerY +
  9450. radius * Math.sin(node.index || index * angle));
  9451. node.dispX = 0;
  9452. node.dispY = 0;
  9453. });
  9454. },
  9455. repulsiveForces: function () {
  9456. var layout = this,
  9457. force,
  9458. distanceR,
  9459. distanceXY,
  9460. bubblePadding = layout.options.bubblePadding;
  9461. layout.nodes.forEach(function (node) {
  9462. node.degree = node.mass;
  9463. node.neighbours = 0;
  9464. layout.nodes.forEach(function (repNode) {
  9465. force = 0;
  9466. if (
  9467. // Node can not repulse itself:
  9468. node !== repNode &&
  9469. // Only close nodes affect each other:
  9470. // Not dragged:
  9471. !node.fixedPosition &&
  9472. (layout.options.seriesInteraction ||
  9473. node.series === repNode.series)) {
  9474. distanceXY = layout.getDistXY(node, repNode);
  9475. distanceR = (layout.vectorLength(distanceXY) -
  9476. (node.marker.radius +
  9477. repNode.marker.radius +
  9478. bubblePadding));
  9479. // TODO padding configurable
  9480. if (distanceR < 0) {
  9481. node.degree += 0.01;
  9482. node.neighbours++;
  9483. force = layout.repulsiveForce(-distanceR / Math.sqrt(node.neighbours), layout.k, node, repNode);
  9484. }
  9485. layout.force('repulsive', node, force * repNode.mass, distanceXY, repNode, distanceR);
  9486. }
  9487. });
  9488. });
  9489. },
  9490. applyLimitBox: function (node) {
  9491. var layout = this,
  9492. distanceXY,
  9493. distanceR,
  9494. factor = 0.01;
  9495. // parentNodeLimit should be used together
  9496. // with seriesInteraction: false
  9497. if (layout.options.splitSeries &&
  9498. !node.isParentNode &&
  9499. layout.options.parentNodeLimit) {
  9500. distanceXY = layout.getDistXY(node, node.series.parentNode);
  9501. distanceR = (node.series.parentNodeRadius -
  9502. node.marker.radius -
  9503. layout.vectorLength(distanceXY));
  9504. if (distanceR < 0 &&
  9505. distanceR > -2 * node.marker.radius) {
  9506. node.plotX -= distanceXY.x * factor;
  9507. node.plotY -= distanceXY.y * factor;
  9508. }
  9509. }
  9510. Reingold.prototype.applyLimitBox.apply(this, arguments);
  9511. }
  9512. });
  9513. // Remove accumulated data points to redistribute all of them again
  9514. // (i.e after hiding series by legend)
  9515. addEvent(Chart, 'beforeRedraw', function () {
  9516. // eslint-disable-next-line no-invalid-this
  9517. if (this.allDataPoints) {
  9518. // eslint-disable-next-line no-invalid-this
  9519. delete this.allDataPoints;
  9520. }
  9521. });
  9522. });
  9523. _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) {
  9524. /* *
  9525. *
  9526. * (c) 2010-2021 Grzegorz Blachlinski, Sebastian Bochan
  9527. *
  9528. * License: www.highcharts.com/license
  9529. *
  9530. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  9531. *
  9532. * */
  9533. var __extends = (this && this.__extends) || (function () {
  9534. var extendStatics = function (d,
  9535. b) {
  9536. extendStatics = Object.setPrototypeOf ||
  9537. ({ __proto__: [] } instanceof Array && function (d,
  9538. b) { d.__proto__ = b; }) ||
  9539. function (d,
  9540. b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
  9541. return extendStatics(d, b);
  9542. };
  9543. return function (d, b) {
  9544. extendStatics(d, b);
  9545. function __() { this.constructor = d; }
  9546. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  9547. };
  9548. })();
  9549. var color = Color.parse;
  9550. var Series = SeriesRegistry.series,
  9551. BubbleSeries = SeriesRegistry.seriesTypes.bubble;
  9552. var addEvent = U.addEvent,
  9553. clamp = U.clamp,
  9554. defined = U.defined,
  9555. extend = U.extend,
  9556. fireEvent = U.fireEvent,
  9557. isArray = U.isArray,
  9558. isNumber = U.isNumber,
  9559. merge = U.merge,
  9560. pick = U.pick;
  9561. var dragNodesMixin = H.dragNodesMixin;
  9562. /* *
  9563. *
  9564. * Class
  9565. *
  9566. * */
  9567. /**
  9568. * @private
  9569. * @class
  9570. * @name Highcharts.seriesTypes.packedbubble
  9571. *
  9572. * @extends Highcharts.Series
  9573. */
  9574. var PackedBubbleSeries = /** @class */ (function (_super) {
  9575. __extends(PackedBubbleSeries, _super);
  9576. function PackedBubbleSeries() {
  9577. /* *
  9578. *
  9579. * Static Properties
  9580. *
  9581. * */
  9582. var _this = _super !== null && _super.apply(this,
  9583. arguments) || this;
  9584. /* *
  9585. *
  9586. * Properties
  9587. *
  9588. * */
  9589. _this.chart = void 0;
  9590. _this.data = void 0;
  9591. _this.layout = void 0;
  9592. _this.options = void 0;
  9593. _this.points = void 0;
  9594. _this.xData = void 0;
  9595. return _this;
  9596. /* eslint-enable valid-jsdoc */
  9597. }
  9598. /* *
  9599. *
  9600. * Functions
  9601. *
  9602. * */
  9603. /* eslint-disable valid-jsdoc */
  9604. /**
  9605. * Create a single array of all points from all series
  9606. * @private
  9607. */
  9608. PackedBubbleSeries.prototype.accumulateAllPoints = function (series) {
  9609. var chart = series.chart,
  9610. allDataPoints = [],
  9611. i,
  9612. j;
  9613. for (i = 0; i < chart.series.length; i++) {
  9614. series = chart.series[i];
  9615. if (series.is('packedbubble') && // #13574
  9616. series.visible ||
  9617. !chart.options.chart.ignoreHiddenSeries) {
  9618. // add data to array only if series is visible
  9619. for (j = 0; j < series.yData.length; j++) {
  9620. allDataPoints.push([
  9621. null, null,
  9622. series.yData[j],
  9623. series.index,
  9624. j,
  9625. {
  9626. id: j,
  9627. marker: {
  9628. radius: 0
  9629. }
  9630. }
  9631. ]);
  9632. }
  9633. }
  9634. }
  9635. return allDataPoints;
  9636. };
  9637. /**
  9638. * Adding the basic layout to series points.
  9639. * @private
  9640. */
  9641. PackedBubbleSeries.prototype.addLayout = function () {
  9642. var series = this,
  9643. layoutOptions = series.options.layoutAlgorithm,
  9644. graphLayoutsStorage = series.chart.graphLayoutsStorage,
  9645. graphLayoutsLookup = series.chart.graphLayoutsLookup,
  9646. chartOptions = series.chart.options.chart,
  9647. layout;
  9648. if (!graphLayoutsStorage) {
  9649. series.chart.graphLayoutsStorage = graphLayoutsStorage = {};
  9650. series.chart.graphLayoutsLookup = graphLayoutsLookup = [];
  9651. }
  9652. layout = graphLayoutsStorage[layoutOptions.type];
  9653. if (!layout) {
  9654. layoutOptions.enableSimulation =
  9655. !defined(chartOptions.forExport) ?
  9656. layoutOptions.enableSimulation :
  9657. !chartOptions.forExport;
  9658. graphLayoutsStorage[layoutOptions.type] = layout =
  9659. new H.layouts[layoutOptions.type]();
  9660. layout.init(layoutOptions);
  9661. graphLayoutsLookup.splice(layout.index, 0, layout);
  9662. }
  9663. series.layout = layout;
  9664. series.points.forEach(function (node) {
  9665. node.mass = 2;
  9666. node.degree = 1;
  9667. node.collisionNmb = 1;
  9668. });
  9669. layout.setArea(0, 0, series.chart.plotWidth, series.chart.plotHeight);
  9670. layout.addElementsToCollection([series], layout.series);
  9671. layout.addElementsToCollection(series.points, layout.nodes);
  9672. };
  9673. /**
  9674. * Function responsible for adding series layout, used for parent nodes.
  9675. * @private
  9676. */
  9677. PackedBubbleSeries.prototype.addSeriesLayout = function () {
  9678. var series = this,
  9679. layoutOptions = series.options.layoutAlgorithm,
  9680. graphLayoutsStorage = series.chart.graphLayoutsStorage,
  9681. graphLayoutsLookup = series.chart.graphLayoutsLookup,
  9682. parentNodeOptions = merge(layoutOptions,
  9683. layoutOptions.parentNodeOptions, {
  9684. enableSimulation: series.layout.options.enableSimulation
  9685. }),
  9686. parentNodeLayout;
  9687. parentNodeLayout = graphLayoutsStorage[layoutOptions.type + '-series'];
  9688. if (!parentNodeLayout) {
  9689. graphLayoutsStorage[layoutOptions.type + '-series'] =
  9690. parentNodeLayout =
  9691. new H.layouts[layoutOptions.type]();
  9692. parentNodeLayout.init(parentNodeOptions);
  9693. graphLayoutsLookup.splice(parentNodeLayout.index, 0, parentNodeLayout);
  9694. }
  9695. series.parentNodeLayout = parentNodeLayout;
  9696. this.createParentNodes();
  9697. };
  9698. /**
  9699. * The function responsible for calculating the parent node radius
  9700. * based on the total surface of iniside-bubbles and the group BBox
  9701. * @private
  9702. */
  9703. PackedBubbleSeries.prototype.calculateParentRadius = function () {
  9704. var series = this,
  9705. bBox,
  9706. parentPadding = 20,
  9707. minParentRadius = 20;
  9708. bBox = series.seriesBox();
  9709. series.parentNodeRadius = clamp(Math.sqrt(2 * series.parentNodeMass / Math.PI) + parentPadding, minParentRadius, bBox ?
  9710. Math.max(Math.sqrt(Math.pow(bBox.width, 2) +
  9711. Math.pow(bBox.height, 2)) / 2 + parentPadding, minParentRadius) :
  9712. Math.sqrt(2 * series.parentNodeMass / Math.PI) + parentPadding);
  9713. if (series.parentNode) {
  9714. series.parentNode.marker.radius =
  9715. series.parentNode.radius = series.parentNodeRadius;
  9716. }
  9717. };
  9718. /**
  9719. * Calculate min and max bubble value for radius calculation.
  9720. * @private
  9721. */
  9722. PackedBubbleSeries.prototype.calculateZExtremes = function () {
  9723. var chart = this.chart,
  9724. zMin = this.options.zMin,
  9725. zMax = this.options.zMax,
  9726. valMin = Infinity,
  9727. valMax = -Infinity;
  9728. if (zMin && zMax) {
  9729. return [zMin, zMax];
  9730. }
  9731. // it is needed to deal with null
  9732. // and undefined values
  9733. chart.series.forEach(function (s) {
  9734. s.yData.forEach(function (p) {
  9735. if (defined(p)) {
  9736. if (p > valMax) {
  9737. valMax = p;
  9738. }
  9739. if (p < valMin) {
  9740. valMin = p;
  9741. }
  9742. }
  9743. });
  9744. });
  9745. zMin = pick(zMin, valMin);
  9746. zMax = pick(zMax, valMax);
  9747. return [zMin, zMax];
  9748. };
  9749. /**
  9750. * Check if two bubbles overlaps.
  9751. * @private
  9752. * @param {Array} first bubble
  9753. * @param {Array} second bubble
  9754. * @return {Boolean} overlap or not
  9755. */
  9756. PackedBubbleSeries.prototype.checkOverlap = function (bubble1, bubble2) {
  9757. var diffX = bubble1[0] - bubble2[0], // diff of X center values
  9758. diffY = bubble1[1] - bubble2[1], // diff of Y center values
  9759. sumRad = bubble1[2] + bubble2[2]; // sum of bubble radius
  9760. return (Math.sqrt(diffX * diffX + diffY * diffY) -
  9761. Math.abs(sumRad)) < -0.001;
  9762. };
  9763. /**
  9764. * Creating parent nodes for split series, in which all the bubbles
  9765. * are rendered.
  9766. * @private
  9767. */
  9768. PackedBubbleSeries.prototype.createParentNodes = function () {
  9769. var series = this,
  9770. chart = series.chart,
  9771. parentNodeLayout = series.parentNodeLayout,
  9772. nodeAdded,
  9773. parentNode = series.parentNode,
  9774. PackedBubblePoint = series.pointClass;
  9775. series.parentNodeMass = 0;
  9776. series.points.forEach(function (p) {
  9777. series.parentNodeMass +=
  9778. Math.PI * Math.pow(p.marker.radius, 2);
  9779. });
  9780. series.calculateParentRadius();
  9781. parentNodeLayout.nodes.forEach(function (node) {
  9782. if (node.seriesIndex === series.index) {
  9783. nodeAdded = true;
  9784. }
  9785. });
  9786. parentNodeLayout.setArea(0, 0, chart.plotWidth, chart.plotHeight);
  9787. if (!nodeAdded) {
  9788. if (!parentNode) {
  9789. parentNode = (new PackedBubblePoint()).init(this, {
  9790. mass: series.parentNodeRadius / 2,
  9791. marker: {
  9792. radius: series.parentNodeRadius
  9793. },
  9794. dataLabels: {
  9795. inside: false
  9796. },
  9797. dataLabelOnNull: true,
  9798. degree: series.parentNodeRadius,
  9799. isParentNode: true,
  9800. seriesIndex: series.index
  9801. });
  9802. }
  9803. if (series.parentNode) {
  9804. parentNode.plotX = series.parentNode.plotX;
  9805. parentNode.plotY = series.parentNode.plotY;
  9806. }
  9807. series.parentNode = parentNode;
  9808. parentNodeLayout.addElementsToCollection([series], parentNodeLayout.series);
  9809. parentNodeLayout.addElementsToCollection([parentNode], parentNodeLayout.nodes);
  9810. }
  9811. };
  9812. /**
  9813. * Function responsible for adding all the layouts to the chart.
  9814. * @private
  9815. */
  9816. PackedBubbleSeries.prototype.deferLayout = function () {
  9817. // TODO split layouts to independent methods
  9818. var series = this,
  9819. layoutOptions = series.options.layoutAlgorithm;
  9820. if (!series.visible) {
  9821. return;
  9822. }
  9823. // layout is using nodes for position calculation
  9824. series.addLayout();
  9825. if (layoutOptions.splitSeries) {
  9826. series.addSeriesLayout();
  9827. }
  9828. };
  9829. PackedBubbleSeries.prototype.destroy = function () {
  9830. // Remove the series from all layouts series collections #11469
  9831. if (this.chart.graphLayoutsLookup) {
  9832. this.chart.graphLayoutsLookup.forEach(function (layout) {
  9833. layout.removeElementFromCollection(this, layout.series);
  9834. }, this);
  9835. }
  9836. if (this.parentNode &&
  9837. this.parentNodeLayout) {
  9838. this.parentNodeLayout.removeElementFromCollection(this.parentNode, this.parentNodeLayout.nodes);
  9839. if (this.parentNode.dataLabel) {
  9840. this.parentNode.dataLabel =
  9841. this.parentNode.dataLabel.destroy();
  9842. }
  9843. }
  9844. Series.prototype.destroy.apply(this, arguments);
  9845. };
  9846. /**
  9847. * Packedbubble has two separate collecions of nodes if split, render
  9848. * dataLabels for both sets:
  9849. * @private
  9850. */
  9851. PackedBubbleSeries.prototype.drawDataLabels = function () {
  9852. var textPath = this.options.dataLabels.textPath,
  9853. points = this.points;
  9854. // Render node labels:
  9855. Series.prototype.drawDataLabels.apply(this, arguments);
  9856. // Render parentNode labels:
  9857. if (this.parentNode) {
  9858. this.parentNode.formatPrefix = 'parentNode';
  9859. this.points = [this.parentNode];
  9860. this.options.dataLabels.textPath =
  9861. this.options.dataLabels.parentNodeTextPath;
  9862. Series.prototype.drawDataLabels.apply(this, arguments);
  9863. // Restore nodes
  9864. this.points = points;
  9865. this.options.dataLabels.textPath = textPath;
  9866. }
  9867. };
  9868. /**
  9869. * Create Background/Parent Nodes for split series.
  9870. * @private
  9871. */
  9872. PackedBubbleSeries.prototype.drawGraph = function () {
  9873. // if the series is not using layout, don't add parent nodes
  9874. if (!this.layout || !this.layout.options.splitSeries) {
  9875. return;
  9876. }
  9877. var series = this,
  9878. chart = series.chart,
  9879. parentAttribs = {},
  9880. nodeMarker = this.layout.options.parentNodeOptions.marker,
  9881. parentOptions = {
  9882. fill: nodeMarker.fillColor || color(series.color).brighten(0.4).get(),
  9883. opacity: nodeMarker.fillOpacity,
  9884. stroke: nodeMarker.lineColor || series.color,
  9885. 'stroke-width': nodeMarker.lineWidth
  9886. },
  9887. visibility = series.visible ? 'inherit' : 'hidden';
  9888. // create the group for parent Nodes if doesn't exist
  9889. if (!this.parentNodesGroup) {
  9890. series.parentNodesGroup = series.plotGroup('parentNodesGroup', 'parentNode', visibility, 0.1, chart.seriesGroup);
  9891. series.group.attr({
  9892. zIndex: 2
  9893. });
  9894. }
  9895. this.calculateParentRadius();
  9896. parentAttribs = merge({
  9897. x: series.parentNode.plotX -
  9898. series.parentNodeRadius,
  9899. y: series.parentNode.plotY -
  9900. series.parentNodeRadius,
  9901. width: series.parentNodeRadius * 2,
  9902. height: series.parentNodeRadius * 2
  9903. }, parentOptions);
  9904. if (!series.parentNode.graphic) {
  9905. series.graph = series.parentNode.graphic =
  9906. chart.renderer.symbol(parentOptions.symbol)
  9907. .add(series.parentNodesGroup);
  9908. }
  9909. series.parentNode.graphic.attr(parentAttribs);
  9910. };
  9911. PackedBubbleSeries.prototype.drawTracker = function () {
  9912. var series = this,
  9913. /* chart = series.chart,
  9914. pointer = chart.pointer,
  9915. onMouseOver = function (e: PointerEvent): void {
  9916. const point = pointer.getPointFromEvent(e);
  9917. // undefined on graph in scatterchart
  9918. if (typeof point !== 'undefined') {
  9919. pointer.isDirectTouch = true;
  9920. point.onMouseOver(e);
  9921. }
  9922. }, */
  9923. parentNode = series.parentNode;
  9924. var dataLabels;
  9925. _super.prototype.drawTracker.call(this);
  9926. // Add reference to the point
  9927. if (parentNode) {
  9928. dataLabels = (isArray(parentNode.dataLabels) ?
  9929. parentNode.dataLabels :
  9930. (parentNode.dataLabel ? [parentNode.dataLabel] : []));
  9931. if (parentNode.graphic) {
  9932. parentNode.graphic.element.point = parentNode;
  9933. }
  9934. dataLabels.forEach(function (dataLabel) {
  9935. if (dataLabel.div) {
  9936. dataLabel.div.point = parentNode;
  9937. }
  9938. else {
  9939. dataLabel.element.point = parentNode;
  9940. }
  9941. });
  9942. }
  9943. };
  9944. /**
  9945. * Calculate radius of bubbles in series.
  9946. * @private
  9947. */
  9948. PackedBubbleSeries.prototype.getPointRadius = function () {
  9949. var series = this,
  9950. chart = series.chart,
  9951. plotWidth = chart.plotWidth,
  9952. plotHeight = chart.plotHeight,
  9953. seriesOptions = series.options,
  9954. useSimulation = seriesOptions.useSimulation,
  9955. smallestSize = Math.min(plotWidth,
  9956. plotHeight),
  9957. extremes = {},
  9958. radii = [],
  9959. allDataPoints = chart.allDataPoints,
  9960. minSize,
  9961. maxSize,
  9962. value,
  9963. radius,
  9964. zExtremes;
  9965. ['minSize', 'maxSize'].forEach(function (prop) {
  9966. var length = parseInt(seriesOptions[prop], 10),
  9967. isPercent = /%$/.test(seriesOptions[prop]);
  9968. extremes[prop] = isPercent ?
  9969. smallestSize * length / 100 :
  9970. length * Math.sqrt(allDataPoints.length);
  9971. });
  9972. chart.minRadius = minSize = extremes.minSize /
  9973. Math.sqrt(allDataPoints.length);
  9974. chart.maxRadius = maxSize = extremes.maxSize /
  9975. Math.sqrt(allDataPoints.length);
  9976. zExtremes = useSimulation ?
  9977. series.calculateZExtremes() :
  9978. [minSize, maxSize];
  9979. (allDataPoints || []).forEach(function (point, i) {
  9980. value = useSimulation ?
  9981. clamp(point[2], zExtremes[0], zExtremes[1]) :
  9982. point[2];
  9983. radius = series.getRadius(zExtremes[0], zExtremes[1], minSize, maxSize, value);
  9984. if (radius === 0) {
  9985. radius = null;
  9986. }
  9987. allDataPoints[i][2] = radius;
  9988. radii.push(radius);
  9989. });
  9990. series.radii = radii;
  9991. };
  9992. PackedBubbleSeries.prototype.init = function () {
  9993. Series.prototype.init.apply(this, arguments);
  9994. /* eslint-disable no-invalid-this */
  9995. // When one series is modified, the others need to be recomputed
  9996. this.eventsToUnbind.push(addEvent(this, 'updatedData', function () {
  9997. this.chart.series.forEach(function (s) {
  9998. if (s.type === this.type) {
  9999. s.isDirty = true;
  10000. }
  10001. }, this);
  10002. }));
  10003. /* eslint-enable no-invalid-this */
  10004. return this;
  10005. };
  10006. /**
  10007. * Mouse up action, finalizing drag&drop.
  10008. * @private
  10009. * @param {Highcharts.Point} point The point that event occured.
  10010. */
  10011. PackedBubbleSeries.prototype.onMouseUp = function (point) {
  10012. if (point.fixedPosition && !point.removed) {
  10013. var distanceXY,
  10014. distanceR,
  10015. layout = this.layout,
  10016. parentNodeLayout = this.parentNodeLayout;
  10017. if (parentNodeLayout && layout.options.dragBetweenSeries) {
  10018. parentNodeLayout.nodes.forEach(function (node) {
  10019. if (point && point.marker &&
  10020. node !== point.series.parentNode) {
  10021. distanceXY = layout.getDistXY(point, node);
  10022. distanceR = (layout.vectorLength(distanceXY) -
  10023. node.marker.radius -
  10024. point.marker.radius);
  10025. if (distanceR < 0) {
  10026. node.series.addPoint(merge(point.options, {
  10027. plotX: point.plotX,
  10028. plotY: point.plotY
  10029. }), false);
  10030. layout.removeElementFromCollection(point, layout.nodes);
  10031. point.remove();
  10032. }
  10033. }
  10034. });
  10035. }
  10036. dragNodesMixin.onMouseUp.apply(this, arguments);
  10037. }
  10038. };
  10039. /**
  10040. * This is the main function responsible
  10041. * for positioning all of the bubbles
  10042. * allDataPoints - bubble array, in format [pixel x value,
  10043. * pixel y value, radius,
  10044. * related series index, related point index]
  10045. * @private
  10046. * @param {Array<Highcharts.PackedBubbleData>} allDataPoints All points from all series
  10047. * @return {Array<Highcharts.PackedBubbleData>} Positions of all bubbles
  10048. */
  10049. PackedBubbleSeries.prototype.placeBubbles = function (allDataPoints) {
  10050. var series = this,
  10051. checkOverlap = series.checkOverlap,
  10052. positionBubble = series.positionBubble,
  10053. bubblePos = [],
  10054. stage = 1,
  10055. j = 0,
  10056. k = 0,
  10057. calculatedBubble,
  10058. sortedArr,
  10059. arr = [],
  10060. i;
  10061. // sort all points
  10062. sortedArr = allDataPoints.sort(function (a, b) {
  10063. return b[2] - a[2];
  10064. });
  10065. if (sortedArr.length) {
  10066. // create first bubble in the middle of the chart
  10067. bubblePos.push([
  10068. [
  10069. 0,
  10070. 0,
  10071. sortedArr[0][2],
  10072. sortedArr[0][3],
  10073. sortedArr[0][4]
  10074. ] // point index
  10075. ]); // 0 level bubble
  10076. if (sortedArr.length > 1) {
  10077. bubblePos.push([
  10078. [
  10079. 0,
  10080. (0 - sortedArr[1][2] -
  10081. sortedArr[0][2]),
  10082. // move bubble above first one
  10083. sortedArr[1][2],
  10084. sortedArr[1][3],
  10085. sortedArr[1][4]
  10086. ]
  10087. ]); // 1 level 1st bubble
  10088. // first two already positioned so starting from 2
  10089. for (i = 2; i < sortedArr.length; i++) {
  10090. sortedArr[i][2] = sortedArr[i][2] || 1;
  10091. // in case if radius is calculated as 0.
  10092. calculatedBubble = positionBubble(bubblePos[stage][j], bubblePos[stage - 1][k], sortedArr[i]); // calculate initial bubble position
  10093. if (checkOverlap(calculatedBubble, bubblePos[stage][0])) {
  10094. /* if new bubble is overlapping with first bubble
  10095. * in current level (stage)
  10096. */
  10097. bubblePos.push([]);
  10098. k = 0;
  10099. /* reset index of bubble, used for
  10100. * positioning the bubbles around it,
  10101. * we are starting from first bubble in next
  10102. * stage because we are changing level to higher
  10103. */
  10104. bubblePos[stage + 1].push(positionBubble(bubblePos[stage][j], bubblePos[stage][0], sortedArr[i]));
  10105. // (last bubble, 1. from curr stage, new bubble)
  10106. stage++; // the new level is created, above current
  10107. j = 0; // set the index of bubble in curr level to 0
  10108. }
  10109. else if (stage > 1 &&
  10110. bubblePos[stage - 1][k + 1] &&
  10111. checkOverlap(calculatedBubble, bubblePos[stage - 1][k + 1])) {
  10112. /* if new bubble is overlapping with one of the prev
  10113. * stage bubbles, it means that - bubble, used for
  10114. * positioning the bubbles around it has changed
  10115. * so we need to recalculate it
  10116. */
  10117. k++;
  10118. bubblePos[stage].push(positionBubble(bubblePos[stage][j], bubblePos[stage - 1][k], sortedArr[i]));
  10119. // (last bubble, prev stage bubble, new bubble)
  10120. j++;
  10121. }
  10122. else { // simply add calculated bubble
  10123. j++;
  10124. bubblePos[stage].push(calculatedBubble);
  10125. }
  10126. }
  10127. }
  10128. series.chart.stages = bubblePos;
  10129. // it may not be necessary but adding it just in case -
  10130. // it is containing all of the bubble levels
  10131. series.chart.rawPositions =
  10132. []
  10133. .concat.apply([], bubblePos);
  10134. // bubble positions merged into one array
  10135. series.resizeRadius();
  10136. arr = series.chart.rawPositions;
  10137. }
  10138. return arr;
  10139. };
  10140. /**
  10141. * Function that is adding one bubble based on positions and sizes of
  10142. * two other bubbles, lastBubble is the last added bubble, newOrigin is
  10143. * the bubble for positioning new bubbles. nextBubble is the curently
  10144. * added bubble for which we are calculating positions
  10145. * @private
  10146. * @param {Array<number>} lastBubble The closest last bubble
  10147. * @param {Array<number>} newOrigin New bubble
  10148. * @param {Array<number>} nextBubble The closest next bubble
  10149. * @return {Array<number>} Bubble with correct positions
  10150. */
  10151. PackedBubbleSeries.prototype.positionBubble = function (lastBubble, newOrigin, nextBubble) {
  10152. var sqrt = Math.sqrt,
  10153. asin = Math.asin,
  10154. acos = Math.acos,
  10155. pow = Math.pow,
  10156. abs = Math.abs,
  10157. distance = sqrt(// dist between lastBubble and newOrigin
  10158. pow((lastBubble[0] - newOrigin[0]), 2) +
  10159. pow((lastBubble[1] - newOrigin[1]), 2)),
  10160. alfa = acos(
  10161. // from cosinus theorem: alfa is an angle used for
  10162. // calculating correct position
  10163. (pow(distance, 2) +
  10164. pow(nextBubble[2] + newOrigin[2], 2) -
  10165. pow(nextBubble[2] + lastBubble[2], 2)) / (2 * (nextBubble[2] + newOrigin[2]) * distance)),
  10166. beta = asin(// from sinus theorem.
  10167. abs(lastBubble[0] - newOrigin[0]) /
  10168. distance),
  10169. // providing helping variables, related to angle between
  10170. // lastBubble and newOrigin
  10171. gamma = (lastBubble[1] - newOrigin[1]) < 0 ? 0 : Math.PI,
  10172. // if new origin y is smaller than last bubble y value
  10173. // (2 and 3 quarter),
  10174. // add Math.PI to final angle
  10175. delta = (lastBubble[0] - newOrigin[0]) *
  10176. (lastBubble[1] - newOrigin[1]) < 0 ?
  10177. 1 : -1, // (1st and 3rd quarter)
  10178. finalAngle = gamma + alfa + beta * delta,
  10179. cosA = Math.cos(finalAngle),
  10180. sinA = Math.sin(finalAngle),
  10181. posX = newOrigin[0] + (newOrigin[2] + nextBubble[2]) * sinA,
  10182. // center of new origin + (radius1 + radius2) * sinus A
  10183. posY = newOrigin[1] - (newOrigin[2] + nextBubble[2]) * cosA;
  10184. return [
  10185. posX,
  10186. posY,
  10187. nextBubble[2],
  10188. nextBubble[3],
  10189. nextBubble[4]
  10190. ]; // the same as described before
  10191. };
  10192. PackedBubbleSeries.prototype.render = function () {
  10193. var series = this,
  10194. dataLabels = [];
  10195. Series.prototype.render.apply(this, arguments);
  10196. // #10823 - dataLabels should stay visible
  10197. // when enabled allowOverlap.
  10198. if (!series.options.dataLabels.allowOverlap) {
  10199. series.data.forEach(function (point) {
  10200. if (isArray(point.dataLabels)) {
  10201. point.dataLabels.forEach(function (dataLabel) {
  10202. dataLabels.push(dataLabel);
  10203. });
  10204. }
  10205. });
  10206. // Only hide overlapping dataLabels for layouts that
  10207. // use simulation. Spiral packedbubble don't need
  10208. // additional dataLabel hiding on every simulation step
  10209. if (series.options.useSimulation) {
  10210. series.chart.hideOverlappingLabels(dataLabels);
  10211. }
  10212. }
  10213. };
  10214. /**
  10215. * The function responsible for resizing the bubble radius.
  10216. * In shortcut: it is taking the initially
  10217. * calculated positions of bubbles. Then it is calculating the min max
  10218. * of both dimensions, creating something in shape of bBox.
  10219. * The comparison of bBox and the size of plotArea
  10220. * (later it may be also the size set by customer) is giving the
  10221. * value how to recalculate the radius so it will match the size
  10222. * @private
  10223. */
  10224. PackedBubbleSeries.prototype.resizeRadius = function () {
  10225. var chart = this.chart,
  10226. positions = chart.rawPositions,
  10227. min = Math.min,
  10228. max = Math.max,
  10229. plotLeft = chart.plotLeft,
  10230. plotTop = chart.plotTop,
  10231. chartHeight = chart.plotHeight,
  10232. chartWidth = chart.plotWidth,
  10233. minX,
  10234. maxX,
  10235. minY,
  10236. maxY,
  10237. radius,
  10238. bBox,
  10239. spaceRatio,
  10240. smallerDimension,
  10241. i;
  10242. minX = minY = Number.POSITIVE_INFINITY; // set initial values
  10243. maxX = maxY = Number.NEGATIVE_INFINITY;
  10244. for (i = 0; i < positions.length; i++) {
  10245. radius = positions[i][2];
  10246. minX = min(minX, positions[i][0] - radius);
  10247. // (x center-radius) is the min x value used by specific bubble
  10248. maxX = max(maxX, positions[i][0] + radius);
  10249. minY = min(minY, positions[i][1] - radius);
  10250. maxY = max(maxY, positions[i][1] + radius);
  10251. }
  10252. bBox = [maxX - minX, maxY - minY];
  10253. spaceRatio = [
  10254. (chartWidth - plotLeft) / bBox[0],
  10255. (chartHeight - plotTop) / bBox[1]
  10256. ];
  10257. smallerDimension = min.apply([], spaceRatio);
  10258. if (Math.abs(smallerDimension - 1) > 1e-10) {
  10259. // if bBox is considered not the same width as possible size
  10260. for (i = 0; i < positions.length; i++) {
  10261. positions[i][2] *= smallerDimension;
  10262. }
  10263. this.placeBubbles(positions);
  10264. }
  10265. else {
  10266. /** if no radius recalculation is needed, we need to position
  10267. * the whole bubbles in center of chart plotarea
  10268. * for this, we are adding two parameters,
  10269. * diffY and diffX, that are related to differences
  10270. * between the initial center and the bounding box
  10271. */
  10272. chart.diffY = chartHeight / 2 +
  10273. plotTop - minY - (maxY - minY) / 2;
  10274. chart.diffX = chartWidth / 2 +
  10275. plotLeft - minX - (maxX - minX) / 2;
  10276. }
  10277. };
  10278. /**
  10279. * The function responsible for calculating series bubble' s bBox.
  10280. * Needed because of exporting failure when useSimulation
  10281. * is set to false
  10282. * @private
  10283. */
  10284. PackedBubbleSeries.prototype.seriesBox = function () {
  10285. var series = this,
  10286. chart = series.chart,
  10287. data = series.data,
  10288. max = Math.max,
  10289. min = Math.min,
  10290. radius,
  10291. // bBox = [xMin, xMax, yMin, yMax]
  10292. bBox = [
  10293. chart.plotLeft,
  10294. chart.plotLeft + chart.plotWidth,
  10295. chart.plotTop,
  10296. chart.plotTop + chart.plotHeight
  10297. ];
  10298. data.forEach(function (p) {
  10299. if (defined(p.plotX) &&
  10300. defined(p.plotY) &&
  10301. p.marker.radius) {
  10302. radius = p.marker.radius;
  10303. bBox[0] = min(bBox[0], p.plotX - radius);
  10304. bBox[1] = max(bBox[1], p.plotX + radius);
  10305. bBox[2] = min(bBox[2], p.plotY - radius);
  10306. bBox[3] = max(bBox[3], p.plotY + radius);
  10307. }
  10308. });
  10309. return isNumber(bBox.width / bBox.height) ?
  10310. bBox :
  10311. null;
  10312. };
  10313. /**
  10314. * Needed because of z-indexing issue if point is added in series.group
  10315. * @private
  10316. */
  10317. PackedBubbleSeries.prototype.setVisible = function () {
  10318. var series = this;
  10319. Series.prototype.setVisible.apply(series, arguments);
  10320. if (series.parentNodeLayout && series.graph) {
  10321. if (series.visible) {
  10322. series.graph.show();
  10323. if (series.parentNode.dataLabel) {
  10324. series.parentNode.dataLabel.show();
  10325. }
  10326. }
  10327. else {
  10328. series.graph.hide();
  10329. series.parentNodeLayout
  10330. .removeElementFromCollection(series.parentNode, series.parentNodeLayout.nodes);
  10331. if (series.parentNode.dataLabel) {
  10332. series.parentNode.dataLabel.hide();
  10333. }
  10334. }
  10335. }
  10336. else if (series.layout) {
  10337. if (series.visible) {
  10338. series.layout.addElementsToCollection(series.points, series.layout.nodes);
  10339. }
  10340. else {
  10341. series.points.forEach(function (node) {
  10342. series.layout.removeElementFromCollection(node, series.layout.nodes);
  10343. });
  10344. }
  10345. }
  10346. };
  10347. /**
  10348. * Extend the base translate method to handle bubble size,
  10349. * and correct positioning them.
  10350. * @private
  10351. */
  10352. PackedBubbleSeries.prototype.translate = function () {
  10353. var series = this,
  10354. chart = series.chart,
  10355. data = series.data,
  10356. index = series.index,
  10357. point,
  10358. radius,
  10359. positions,
  10360. i,
  10361. useSimulation = series.options.useSimulation;
  10362. series.processedXData = series.xData;
  10363. series.generatePoints();
  10364. // merged data is an array with all of the data from all series
  10365. if (!defined(chart.allDataPoints)) {
  10366. chart.allDataPoints = series.accumulateAllPoints(series);
  10367. // calculate radius for all added data
  10368. series.getPointRadius();
  10369. }
  10370. // after getting initial radius, calculate bubble positions
  10371. if (useSimulation) {
  10372. positions = chart.allDataPoints;
  10373. }
  10374. else {
  10375. positions = series.placeBubbles(chart.allDataPoints);
  10376. series.options.draggable = false;
  10377. }
  10378. // Set the shape and arguments to be picked up in drawPoints
  10379. for (i = 0; i < positions.length; i++) {
  10380. if (positions[i][3] === index) {
  10381. // update the series points with the val from positions
  10382. // array
  10383. point = data[positions[i][4]];
  10384. radius = positions[i][2];
  10385. if (!useSimulation) {
  10386. point.plotX = (positions[i][0] - chart.plotLeft +
  10387. chart.diffX);
  10388. point.plotY = (positions[i][1] - chart.plotTop +
  10389. chart.diffY);
  10390. }
  10391. point.marker = extend(point.marker, {
  10392. radius: radius,
  10393. width: 2 * radius,
  10394. height: 2 * radius
  10395. });
  10396. point.radius = radius;
  10397. }
  10398. }
  10399. if (useSimulation) {
  10400. series.deferLayout();
  10401. }
  10402. fireEvent(series, 'afterTranslate');
  10403. };
  10404. /**
  10405. * A packed bubble series is a two dimensional series type, where each point
  10406. * renders a value in X, Y position. Each point is drawn as a bubble
  10407. * where the bubbles don't overlap with each other and the radius
  10408. * of the bubble relates to the value.
  10409. *
  10410. * @sample highcharts/demo/packed-bubble/
  10411. * Packed bubble chart
  10412. * @sample highcharts/demo/packed-bubble-split/
  10413. * Split packed bubble chart
  10414. * @extends plotOptions.bubble
  10415. * @excluding connectEnds, connectNulls, cropThreshold, dragDrop, jitter,
  10416. * keys, pointPlacement, sizeByAbsoluteValue, step, xAxis,
  10417. * yAxis, zMax, zMin, dataSorting, boostThreshold,
  10418. * boostBlending
  10419. * @product highcharts
  10420. * @since 7.0.0
  10421. * @requires highcharts-more
  10422. * @optionparent plotOptions.packedbubble
  10423. */
  10424. PackedBubbleSeries.defaultOptions = merge(BubbleSeries.defaultOptions, {
  10425. /**
  10426. * Minimum bubble size. Bubbles will automatically size between the
  10427. * `minSize` and `maxSize` to reflect the value of each bubble.
  10428. * Can be either pixels (when no unit is given), or a percentage of
  10429. * the smallest one of the plot width and height, divided by the square
  10430. * root of total number of points.
  10431. *
  10432. * @sample highcharts/plotoptions/bubble-size/
  10433. * Bubble size
  10434. *
  10435. * @type {number|string}
  10436. *
  10437. * @private
  10438. */
  10439. minSize: '10%',
  10440. /**
  10441. * Maximum bubble size. Bubbles will automatically size between the
  10442. * `minSize` and `maxSize` to reflect the value of each bubble.
  10443. * Can be either pixels (when no unit is given), or a percentage of
  10444. * the smallest one of the plot width and height, divided by the square
  10445. * root of total number of points.
  10446. *
  10447. * @sample highcharts/plotoptions/bubble-size/
  10448. * Bubble size
  10449. *
  10450. * @type {number|string}
  10451. *
  10452. * @private
  10453. */
  10454. maxSize: '50%',
  10455. sizeBy: 'area',
  10456. zoneAxis: 'y',
  10457. crisp: false,
  10458. tooltip: {
  10459. pointFormat: 'Value: {point.value}'
  10460. },
  10461. /**
  10462. * Flag to determine if nodes are draggable or not. Available for
  10463. * graph with useSimulation set to true only.
  10464. *
  10465. * @since 7.1.0
  10466. *
  10467. * @private
  10468. */
  10469. draggable: true,
  10470. /**
  10471. * An option is giving a possibility to choose between using simulation
  10472. * for calculating bubble positions. These reflects in both animation
  10473. * and final position of bubbles. Simulation is also adding options to
  10474. * the series graph based on used layout. In case of big data sets, with
  10475. * any performance issues, it is possible to disable animation and pack
  10476. * bubble in a simple circular way.
  10477. *
  10478. * @sample highcharts/series-packedbubble/spiral/
  10479. * useSimulation set to false
  10480. *
  10481. * @since 7.1.0
  10482. *
  10483. * @private
  10484. */
  10485. useSimulation: true,
  10486. /**
  10487. * Series options for parent nodes.
  10488. *
  10489. * @since 8.1.1
  10490. *
  10491. * @private
  10492. */
  10493. parentNode: {
  10494. /**
  10495. * Allow this series' parent nodes to be selected
  10496. * by clicking on the graph.
  10497. *
  10498. * @since 8.1.1
  10499. */
  10500. allowPointSelect: false
  10501. },
  10502. /**
  10503. /**
  10504. *
  10505. * @declare Highcharts.SeriesPackedBubbleDataLabelsOptionsObject
  10506. *
  10507. * @private
  10508. */
  10509. dataLabels: {
  10510. /**
  10511. * The
  10512. * [format string](https://www.highcharts.com/docs/chart-concepts/labels-and-string-formatting)
  10513. * specifying what to show for _node_ in the networkgraph. In v7.0
  10514. * defaults to `{key}`, since v7.1 defaults to `undefined` and
  10515. * `formatter` is used instead.
  10516. *
  10517. * @type {string}
  10518. * @since 7.0.0
  10519. * @apioption plotOptions.packedbubble.dataLabels.format
  10520. */
  10521. // eslint-disable-next-line valid-jsdoc
  10522. /**
  10523. * Callback JavaScript function to format the data label for a node.
  10524. * Note that if a `format` is defined, the format takes precedence
  10525. * and the formatter is ignored.
  10526. *
  10527. * @type {Highcharts.SeriesPackedBubbleDataLabelsFormatterCallbackFunction}
  10528. * @since 7.0.0
  10529. */
  10530. formatter: function () {
  10531. return this.point.value;
  10532. },
  10533. /**
  10534. * @type {string}
  10535. * @since 7.1.0
  10536. * @apioption plotOptions.packedbubble.dataLabels.parentNodeFormat
  10537. */
  10538. // eslint-disable-next-line valid-jsdoc
  10539. /**
  10540. * @type {Highcharts.SeriesPackedBubbleDataLabelsFormatterCallbackFunction}
  10541. * @since 7.1.0
  10542. */
  10543. parentNodeFormatter: function () {
  10544. return this.name;
  10545. },
  10546. /**
  10547. * @sample {highcharts} highcharts/series-packedbubble/packed-dashboard
  10548. * Dashboard with dataLabels on parentNodes
  10549. *
  10550. * @declare Highcharts.SeriesPackedBubbleDataLabelsTextPathOptionsObject
  10551. * @since 7.1.0
  10552. */
  10553. parentNodeTextPath: {
  10554. /**
  10555. * Presentation attributes for the text path.
  10556. *
  10557. * @type {Highcharts.SVGAttributes}
  10558. * @since 7.1.0
  10559. * @apioption plotOptions.packedbubble.dataLabels.attributes
  10560. */
  10561. /**
  10562. * Enable or disable `textPath` option for link's or marker's
  10563. * data labels.
  10564. *
  10565. * @since 7.1.0
  10566. */
  10567. enabled: true
  10568. },
  10569. /**
  10570. * Options for a _node_ label text which should follow marker's
  10571. * shape.
  10572. *
  10573. * **Note:** Only SVG-based renderer supports this option.
  10574. *
  10575. * @extends plotOptions.series.dataLabels.textPath
  10576. * @apioption plotOptions.packedbubble.dataLabels.textPath
  10577. */
  10578. padding: 0,
  10579. style: {
  10580. transition: 'opacity 2000ms'
  10581. }
  10582. },
  10583. /**
  10584. * Options for layout algorithm when simulation is enabled. Inside there
  10585. * are options to change the speed, padding, initial bubbles positions
  10586. * and more.
  10587. *
  10588. * @extends plotOptions.networkgraph.layoutAlgorithm
  10589. * @excluding approximation, attractiveForce, repulsiveForce, theta
  10590. * @since 7.1.0
  10591. *
  10592. * @private
  10593. */
  10594. layoutAlgorithm: {
  10595. /**
  10596. * Initial layout algorithm for positioning nodes. Can be one of
  10597. * the built-in options ("circle", "random") or a function where
  10598. * positions should be set on each node (`this.nodes`) as
  10599. * `node.plotX` and `node.plotY`.
  10600. *
  10601. * @sample highcharts/series-networkgraph/initial-positions/
  10602. * Initial positions with callback
  10603. *
  10604. * @type {"circle"|"random"|Function}
  10605. */
  10606. initialPositions: 'circle',
  10607. /**
  10608. * @sample highcharts/series-packedbubble/initial-radius/
  10609. * Initial radius set to 200
  10610. *
  10611. * @extends plotOptions.networkgraph.layoutAlgorithm.initialPositionRadius
  10612. * @excluding states
  10613. */
  10614. initialPositionRadius: 20,
  10615. /**
  10616. * The distance between two bubbles, when the algorithm starts to
  10617. * treat two bubbles as overlapping. The `bubblePadding` is also the
  10618. * expected distance between all the bubbles on simulation end.
  10619. */
  10620. bubblePadding: 5,
  10621. /**
  10622. * Whether bubbles should interact with their parentNode to keep
  10623. * them inside.
  10624. */
  10625. parentNodeLimit: false,
  10626. /**
  10627. * Whether series should interact with each other or not. When
  10628. * `parentNodeLimit` is set to true, thi option should be set to
  10629. * false to avoid sticking points in wrong series parentNode.
  10630. */
  10631. seriesInteraction: true,
  10632. /**
  10633. * In case of split series, this option allows user to drag and
  10634. * drop points between series, for changing point related series.
  10635. *
  10636. * @sample highcharts/series-packedbubble/packed-dashboard/
  10637. * Example of drag'n drop bubbles for bubble kanban
  10638. */
  10639. dragBetweenSeries: false,
  10640. /**
  10641. * Layout algorithm options for parent nodes.
  10642. *
  10643. * @extends plotOptions.networkgraph.layoutAlgorithm
  10644. * @excluding approximation, attractiveForce, enableSimulation,
  10645. * repulsiveForce, theta
  10646. */
  10647. parentNodeOptions: {
  10648. maxIterations: 400,
  10649. gravitationalConstant: 0.03,
  10650. maxSpeed: 50,
  10651. initialPositionRadius: 100,
  10652. seriesInteraction: true,
  10653. /**
  10654. * Styling options for parentNodes markers. Similar to
  10655. * line.marker options.
  10656. *
  10657. * @sample highcharts/series-packedbubble/parentnode-style/
  10658. * Bubble size
  10659. *
  10660. * @extends plotOptions.series.marker
  10661. * @excluding states
  10662. */
  10663. marker: {
  10664. fillColor: null,
  10665. fillOpacity: 1,
  10666. lineWidth: 1,
  10667. lineColor: null,
  10668. symbol: 'circle'
  10669. }
  10670. },
  10671. enableSimulation: true,
  10672. /**
  10673. * Type of the algorithm used when positioning bubbles.
  10674. * @ignore-option
  10675. */
  10676. type: 'packedbubble',
  10677. /**
  10678. * Integration type. Integration determines how forces are applied
  10679. * on particles. The `packedbubble` integration is based on
  10680. * the networkgraph `verlet` integration, where the new position
  10681. * is based on a previous position without velocity:
  10682. * `newPosition += previousPosition - newPosition`.
  10683. *
  10684. * @sample highcharts/series-networkgraph/forces/
  10685. *
  10686. * @ignore-option
  10687. */
  10688. integration: 'packedbubble',
  10689. maxIterations: 1000,
  10690. /**
  10691. * Whether to split series into individual groups or to mix all
  10692. * series together.
  10693. *
  10694. * @since 7.1.0
  10695. * @default false
  10696. */
  10697. splitSeries: false,
  10698. /**
  10699. * Max speed that node can get in one iteration. In terms of
  10700. * simulation, it's a maximum translation (in pixels) that a node
  10701. * can move (in both, x and y, dimensions). While `friction` is
  10702. * applied on all nodes, max speed is applied only for nodes that
  10703. * move very fast, for example small or disconnected ones.
  10704. *
  10705. * @see [layoutAlgorithm.integration](#series.networkgraph.layoutAlgorithm.integration)
  10706. *
  10707. * @see [layoutAlgorithm.friction](#series.networkgraph.layoutAlgorithm.friction)
  10708. */
  10709. maxSpeed: 5,
  10710. gravitationalConstant: 0.01,
  10711. friction: -0.981
  10712. }
  10713. });
  10714. return PackedBubbleSeries;
  10715. }(BubbleSeries));
  10716. extend(PackedBubbleSeries.prototype, {
  10717. alignDataLabel: Series.prototype.alignDataLabel,
  10718. axisTypes: [],
  10719. directTouch: true,
  10720. /**
  10721. * Array of internal forces. Each force should be later defined in
  10722. * integrations.js.
  10723. * @private
  10724. */
  10725. forces: ['barycenter', 'repulsive'],
  10726. /**
  10727. * An internal option used for allowing nodes dragging.
  10728. * @private
  10729. */
  10730. hasDraggableNodes: true,
  10731. isCartesian: false,
  10732. noSharedTooltip: true,
  10733. /**
  10734. * Mouse down action, initializing drag&drop mode.
  10735. * @private
  10736. * @param {global.Event} event Browser event, before normalization.
  10737. * @param {Highcharts.Point} point The point that event occured.
  10738. */
  10739. onMouseDown: dragNodesMixin.onMouseDown,
  10740. /**
  10741. * Mouse move action during drag&drop.
  10742. * @private
  10743. * @param {global.Event} event Browser event, before normalization.
  10744. * @param {Highcharts.Point} point The point that event occured.
  10745. */
  10746. onMouseMove: dragNodesMixin.onMouseMove,
  10747. pointArrayMap: ['value'],
  10748. pointClass: PackedBubblePoint,
  10749. pointValKey: 'value',
  10750. /**
  10751. * Redraw halo on mousemove during the drag&drop action.
  10752. * @private
  10753. * @param {Highcharts.Point} point The point that should show halo.
  10754. */
  10755. redrawHalo: dragNodesMixin.redrawHalo,
  10756. requireSorting: false,
  10757. // solving #12287
  10758. searchPoint: H.noop,
  10759. trackerGroups: ['group', 'dataLabelsGroup', 'parentNodesGroup']
  10760. });
  10761. SeriesRegistry.registerSeriesType('packedbubble', PackedBubbleSeries);
  10762. /* *
  10763. *
  10764. * Default Export
  10765. *
  10766. * */
  10767. /* *
  10768. *
  10769. * API Declarations
  10770. *
  10771. * */
  10772. /**
  10773. * Formatter callback function.
  10774. *
  10775. * @callback Highcharts.SeriesPackedBubbleDataLabelsFormatterCallbackFunction
  10776. *
  10777. * @param {Highcharts.SeriesPackedBubbleDataLabelsFormatterContextObject} this
  10778. * Data label context to format
  10779. *
  10780. * @return {string}
  10781. * Formatted data label text
  10782. */
  10783. /**
  10784. * Context for the formatter function.
  10785. *
  10786. * @interface Highcharts.SeriesPackedBubbleDataLabelsFormatterContextObject
  10787. * @extends Highcharts.PointLabelObject
  10788. * @since 7.0.0
  10789. */ /**
  10790. * The color of the node.
  10791. * @name Highcharts.SeriesPackedBubbleDataLabelsFormatterContextObject#color
  10792. * @type {Highcharts.ColorString}
  10793. * @since 7.0.0
  10794. */ /**
  10795. * The point (node) object. The node name, if defined, is available through
  10796. * `this.point.name`. Arrays: `this.point.linksFrom` and `this.point.linksTo`
  10797. * contains all nodes connected to this point.
  10798. * @name Highcharts.SeriesPackedBubbleDataLabelsFormatterContextObject#point
  10799. * @type {Highcharts.Point}
  10800. * @since 7.0.0
  10801. */ /**
  10802. * The ID of the node.
  10803. * @name Highcharts.SeriesPackedBubbleDataLabelsFormatterContextObject#key
  10804. * @type {string}
  10805. * @since 7.0.0
  10806. */
  10807. ''; // detach doclets above
  10808. /* *
  10809. *
  10810. * API Options
  10811. *
  10812. * */
  10813. /**
  10814. * A `packedbubble` series. If the [type](#series.packedbubble.type) option is
  10815. * not specified, it is inherited from [chart.type](#chart.type).
  10816. *
  10817. * @type {Object}
  10818. * @extends series,plotOptions.packedbubble
  10819. * @excluding cropThreshold, dataParser, dataSorting, dataURL, dragDrop, stack,
  10820. * boostThreshold, boostBlending
  10821. * @product highcharts
  10822. * @requires highcharts-more
  10823. * @apioption series.packedbubble
  10824. */
  10825. /**
  10826. * An array of data points for the series. For the `packedbubble` series type,
  10827. * points can be given in the following ways:
  10828. *
  10829. * 1. An array of `values`.
  10830. *
  10831. * ```js
  10832. * data: [5, 1, 20]
  10833. * ```
  10834. *
  10835. * 2. An array of objects with named values. The objects are point
  10836. * configuration objects as seen below. If the total number of data points
  10837. * exceeds the series' [turboThreshold](#series.packedbubble.turboThreshold),
  10838. * this option is not available.
  10839. *
  10840. * ```js
  10841. * data: [{
  10842. * value: 1,
  10843. * name: "Point2",
  10844. * color: "#00FF00"
  10845. * }, {
  10846. * value: 5,
  10847. * name: "Point1",
  10848. * color: "#FF00FF"
  10849. * }]
  10850. * ```
  10851. *
  10852. * @type {Array<Object|Array>}
  10853. * @extends series.line.data
  10854. * @excluding marker, x, y
  10855. * @sample {highcharts} highcharts/series/data-array-of-objects/
  10856. * Config objects
  10857. * @product highcharts
  10858. * @apioption series.packedbubble.data
  10859. */
  10860. /**
  10861. * @type {Highcharts.SeriesPackedBubbleDataLabelsOptionsObject|Array<Highcharts.SeriesPackedBubbleDataLabelsOptionsObject>}
  10862. * @product highcharts
  10863. * @apioption series.packedbubble.data.dataLabels
  10864. */
  10865. /**
  10866. * @excluding enabled,enabledThreshold,height,radius,width
  10867. * @product highcharts
  10868. * @apioption series.packedbubble.marker
  10869. */
  10870. ''; // adds doclets above to transpiled file
  10871. return PackedBubbleSeries;
  10872. });
  10873. _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) {
  10874. /* *
  10875. *
  10876. * (c) 2010-2021 Torstein Honsi
  10877. *
  10878. * License: www.highcharts.com/license
  10879. *
  10880. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  10881. *
  10882. * */
  10883. var animObject = A.animObject;
  10884. var seriesTypes = SeriesRegistry.seriesTypes;
  10885. var addEvent = U.addEvent,
  10886. defined = U.defined,
  10887. find = U.find,
  10888. isNumber = U.isNumber,
  10889. pick = U.pick,
  10890. splat = U.splat,
  10891. uniqueKey = U.uniqueKey,
  10892. wrap = U.wrap;
  10893. // Extensions for polar charts. Additionally, much of the geometry required for
  10894. // polar charts is gathered in RadialAxes.js.
  10895. var seriesProto = Series.prototype,
  10896. pointerProto = Pointer.prototype,
  10897. columnProto,
  10898. arearangeProto;
  10899. /* eslint-disable no-invalid-this, valid-jsdoc */
  10900. /**
  10901. * Search a k-d tree by the point angle, used for shared tooltips in polar
  10902. * charts
  10903. * @private
  10904. */
  10905. seriesProto.searchPointByAngle = function (e) {
  10906. var series = this,
  10907. chart = series.chart,
  10908. xAxis = series.xAxis,
  10909. center = xAxis.pane.center,
  10910. plotX = e.chartX - center[0] - chart.plotLeft,
  10911. plotY = e.chartY - center[1] - chart.plotTop;
  10912. return this.searchKDTree({
  10913. clientX: 180 + (Math.atan2(plotX, plotY) * (-180 / Math.PI))
  10914. });
  10915. };
  10916. /**
  10917. * #6212 Calculate connectors for spline series in polar chart.
  10918. * @private
  10919. * @param {boolean} calculateNeighbours
  10920. * Check if connectors should be calculated for neighbour points as
  10921. * well allows short recurence
  10922. */
  10923. seriesProto.getConnectors = function (segment, index, calculateNeighbours, connectEnds) {
  10924. var i,
  10925. prevPointInd,
  10926. nextPointInd,
  10927. previousPoint,
  10928. nextPoint,
  10929. previousX,
  10930. previousY,
  10931. nextX,
  10932. nextY,
  10933. plotX,
  10934. plotY,
  10935. ret,
  10936. // 1 means control points midway between points, 2 means 1/3 from
  10937. // the point, 3 is 1/4 etc;
  10938. smoothing = 1.5, denom = smoothing + 1, leftContX, leftContY, rightContX, rightContY, dLControlPoint, // distance left control point
  10939. dRControlPoint, leftContAngle, rightContAngle, jointAngle, addedNumber = connectEnds ? 1 : 0;
  10940. // Calculate final index of points depending on the initial index value.
  10941. // Because of calculating neighbours, index may be outisde segment
  10942. // array.
  10943. if (index >= 0 && index <= segment.length - 1) {
  10944. i = index;
  10945. }
  10946. else if (index < 0) {
  10947. i = segment.length - 1 + index;
  10948. }
  10949. else {
  10950. i = 0;
  10951. }
  10952. prevPointInd = (i - 1 < 0) ? segment.length - (1 + addedNumber) : i - 1;
  10953. nextPointInd = (i + 1 > segment.length - 1) ? addedNumber : i + 1;
  10954. previousPoint = segment[prevPointInd];
  10955. nextPoint = segment[nextPointInd];
  10956. previousX = previousPoint.plotX;
  10957. previousY = previousPoint.plotY;
  10958. nextX = nextPoint.plotX;
  10959. nextY = nextPoint.plotY;
  10960. plotX = segment[i].plotX; // actual point
  10961. plotY = segment[i].plotY;
  10962. leftContX = (smoothing * plotX + previousX) / denom;
  10963. leftContY = (smoothing * plotY + previousY) / denom;
  10964. rightContX = (smoothing * plotX + nextX) / denom;
  10965. rightContY = (smoothing * plotY + nextY) / denom;
  10966. dLControlPoint = Math.sqrt(Math.pow(leftContX - plotX, 2) + Math.pow(leftContY - plotY, 2));
  10967. dRControlPoint = Math.sqrt(Math.pow(rightContX - plotX, 2) + Math.pow(rightContY - plotY, 2));
  10968. leftContAngle = Math.atan2(leftContY - plotY, leftContX - plotX);
  10969. rightContAngle = Math.atan2(rightContY - plotY, rightContX - plotX);
  10970. jointAngle = (Math.PI / 2) + ((leftContAngle + rightContAngle) / 2);
  10971. // Ensure the right direction, jointAngle should be in the same quadrant
  10972. // as leftContAngle
  10973. if (Math.abs(leftContAngle - jointAngle) > Math.PI / 2) {
  10974. jointAngle -= Math.PI;
  10975. }
  10976. // Find the corrected control points for a spline straight through the
  10977. // point
  10978. leftContX = plotX + Math.cos(jointAngle) * dLControlPoint;
  10979. leftContY = plotY + Math.sin(jointAngle) * dLControlPoint;
  10980. rightContX = plotX + Math.cos(Math.PI + jointAngle) * dRControlPoint;
  10981. rightContY = plotY + Math.sin(Math.PI + jointAngle) * dRControlPoint;
  10982. // push current point's connectors into returned object
  10983. ret = {
  10984. rightContX: rightContX,
  10985. rightContY: rightContY,
  10986. leftContX: leftContX,
  10987. leftContY: leftContY,
  10988. plotX: plotX,
  10989. plotY: plotY
  10990. };
  10991. // calculate connectors for previous and next point and push them inside
  10992. // returned object
  10993. if (calculateNeighbours) {
  10994. ret.prevPointCont = this.getConnectors(segment, prevPointInd, false, connectEnds);
  10995. }
  10996. return ret;
  10997. };
  10998. /**
  10999. * Translate a point's plotX and plotY from the internal angle and radius
  11000. * measures to true plotX, plotY coordinates
  11001. * @private
  11002. */
  11003. seriesProto.toXY = function (point) {
  11004. var xy,
  11005. chart = this.chart,
  11006. xAxis = this.xAxis,
  11007. yAxis = this.yAxis,
  11008. plotX = point.plotX,
  11009. plotY = point.plotY,
  11010. series = point.series,
  11011. inverted = chart.inverted,
  11012. pointY = point.y,
  11013. radius = inverted ? plotX : yAxis.len - plotY,
  11014. clientX;
  11015. // Corrected y position of inverted series other than column
  11016. if (inverted && series && !series.isRadialBar) {
  11017. point.plotY = plotY =
  11018. typeof pointY === 'number' ? (yAxis.translate(pointY) || 0) : 0;
  11019. }
  11020. // Save rectangular plotX, plotY for later computation
  11021. point.rectPlotX = plotX;
  11022. point.rectPlotY = plotY;
  11023. if (yAxis.center) {
  11024. radius += yAxis.center[3] / 2;
  11025. }
  11026. // Find the polar plotX and plotY
  11027. xy = inverted ? yAxis.postTranslate(plotY, radius) :
  11028. xAxis.postTranslate(plotX, radius);
  11029. point.plotX = point.polarPlotX = xy.x - chart.plotLeft;
  11030. point.plotY = point.polarPlotY = xy.y - chart.plotTop;
  11031. // If shared tooltip, record the angle in degrees in order to align X
  11032. // points. Otherwise, use a standard k-d tree to get the nearest point
  11033. // in two dimensions.
  11034. if (this.kdByAngle) {
  11035. clientX = ((plotX / Math.PI * 180) +
  11036. xAxis.pane.options.startAngle) % 360;
  11037. if (clientX < 0) { // #2665
  11038. clientX += 360;
  11039. }
  11040. point.clientX = clientX;
  11041. }
  11042. else {
  11043. point.clientX = point.plotX;
  11044. }
  11045. };
  11046. if (seriesTypes.spline) {
  11047. /**
  11048. * Overridden method for calculating a spline from one point to the next
  11049. * @private
  11050. */
  11051. wrap(seriesTypes.spline.prototype, 'getPointSpline', function (proceed, segment, point, i) {
  11052. var ret,
  11053. connectors;
  11054. if (this.chart.polar) {
  11055. // moveTo or lineTo
  11056. if (!i) {
  11057. ret = ['M', point.plotX, point.plotY];
  11058. }
  11059. else { // curve from last point to this
  11060. connectors = this.getConnectors(segment, i, true, this.connectEnds);
  11061. ret = [
  11062. 'C',
  11063. connectors.prevPointCont.rightContX,
  11064. connectors.prevPointCont.rightContY,
  11065. connectors.leftContX,
  11066. connectors.leftContY,
  11067. connectors.plotX,
  11068. connectors.plotY
  11069. ];
  11070. }
  11071. }
  11072. else {
  11073. ret = proceed.call(this, segment, point, i);
  11074. }
  11075. return ret;
  11076. });
  11077. // #6430 Areasplinerange series use unwrapped getPointSpline method, so
  11078. // we need to set this method again.
  11079. if (seriesTypes.areasplinerange) {
  11080. seriesTypes.areasplinerange.prototype.getPointSpline = seriesTypes.spline.prototype.getPointSpline;
  11081. }
  11082. }
  11083. /**
  11084. * Extend translate. The plotX and plotY values are computed as if the polar
  11085. * chart were a cartesian plane, where plotX denotes the angle in radians
  11086. * and (yAxis.len - plotY) is the pixel distance from center.
  11087. * @private
  11088. */
  11089. addEvent(Series, 'afterTranslate', function () {
  11090. var series = this;
  11091. var chart = series.chart;
  11092. if (chart.polar && series.xAxis) {
  11093. // Prepare k-d-tree handling. It searches by angle (clientX) in
  11094. // case of shared tooltip, and by two dimensional distance in case
  11095. // of non-shared.
  11096. series.kdByAngle = chart.tooltip && chart.tooltip.shared;
  11097. if (series.kdByAngle) {
  11098. series.searchPoint = series.searchPointByAngle;
  11099. }
  11100. else {
  11101. series.options.findNearestPointBy = 'xy';
  11102. }
  11103. // Postprocess plot coordinates
  11104. if (!series.preventPostTranslate) {
  11105. var points = series.points;
  11106. var i = points.length;
  11107. while (i--) {
  11108. // Translate plotX, plotY from angle and radius to true plot
  11109. // coordinates
  11110. series.toXY(points[i]);
  11111. // Treat points below Y axis min as null (#10082)
  11112. if (!chart.hasParallelCoordinates &&
  11113. !series.yAxis.reversed &&
  11114. points[i].y < series.yAxis.min) {
  11115. points[i].isNull = true;
  11116. }
  11117. }
  11118. }
  11119. // Perform clip after render
  11120. if (!this.hasClipCircleSetter) {
  11121. this.hasClipCircleSetter = !!series.eventsToUnbind.push(addEvent(series, 'afterRender', function () {
  11122. var circ;
  11123. if (chart.polar) {
  11124. // For clipping purposes there is a need for
  11125. // coordinates from the absolute center
  11126. circ = this.yAxis.pane.center;
  11127. if (!this.clipCircle) {
  11128. this.clipCircle = chart.renderer.clipCircle(circ[0], circ[1], circ[2] / 2, circ[3] / 2);
  11129. }
  11130. else {
  11131. this.clipCircle.animate({
  11132. x: circ[0],
  11133. y: circ[1],
  11134. r: circ[2] / 2,
  11135. innerR: circ[3] / 2
  11136. });
  11137. }
  11138. this.group.clip(this.clipCircle);
  11139. this.setClip = H.noop;
  11140. }
  11141. }));
  11142. }
  11143. }
  11144. }, { order: 2 }); // Run after translation of ||-coords
  11145. /**
  11146. * Extend getSegmentPath to allow connecting ends across 0 to provide a
  11147. * closed circle in line-like series.
  11148. * @private
  11149. */
  11150. wrap(seriesTypes.line.prototype, 'getGraphPath', function (proceed, points) {
  11151. var series = this,
  11152. i,
  11153. firstValid,
  11154. popLastPoint;
  11155. // Connect the path
  11156. if (this.chart.polar) {
  11157. points = points || this.points;
  11158. // Append first valid point in order to connect the ends
  11159. for (i = 0; i < points.length; i++) {
  11160. if (!points[i].isNull) {
  11161. firstValid = i;
  11162. break;
  11163. }
  11164. }
  11165. /**
  11166. * Polar charts only. Whether to connect the ends of a line series
  11167. * plot across the extremes.
  11168. *
  11169. * @sample {highcharts} highcharts/plotoptions/line-connectends-false/
  11170. * Do not connect
  11171. *
  11172. * @type {boolean}
  11173. * @since 2.3.0
  11174. * @product highcharts
  11175. * @apioption plotOptions.series.connectEnds
  11176. */
  11177. if (this.options.connectEnds !== false &&
  11178. typeof firstValid !== 'undefined') {
  11179. this.connectEnds = true; // re-used in splines
  11180. points.splice(points.length, 0, points[firstValid]);
  11181. popLastPoint = true;
  11182. }
  11183. // For area charts, pseudo points are added to the graph, now we
  11184. // need to translate these
  11185. points.forEach(function (point) {
  11186. if (typeof point.polarPlotY === 'undefined') {
  11187. series.toXY(point);
  11188. }
  11189. });
  11190. }
  11191. // Run uber method
  11192. var ret = proceed.apply(this,
  11193. [].slice.call(arguments, 1));
  11194. // #6212 points.splice method is adding points to an array. In case of
  11195. // areaspline getGraphPath method is used two times and in both times
  11196. // points are added to an array. That is why points.pop is used, to get
  11197. // unmodified points.
  11198. if (popLastPoint) {
  11199. points.pop();
  11200. }
  11201. return ret;
  11202. });
  11203. var polarAnimate = function (proceed,
  11204. init) {
  11205. var series = this,
  11206. chart = this.chart,
  11207. animation = this.options.animation,
  11208. group = this.group,
  11209. markerGroup = this.markerGroup,
  11210. center = this.xAxis.center,
  11211. plotLeft = chart.plotLeft,
  11212. plotTop = chart.plotTop,
  11213. attribs,
  11214. paneInnerR,
  11215. graphic,
  11216. shapeArgs,
  11217. r,
  11218. innerR;
  11219. // Specific animation for polar charts
  11220. if (chart.polar) {
  11221. if (series.isRadialBar) {
  11222. if (!init) {
  11223. // Run the pie animation for radial bars
  11224. series.startAngleRad = pick(series.translatedThreshold, series.xAxis.startAngleRad);
  11225. H.seriesTypes.pie.prototype.animate.call(series, init);
  11226. }
  11227. }
  11228. else {
  11229. // Enable animation on polar charts only in SVG. In VML, the scaling
  11230. // is different, plus animation would be so slow it would't matter.
  11231. if (chart.renderer.isSVG) {
  11232. animation = animObject(animation);
  11233. // A different animation needed for column like series
  11234. if (series.is('column')) {
  11235. if (!init) {
  11236. paneInnerR = center[3] / 2;
  11237. series.points.forEach(function (point) {
  11238. graphic = point.graphic;
  11239. shapeArgs = point.shapeArgs;
  11240. r = shapeArgs && shapeArgs.r;
  11241. innerR = shapeArgs && shapeArgs.innerR;
  11242. if (graphic && shapeArgs) {
  11243. // start values
  11244. graphic.attr({
  11245. r: paneInnerR,
  11246. innerR: paneInnerR
  11247. });
  11248. // animate
  11249. graphic.animate({
  11250. r: r,
  11251. innerR: innerR
  11252. }, series.options.animation);
  11253. }
  11254. });
  11255. }
  11256. }
  11257. else {
  11258. // Initialize the animation
  11259. if (init) {
  11260. // Scale down the group and place it in the center
  11261. attribs = {
  11262. translateX: center[0] + plotLeft,
  11263. translateY: center[1] + plotTop,
  11264. scaleX: 0.001,
  11265. scaleY: 0.001
  11266. };
  11267. group.attr(attribs);
  11268. if (markerGroup) {
  11269. markerGroup.attr(attribs);
  11270. }
  11271. // Run the animation
  11272. }
  11273. else {
  11274. attribs = {
  11275. translateX: plotLeft,
  11276. translateY: plotTop,
  11277. scaleX: 1,
  11278. scaleY: 1
  11279. };
  11280. group.animate(attribs, animation);
  11281. if (markerGroup) {
  11282. markerGroup.animate(attribs, animation);
  11283. }
  11284. }
  11285. }
  11286. }
  11287. }
  11288. // For non-polar charts, revert to the basic animation
  11289. }
  11290. else {
  11291. proceed.call(this, init);
  11292. }
  11293. };
  11294. // Define the animate method for regular series
  11295. wrap(seriesProto, 'animate', polarAnimate);
  11296. if (seriesTypes.column) {
  11297. arearangeProto = seriesTypes.arearange.prototype;
  11298. columnProto = seriesTypes.column.prototype;
  11299. columnProto.polarArc = function (low, high, start, end) {
  11300. var center = this.xAxis.center,
  11301. len = this.yAxis.len,
  11302. paneInnerR = center[3] / 2,
  11303. r = len - high + paneInnerR,
  11304. innerR = len - pick(low,
  11305. len) + paneInnerR;
  11306. // Prevent columns from shooting through the pane's center
  11307. if (this.yAxis.reversed) {
  11308. if (r < 0) {
  11309. r = paneInnerR;
  11310. }
  11311. if (innerR < 0) {
  11312. innerR = paneInnerR;
  11313. }
  11314. }
  11315. // Return a new shapeArgs
  11316. return {
  11317. x: center[0],
  11318. y: center[1],
  11319. r: r,
  11320. innerR: innerR,
  11321. start: start,
  11322. end: end
  11323. };
  11324. };
  11325. /**
  11326. * Define the animate method for columnseries
  11327. * @private
  11328. */
  11329. wrap(columnProto, 'animate', polarAnimate);
  11330. /**
  11331. * Extend the column prototype's translate method
  11332. * @private
  11333. */
  11334. wrap(columnProto, 'translate', function (proceed) {
  11335. var series = this,
  11336. options = series.options,
  11337. threshold = options.threshold,
  11338. stacking = options.stacking,
  11339. chart = series.chart,
  11340. xAxis = series.xAxis,
  11341. yAxis = series.yAxis,
  11342. reversed = yAxis.reversed,
  11343. center = yAxis.center,
  11344. startAngleRad = xAxis.startAngleRad,
  11345. endAngleRad = xAxis.endAngleRad,
  11346. visibleRange = endAngleRad - startAngleRad,
  11347. thresholdAngleRad,
  11348. points,
  11349. point,
  11350. i,
  11351. yMin,
  11352. yMax,
  11353. start,
  11354. end,
  11355. tooltipPos,
  11356. pointX,
  11357. pointY,
  11358. stackValues,
  11359. stack,
  11360. barX,
  11361. innerR,
  11362. r;
  11363. series.preventPostTranslate = true;
  11364. // Run uber method
  11365. proceed.call(series);
  11366. // Postprocess plot coordinates
  11367. if (xAxis.isRadial) {
  11368. points = series.points;
  11369. i = points.length;
  11370. yMin = yAxis.translate(yAxis.min);
  11371. yMax = yAxis.translate(yAxis.max);
  11372. threshold = options.threshold || 0;
  11373. if (chart.inverted) {
  11374. // Finding a correct threshold
  11375. if (isNumber(threshold)) {
  11376. thresholdAngleRad = yAxis.translate(threshold);
  11377. // Checks if threshold is outside the visible range
  11378. if (defined(thresholdAngleRad)) {
  11379. if (thresholdAngleRad < 0) {
  11380. thresholdAngleRad = 0;
  11381. }
  11382. else if (thresholdAngleRad > visibleRange) {
  11383. thresholdAngleRad = visibleRange;
  11384. }
  11385. // Adding start angle offset
  11386. series.translatedThreshold =
  11387. thresholdAngleRad + startAngleRad;
  11388. }
  11389. }
  11390. }
  11391. while (i--) {
  11392. point = points[i];
  11393. barX = point.barX;
  11394. pointX = point.x;
  11395. pointY = point.y;
  11396. point.shapeType = 'arc';
  11397. if (chart.inverted) {
  11398. point.plotY = yAxis.translate(pointY);
  11399. if (stacking && yAxis.stacking) {
  11400. stack = yAxis.stacking.stacks[(pointY < 0 ? '-' : '') +
  11401. series.stackKey];
  11402. if (series.visible && stack && stack[pointX]) {
  11403. if (!point.isNull) {
  11404. stackValues = stack[pointX].points[series.getStackIndicator(void 0, pointX, series.index).key];
  11405. // Translating to radial values
  11406. start = yAxis.translate(stackValues[0]);
  11407. end = yAxis.translate(stackValues[1]);
  11408. // If starting point is beyond the
  11409. // range, set it to 0
  11410. if (defined(start)) {
  11411. start = U.clamp(start, 0, visibleRange);
  11412. }
  11413. }
  11414. }
  11415. }
  11416. else {
  11417. // Initial start and end angles for radial bar
  11418. start = thresholdAngleRad;
  11419. end = point.plotY;
  11420. }
  11421. if (start > end) {
  11422. // Swapping start and end
  11423. end = [start, start = end][0];
  11424. }
  11425. // Prevent from rendering point outside the
  11426. // acceptable circular range
  11427. if (!reversed) {
  11428. if (start < yMin) {
  11429. start = yMin;
  11430. }
  11431. else if (end > yMax) {
  11432. end = yMax;
  11433. }
  11434. else if (end < yMin || start > yMax) {
  11435. start = end = 0;
  11436. }
  11437. }
  11438. else {
  11439. if (end > yMin) {
  11440. end = yMin;
  11441. }
  11442. else if (start < yMax) {
  11443. start = yMax;
  11444. }
  11445. else if (start > yMin || end < yMax) {
  11446. start = end = visibleRange;
  11447. }
  11448. }
  11449. if (yAxis.min > yAxis.max) {
  11450. start = end = reversed ? visibleRange : 0;
  11451. }
  11452. start += startAngleRad;
  11453. end += startAngleRad;
  11454. if (center) {
  11455. point.barX = barX += center[3] / 2;
  11456. }
  11457. // In case when radius, inner radius or both are
  11458. // negative, a point is rendered but partially or as
  11459. // a center point
  11460. innerR = Math.max(barX, 0);
  11461. r = Math.max(barX + point.pointWidth, 0);
  11462. point.shapeArgs = {
  11463. x: center && center[0],
  11464. y: center && center[1],
  11465. r: r,
  11466. innerR: innerR,
  11467. start: start,
  11468. end: end
  11469. };
  11470. // Fade out the points if not inside the polar "plot area"
  11471. point.opacity = start === end ? 0 : void 0;
  11472. // A correct value for stacked or not fully visible
  11473. // point
  11474. point.plotY = (defined(series.translatedThreshold) &&
  11475. (start < series.translatedThreshold ? start : end)) -
  11476. startAngleRad;
  11477. }
  11478. else {
  11479. start = barX + startAngleRad;
  11480. // Changed the way polar columns are drawn in order to make
  11481. // it more consistent with the drawing of inverted columns
  11482. // (they are using the same function now). Also, it was
  11483. // essential to make the animation work correctly (the
  11484. // scaling of the group) is replaced by animating each
  11485. // element separately.
  11486. point.shapeArgs = series.polarArc(point.yBottom, point.plotY, start, start + point.pointWidth);
  11487. }
  11488. // Provided a correct coordinates for the tooltip
  11489. series.toXY(point);
  11490. if (chart.inverted) {
  11491. tooltipPos = yAxis.postTranslate(point.rectPlotY, barX + point.pointWidth / 2);
  11492. point.tooltipPos = [
  11493. tooltipPos.x - chart.plotLeft,
  11494. tooltipPos.y - chart.plotTop
  11495. ];
  11496. }
  11497. else {
  11498. point.tooltipPos = [point.plotX, point.plotY];
  11499. }
  11500. if (center) {
  11501. point.ttBelow = point.plotY > center[1];
  11502. }
  11503. }
  11504. }
  11505. });
  11506. /**
  11507. * Find correct align and vertical align based on an angle in polar chart
  11508. * @private
  11509. */
  11510. columnProto.findAlignments = function (angle, options) {
  11511. var align,
  11512. verticalAlign;
  11513. if (options.align === null) {
  11514. if (angle > 20 && angle < 160) {
  11515. align = 'left'; // right hemisphere
  11516. }
  11517. else if (angle > 200 && angle < 340) {
  11518. align = 'right'; // left hemisphere
  11519. }
  11520. else {
  11521. align = 'center'; // top or bottom
  11522. }
  11523. options.align = align;
  11524. }
  11525. if (options.verticalAlign === null) {
  11526. if (angle < 45 || angle > 315) {
  11527. verticalAlign = 'bottom'; // top part
  11528. }
  11529. else if (angle > 135 && angle < 225) {
  11530. verticalAlign = 'top'; // bottom part
  11531. }
  11532. else {
  11533. verticalAlign = 'middle'; // left or right
  11534. }
  11535. options.verticalAlign = verticalAlign;
  11536. }
  11537. return options;
  11538. };
  11539. if (arearangeProto) {
  11540. arearangeProto.findAlignments = columnProto.findAlignments;
  11541. }
  11542. /**
  11543. * Align column data labels outside the columns. #1199.
  11544. * @private
  11545. */
  11546. wrap(columnProto, 'alignDataLabel', function (proceed, point, dataLabel, options, alignTo, isNew) {
  11547. var chart = this.chart,
  11548. inside = pick(options.inside, !!this.options.stacking),
  11549. angle,
  11550. shapeArgs,
  11551. labelPos;
  11552. if (chart.polar) {
  11553. angle = point.rectPlotX / Math.PI * 180;
  11554. if (!chart.inverted) {
  11555. // Align nicely outside the perimeter of the columns
  11556. if (this.findAlignments) {
  11557. options = this.findAlignments(angle, options);
  11558. }
  11559. }
  11560. else { // Required corrections for data labels of inverted bars
  11561. // The plotX and plotY are correctly set therefore they
  11562. // don't need to be swapped (inverted argument is false)
  11563. this.forceDL = chart.isInsidePlot(point.plotX, Math.round(point.plotY), false);
  11564. // Checks if labels should be positioned inside
  11565. if (inside && point.shapeArgs) {
  11566. shapeArgs = point.shapeArgs;
  11567. // Calculates pixel positions for a data label to be
  11568. // inside
  11569. labelPos =
  11570. this.yAxis.postTranslate(
  11571. // angle
  11572. (shapeArgs.start + shapeArgs.end) / 2 -
  11573. this
  11574. .xAxis.startAngleRad,
  11575. // radius
  11576. point.barX +
  11577. point.pointWidth / 2);
  11578. alignTo = {
  11579. x: labelPos.x - chart.plotLeft,
  11580. y: labelPos.y - chart.plotTop
  11581. };
  11582. }
  11583. else if (point.tooltipPos) {
  11584. alignTo = {
  11585. x: point.tooltipPos[0],
  11586. y: point.tooltipPos[1]
  11587. };
  11588. }
  11589. options.align = pick(options.align, 'center');
  11590. options.verticalAlign =
  11591. pick(options.verticalAlign, 'middle');
  11592. }
  11593. seriesProto.alignDataLabel.call(this, point, dataLabel, options, alignTo, isNew);
  11594. // Hide label of a point (only inverted) that is outside the
  11595. // visible y range
  11596. if (this.isRadialBar && point.shapeArgs &&
  11597. point.shapeArgs.start === point.shapeArgs.end) {
  11598. dataLabel.hide(true);
  11599. }
  11600. }
  11601. else {
  11602. proceed.call(this, point, dataLabel, options, alignTo, isNew);
  11603. }
  11604. });
  11605. }
  11606. /**
  11607. * Extend getCoordinates to prepare for polar axis values
  11608. * @private
  11609. */
  11610. wrap(pointerProto, 'getCoordinates', function (proceed, e) {
  11611. var chart = this.chart,
  11612. ret = {
  11613. xAxis: [],
  11614. yAxis: []
  11615. };
  11616. if (chart.polar) {
  11617. chart.axes.forEach(function (axis) {
  11618. var isXAxis = axis.isXAxis,
  11619. center = axis.center,
  11620. x,
  11621. y;
  11622. // Skip colorAxis
  11623. if (axis.coll === 'colorAxis') {
  11624. return;
  11625. }
  11626. x = e.chartX - center[0] - chart.plotLeft;
  11627. y = e.chartY - center[1] - chart.plotTop;
  11628. ret[isXAxis ? 'xAxis' : 'yAxis'].push({
  11629. axis: axis,
  11630. value: axis.translate(isXAxis ?
  11631. Math.PI - Math.atan2(x, y) : // angle
  11632. // distance from center
  11633. Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)), true)
  11634. });
  11635. });
  11636. }
  11637. else {
  11638. ret = proceed.call(this, e);
  11639. }
  11640. return ret;
  11641. });
  11642. SVGRenderer.prototype.clipCircle = function (x, y, r, innerR) {
  11643. var wrapper,
  11644. id = uniqueKey(),
  11645. clipPath = this.createElement('clipPath').attr({
  11646. id: id
  11647. }).add(this.defs);
  11648. wrapper = innerR ?
  11649. this.arc(x, y, r, innerR, 0, 2 * Math.PI).add(clipPath) :
  11650. this.circle(x, y, r).add(clipPath);
  11651. wrapper.id = id;
  11652. wrapper.clipPath = clipPath;
  11653. return wrapper;
  11654. };
  11655. addEvent(Chart, 'getAxes', function () {
  11656. if (!this.pane) {
  11657. this.pane = [];
  11658. }
  11659. splat(this.options.pane).forEach(function (paneOptions) {
  11660. new Pane(// eslint-disable-line no-new
  11661. paneOptions, this);
  11662. }, this);
  11663. });
  11664. addEvent(Chart, 'afterDrawChartBox', function () {
  11665. this.pane.forEach(function (pane) {
  11666. pane.render();
  11667. });
  11668. });
  11669. addEvent(Series, 'afterInit', function () {
  11670. var chart = this.chart;
  11671. // Add flags that identifies radial inverted series
  11672. if (chart.inverted && chart.polar) {
  11673. this.isRadialSeries = true;
  11674. if (this.is('column')) {
  11675. this.isRadialBar = true;
  11676. }
  11677. }
  11678. });
  11679. /**
  11680. * Extend chart.get to also search in panes. Used internally in
  11681. * responsiveness and chart.update.
  11682. * @private
  11683. */
  11684. wrap(Chart.prototype, 'get', function (proceed, id) {
  11685. return find(this.pane || [], function (pane) {
  11686. return pane.options.id === id;
  11687. }) || proceed.call(this, id);
  11688. });
  11689. });
  11690. _registerModule(_modules, 'masters/highcharts-more.src.js', [], function () {
  11691. });
  11692. }));