highcharts-more.src.js 502 KB

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