Axis.js 221 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442
  1. /* *
  2. * (c) 2010-2019 Torstein Honsi
  3. *
  4. * License: www.highcharts.com/license
  5. */
  6. /**
  7. * @callback Highcharts.AxisEventCallbackFunction
  8. *
  9. * @param {Highcharts.Axis} this
  10. */
  11. /**
  12. * Options for crosshairs on axes.
  13. *
  14. * @typedef {Highcharts.XAxisCrosshairOptions|Highcharts.YAxisCrosshairOptions} Highcharts.AxisCrosshairOptions
  15. */
  16. /**
  17. * @interface Highcharts.AxisLabelsFormatterContextObject
  18. *//**
  19. * @name Highcharts.AxisLabelsFormatterContextObject#axis
  20. * @type {Highcharts.Axis}
  21. *//**
  22. * @name Highcharts.AxisLabelsFormatterContextObject#chart
  23. * @type {Highcharts.Chart}
  24. *//**
  25. * @name Highcharts.AxisLabelsFormatterContextObject#isFirst
  26. * @type {boolean}
  27. *//**
  28. * @name Highcharts.AxisLabelsFormatterContextObject#isLast
  29. * @type {boolean}
  30. *//**
  31. * @name Highcharts.AxisLabelsFormatterContextObject#value
  32. * @type {number}
  33. */
  34. /**
  35. * Options for axes.
  36. *
  37. * @typedef {Highcharts.XAxisOptions|Highcharts.YAxisOptions|Highcharts.ZAxisOptions} Highcharts.AxisOptions
  38. */
  39. /**
  40. * The returned object literal from the {@link Highcharts.Axis#getExtremes}
  41. * function.
  42. *
  43. * @interface Highcharts.ExtremesObject
  44. *//**
  45. * The maximum value of the axis' associated series.
  46. * @name Highcharts.ExtremesObject#dataMax
  47. * @type {number}
  48. *//**
  49. * The minimum value of the axis' associated series.
  50. * @name Highcharts.ExtremesObject#dataMin
  51. * @type {number}
  52. *//**
  53. * The maximum axis value, either automatic or set manually. If the `max` option
  54. * is not set, `maxPadding` is 0 and `endOnTick` is false, this value will be
  55. * the same as `dataMax`.
  56. * @name Highcharts.ExtremesObject#max
  57. * @type {number}
  58. *//**
  59. * The minimum axis value, either automatic or set manually. If the `min` option
  60. * is not set, `minPadding` is 0 and `startOnTick` is false, this value will be
  61. * the same as `dataMin`.
  62. * @name Highcharts.ExtremesObject#min
  63. * @type {number}
  64. *//**
  65. * The user defined maximum, either from the `max` option or from a zoom or
  66. * `setExtremes` action.
  67. * @name Highcharts.ExtremesObject#userMax
  68. * @type {number}
  69. *//**
  70. * The user defined minimum, either from the `min` option or from a zoom or
  71. * `setExtremes` action.
  72. * @name Highcharts.ExtremesObject#userMin
  73. * @type {number}
  74. */
  75. /**
  76. * @callback Highcharts.AxisPointBreakEventCallbackFunction
  77. *
  78. * @param {Highcharts.Axis} this
  79. *
  80. * @param {Highcharts.AxisPointBreakEventObject} event
  81. */
  82. /**
  83. * @interface Highcharts.AxisPointBreakEventObject
  84. *//**
  85. * @name Highcharts.AxisPointBreakEventObject#brk
  86. * @type {Highcharts.Dictionary<number>}
  87. *//**
  88. * @name Highcharts.AxisPointBreakEventObject#point
  89. * @type {Highcharts.Point}
  90. *//**
  91. * @name Highcharts.AxisPointBreakEventObject#preventDefault
  92. * @type {Function}
  93. *//**
  94. * @name Highcharts.AxisPointBreakEventObject#target
  95. * @type {Highcharts.SVGElement}
  96. *//**
  97. * @name Highcharts.AxisPointBreakEventObject#type
  98. * @type {"pointBreak"|"pointInBreak"}
  99. */
  100. /**
  101. * @callback Highcharts.AxisSetExtremesEventCallbackFunction
  102. *
  103. * @param {Highcharts.Axis} this
  104. *
  105. * @param {Highcharts.AxisSetExtremesEventObject} event
  106. */
  107. /**
  108. * @interface Highcharts.AxisSetExtremesEventObject
  109. *//**
  110. * @name Highcharts.AxisSetExtremesEventObject#dataMax
  111. * @type {number}
  112. *//**
  113. * @name Highcharts.AxisSetExtremesEventObject#dataMin
  114. * @type {number}
  115. *//**
  116. * @name Highcharts.AxisSetExtremesEventObject#max
  117. * @type {number}
  118. *//**
  119. * @name Highcharts.AxisSetExtremesEventObject#min
  120. * @type {number}
  121. *//**
  122. * @name Highcharts.AxisSetExtremesEventObject#preventDefault
  123. * @type {Function}
  124. *//**
  125. * @name Highcharts.AxisSetExtremesEventObject#target
  126. * @type {Highcharts.SVGElement}
  127. *//**
  128. * @name Highcharts.AxisSetExtremesEventObject#trigger
  129. * @type {string}
  130. *//**
  131. * @name Highcharts.AxisSetExtremesEventObject#type
  132. * @type {"setExtremes"}
  133. *//**
  134. * @name Highcharts.AxisSetExtremesEventObject#userMax
  135. * @type {number}
  136. *//**
  137. * @name Highcharts.AxisSetExtremesEventObject#userMin
  138. * @type {number}
  139. */
  140. /**
  141. * @callback Highcharts.AxisTickPositionerCallbackFunction
  142. *
  143. * @param {Highcharts.Axis} this
  144. *
  145. * @return {Array<number>}
  146. */
  147. 'use strict';
  148. import H from './Globals.js';
  149. import './Utilities.js';
  150. import './Color.js';
  151. import './Options.js';
  152. import './Tick.js';
  153. var addEvent = H.addEvent,
  154. animObject = H.animObject,
  155. arrayMax = H.arrayMax,
  156. arrayMin = H.arrayMin,
  157. color = H.color,
  158. correctFloat = H.correctFloat,
  159. defaultOptions = H.defaultOptions,
  160. defined = H.defined,
  161. deg2rad = H.deg2rad,
  162. destroyObjectProperties = H.destroyObjectProperties,
  163. extend = H.extend,
  164. fireEvent = H.fireEvent,
  165. format = H.format,
  166. getMagnitude = H.getMagnitude,
  167. isArray = H.isArray,
  168. isNumber = H.isNumber,
  169. isString = H.isString,
  170. merge = H.merge,
  171. normalizeTickInterval = H.normalizeTickInterval,
  172. objectEach = H.objectEach,
  173. pick = H.pick,
  174. removeEvent = H.removeEvent,
  175. splat = H.splat,
  176. syncTimeout = H.syncTimeout,
  177. Tick = H.Tick;
  178. /**
  179. * Create a new axis object. Called internally when instanciating a new chart or
  180. * adding axes by {@link Highcharts.Chart#addAxis}.
  181. *
  182. * A chart can have from 0 axes (pie chart) to multiples. In a normal, single
  183. * series cartesian chart, there is one X axis and one Y axis.
  184. *
  185. * The X axis or axes are referenced by {@link Highcharts.Chart.xAxis}, which is
  186. * an array of Axis objects. If there is only one axis, it can be referenced
  187. * through `chart.xAxis[0]`, and multiple axes have increasing indices. The same
  188. * pattern goes for Y axes.
  189. *
  190. * If you need to get the axes from a series object, use the `series.xAxis` and
  191. * `series.yAxis` properties. These are not arrays, as one series can only be
  192. * associated to one X and one Y axis.
  193. *
  194. * A third way to reference the axis programmatically is by `id`. Add an `id` in
  195. * the axis configuration options, and get the axis by
  196. * {@link Highcharts.Chart#get}.
  197. *
  198. * Configuration options for the axes are given in options.xAxis and
  199. * options.yAxis.
  200. *
  201. * @class
  202. * @name Highcharts.Axis
  203. *
  204. * @param {Highcharts.Chart} chart
  205. * The Chart instance to apply the axis on.
  206. *
  207. * @param {Highcharts.AxisOptions} options
  208. * Axis options.
  209. */
  210. var Axis = function () {
  211. this.init.apply(this, arguments);
  212. };
  213. H.extend(Axis.prototype, /** @lends Highcharts.Axis.prototype */{
  214. /**
  215. * The X axis or category axis. Normally this is the horizontal axis,
  216. * though if the chart is inverted this is the vertical axis. In case of
  217. * multiple axes, the xAxis node is an array of configuration objects.
  218. *
  219. * See the [Axis class](/class-reference/Highcharts.Axis) for programmatic
  220. * access to the axis.
  221. *
  222. * @productdesc {highmaps}
  223. * In Highmaps, the axis is hidden, but it is used behind the scenes to
  224. * control features like zooming and panning. Zooming is in effect the same
  225. * as setting the extremes of one of the exes.
  226. *
  227. * @type {*|Array<*>}
  228. * @optionparent xAxis
  229. */
  230. defaultOptions: {
  231. /**
  232. * When using multiple axis, the ticks of two or more opposite axes
  233. * will automatically be aligned by adding ticks to the axis or axes
  234. * with the least ticks, as if `tickAmount` were specified.
  235. *
  236. * This can be prevented by setting `alignTicks` to false. If the grid
  237. * lines look messy, it's a good idea to hide them for the secondary
  238. * axis by setting `gridLineWidth` to 0.
  239. *
  240. * If `startOnTick` or `endOnTick` in an Axis options are set to false,
  241. * then the `alignTicks ` will be disabled for the Axis.
  242. *
  243. * Disabled for logarithmic axes.
  244. *
  245. * @type {boolean}
  246. * @default true
  247. * @product highcharts highstock gantt
  248. * @apioption xAxis.alignTicks
  249. */
  250. /**
  251. * Whether to allow decimals in this axis' ticks. When counting
  252. * integers, like persons or hits on a web page, decimals should
  253. * be avoided in the labels.
  254. *
  255. * @see [minTickInterval](#xAxis.minTickInterval)
  256. *
  257. * @sample {highcharts|highstock} highcharts/yaxis/allowdecimals-true/
  258. * True by default
  259. * @sample {highcharts|highstock} highcharts/yaxis/allowdecimals-false/
  260. * False
  261. *
  262. * @type {boolean}
  263. * @default true
  264. * @since 2.0
  265. * @apioption xAxis.allowDecimals
  266. */
  267. /**
  268. * When using an alternate grid color, a band is painted across the
  269. * plot area between every other grid line.
  270. *
  271. * @sample {highcharts} highcharts/yaxis/alternategridcolor/
  272. * Alternate grid color on the Y axis
  273. * @sample {highstock} stock/xaxis/alternategridcolor/
  274. * Alternate grid color on the Y axis
  275. *
  276. * @type {Highcharts.ColorString}
  277. * @apioption xAxis.alternateGridColor
  278. */
  279. /**
  280. * An array defining breaks in the axis, the sections defined will be
  281. * left out and all the points shifted closer to each other.
  282. *
  283. * @productdesc {highcharts}
  284. * Requires that the broken-axis.js module is loaded.
  285. *
  286. * @sample {highcharts} highcharts/axisbreak/break-simple/
  287. * Simple break
  288. * @sample {highcharts|highstock} highcharts/axisbreak/break-visualized/
  289. * Advanced with callback
  290. * @sample {highstock} stock/demo/intraday-breaks/
  291. * Break on nights and weekends
  292. *
  293. * @type {Array<*>}
  294. * @since 4.1.0
  295. * @product highcharts highstock gantt
  296. * @apioption xAxis.breaks
  297. */
  298. /**
  299. * A number indicating how much space should be left between the start
  300. * and the end of the break. The break size is given in axis units,
  301. * so for instance on a `datetime` axis, a break size of 3600000 would
  302. * indicate the equivalent of an hour.
  303. *
  304. * @type {number}
  305. * @default 0
  306. * @since 4.1.0
  307. * @product highcharts highstock gantt
  308. * @apioption xAxis.breaks.breakSize
  309. */
  310. /**
  311. * The point where the break starts.
  312. *
  313. * @type {number}
  314. * @since 4.1.0
  315. * @product highcharts highstock gantt
  316. * @apioption xAxis.breaks.from
  317. */
  318. /**
  319. * Defines an interval after which the break appears again. By default
  320. * the breaks do not repeat.
  321. *
  322. * @type {number}
  323. * @default 0
  324. * @since 4.1.0
  325. * @product highcharts highstock gantt
  326. * @apioption xAxis.breaks.repeat
  327. */
  328. /**
  329. * The point where the break ends.
  330. *
  331. * @type {number}
  332. * @since 4.1.0
  333. * @product highcharts highstock gantt
  334. * @apioption xAxis.breaks.to
  335. */
  336. /**
  337. * If categories are present for the xAxis, names are used instead of
  338. * numbers for that axis. Since Highcharts 3.0, categories can also
  339. * be extracted by giving each point a [name](#series.data) and setting
  340. * axis [type](#xAxis.type) to `category`. However, if you have multiple
  341. * series, best practice remains defining the `categories` array.
  342. *
  343. * Example:
  344. *
  345. * <pre>categories: ['Apples', 'Bananas', 'Oranges']</pre>
  346. *
  347. * @sample {highcharts} highcharts/demo/line-labels/
  348. * With
  349. * @sample {highcharts} highcharts/xaxis/categories/
  350. * Without
  351. *
  352. * @type {Array<string>}
  353. * @product highcharts gantt
  354. * @apioption xAxis.categories
  355. */
  356. /**
  357. * The highest allowed value for automatically computed axis extremes.
  358. *
  359. * @see [floor](#xAxis.floor)
  360. *
  361. * @sample {highcharts|highstock} highcharts/yaxis/floor-ceiling/
  362. * Floor and ceiling
  363. *
  364. * @type {number}
  365. * @since 4.0
  366. * @product highcharts highstock gantt
  367. * @apioption xAxis.ceiling
  368. */
  369. /**
  370. * A class name that opens for styling the axis by CSS, especially in
  371. * Highcharts styled mode. The class name is applied to group elements
  372. * for the grid, axis elements and labels.
  373. *
  374. * @sample {highcharts|highstock|highmaps} highcharts/css/axis/
  375. * Multiple axes with separate styling
  376. *
  377. * @type {string}
  378. * @since 5.0.0
  379. * @apioption xAxis.className
  380. */
  381. /**
  382. * Configure a crosshair that follows either the mouse pointer or the
  383. * hovered point.
  384. *
  385. * In styled mode, the crosshairs are styled in the
  386. * `.highcharts-crosshair`, `.highcharts-crosshair-thin` or
  387. * `.highcharts-xaxis-category` classes.
  388. *
  389. * @productdesc {highstock}
  390. * In Highstock, by default, the crosshair is enabled on the X axis and
  391. * disabled on the Y axis.
  392. *
  393. * @sample {highcharts} highcharts/xaxis/crosshair-both/
  394. * Crosshair on both axes
  395. * @sample {highstock} stock/xaxis/crosshairs-xy/
  396. * Crosshair on both axes
  397. * @sample {highmaps} highcharts/xaxis/crosshair-both/
  398. * Crosshair on both axes
  399. *
  400. * @type {boolean|*}
  401. * @default false
  402. * @since 4.1
  403. * @apioption xAxis.crosshair
  404. */
  405. /**
  406. * A class name for the crosshair, especially as a hook for styling.
  407. *
  408. * @type {string}
  409. * @since 5.0.0
  410. * @apioption xAxis.crosshair.className
  411. */
  412. /**
  413. * The color of the crosshair. Defaults to `#cccccc` for numeric and
  414. * datetime axes, and `rgba(204,214,235,0.25)` for category axes, where
  415. * the crosshair by default highlights the whole category.
  416. *
  417. * @sample {highcharts|highstock|highmaps} highcharts/xaxis/crosshair-customized/
  418. * Customized crosshairs
  419. *
  420. * @type {Highcharts.ColorString}
  421. * @default #cccccc
  422. * @since 4.1
  423. * @apioption xAxis.crosshair.color
  424. */
  425. /**
  426. * The dash style for the crosshair. See
  427. * [series.dashStyle](#plotOptions.series.dashStyle)
  428. * for possible values.
  429. *
  430. * @sample {highcharts|highmaps} highcharts/xaxis/crosshair-dotted/
  431. * Dotted crosshair
  432. * @sample {highstock} stock/xaxis/crosshair-dashed/
  433. * Dashed X axis crosshair
  434. *
  435. * @type {Highcharts.DashStyleType}
  436. * @default Solid
  437. * @since 4.1
  438. * @apioption xAxis.crosshair.dashStyle
  439. */
  440. /**
  441. * A label on the axis next to the crosshair.
  442. *
  443. * In styled mode, the label is styled with the
  444. * `.highcharts-crosshair-label` class.
  445. *
  446. * @sample {highstock} stock/xaxis/crosshair-label/
  447. * Crosshair labels
  448. * @sample {highstock} highcharts/css/crosshair-label/
  449. * Style mode
  450. *
  451. * @since 2.1
  452. * @product highstock
  453. * @apioption xAxis.crosshair.label
  454. */
  455. /**
  456. * Alignment of the label compared to the axis. Defaults to `left` for
  457. * right-side axes, `right` for left-side axes and `center` for
  458. * horizontal axes.
  459. *
  460. * @type {string}
  461. * @since 2.1
  462. * @product highstock
  463. * @apioption xAxis.crosshair.label.align
  464. */
  465. /**
  466. * The background color for the label. Defaults to the related series
  467. * color, or `#666666` if that is not available.
  468. *
  469. * @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
  470. * @since 2.1
  471. * @product highstock
  472. * @apioption xAxis.crosshair.label.backgroundColor
  473. */
  474. /**
  475. * The border color for the crosshair label
  476. *
  477. * @type {Highcharts.ColorString}
  478. * @since 2.1
  479. * @product highstock
  480. * @apioption xAxis.crosshair.label.borderColor
  481. */
  482. /**
  483. * The border corner radius of the crosshair label.
  484. *
  485. * @type {number}
  486. * @default 3
  487. * @since 2.1.10
  488. * @product highstock
  489. * @apioption xAxis.crosshair.label.borderRadius
  490. */
  491. /**
  492. * The border width for the crosshair label.
  493. *
  494. * @type {number}
  495. * @default 0
  496. * @since 2.1
  497. * @product highstock
  498. * @apioption xAxis.crosshair.label.borderWidth
  499. */
  500. /**
  501. * A format string for the crosshair label. Defaults to `{value}` for
  502. * numeric axes and `{value:%b %d, %Y}` for datetime axes.
  503. *
  504. * @type {string}
  505. * @since 2.1
  506. * @product highstock
  507. * @apioption xAxis.crosshair.label.format
  508. */
  509. /**
  510. * Formatter function for the label text.
  511. *
  512. * @type {Highcharts.FormatterCallbackFunction<object>}
  513. * @since 2.1
  514. * @product highstock
  515. * @apioption xAxis.crosshair.label.formatter
  516. */
  517. /**
  518. * Padding inside the crosshair label.
  519. *
  520. * @type {number}
  521. * @default 8
  522. * @since 2.1
  523. * @product highstock
  524. * @apioption xAxis.crosshair.label.padding
  525. */
  526. /**
  527. * The shape to use for the label box.
  528. *
  529. * @type {string}
  530. * @default callout
  531. * @since 2.1
  532. * @product highstock
  533. * @apioption xAxis.crosshair.label.shape
  534. */
  535. /**
  536. * Text styles for the crosshair label.
  537. *
  538. * @type {Highcharts.CSSObject}
  539. * @default {"color": "white", "fontWeight": "normal", "fontSize": "11px", "textAlign": "center"}
  540. * @since 2.1
  541. * @product highstock
  542. * @apioption xAxis.crosshair.label.style
  543. */
  544. /**
  545. * Whether the crosshair should snap to the point or follow the pointer
  546. * independent of points.
  547. *
  548. * @sample {highcharts|highstock} highcharts/xaxis/crosshair-snap-false/
  549. * True by default
  550. * @sample {highmaps} maps/demo/latlon-advanced/
  551. * Snap is false
  552. *
  553. * @type {boolean}
  554. * @default true
  555. * @since 4.1
  556. * @apioption xAxis.crosshair.snap
  557. */
  558. /**
  559. * The pixel width of the crosshair. Defaults to 1 for numeric or
  560. * datetime axes, and for one category width for category axes.
  561. *
  562. * @sample {highcharts} highcharts/xaxis/crosshair-customized/
  563. * Customized crosshairs
  564. * @sample {highstock} highcharts/xaxis/crosshair-customized/
  565. * Customized crosshairs
  566. * @sample {highmaps} highcharts/xaxis/crosshair-customized/
  567. * Customized crosshairs
  568. *
  569. * @type {number}
  570. * @default 1
  571. * @since 4.1
  572. * @apioption xAxis.crosshair.width
  573. */
  574. /**
  575. * The Z index of the crosshair. Higher Z indices allow drawing the
  576. * crosshair on top of the series or behind the grid lines.
  577. *
  578. * @type {number}
  579. * @default 2
  580. * @since 4.1
  581. * @apioption xAxis.crosshair.zIndex
  582. */
  583. /**
  584. * For a datetime axis, the scale will automatically adjust to the
  585. * appropriate unit. This member gives the default string
  586. * representations used for each unit. For intermediate values,
  587. * different units may be used, for example the `day` unit can be used
  588. * on midnight and `hour` unit be used for intermediate values on the
  589. * same axis. For an overview of the replacement codes, see
  590. * [dateFormat](/class-reference/Highcharts#dateFormat). Defaults to:
  591. *
  592. * <pre>{
  593. * millisecond: '%H:%M:%S.%L',
  594. * second: '%H:%M:%S',
  595. * minute: '%H:%M',
  596. * hour: '%H:%M',
  597. * day: '%e. %b',
  598. * week: '%e. %b',
  599. * month: '%b \'%y',
  600. * year: '%Y'
  601. * }</pre>
  602. *
  603. * @sample {highcharts} highcharts/xaxis/datetimelabelformats/
  604. * Different day format on X axis
  605. * @sample {highstock} stock/xaxis/datetimelabelformats/
  606. * More information in x axis labels
  607. *
  608. * @product highcharts highstock gantt
  609. */
  610. dateTimeLabelFormats: {
  611. millisecond: {
  612. main: '%H:%M:%S.%L',
  613. range: false
  614. },
  615. second: {
  616. main: '%H:%M:%S',
  617. range: false
  618. },
  619. minute: {
  620. main: '%H:%M',
  621. range: false
  622. },
  623. hour: {
  624. main: '%H:%M',
  625. range: false
  626. },
  627. day: {
  628. main: '%e. %b'
  629. },
  630. week: {
  631. main: '%e. %b'
  632. },
  633. month: {
  634. main: '%b \'%y'
  635. },
  636. year: {
  637. main: '%Y'
  638. }
  639. },
  640. /**
  641. * _Requires Accessibility module_
  642. *
  643. * Description of the axis to screen reader users.
  644. *
  645. * @type {string}
  646. * @since 5.0.0
  647. * @apioption xAxis.description
  648. */
  649. /**
  650. * Whether to force the axis to end on a tick. Use this option with
  651. * the `maxPadding` option to control the axis end.
  652. *
  653. * @productdesc {highstock}
  654. * In Highstock, `endOnTick` is always false when the navigator is
  655. * enabled, to prevent jumpy scrolling.
  656. *
  657. * @sample {highcharts} highcharts/chart/reflow-true/
  658. * True by default
  659. * @sample {highcharts} highcharts/yaxis/endontick/
  660. * False
  661. * @sample {highstock} stock/demo/basic-line/
  662. * True by default
  663. * @sample {highstock} stock/xaxis/endontick/
  664. * False
  665. *
  666. * @since 1.2.0
  667. */
  668. endOnTick: false,
  669. /**
  670. * Event handlers for the axis.
  671. *
  672. * @type {*}
  673. * @apioption xAxis.events
  674. */
  675. /**
  676. * An event fired after the breaks have rendered.
  677. *
  678. * @see [breaks](#xAxis.breaks)
  679. *
  680. * @sample {highcharts} highcharts/axisbreak/break-event/
  681. * AfterBreak Event
  682. *
  683. * @type {Highcharts.AxisEventCallbackFunction}
  684. * @since 4.1.0
  685. * @product highcharts gantt
  686. * @apioption xAxis.events.afterBreaks
  687. */
  688. /**
  689. * As opposed to the `setExtremes` event, this event fires after the
  690. * final min and max values are computed and corrected for `minRange`.
  691. *
  692. * Fires when the minimum and maximum is set for the axis, either by
  693. * calling the `.setExtremes()` method or by selecting an area in the
  694. * chart. One parameter, `event`, is passed to the function, containing
  695. * common event information.
  696. *
  697. * The new user set minimum and maximum values can be found by
  698. * `event.min` and `event.max`. These reflect the axis minimum and
  699. * maximum in axis values. The actual data extremes are found in
  700. * `event.dataMin` and `event.dataMax`.
  701. *
  702. * @type {Highcharts.AxisEventCallbackFunction}
  703. * @since 2.3
  704. * @context Axis
  705. * @apioption xAxis.events.afterSetExtremes
  706. */
  707. /**
  708. * An event fired when a break from this axis occurs on a point.
  709. *
  710. * @see [breaks](#xAxis.breaks)
  711. *
  712. * @sample {highcharts} highcharts/axisbreak/break-visualized/
  713. * Visualization of a Break
  714. *
  715. * @type {Highcharts.AxisPointBreakEventCallbackFunction}
  716. * @since 4.1.0
  717. * @product highcharts gantt
  718. * @context Axis
  719. * @apioption xAxis.events.pointBreak
  720. */
  721. /**
  722. * An event fired when a point falls inside a break from this axis.
  723. *
  724. * @type {Highcharts.AxisPointBreakEventCallbackFunction}
  725. * @product highcharts highstock gantt
  726. * @context Axis
  727. * @apioption xAxis.events.pointInBreak
  728. */
  729. /**
  730. * Fires when the minimum and maximum is set for the axis, either by
  731. * calling the `.setExtremes()` method or by selecting an area in the
  732. * chart. One parameter, `event`, is passed to the function,
  733. * containing common event information.
  734. *
  735. * The new user set minimum and maximum values can be found by
  736. * `event.min` and `event.max`. These reflect the axis minimum and
  737. * maximum in data values. When an axis is zoomed all the way out from
  738. * the "Reset zoom" button, `event.min` and `event.max` are null, and
  739. * the new extremes are set based on `this.dataMin` and `this.dataMax`.
  740. *
  741. * @sample {highstock} stock/xaxis/events-setextremes/
  742. * Log new extremes on x axis
  743. *
  744. * @type {Highcharts.AxisSetExtremesEventCallbackFunction}
  745. * @since 1.2.0
  746. * @context Axis
  747. * @apioption xAxis.events.setExtremes
  748. */
  749. /**
  750. * The lowest allowed value for automatically computed axis extremes.
  751. *
  752. * @see [ceiling](#yAxis.ceiling)
  753. *
  754. * @sample {highcharts} highcharts/yaxis/floor-ceiling/
  755. * Floor and ceiling
  756. * @sample {highstock} stock/demo/lazy-loading/
  757. * Prevent negative stock price on Y axis
  758. *
  759. * @type {number}
  760. * @since 4.0
  761. * @product highcharts highstock gantt
  762. * @apioption xAxis.floor
  763. */
  764. /**
  765. * The dash or dot style of the grid lines. For possible values, see
  766. * [this demonstration](https://jsfiddle.net/gh/get/library/pure/highcharts/highcharts/tree/master/samples/highcharts/plotoptions/series-dashstyle-all/).
  767. *
  768. * @sample {highcharts} highcharts/yaxis/gridlinedashstyle/
  769. * Long dashes
  770. * @sample {highstock} stock/xaxis/gridlinedashstyle/
  771. * Long dashes
  772. *
  773. * @type {Highcharts.DashStyleType}
  774. * @default Solid
  775. * @since 1.2
  776. * @apioption xAxis.gridLineDashStyle
  777. */
  778. /**
  779. * The Z index of the grid lines.
  780. *
  781. * @sample {highcharts|highstock} highcharts/xaxis/gridzindex/
  782. * A Z index of 4 renders the grid above the graph
  783. *
  784. * @type {number}
  785. * @default 1
  786. * @product highcharts highstock gantt
  787. * @apioption xAxis.gridZIndex
  788. */
  789. /**
  790. * An id for the axis. This can be used after render time to get
  791. * a pointer to the axis object through `chart.get()`.
  792. *
  793. * @sample {highcharts} highcharts/xaxis/id/
  794. * Get the object
  795. * @sample {highstock} stock/xaxis/id/
  796. * Get the object
  797. *
  798. * @type {string}
  799. * @since 1.2.0
  800. * @apioption xAxis.id
  801. */
  802. /**
  803. * The axis labels show the number or category for each tick.
  804. *
  805. * @productdesc {highmaps}
  806. * X and Y axis labels are by default disabled in Highmaps, but the
  807. * functionality is inherited from Highcharts and used on `colorAxis`,
  808. * and can be enabled on X and Y axes too.
  809. */
  810. labels: {
  811. /**
  812. * What part of the string the given position is anchored to.
  813. * If `left`, the left side of the string is at the axis position.
  814. * Can be one of `"left"`, `"center"` or `"right"`. Defaults to
  815. * an intelligent guess based on which side of the chart the axis
  816. * is on and the rotation of the label.
  817. *
  818. * @see [reserveSpace](#xAxis.labels.reserveSpace)
  819. *
  820. * @sample {highcharts} highcharts/xaxis/labels-align-left/
  821. * Left
  822. * @sample {highcharts} highcharts/xaxis/labels-align-right/
  823. * Right
  824. * @sample {highcharts} highcharts/xaxis/labels-reservespace-true/
  825. * Left-aligned labels on a vertical category axis
  826. *
  827. * @type {string}
  828. * @validvalue ["left", "center", "right"]
  829. * @apioption xAxis.labels.align
  830. */
  831. /**
  832. * For horizontal axes, the allowed degrees of label rotation
  833. * to prevent overlapping labels. If there is enough space,
  834. * labels are not rotated. As the chart gets narrower, it
  835. * will start rotating the labels -45 degrees, then remove
  836. * every second label and try again with rotations 0 and -45 etc.
  837. * Set it to `false` to disable rotation, which will
  838. * cause the labels to word-wrap if possible.
  839. *
  840. * @sample {highcharts|highstock} highcharts/xaxis/labels-autorotation-default/
  841. * Default auto rotation of 0 or -45
  842. * @sample {highcharts|highstock} highcharts/xaxis/labels-autorotation-0-90/
  843. * Custom graded auto rotation
  844. *
  845. * @type {Array<number>}
  846. * @default [-45]
  847. * @since 4.1.0
  848. * @product highcharts highstock gantt
  849. * @apioption xAxis.labels.autoRotation
  850. */
  851. /**
  852. * When each category width is more than this many pixels, we don't
  853. * apply auto rotation. Instead, we lay out the axis label with word
  854. * wrap. A lower limit makes sense when the label contains multiple
  855. * short words that don't extend the available horizontal space for
  856. * each label.
  857. *
  858. * @sample {highcharts} highcharts/xaxis/labels-autorotationlimit/
  859. * Lower limit
  860. *
  861. * @type {number}
  862. * @default 80
  863. * @since 4.1.5
  864. * @product highcharts gantt
  865. * @apioption xAxis.labels.autoRotationLimit
  866. */
  867. /**
  868. * Polar charts only. The label's pixel distance from the perimeter
  869. * of the plot area.
  870. *
  871. * @type {number}
  872. * @default 15
  873. * @product highcharts gantt
  874. * @apioption xAxis.labels.distance
  875. */
  876. /**
  877. * Enable or disable the axis labels.
  878. *
  879. * @sample {highcharts} highcharts/xaxis/labels-enabled/
  880. * X axis labels disabled
  881. * @sample {highstock} stock/xaxis/labels-enabled/
  882. * X axis labels disabled
  883. *
  884. * @default {highcharts|highstock|gantt} true
  885. * @default {highmaps} false
  886. */
  887. enabled: true,
  888. /**
  889. * A [format string](https://www.highcharts.com/docs/chart-concepts/labels-and-string-formatting)
  890. * for the axis label.
  891. *
  892. * @sample {highcharts|highstock} highcharts/yaxis/labels-format/
  893. * Add units to Y axis label
  894. *
  895. * @type {string}
  896. * @default {value}
  897. * @since 3.0
  898. * @apioption xAxis.labels.format
  899. */
  900. /**
  901. * Callback JavaScript function to format the label. The value
  902. * is given by `this.value`. Additional properties for `this` are
  903. * `axis`, `chart`, `isFirst` and `isLast`. The value of the default
  904. * label formatter can be retrieved by calling
  905. * `this.axis.defaultLabelFormatter.call(this)` within the function.
  906. *
  907. * Defaults to:
  908. *
  909. * <pre>function() {
  910. * return this.value;
  911. * }</pre>
  912. *
  913. * @sample {highcharts} highcharts/xaxis/labels-formatter-linked/
  914. * Linked category names
  915. * @sample {highcharts} highcharts/xaxis/labels-formatter-extended/
  916. * Modified numeric labels
  917. * @sample {highstock} stock/xaxis/labels-formatter/
  918. * Added units on Y axis
  919. *
  920. * @type {Highcharts.FormatterCallbackFunction<Highcharts.AxisLabelsFormatterContextObject>}
  921. * @apioption xAxis.labels.formatter
  922. */
  923. /**
  924. * The number of pixels to indent the labels per level in a treegrid
  925. * axis.
  926. *
  927. * @sample gantt/treegrid-axis/demo
  928. * Indentation 10px by default.
  929. * @sample gantt/treegrid-axis/indentation-0px
  930. * Indentation set to 0px.
  931. *
  932. * @product gantt
  933. */
  934. indentation: 10,
  935. /**
  936. * Horizontal axis only. When `staggerLines` is not set,
  937. * `maxStaggerLines` defines how many lines the axis is allowed to
  938. * add to automatically avoid overlapping X labels. Set to `1` to
  939. * disable overlap detection.
  940. *
  941. * @deprecated
  942. * @type {number}
  943. * @default 5
  944. * @since 1.3.3
  945. * @apioption xAxis.labels.maxStaggerLines
  946. */
  947. /**
  948. * How to handle overflowing labels on horizontal axis. If set to
  949. * `"allow"`, it will not be aligned at all. By default it
  950. * `"justify"` labels inside the chart area. If there is room to
  951. * move it, it will be aligned to the edge, else it will be removed.
  952. *
  953. * @type {boolean|string}
  954. * @default justify
  955. * @since 2.2.5
  956. * @validvalue ["allow", "justify"]
  957. * @apioption xAxis.labels.overflow
  958. */
  959. /**
  960. * The pixel padding for axis labels, to ensure white space between
  961. * them.
  962. *
  963. * @type {number}
  964. * @default 5
  965. * @product highcharts gantt
  966. * @apioption xAxis.labels.padding
  967. */
  968. /**
  969. * Whether to reserve space for the labels. By default, space is
  970. * reserved for the labels in these cases:
  971. *
  972. * * On all horizontal axes.
  973. * * On vertical axes if `label.align` is `right` on a left-side
  974. * axis or `left` on a right-side axis.
  975. * * On vertical axes if `label.align` is `center`.
  976. *
  977. * This can be turned off when for example the labels are rendered
  978. * inside the plot area instead of outside.
  979. *
  980. * @see [labels.align](#xAxis.labels.align)
  981. *
  982. * @sample {highcharts} highcharts/xaxis/labels-reservespace/
  983. * No reserved space, labels inside plot
  984. * @sample {highcharts} highcharts/xaxis/labels-reservespace-true/
  985. * Left-aligned labels on a vertical category axis
  986. *
  987. * @type {boolean}
  988. * @since 4.1.10
  989. * @product highcharts gantt
  990. * @apioption xAxis.labels.reserveSpace
  991. */
  992. /**
  993. * Rotation of the labels in degrees.
  994. *
  995. * @sample {highcharts} highcharts/xaxis/labels-rotation/
  996. * X axis labels rotated 90°
  997. *
  998. * @type {number}
  999. * @default 0
  1000. * @apioption xAxis.labels.rotation
  1001. */
  1002. /**
  1003. * Horizontal axes only. The number of lines to spread the labels
  1004. * over to make room or tighter labels.
  1005. *
  1006. * @sample {highcharts} highcharts/xaxis/labels-staggerlines/
  1007. * Show labels over two lines
  1008. * @sample {highstock} stock/xaxis/labels-staggerlines/
  1009. * Show labels over two lines
  1010. *
  1011. * @type {number}
  1012. * @since 2.1
  1013. * @apioption xAxis.labels.staggerLines
  1014. */
  1015. /**
  1016. * To show only every _n_'th label on the axis, set the step to _n_.
  1017. * Setting the step to 2 shows every other label.
  1018. *
  1019. * By default, the step is calculated automatically to avoid
  1020. * overlap. To prevent this, set it to 1\. This usually only
  1021. * happens on a category axis, and is often a sign that you have
  1022. * chosen the wrong axis type.
  1023. *
  1024. * Read more at
  1025. * [Axis docs](https://www.highcharts.com/docs/chart-concepts/axes)
  1026. * => What axis should I use?
  1027. *
  1028. * @sample {highcharts} highcharts/xaxis/labels-step/
  1029. * Showing only every other axis label on a categorized
  1030. * x-axis
  1031. * @sample {highcharts} highcharts/xaxis/labels-step-auto/
  1032. * Auto steps on a category axis
  1033. *
  1034. * @type {number}
  1035. * @since 2.1
  1036. * @apioption xAxis.labels.step
  1037. */
  1038. /**
  1039. * Whether to [use HTML](https://www.highcharts.com/docs/chart-concepts/labels-and-string-formatting#html)
  1040. * to render the labels.
  1041. *
  1042. * @type {boolean}
  1043. * @default false
  1044. * @apioption xAxis.labels.useHTML
  1045. */
  1046. /**
  1047. * The x position offset of the label relative to the tick position
  1048. * on the axis.
  1049. *
  1050. * @sample {highcharts} highcharts/xaxis/labels-x/
  1051. * Y axis labels placed on grid lines
  1052. */
  1053. x: 0,
  1054. /**
  1055. * The y position offset of the label relative to the tick position
  1056. * on the axis. The default makes it adapt to the font size on
  1057. * bottom axis.
  1058. *
  1059. * @sample {highcharts} highcharts/xaxis/labels-x/
  1060. * Y axis labels placed on grid lines
  1061. *
  1062. * @type {number}
  1063. * @apioption xAxis.labels.y
  1064. */
  1065. /**
  1066. * The Z index for the axis labels.
  1067. *
  1068. * @type {number}
  1069. * @default 7
  1070. * @apioption xAxis.labels.zIndex
  1071. */
  1072. /**
  1073. * CSS styles for the label. Use `whiteSpace: 'nowrap'` to prevent
  1074. * wrapping of category labels. Use `textOverflow: 'none'` to
  1075. * prevent ellipsis (dots).
  1076. *
  1077. * In styled mode, the labels are styled with the
  1078. * `.highcharts-axis-labels` class.
  1079. *
  1080. * @sample {highcharts} highcharts/xaxis/labels-style/
  1081. * Red X axis labels
  1082. *
  1083. * @type {Highcharts.CSSObject}
  1084. * @default {"color": "#666666", "cursor": "default", "fontSize": "11px"}
  1085. */
  1086. style: {
  1087. /** @ignore-option */
  1088. color: '#666666',
  1089. /** @ignore-option */
  1090. cursor: 'default',
  1091. /** @ignore-option */
  1092. fontSize: '11px'
  1093. }
  1094. },
  1095. /**
  1096. * Index of another axis that this axis is linked to. When an axis is
  1097. * linked to a master axis, it will take the same extremes as
  1098. * the master, but as assigned by min or max or by setExtremes.
  1099. * It can be used to show additional info, or to ease reading the
  1100. * chart by duplicating the scales.
  1101. *
  1102. * @sample {highcharts} highcharts/xaxis/linkedto/
  1103. * Different string formats of the same date
  1104. * @sample {highcharts} highcharts/yaxis/linkedto/
  1105. * Y values on both sides
  1106. *
  1107. * @type {number}
  1108. * @since 2.0.2
  1109. * @product highcharts highstock gantt
  1110. * @apioption xAxis.linkedTo
  1111. */
  1112. /**
  1113. * The maximum value of the axis. If `null`, the max value is
  1114. * automatically calculated.
  1115. *
  1116. * If the [endOnTick](#yAxis.endOnTick) option is true, the `max` value
  1117. * might be rounded up.
  1118. *
  1119. * If a [tickAmount](#yAxis.tickAmount) is set, the axis may be extended
  1120. * beyond the set max in order to reach the given number of ticks. The
  1121. * same may happen in a chart with multiple axes, determined by [chart.
  1122. * alignTicks](#chart), where a `tickAmount` is applied internally.
  1123. *
  1124. * @sample {highcharts} highcharts/yaxis/max-200/
  1125. * Y axis max of 200
  1126. * @sample {highcharts} highcharts/yaxis/max-logarithmic/
  1127. * Y axis max on logarithmic axis
  1128. * @sample {highstock} stock/xaxis/min-max/
  1129. * Fixed min and max on X axis
  1130. * @sample {highmaps} maps/axis/min-max/
  1131. * Pre-zoomed to a specific area
  1132. *
  1133. * @type {number}
  1134. * @apioption xAxis.max
  1135. */
  1136. /**
  1137. * Padding of the max value relative to the length of the axis. A
  1138. * padding of 0.05 will make a 100px axis 5px longer. This is useful
  1139. * when you don't want the highest data value to appear on the edge
  1140. * of the plot area. When the axis' `max` option is set or a max extreme
  1141. * is set using `axis.setExtremes()`, the maxPadding will be ignored.
  1142. *
  1143. * @sample {highcharts} highcharts/yaxis/maxpadding/
  1144. * Max padding of 0.25 on y axis
  1145. * @sample {highstock} stock/xaxis/minpadding-maxpadding/
  1146. * Greater min- and maxPadding
  1147. * @sample {highmaps} maps/chart/plotbackgroundcolor-gradient/
  1148. * Add some padding
  1149. *
  1150. * @default {highcharts} 0.01
  1151. * @default {highstock|highmaps} 0
  1152. * @since 1.2.0
  1153. */
  1154. maxPadding: 0.01,
  1155. /**
  1156. * Deprecated. Use `minRange` instead.
  1157. *
  1158. * @deprecated
  1159. * @type {number}
  1160. * @product highcharts highstock
  1161. * @apioption xAxis.maxZoom
  1162. */
  1163. /**
  1164. * The minimum value of the axis. If `null` the min value is
  1165. * automatically calculated.
  1166. *
  1167. * If the [startOnTick](#yAxis.startOnTick) option is true (default),
  1168. * the `min` value might be rounded down.
  1169. *
  1170. * The automatically calculated minimum value is also affected by
  1171. * [floor](#yAxis.floor), [softMin](#yAxis.softMin),
  1172. * [minPadding](#yAxis.minPadding), [minRange](#yAxis.minRange)
  1173. * as well as [series.threshold](#plotOptions.series.threshold)
  1174. * and [series.softThreshold](#plotOptions.series.softThreshold).
  1175. *
  1176. * @sample {highcharts} highcharts/yaxis/min-startontick-false/
  1177. * -50 with startOnTick to false
  1178. * @sample {highcharts} highcharts/yaxis/min-startontick-true/
  1179. * -50 with startOnTick true by default
  1180. * @sample {highstock} stock/xaxis/min-max/
  1181. * Set min and max on X axis
  1182. * @sample {highmaps} maps/axis/min-max/
  1183. * Pre-zoomed to a specific area
  1184. *
  1185. * @type {number}
  1186. * @apioption xAxis.min
  1187. */
  1188. /**
  1189. * The dash or dot style of the minor grid lines. For possible values,
  1190. * see [this demonstration](https://jsfiddle.net/gh/get/library/pure/highcharts/highcharts/tree/master/samples/highcharts/plotoptions/series-dashstyle-all/).
  1191. *
  1192. * @sample {highcharts} highcharts/yaxis/minorgridlinedashstyle/
  1193. * Long dashes on minor grid lines
  1194. * @sample {highstock} stock/xaxis/minorgridlinedashstyle/
  1195. * Long dashes on minor grid lines
  1196. *
  1197. * @type {Highcharts.DashStyleType}
  1198. * @default Solid
  1199. * @since 1.2
  1200. * @apioption xAxis.minorGridLineDashStyle
  1201. */
  1202. /**
  1203. * Specific tick interval in axis units for the minor ticks. On a linear
  1204. * axis, if `"auto"`, the minor tick interval is calculated as a fifth
  1205. * of the tickInterval. If `null` or `undefined`, minor ticks are not
  1206. * shown.
  1207. *
  1208. * On logarithmic axes, the unit is the power of the value. For example,
  1209. * setting the minorTickInterval to 1 puts one tick on each of 0.1, 1,
  1210. * 10, 100 etc. Setting the minorTickInterval to 0.1 produces 9 ticks
  1211. * between 1 and 10, 10 and 100 etc.
  1212. *
  1213. * If user settings dictate minor ticks to become too dense, they don't
  1214. * make sense, and will be ignored to prevent performance problems.
  1215. *
  1216. * @sample {highcharts} highcharts/yaxis/minortickinterval-null/
  1217. * Null by default
  1218. * @sample {highcharts} highcharts/yaxis/minortickinterval-5/
  1219. * 5 units
  1220. * @sample {highcharts} highcharts/yaxis/minortickinterval-log-auto/
  1221. * "auto"
  1222. * @sample {highcharts} highcharts/yaxis/minortickinterval-log/
  1223. * 0.1
  1224. * @sample {highstock} stock/demo/basic-line/
  1225. * Null by default
  1226. * @sample {highstock} stock/xaxis/minortickinterval-auto/
  1227. * "auto"
  1228. *
  1229. * @type {number|string|null}
  1230. * @apioption xAxis.minorTickInterval
  1231. */
  1232. /**
  1233. * The pixel length of the minor tick marks.
  1234. *
  1235. * @sample {highcharts} highcharts/yaxis/minorticklength/
  1236. * 10px on Y axis
  1237. * @sample {highstock} stock/xaxis/minorticks/
  1238. * 10px on Y axis
  1239. */
  1240. minorTickLength: 2,
  1241. /**
  1242. * The position of the minor tick marks relative to the axis line.
  1243. * Can be one of `inside` and `outside`.
  1244. *
  1245. * @sample {highcharts} highcharts/yaxis/minortickposition-outside/
  1246. * Outside by default
  1247. * @sample {highcharts} highcharts/yaxis/minortickposition-inside/
  1248. * Inside
  1249. * @sample {highstock} stock/xaxis/minorticks/
  1250. * Inside
  1251. *
  1252. * @validvalue ["inside", "outside"]
  1253. */
  1254. minorTickPosition: 'outside',
  1255. /**
  1256. * Enable or disable minor ticks. Unless
  1257. * [minorTickInterval](#xAxis.minorTickInterval) is set, the tick
  1258. * interval is calculated as a fifth of the `tickInterval`.
  1259. *
  1260. * On a logarithmic axis, minor ticks are laid out based on a best
  1261. * guess, attempting to enter approximately 5 minor ticks between
  1262. * each major tick.
  1263. *
  1264. * Prior to v6.0.0, ticks were unabled in auto layout by setting
  1265. * `minorTickInterval` to `"auto"`.
  1266. *
  1267. * @productdesc {highcharts}
  1268. * On axes using [categories](#xAxis.categories), minor ticks are not
  1269. * supported.
  1270. *
  1271. * @sample {highcharts} highcharts/yaxis/minorticks-true/
  1272. * Enabled on linear Y axis
  1273. *
  1274. * @type {boolean}
  1275. * @default false
  1276. * @since 6.0.0
  1277. * @apioption xAxis.minorTicks
  1278. */
  1279. /**
  1280. * The pixel width of the minor tick mark.
  1281. *
  1282. * @sample {highcharts} highcharts/yaxis/minortickwidth/
  1283. * 3px width
  1284. * @sample {highstock} stock/xaxis/minorticks/
  1285. * 1px width
  1286. *
  1287. * @type {number}
  1288. * @default 0
  1289. * @apioption xAxis.minorTickWidth
  1290. */
  1291. /**
  1292. * Padding of the min value relative to the length of the axis. A
  1293. * padding of 0.05 will make a 100px axis 5px longer. This is useful
  1294. * when you don't want the lowest data value to appear on the edge
  1295. * of the plot area. When the axis' `min` option is set or a min extreme
  1296. * is set using `axis.setExtremes()`, the minPadding will be ignored.
  1297. *
  1298. * @sample {highcharts} highcharts/yaxis/minpadding/
  1299. * Min padding of 0.2
  1300. * @sample {highstock} stock/xaxis/minpadding-maxpadding/
  1301. * Greater min- and maxPadding
  1302. * @sample {highmaps} maps/chart/plotbackgroundcolor-gradient/
  1303. * Add some padding
  1304. *
  1305. * @default {highcharts} 0.01
  1306. * @default {highstock|highmaps} 0
  1307. * @since 1.2.0
  1308. * @product highcharts highstock gantt
  1309. */
  1310. minPadding: 0.01,
  1311. /**
  1312. * The minimum range to display on this axis. The entire axis will not
  1313. * be allowed to span over a smaller interval than this. For example,
  1314. * for a datetime axis the main unit is milliseconds. If minRange is
  1315. * set to 3600000, you can't zoom in more than to one hour.
  1316. *
  1317. * The default minRange for the x axis is five times the smallest
  1318. * interval between any of the data points.
  1319. *
  1320. * On a logarithmic axis, the unit for the minimum range is the power.
  1321. * So a minRange of 1 means that the axis can be zoomed to 10-100,
  1322. * 100-1000, 1000-10000 etc.
  1323. *
  1324. * Note that the `minPadding`, `maxPadding`, `startOnTick` and
  1325. * `endOnTick` settings also affect how the extremes of the axis
  1326. * are computed.
  1327. *
  1328. * @sample {highcharts} highcharts/xaxis/minrange/
  1329. * Minimum range of 5
  1330. * @sample {highstock} stock/xaxis/minrange/
  1331. * Max zoom of 6 months overrides user selections
  1332. * @sample {highmaps} maps/axis/minrange/
  1333. * Minimum range of 1000
  1334. *
  1335. * @type {number}
  1336. * @apioption xAxis.minRange
  1337. */
  1338. /**
  1339. * The minimum tick interval allowed in axis values. For example on
  1340. * zooming in on an axis with daily data, this can be used to prevent
  1341. * the axis from showing hours. Defaults to the closest distance between
  1342. * two points on the axis.
  1343. *
  1344. * @type {number}
  1345. * @since 2.3.0
  1346. * @apioption xAxis.minTickInterval
  1347. */
  1348. /**
  1349. * The distance in pixels from the plot area to the axis line.
  1350. * A positive offset moves the axis with it's line, labels and ticks
  1351. * away from the plot area. This is typically used when two or more
  1352. * axes are displayed on the same side of the plot. With multiple
  1353. * axes the offset is dynamically adjusted to avoid collision, this
  1354. * can be overridden by setting offset explicitly.
  1355. *
  1356. * @sample {highcharts} highcharts/yaxis/offset/
  1357. * Y axis offset of 70
  1358. * @sample {highcharts} highcharts/yaxis/offset-centered/
  1359. * Axes positioned in the center of the plot
  1360. * @sample {highstock} stock/xaxis/offset/
  1361. * Y axis offset by 70 px
  1362. *
  1363. * @type {number}
  1364. * @default 0
  1365. * @apioption xAxis.offset
  1366. */
  1367. /**
  1368. * Whether to display the axis on the opposite side of the normal. The
  1369. * normal is on the left side for vertical axes and bottom for
  1370. * horizontal, so the opposite sides will be right and top respectively.
  1371. * This is typically used with dual or multiple axes.
  1372. *
  1373. * @sample {highcharts} highcharts/yaxis/opposite/
  1374. * Secondary Y axis opposite
  1375. * @sample {highstock} stock/xaxis/opposite/
  1376. * Y axis on left side
  1377. *
  1378. * @type {boolean}
  1379. * @default false
  1380. * @apioption xAxis.opposite
  1381. */
  1382. /**
  1383. * In an ordinal axis, the points are equally spaced in the chart
  1384. * regardless of the actual time or x distance between them. This means
  1385. * that missing data periods (e.g. nights or weekends for a stock chart)
  1386. * will not take up space in the chart.
  1387. * Having `ordinal: false` will show any gaps created by the `gapSize`
  1388. * setting proportionate to their duration.
  1389. *
  1390. * In stock charts the X axis is ordinal by default, unless
  1391. * the boost module is used and at least one of the series' data length
  1392. * exceeds the [boostThreshold](#series.line.boostThreshold).
  1393. *
  1394. * @sample {highstock} stock/xaxis/ordinal-true/
  1395. * True by default
  1396. * @sample {highstock} stock/xaxis/ordinal-false/
  1397. * False
  1398. *
  1399. * @type {boolean}
  1400. * @default true
  1401. * @since 1.1
  1402. * @product highstock
  1403. * @apioption xAxis.ordinal
  1404. */
  1405. /**
  1406. * Additional range on the right side of the xAxis. Works similar to
  1407. * `xAxis.maxPadding`, but value is set in milliseconds. Can be set for
  1408. * both main `xAxis` and the navigator's `xAxis`.
  1409. *
  1410. * @sample {highstock} stock/xaxis/overscroll/
  1411. * One minute overscroll with live data
  1412. *
  1413. * @type {number}
  1414. * @default 0
  1415. * @since 6.0.0
  1416. * @product highstock
  1417. * @apioption xAxis.overscroll
  1418. */
  1419. /**
  1420. * Refers to the index in the [panes](#panes) array. Used for circular
  1421. * gauges and polar charts. When the option is not set then first pane
  1422. * will be used.
  1423. *
  1424. * @sample highcharts/demo/gauge-vu-meter
  1425. * Two gauges with different center
  1426. *
  1427. * @type {number}
  1428. * @product highcharts
  1429. * @apioption xAxis.pane
  1430. */
  1431. /**
  1432. * The zoomed range to display when only defining one or none of `min`
  1433. * or `max`. For example, to show the latest month, a range of one month
  1434. * can be set.
  1435. *
  1436. * @sample {highstock} stock/xaxis/range/
  1437. * Setting a zoomed range when the rangeSelector is disabled
  1438. *
  1439. * @type {number}
  1440. * @product highstock
  1441. * @apioption xAxis.range
  1442. */
  1443. /**
  1444. * Whether to reverse the axis so that the highest number is closest
  1445. * to the origin. If the chart is inverted, the x axis is reversed by
  1446. * default.
  1447. *
  1448. * @sample {highcharts} highcharts/yaxis/reversed/
  1449. * Reversed Y axis
  1450. * @sample {highstock} stock/xaxis/reversed/
  1451. * Reversed Y axis
  1452. *
  1453. * @type {boolean}
  1454. * @default false
  1455. * @apioption xAxis.reversed
  1456. */
  1457. // reversed: false,
  1458. /**
  1459. * This option determines how stacks should be ordered within a group.
  1460. * For example reversed xAxis also reverses stacks, so first series
  1461. * comes last in a group. To keep order like for non-reversed xAxis
  1462. * enable this option.
  1463. *
  1464. * @sample {highcharts} highcharts/xaxis/reversedstacks/
  1465. * Reversed stacks comparison
  1466. * @sample {highstock} highcharts/xaxis/reversedstacks/
  1467. * Reversed stacks comparison
  1468. *
  1469. * @type {boolean}
  1470. * @default false
  1471. * @since 6.1.1
  1472. * @product highcharts highstock
  1473. * @apioption xAxis.reversedStacks
  1474. */
  1475. /**
  1476. * An optional scrollbar to display on the X axis in response to
  1477. * limiting the minimum and maximum of the axis values.
  1478. *
  1479. * In styled mode, all the presentational options for the scrollbar are
  1480. * replaced by the classes `.highcharts-scrollbar-thumb`,
  1481. * `.highcharts-scrollbar-arrow`, `.highcharts-scrollbar-button`,
  1482. * `.highcharts-scrollbar-rifles` and `.highcharts-scrollbar-track`.
  1483. *
  1484. * @sample {highstock} stock/yaxis/heatmap-scrollbars/
  1485. * Heatmap with both scrollbars
  1486. *
  1487. * @extends scrollbar
  1488. * @since 4.2.6
  1489. * @product highstock
  1490. * @apioption xAxis.scrollbar
  1491. */
  1492. /**
  1493. * Whether to show the axis line and title when the axis has no data.
  1494. *
  1495. * @sample {highcharts} highcharts/yaxis/showempty/
  1496. * When clicking the legend to hide series, one axis preserves
  1497. * line and title, the other doesn't
  1498. * @sample {highstock} highcharts/yaxis/showempty/
  1499. * When clicking the legend to hide series, one axis preserves
  1500. * line and title, the other doesn't
  1501. *
  1502. * @type {boolean}
  1503. * @default true
  1504. * @since 1.1
  1505. * @apioption xAxis.showEmpty
  1506. */
  1507. /**
  1508. * Whether to show the first tick label.
  1509. *
  1510. * @sample {highcharts} highcharts/xaxis/showfirstlabel-false/
  1511. * Set to false on X axis
  1512. * @sample {highstock} stock/xaxis/showfirstlabel/
  1513. * Labels below plot lines on Y axis
  1514. *
  1515. * @type {boolean}
  1516. * @default true
  1517. * @apioption xAxis.showFirstLabel
  1518. */
  1519. /**
  1520. * Whether to show the last tick label. Defaults to `true` on cartesian
  1521. * charts, and `false` on polar charts.
  1522. *
  1523. * @sample {highcharts} highcharts/xaxis/showlastlabel-true/
  1524. * Set to true on X axis
  1525. * @sample {highstock} stock/xaxis/showfirstlabel/
  1526. * Labels below plot lines on Y axis
  1527. *
  1528. * @type {boolean}
  1529. * @default true
  1530. * @product highcharts highstock gantt
  1531. * @apioption xAxis.showLastLabel
  1532. */
  1533. /**
  1534. * A soft maximum for the axis. If the series data maximum is less than
  1535. * this, the axis will stay at this maximum, but if the series data
  1536. * maximum is higher, the axis will flex to show all data.
  1537. *
  1538. * @sample highcharts/yaxis/softmin-softmax/
  1539. * Soft min and max
  1540. *
  1541. * @type {number}
  1542. * @since 5.0.1
  1543. * @product highcharts highstock gantt
  1544. * @apioption xAxis.softMax
  1545. */
  1546. /**
  1547. * A soft minimum for the axis. If the series data minimum is greater
  1548. * than this, the axis will stay at this minimum, but if the series
  1549. * data minimum is lower, the axis will flex to show all data.
  1550. *
  1551. * @sample highcharts/yaxis/softmin-softmax/
  1552. * Soft min and max
  1553. *
  1554. * @type {number}
  1555. * @since 5.0.1
  1556. * @product highcharts highstock gantt
  1557. * @apioption xAxis.softMin
  1558. */
  1559. /**
  1560. * For datetime axes, this decides where to put the tick between weeks.
  1561. * 0 = Sunday, 1 = Monday.
  1562. *
  1563. * @sample {highcharts} highcharts/xaxis/startofweek-monday/
  1564. * Monday by default
  1565. * @sample {highcharts} highcharts/xaxis/startofweek-sunday/
  1566. * Sunday
  1567. * @sample {highstock} stock/xaxis/startofweek-1
  1568. * Monday by default
  1569. * @sample {highstock} stock/xaxis/startofweek-0
  1570. * Sunday
  1571. *
  1572. * @product highcharts highstock gantt
  1573. */
  1574. startOfWeek: 1,
  1575. /**
  1576. * Whether to force the axis to start on a tick. Use this option with
  1577. * the `minPadding` option to control the axis start.
  1578. *
  1579. * @productdesc {highstock}
  1580. * In Highstock, `startOnTick` is always false when the navigator is
  1581. * enabled, to prevent jumpy scrolling.
  1582. *
  1583. * @sample {highcharts} highcharts/xaxis/startontick-false/
  1584. * False by default
  1585. * @sample {highcharts} highcharts/xaxis/startontick-true/
  1586. * True
  1587. * @sample {highstock} stock/xaxis/endontick/
  1588. * False for Y axis
  1589. *
  1590. * @since 1.2.0
  1591. */
  1592. startOnTick: false,
  1593. /**
  1594. * The amount of ticks to draw on the axis. This opens up for aligning
  1595. * the ticks of multiple charts or panes within a chart. This option
  1596. * overrides the `tickPixelInterval` option.
  1597. *
  1598. * This option only has an effect on linear axes. Datetime, logarithmic
  1599. * or category axes are not affected.
  1600. *
  1601. * @sample {highcharts} highcharts/yaxis/tickamount/
  1602. * 8 ticks on Y axis
  1603. * @sample {highstock} highcharts/yaxis/tickamount/
  1604. * 8 ticks on Y axis
  1605. *
  1606. * @type {number}
  1607. * @since 4.1.0
  1608. * @product highcharts highstock gantt
  1609. * @apioption xAxis.tickAmount
  1610. */
  1611. /**
  1612. * The interval of the tick marks in axis units. When `undefined`, the
  1613. * tick interval is computed to approximately follow the
  1614. * [tickPixelInterval](#xAxis.tickPixelInterval) on linear and datetime
  1615. * axes. On categorized axes, a `undefined` tickInterval will default to
  1616. * 1, one category. Note that datetime axes are based on milliseconds,
  1617. * so for example an interval of one day is expressed as
  1618. * `24 * 3600 * 1000`.
  1619. *
  1620. * On logarithmic axes, the tickInterval is based on powers, so a
  1621. * tickInterval of 1 means one tick on each of 0.1, 1, 10, 100 etc. A
  1622. * tickInterval of 2 means a tick of 0.1, 10, 1000 etc. A tickInterval
  1623. * of 0.2 puts a tick on 0.1, 0.2, 0.4, 0.6, 0.8, 1, 2, 4, 6, 8, 10, 20,
  1624. * 40 etc.
  1625. *
  1626. *
  1627. * If the tickInterval is too dense for labels to be drawn, Highcharts
  1628. * may remove ticks.
  1629. *
  1630. * If the chart has multiple axes, the [alignTicks](#chart.alignTicks)
  1631. * option may interfere with the `tickInterval` setting.
  1632. *
  1633. * @see [tickPixelInterval](#xAxis.tickPixelInterval)
  1634. * @see [tickPositions](#xAxis.tickPositions)
  1635. * @see [tickPositioner](#xAxis.tickPositioner)
  1636. *
  1637. * @sample {highcharts} highcharts/xaxis/tickinterval-5/
  1638. * Tick interval of 5 on a linear axis
  1639. * @sample {highstock} stock/xaxis/tickinterval/
  1640. * Tick interval of 0.01 on Y axis
  1641. *
  1642. * @type {number}
  1643. * @apioption xAxis.tickInterval
  1644. */
  1645. /**
  1646. * The pixel length of the main tick marks.
  1647. *
  1648. * @sample {highcharts} highcharts/xaxis/ticklength/
  1649. * 20 px tick length on the X axis
  1650. * @sample {highstock} stock/xaxis/ticks/
  1651. * Formatted ticks on X axis
  1652. */
  1653. tickLength: 10,
  1654. /**
  1655. * If tickInterval is `null` this option sets the approximate pixel
  1656. * interval of the tick marks. Not applicable to categorized axis.
  1657. *
  1658. * The tick interval is also influenced by the [minTickInterval](
  1659. * #xAxis.minTickInterval) option, that, by default prevents ticks from
  1660. * being denser than the data points.
  1661. *
  1662. * @see [tickInterval](#xAxis.tickInterval)
  1663. * @see [tickPositioner](#xAxis.tickPositioner)
  1664. * @see [tickPositions](#xAxis.tickPositions)
  1665. *
  1666. * @sample {highcharts} highcharts/xaxis/tickpixelinterval-50/
  1667. * 50 px on X axis
  1668. * @sample {highstock} stock/xaxis/tickpixelinterval/
  1669. * 200 px on X axis
  1670. */
  1671. tickPixelInterval: 100,
  1672. /**
  1673. * For categorized axes only. If `on` the tick mark is placed in the
  1674. * center of the category, if `between` the tick mark is placed between
  1675. * categories. The default is `between` if the `tickInterval` is 1, else
  1676. * `on`.
  1677. *
  1678. * @sample {highcharts} highcharts/xaxis/tickmarkplacement-between/
  1679. * "between" by default
  1680. * @sample {highcharts} highcharts/xaxis/tickmarkplacement-on/
  1681. * "on"
  1682. *
  1683. * @product highcharts gantt
  1684. * @validvalue ["on", "between"]
  1685. */
  1686. tickmarkPlacement: 'between',
  1687. /**
  1688. * The position of the major tick marks relative to the axis line.
  1689. * Can be one of `inside` and `outside`.
  1690. *
  1691. * @sample {highcharts} highcharts/xaxis/tickposition-outside/
  1692. * "outside" by default
  1693. * @sample {highcharts} highcharts/xaxis/tickposition-inside/
  1694. * "inside"
  1695. * @sample {highstock} stock/xaxis/ticks/
  1696. * Formatted ticks on X axis
  1697. *
  1698. * @validvalue ["inside", "outside"]
  1699. */
  1700. tickPosition: 'outside',
  1701. /**
  1702. * A callback function returning array defining where the ticks are
  1703. * laid out on the axis. This overrides the default behaviour of
  1704. * [tickPixelInterval](#xAxis.tickPixelInterval) and [tickInterval](
  1705. * #xAxis.tickInterval). The automatic tick positions are accessible
  1706. * through `this.tickPositions` and can be modified by the callback.
  1707. *
  1708. * @see [tickPositions](#xAxis.tickPositions)
  1709. *
  1710. * @sample {highcharts} highcharts/xaxis/tickpositions-tickpositioner/
  1711. * Demo of tickPositions and tickPositioner
  1712. * @sample {highstock} highcharts/xaxis/tickpositions-tickpositioner/
  1713. * Demo of tickPositions and tickPositioner
  1714. *
  1715. * @type {Highcharts.AxisTickPositionerCallbackFunction}
  1716. * @apioption xAxis.tickPositioner
  1717. */
  1718. /**
  1719. * An array defining where the ticks are laid out on the axis. This
  1720. * overrides the default behaviour of [tickPixelInterval](
  1721. * #xAxis.tickPixelInterval) and [tickInterval](#xAxis.tickInterval).
  1722. *
  1723. * @see [tickPositioner](#xAxis.tickPositioner)
  1724. *
  1725. * @sample {highcharts} highcharts/xaxis/tickpositions-tickpositioner/
  1726. * Demo of tickPositions and tickPositioner
  1727. * @sample {highstock} highcharts/xaxis/tickpositions-tickpositioner/
  1728. * Demo of tickPositions and tickPositioner
  1729. *
  1730. * @type {Array<number>}
  1731. * @apioption xAxis.tickPositions
  1732. */
  1733. /**
  1734. * The pixel width of the major tick marks.
  1735. *
  1736. * In styled mode, the stroke width is given in the `.highcharts-tick`
  1737. * class.
  1738. *
  1739. * @sample {highcharts} highcharts/xaxis/tickwidth/
  1740. * 10 px width
  1741. * @sample {highcharts} highcharts/css/axis-grid/
  1742. * Styled mode
  1743. * @sample {highstock} stock/xaxis/ticks/
  1744. * Formatted ticks on X axis
  1745. * @sample {highstock} highcharts/css/axis-grid/
  1746. * Styled mode
  1747. *
  1748. * @type {number}
  1749. * @default {highcharts} 1
  1750. * @default {highstock} 1
  1751. * @default {highmaps} 0
  1752. * @apioption xAxis.tickWidth
  1753. */
  1754. /**
  1755. * The axis title, showing next to the axis line.
  1756. *
  1757. * @productdesc {highmaps}
  1758. * In Highmaps, the axis is hidden by default, but adding an axis title
  1759. * is still possible. X axis and Y axis titles will appear at the bottom
  1760. * and left by default.
  1761. */
  1762. title: {
  1763. /**
  1764. * Deprecated. Set the `text` to `null` to disable the title.
  1765. *
  1766. * @deprecated
  1767. * @type {string}
  1768. * @default middle
  1769. * @product highcharts
  1770. * @apioption xAxis.title.enabled
  1771. */
  1772. /**
  1773. * The pixel distance between the axis labels or line and the title.
  1774. * Defaults to 0 for horizontal axes, 10 for vertical
  1775. *
  1776. * @sample {highcharts} highcharts/xaxis/title-margin/
  1777. * Y axis title margin of 60
  1778. *
  1779. * @type {number}
  1780. * @apioption xAxis.title.margin
  1781. */
  1782. /**
  1783. * The distance of the axis title from the axis line. By default,
  1784. * this distance is computed from the offset width of the labels,
  1785. * the labels' distance from the axis and the title's margin.
  1786. * However when the offset option is set, it overrides all this.
  1787. *
  1788. * @sample {highcharts} highcharts/yaxis/title-offset/
  1789. * Place the axis title on top of the axis
  1790. * @sample {highstock} highcharts/yaxis/title-offset/
  1791. * Place the axis title on top of the Y axis
  1792. *
  1793. * @type {number}
  1794. * @since 2.2.0
  1795. * @apioption xAxis.title.offset
  1796. */
  1797. /**
  1798. * Whether to reserve space for the title when laying out the axis.
  1799. *
  1800. * @type {boolean}
  1801. * @default true
  1802. * @since 5.0.11
  1803. * @product highcharts highstock gantt
  1804. * @apioption xAxis.title.reserveSpace
  1805. */
  1806. /**
  1807. * The rotation of the text in degrees. 0 is horizontal, 270 is
  1808. * vertical reading from bottom to top.
  1809. *
  1810. * @sample {highcharts} highcharts/yaxis/title-offset/
  1811. * Horizontal
  1812. *
  1813. * @type {number}
  1814. * @default 0
  1815. * @apioption xAxis.title.rotation
  1816. */
  1817. /**
  1818. * The actual text of the axis title. It can contain basic HTML text
  1819. * markup like <b>, <i> and spans with style.
  1820. *
  1821. * @sample {highcharts} highcharts/xaxis/title-text/
  1822. * Custom HTML
  1823. * @sample {highstock} stock/xaxis/title-text/
  1824. * Titles for both axes
  1825. *
  1826. * @type {string|null}
  1827. * @apioption xAxis.title.text
  1828. */
  1829. /**
  1830. * Alignment of the text, can be `"left"`, `"right"` or `"center"`.
  1831. * Default alignment depends on the
  1832. * [title.align](xAxis.title.align):
  1833. *
  1834. * Horizontal axes:
  1835. * - for `align` = `"low"`, `textAlign` is set to `left`
  1836. * - for `align` = `"middle"`, `textAlign` is set to `center`
  1837. * - for `align` = `"high"`, `textAlign` is set to `right`
  1838. *
  1839. * Vertical axes:
  1840. * - for `align` = `"low"` and `opposite` = `true`, `textAlign` is
  1841. * set to `right`
  1842. * - for `align` = `"low"` and `opposite` = `false`, `textAlign` is
  1843. * set to `left`
  1844. * - for `align` = `"middle"`, `textAlign` is set to `center`
  1845. * - for `align` = `"high"` and `opposite` = `true` `textAlign` is
  1846. * set to `left`
  1847. * - for `align` = `"high"` and `opposite` = `false` `textAlign` is
  1848. * set to `right`
  1849. *
  1850. * @type {string}
  1851. * @apioption xAxis.title.textAlign
  1852. */
  1853. /**
  1854. * Whether to [use HTML](https://www.highcharts.com/docs/chart-concepts/labels-and-string-formatting#html)
  1855. * to render the axis title.
  1856. *
  1857. * @type {boolean}
  1858. * @default false
  1859. * @product highcharts highstock gantt
  1860. * @apioption xAxis.title.useHTML
  1861. */
  1862. /**
  1863. * Horizontal pixel offset of the title position.
  1864. *
  1865. * @type {number}
  1866. * @default 0
  1867. * @since 4.1.6
  1868. * @product highcharts highstock gantt
  1869. * @apioption xAxis.title.x
  1870. */
  1871. /**
  1872. * Vertical pixel offset of the title position.
  1873. *
  1874. * @type {number}
  1875. * @product highcharts highstock gantt
  1876. * @apioption xAxis.title.y
  1877. */
  1878. /**
  1879. * Alignment of the title relative to the axis values. Possible
  1880. * values are "low", "middle" or "high".
  1881. *
  1882. * @sample {highcharts} highcharts/xaxis/title-align-low/
  1883. * "low"
  1884. * @sample {highcharts} highcharts/xaxis/title-align-center/
  1885. * "middle" by default
  1886. * @sample {highcharts} highcharts/xaxis/title-align-high/
  1887. * "high"
  1888. * @sample {highcharts} highcharts/yaxis/title-offset/
  1889. * Place the Y axis title on top of the axis
  1890. * @sample {highstock} stock/xaxis/title-align/
  1891. * Aligned to "high" value
  1892. *
  1893. * @validvalue ["low", "middle", "high"]
  1894. */
  1895. align: 'middle',
  1896. /**
  1897. * CSS styles for the title. If the title text is longer than the
  1898. * axis length, it will wrap to multiple lines by default. This can
  1899. * be customized by setting `textOverflow: 'ellipsis'`, by
  1900. * setting a specific `width` or by setting `whiteSpace: 'nowrap'`.
  1901. *
  1902. * In styled mode, the stroke width is given in the
  1903. * `.highcharts-axis-title` class.
  1904. *
  1905. * @sample {highcharts} highcharts/xaxis/title-style/
  1906. * Red
  1907. * @sample {highcharts} highcharts/css/axis/
  1908. * Styled mode
  1909. *
  1910. * @type {Highcharts.CSSObject}
  1911. * @default {"color": "#666666"}
  1912. */
  1913. style: {
  1914. /** @ignore-option */
  1915. color: '#666666'
  1916. }
  1917. },
  1918. /**
  1919. * The type of axis. Can be one of `linear`, `logarithmic`, `datetime`
  1920. * or `category`. In a datetime axis, the numbers are given in
  1921. * milliseconds, and tick marks are placed on appropriate values like
  1922. * full hours or days. In a category axis, the
  1923. * [point names](#series.line.data.name) of the chart's series are used
  1924. * for categories, if not a [categories](#xAxis.categories) array is
  1925. * defined.
  1926. *
  1927. * @sample {highcharts} highcharts/xaxis/type-linear/
  1928. * Linear
  1929. * @sample {highcharts} highcharts/yaxis/type-log/
  1930. * Logarithmic
  1931. * @sample {highcharts} highcharts/yaxis/type-log-minorgrid/
  1932. * Logarithmic with minor grid lines
  1933. * @sample {highcharts} highcharts/xaxis/type-log-both/
  1934. * Logarithmic on two axes
  1935. * @sample {highcharts} highcharts/yaxis/type-log-negative/
  1936. * Logarithmic with extension to emulate negative values
  1937. *
  1938. * @product highcharts gantt
  1939. * @validvalue ["linear", "logarithmic", "datetime", "category"]
  1940. */
  1941. type: 'linear',
  1942. /**
  1943. * The type of axis. Can be one of `linear`, `logarithmic`, `datetime`,
  1944. * `category` or `treegrid`. Defaults to `treegrid` for Gantt charts,
  1945. * `linear` for other chart types.
  1946. *
  1947. * In a datetime axis, the numbers are given in milliseconds, and tick
  1948. * marks are placed on appropriate values, like full hours or days. In a
  1949. * category or treegrid axis, the [point names](#series.line.data.name)
  1950. * of the chart's series are used for categories, if a
  1951. * [categories](#xAxis.categories) array is not defined.
  1952. *
  1953. * @sample {highcharts} highcharts/yaxis/type-log-minorgrid/
  1954. * Logarithmic with minor grid lines
  1955. * @sample {highcharts} highcharts/yaxis/type-log-negative/
  1956. * Logarithmic with extension to emulate negative values
  1957. * @sample {gantt} gantt/treegrid-axis/demo
  1958. * Treegrid axis
  1959. *
  1960. * @default {highcharts} linear
  1961. * @default {gantt} treegrid
  1962. * @product highcharts gantt
  1963. * @validvalue ["linear", "logarithmic", "datetime", "category",
  1964. * "treegrid"]
  1965. * @apioption yAxis.type
  1966. */
  1967. /**
  1968. * Applies only when the axis `type` is `category`. When `uniqueNames`
  1969. * is true, points are placed on the X axis according to their names.
  1970. * If the same point name is repeated in the same or another series,
  1971. * the point is placed on the same X position as other points of the
  1972. * same name. When `uniqueNames` is false, the points are laid out in
  1973. * increasing X positions regardless of their names, and the X axis
  1974. * category will take the name of the last point in each position.
  1975. *
  1976. * @sample {highcharts} highcharts/xaxis/uniquenames-true/
  1977. * True by default
  1978. * @sample {highcharts} highcharts/xaxis/uniquenames-false/
  1979. * False
  1980. *
  1981. * @type {boolean}
  1982. * @default true
  1983. * @since 4.2.7
  1984. * @product highcharts gantt
  1985. * @apioption xAxis.uniqueNames
  1986. */
  1987. /**
  1988. * Datetime axis only. An array determining what time intervals the
  1989. * ticks are allowed to fall on. Each array item is an array where the
  1990. * first value is the time unit and the second value another array of
  1991. * allowed multiples. Defaults to:
  1992. *
  1993. * <pre>units: [[
  1994. * 'millisecond', // unit name
  1995. * [1, 2, 5, 10, 20, 25, 50, 100, 200, 500] // allowed multiples
  1996. * ], [
  1997. * 'second',
  1998. * [1, 2, 5, 10, 15, 30]
  1999. * ], [
  2000. * 'minute',
  2001. * [1, 2, 5, 10, 15, 30]
  2002. * ], [
  2003. * 'hour',
  2004. * [1, 2, 3, 4, 6, 8, 12]
  2005. * ], [
  2006. * 'day',
  2007. * [1]
  2008. * ], [
  2009. * 'week',
  2010. * [1]
  2011. * ], [
  2012. * 'month',
  2013. * [1, 3, 6]
  2014. * ], [
  2015. * 'year',
  2016. * null
  2017. * ]]</pre>
  2018. *
  2019. * @type {Array<Array<string,(Array<number>|null)>>}
  2020. * @product highcharts highstock gantt
  2021. * @apioption xAxis.units
  2022. */
  2023. /**
  2024. * Whether axis, including axis title, line, ticks and labels, should
  2025. * be visible.
  2026. *
  2027. * @type {boolean}
  2028. * @default true
  2029. * @since 4.1.9
  2030. * @product highcharts highstock gantt
  2031. * @apioption xAxis.visible
  2032. */
  2033. /**
  2034. * Color of the minor, secondary grid lines.
  2035. *
  2036. * In styled mode, the stroke width is given in the
  2037. * `.highcharts-minor-grid-line` class.
  2038. *
  2039. * @sample {highcharts} highcharts/yaxis/minorgridlinecolor/
  2040. * Bright grey lines from Y axis
  2041. * @sample {highcharts|highstock} highcharts/css/axis-grid/
  2042. * Styled mode
  2043. * @sample {highstock} stock/xaxis/minorgridlinecolor/
  2044. * Bright grey lines from Y axis
  2045. *
  2046. * @type {Highcharts.ColorString}
  2047. * @default #f2f2f2
  2048. */
  2049. minorGridLineColor: '#f2f2f2',
  2050. /**
  2051. * Width of the minor, secondary grid lines.
  2052. *
  2053. * In styled mode, the stroke width is given in the
  2054. * `.highcharts-grid-line` class.
  2055. *
  2056. * @sample {highcharts} highcharts/yaxis/minorgridlinewidth/
  2057. * 2px lines from Y axis
  2058. * @sample {highcharts|highstock} highcharts/css/axis-grid/
  2059. * Styled mode
  2060. * @sample {highstock} stock/xaxis/minorgridlinewidth/
  2061. * 2px lines from Y axis
  2062. */
  2063. minorGridLineWidth: 1,
  2064. /**
  2065. * Color for the minor tick marks.
  2066. *
  2067. * @sample {highcharts} highcharts/yaxis/minortickcolor/
  2068. * Black tick marks on Y axis
  2069. * @sample {highstock} stock/xaxis/minorticks/
  2070. * Black tick marks on Y axis
  2071. *
  2072. * @type {Highcharts.ColorString}
  2073. * @default #999999
  2074. */
  2075. minorTickColor: '#999999',
  2076. /**
  2077. * The color of the line marking the axis itself.
  2078. *
  2079. * In styled mode, the line stroke is given in the
  2080. * `.highcharts-axis-line` or `.highcharts-xaxis-line` class.
  2081. *
  2082. * @productdesc {highmaps}
  2083. * In Highmaps, the axis line is hidden by default, because the axis is
  2084. * not visible by default.
  2085. *
  2086. * @sample {highcharts} highcharts/yaxis/linecolor/
  2087. * A red line on Y axis
  2088. * @sample {highcharts|highstock} highcharts/css/axis/
  2089. * Axes in styled mode
  2090. * @sample {highstock} stock/xaxis/linecolor/
  2091. * A red line on X axis
  2092. *
  2093. * @type {Highcharts.ColorString}
  2094. * @default #ccd6eb
  2095. */
  2096. lineColor: '#ccd6eb',
  2097. /**
  2098. * The width of the line marking the axis itself.
  2099. *
  2100. * In styled mode, the stroke width is given in the
  2101. * `.highcharts-axis-line` or `.highcharts-xaxis-line` class.
  2102. *
  2103. * @sample {highcharts} highcharts/yaxis/linecolor/
  2104. * A 1px line on Y axis
  2105. * @sample {highcharts|highstock} highcharts/css/axis/
  2106. * Axes in styled mode
  2107. * @sample {highstock} stock/xaxis/linewidth/
  2108. * A 2px line on X axis
  2109. *
  2110. * @default {highcharts|highstock} 1
  2111. * @default {highmaps} 0
  2112. */
  2113. lineWidth: 1,
  2114. /**
  2115. * Color of the grid lines extending the ticks across the plot area.
  2116. *
  2117. * In styled mode, the stroke is given in the `.highcharts-grid-line`
  2118. * class.
  2119. *
  2120. * @productdesc {highmaps}
  2121. * In Highmaps, the grid lines are hidden by default.
  2122. *
  2123. * @sample {highcharts} highcharts/yaxis/gridlinecolor/
  2124. * Green lines
  2125. * @sample {highcharts|highstock} highcharts/css/axis-grid/
  2126. * Styled mode
  2127. * @sample {highstock} stock/xaxis/gridlinecolor/
  2128. * Green lines
  2129. *
  2130. * @type {Highcharts.ColorString}
  2131. * @default #e6e6e6
  2132. */
  2133. gridLineColor: '#e6e6e6',
  2134. // gridLineDashStyle: 'solid',
  2135. /**
  2136. * The width of the grid lines extending the ticks across the plot area.
  2137. *
  2138. * In styled mode, the stroke width is given in the
  2139. * `.highcharts-grid-line` class.
  2140. *
  2141. * @sample {highcharts} highcharts/yaxis/gridlinewidth/
  2142. * 2px lines
  2143. * @sample {highcharts|highstock} highcharts/css/axis-grid/
  2144. * Styled mode
  2145. * @sample {highstock} stock/xaxis/gridlinewidth/
  2146. * 2px lines
  2147. *
  2148. * @type {number}
  2149. * @default 0
  2150. * @apioption xAxis.gridLineWidth
  2151. */
  2152. // gridLineWidth: 0,
  2153. /**
  2154. * Color for the main tick marks.
  2155. *
  2156. * In styled mode, the stroke is given in the `.highcharts-tick`
  2157. * class.
  2158. *
  2159. * @sample {highcharts} highcharts/xaxis/tickcolor/
  2160. * Red ticks on X axis
  2161. * @sample {highcharts|highstock} highcharts/css/axis-grid/
  2162. * Styled mode
  2163. * @sample {highstock} stock/xaxis/ticks/
  2164. * Formatted ticks on X axis
  2165. *
  2166. * @type {Highcharts.ColorString}
  2167. * @default #ccd6eb
  2168. */
  2169. tickColor: '#ccd6eb'
  2170. // tickWidth: 1
  2171. },
  2172. /**
  2173. * The Y axis or value axis. Normally this is the vertical axis,
  2174. * though if the chart is inverted this is the horizontal axis.
  2175. * In case of multiple axes, the yAxis node is an array of
  2176. * configuration objects.
  2177. *
  2178. * See [the Axis object](/class-reference/Highcharts.Axis) for programmatic
  2179. * access to the axis.
  2180. *
  2181. * @type {*|Array<*>}
  2182. * @extends xAxis
  2183. * @excluding ordinal,overscroll,currentDateIndicator
  2184. * @optionparent yAxis
  2185. */
  2186. defaultYAxisOptions: {
  2187. /**
  2188. * In a polar chart, this is the angle of the Y axis in degrees, where
  2189. * 0 is up and 90 is right. The angle determines the position of the
  2190. * axis line and the labels, though the coordinate system is unaffected.
  2191. *
  2192. * @sample {highcharts} highcharts/yaxis/angle/
  2193. * Dual axis polar chart
  2194. *
  2195. * @type {number}
  2196. * @default 0
  2197. * @since 4.2.7
  2198. * @product highcharts
  2199. * @apioption yAxis.angle
  2200. */
  2201. /**
  2202. * Polar charts only. Whether the grid lines should draw as a polygon
  2203. * with straight lines between categories, or as circles. Can be either
  2204. * `circle` or `polygon`.
  2205. *
  2206. * @sample {highcharts} highcharts/demo/polar-spider/
  2207. * Polygon grid lines
  2208. * @sample {highcharts} highcharts/yaxis/gridlineinterpolation/
  2209. * Circle and polygon
  2210. *
  2211. * @type {string}
  2212. * @product highcharts
  2213. * @validvalue ["circle", "polygon"]
  2214. * @apioption yAxis.gridLineInterpolation
  2215. */
  2216. /**
  2217. * The height of the Y axis. If it's a number, it is interpreted as
  2218. * pixels.
  2219. *
  2220. * Since Highstock 2: If it's a percentage string, it is interpreted
  2221. * as percentages of the total plot height.
  2222. *
  2223. * @see [yAxis.top](#yAxis.top)
  2224. *
  2225. * @sample {highstock} stock/demo/candlestick-and-volume/
  2226. * Percentage height panes
  2227. *
  2228. * @type {number|string}
  2229. * @product highstock
  2230. * @apioption yAxis.height
  2231. */
  2232. /**
  2233. * Solid gauge only. Unless [stops](#yAxis.stops) are set, the color
  2234. * to represent the maximum value of the Y axis.
  2235. *
  2236. * @sample {highcharts} highcharts/yaxis/mincolor-maxcolor/
  2237. * Min and max colors
  2238. *
  2239. * @type {Highcharts.ColorString}
  2240. * @default #003399
  2241. * @since 4.0
  2242. * @product highcharts
  2243. * @apioption yAxis.maxColor
  2244. */
  2245. /**
  2246. * Solid gauge only. Unless [stops](#yAxis.stops) are set, the color
  2247. * to represent the minimum value of the Y axis.
  2248. *
  2249. * @sample {highcharts} highcharts/yaxis/mincolor-maxcolor/
  2250. * Min and max color
  2251. *
  2252. * @type {Highcharts.ColorString}
  2253. * @default #e6ebf5
  2254. * @since 4.0
  2255. * @product highcharts
  2256. * @apioption yAxis.minColor
  2257. */
  2258. /**
  2259. * Whether to reverse the axis so that the highest number is closest
  2260. * to the origin.
  2261. *
  2262. * @sample {highcharts} highcharts/yaxis/reversed/
  2263. * Reversed Y axis
  2264. * @sample {highstock} stock/xaxis/reversed/
  2265. * Reversed Y axis
  2266. *
  2267. * @type {boolean}
  2268. * @default {highcharts} false
  2269. * @default {highstock} false
  2270. * @default {highmaps} true
  2271. * @default {gantt} true
  2272. * @apioption yAxis.reversed
  2273. */
  2274. /**
  2275. * If `true`, the first series in a stack will be drawn on top in a
  2276. * positive, non-reversed Y axis. If `false`, the first series is in
  2277. * the base of the stack.
  2278. *
  2279. * @sample {highcharts} highcharts/yaxis/reversedstacks-false/
  2280. * Non-reversed stacks
  2281. * @sample {highstock} highcharts/yaxis/reversedstacks-false/
  2282. * Non-reversed stacks
  2283. *
  2284. * @type {boolean}
  2285. * @default true
  2286. * @since 3.0.10
  2287. * @product highcharts highstock
  2288. * @apioption yAxis.reversedStacks
  2289. */
  2290. /**
  2291. * Solid gauge series only. Color stops for the solid gauge. Use this
  2292. * in cases where a linear gradient between a `minColor` and `maxColor`
  2293. * is not sufficient. The stops is an array of tuples, where the first
  2294. * item is a float between 0 and 1 assigning the relative position in
  2295. * the gradient, and the second item is the color.
  2296. *
  2297. * For solid gauges, the Y axis also inherits the concept of
  2298. * [data classes](http://api.highcharts.com/highmaps#colorAxis.dataClasses)
  2299. * from the Highmaps color axis.
  2300. *
  2301. * @see [minColor](#yAxis.minColor)
  2302. * @see [maxColor](#yAxis.maxColor)
  2303. *
  2304. * @sample {highcharts} highcharts/demo/gauge-solid/
  2305. * True by default
  2306. *
  2307. * @type {Array<Array<number,Highcharts.ColorString>>}
  2308. * @since 4.0
  2309. * @product highcharts
  2310. * @apioption yAxis.stops
  2311. */
  2312. /**
  2313. * The pixel width of the major tick marks.
  2314. *
  2315. * @sample {highcharts} highcharts/xaxis/tickwidth/ 10 px width
  2316. * @sample {highstock} stock/xaxis/ticks/ Formatted ticks on X axis
  2317. *
  2318. * @type {number}
  2319. * @default 0
  2320. * @product highcharts highstock gantt
  2321. * @apioption yAxis.tickWidth
  2322. */
  2323. /**
  2324. * Angular gauges and solid gauges only. The label's pixel distance
  2325. * from the perimeter of the plot area.
  2326. *
  2327. * @type {number}
  2328. * @default -25
  2329. * @product highcharts
  2330. * @apioption yAxis.labels.distance
  2331. */
  2332. /**
  2333. * The y position offset of the label relative to the tick position
  2334. * on the axis.
  2335. *
  2336. * @sample {highcharts} highcharts/xaxis/labels-x/
  2337. * Y axis labels placed on grid lines
  2338. *
  2339. * @type {number}
  2340. * @default {highcharts} 3
  2341. * @default {highstock} -2
  2342. * @default {highmaps} 3
  2343. * @apioption yAxis.labels.y
  2344. */
  2345. /**
  2346. * @productdesc {highstock}
  2347. * In Highstock, `endOnTick` is always false when the navigator is
  2348. * enabled, to prevent jumpy scrolling.
  2349. */
  2350. endOnTick: true,
  2351. /**
  2352. * Padding of the max value relative to the length of the axis. A
  2353. * padding of 0.05 will make a 100px axis 5px longer. This is useful
  2354. * when you don't want the highest data value to appear on the edge
  2355. * of the plot area. When the axis' `max` option is set or a max extreme
  2356. * is set using `axis.setExtremes()`, the maxPadding will be ignored.
  2357. *
  2358. * @sample {highcharts} highcharts/yaxis/maxpadding-02/
  2359. * Max padding of 0.2
  2360. * @sample {highstock} stock/xaxis/minpadding-maxpadding/
  2361. * Greater min- and maxPadding
  2362. *
  2363. * @since 1.2.0
  2364. * @product highcharts highstock gantt
  2365. */
  2366. maxPadding: 0.05,
  2367. /**
  2368. * Padding of the min value relative to the length of the axis. A
  2369. * padding of 0.05 will make a 100px axis 5px longer. This is useful
  2370. * when you don't want the lowest data value to appear on the edge
  2371. * of the plot area. When the axis' `min` option is set or a max extreme
  2372. * is set using `axis.setExtremes()`, the maxPadding will be ignored.
  2373. *
  2374. * @sample {highcharts} highcharts/yaxis/minpadding/
  2375. * Min padding of 0.2
  2376. * @sample {highstock} stock/xaxis/minpadding-maxpadding/
  2377. * Greater min- and maxPadding
  2378. *
  2379. * @since 1.2.0
  2380. * @product highcharts highstock gantt
  2381. */
  2382. minPadding: 0.05,
  2383. /**
  2384. * @productdesc {highstock}
  2385. * In Highstock 1.x, the Y axis was placed on the left side by default.
  2386. *
  2387. * @sample {highcharts} highcharts/yaxis/opposite/
  2388. * Secondary Y axis opposite
  2389. * @sample {highstock} stock/xaxis/opposite/
  2390. * Y axis on left side
  2391. *
  2392. * @type {boolean}
  2393. * @default {highstock} true
  2394. * @default {highcharts} false
  2395. * @product highstock highcharts gantt
  2396. * @apioption yAxis.opposite
  2397. */
  2398. /**
  2399. * @see [tickInterval](#xAxis.tickInterval)
  2400. * @see [tickPositioner](#xAxis.tickPositioner)
  2401. * @see [tickPositions](#xAxis.tickPositions)
  2402. */
  2403. tickPixelInterval: 72,
  2404. showLastLabel: true,
  2405. /**
  2406. * @extends xAxis.labels
  2407. */
  2408. labels: {
  2409. /**
  2410. * What part of the string the given position is anchored to. Can
  2411. * be one of `"left"`, `"center"` or `"right"`. The exact position
  2412. * also depends on the `labels.x` setting.
  2413. *
  2414. * Angular gauges and solid gauges defaults to `center`.
  2415. *
  2416. * @sample {highcharts} highcharts/yaxis/labels-align-left/
  2417. * Left
  2418. *
  2419. * @type {string}
  2420. * @default {highcharts|highmaps} right
  2421. * @default {highstock} left
  2422. * @validvalue ["left", "center", "right"]
  2423. * @apioption yAxis.labels.align
  2424. */
  2425. /**
  2426. * The x position offset of the label relative to the tick position
  2427. * on the axis. Defaults to -15 for left axis, 15 for right axis.
  2428. *
  2429. * @sample {highcharts} highcharts/xaxis/labels-x/
  2430. * Y axis labels placed on grid lines
  2431. */
  2432. x: -8
  2433. },
  2434. /**
  2435. * @productdesc {highmaps}
  2436. * In Highmaps, the axis line is hidden by default, because the axis is
  2437. * not visible by default.
  2438. *
  2439. * @type {Highcharts.ColorString}
  2440. * @apioption yAxis.lineColor
  2441. */
  2442. /**
  2443. * @sample {highcharts} highcharts/yaxis/max-200/
  2444. * Y axis max of 200
  2445. * @sample {highcharts} highcharts/yaxis/max-logarithmic/
  2446. * Y axis max on logarithmic axis
  2447. * @sample {highstock} stock/yaxis/min-max/
  2448. * Fixed min and max on Y axis
  2449. * @sample {highmaps} maps/axis/min-max/
  2450. * Pre-zoomed to a specific area
  2451. *
  2452. * @type {number}
  2453. * @apioption yAxis.max
  2454. */
  2455. /**
  2456. * @sample {highcharts} highcharts/yaxis/min-startontick-false/
  2457. * -50 with startOnTick to false
  2458. * @sample {highcharts} highcharts/yaxis/min-startontick-true/
  2459. * -50 with startOnTick true by default
  2460. * @sample {highstock} stock/yaxis/min-max/
  2461. * Fixed min and max on Y axis
  2462. * @sample {highmaps} maps/axis/min-max/
  2463. * Pre-zoomed to a specific area
  2464. *
  2465. * @type {number}
  2466. * @apioption yAxis.min
  2467. */
  2468. /**
  2469. * An optional scrollbar to display on the Y axis in response to
  2470. * limiting the minimum an maximum of the axis values.
  2471. *
  2472. * In styled mode, all the presentational options for the scrollbar
  2473. * are replaced by the classes `.highcharts-scrollbar-thumb`,
  2474. * `.highcharts-scrollbar-arrow`, `.highcharts-scrollbar-button`,
  2475. * `.highcharts-scrollbar-rifles` and `.highcharts-scrollbar-track`.
  2476. *
  2477. * @sample {highstock} stock/yaxis/scrollbar/
  2478. * Scrollbar on the Y axis
  2479. *
  2480. * @extends scrollbar
  2481. * @since 4.2.6
  2482. * @product highstock
  2483. * @excluding height
  2484. * @apioption yAxis.scrollbar
  2485. */
  2486. /**
  2487. * Enable the scrollbar on the Y axis.
  2488. *
  2489. * @sample {highstock} stock/yaxis/scrollbar/
  2490. * Enabled on Y axis
  2491. *
  2492. * @type {boolean}
  2493. * @default false
  2494. * @since 4.2.6
  2495. * @product highstock
  2496. * @apioption yAxis.scrollbar.enabled
  2497. */
  2498. /**
  2499. * Pixel margin between the scrollbar and the axis elements.
  2500. *
  2501. * @type {number}
  2502. * @default 10
  2503. * @since 4.2.6
  2504. * @product highstock
  2505. * @apioption yAxis.scrollbar.margin
  2506. */
  2507. /**
  2508. * Whether to show the scrollbar when it is fully zoomed out at max
  2509. * range. Setting it to `false` on the Y axis makes the scrollbar stay
  2510. * hidden until the user zooms in, like common in browsers.
  2511. *
  2512. * @type {boolean}
  2513. * @default true
  2514. * @since 4.2.6
  2515. * @product highstock
  2516. * @apioption yAxis.scrollbar.showFull
  2517. */
  2518. /**
  2519. * The width of a vertical scrollbar or height of a horizontal
  2520. * scrollbar. Defaults to 20 on touch devices.
  2521. *
  2522. * @type {number}
  2523. * @default 14
  2524. * @since 4.2.6
  2525. * @product highstock
  2526. * @apioption yAxis.scrollbar.size
  2527. */
  2528. /**
  2529. * Z index of the scrollbar elements.
  2530. *
  2531. * @type {number}
  2532. * @default 3
  2533. * @since 4.2.6
  2534. * @product highstock
  2535. * @apioption yAxis.scrollbar.zIndex
  2536. */
  2537. /**
  2538. * A soft maximum for the axis. If the series data maximum is less
  2539. * than this, the axis will stay at this maximum, but if the series
  2540. * data maximum is higher, the axis will flex to show all data.
  2541. *
  2542. * **Note**: The [series.softThreshold](
  2543. * #plotOptions.series.softThreshold) option takes precedence over this
  2544. * option.
  2545. *
  2546. * @sample highcharts/yaxis/softmin-softmax/
  2547. * Soft min and max
  2548. *
  2549. * @type {number}
  2550. * @since 5.0.1
  2551. * @product highcharts highstock gantt
  2552. * @apioption yAxis.softMax
  2553. */
  2554. /**
  2555. * A soft minimum for the axis. If the series data minimum is greater
  2556. * than this, the axis will stay at this minimum, but if the series
  2557. * data minimum is lower, the axis will flex to show all data.
  2558. *
  2559. * **Note**: The [series.softThreshold](
  2560. * #plotOptions.series.softThreshold) option takes precedence over this
  2561. * option.
  2562. *
  2563. * @sample highcharts/yaxis/softmin-softmax/
  2564. * Soft min and max
  2565. *
  2566. * @type {number}
  2567. * @since 5.0.1
  2568. * @product highcharts highstock gantt
  2569. * @apioption yAxis.softMin
  2570. */
  2571. /**
  2572. * Defines the horizontal alignment of the stack total label. Can be one
  2573. * of `"left"`, `"center"` or `"right"`. The default value is calculated
  2574. * at runtime and depends on orientation and whether the stack is
  2575. * positive or negative.
  2576. *
  2577. * @sample {highcharts} highcharts/yaxis/stacklabels-align-left/
  2578. * Aligned to the left
  2579. * @sample {highcharts} highcharts/yaxis/stacklabels-align-center/
  2580. * Aligned in center
  2581. * @sample {highcharts} highcharts/yaxis/stacklabels-align-right/
  2582. * Aligned to the right
  2583. *
  2584. * @type {Highcharts.AlignType}
  2585. * @since 2.1.5
  2586. * @product highcharts
  2587. * @apioption yAxis.stackLabels.align
  2588. */
  2589. /**
  2590. * A [format string](http://docs.highcharts.com/#formatting) for the
  2591. * data label. Available variables are the same as for `formatter`.
  2592. *
  2593. * @type {string}
  2594. * @default {total}
  2595. * @since 3.0.2
  2596. * @product highcharts highstock
  2597. * @apioption yAxis.stackLabels.format
  2598. */
  2599. /**
  2600. * Rotation of the labels in degrees.
  2601. *
  2602. * @sample {highcharts} highcharts/yaxis/stacklabels-rotation/
  2603. * Labels rotated 45°
  2604. *
  2605. * @type {number}
  2606. * @default 0
  2607. * @since 2.1.5
  2608. * @product highcharts
  2609. * @apioption yAxis.stackLabels.rotation
  2610. */
  2611. /**
  2612. * The text alignment for the label. While `align` determines where the
  2613. * texts anchor point is placed with regards to the stack, `textAlign`
  2614. * determines how the text is aligned against its anchor point. Possible
  2615. * values are `"left"`, `"center"` and `"right"`. The default value is
  2616. * calculated at runtime and depends on orientation and whether the
  2617. * stack is positive or negative.
  2618. *
  2619. * @sample {highcharts} highcharts/yaxis/stacklabels-textalign-left/
  2620. * Label in center position but text-aligned left
  2621. *
  2622. * @type {Highcharts.AlignType}
  2623. * @since 2.1.5
  2624. * @product highcharts
  2625. * @apioption yAxis.stackLabels.textAlign
  2626. */
  2627. /**
  2628. * Whether to [use HTML](https://www.highcharts.com/docs/chart-concepts/labels-and-string-formatting#html)
  2629. * to render the labels.
  2630. *
  2631. * @type {boolean}
  2632. * @default false
  2633. * @since 3.0
  2634. * @product highcharts highstock
  2635. * @apioption yAxis.stackLabels.useHTML
  2636. */
  2637. /**
  2638. * Defines the vertical alignment of the stack total label. Can be one
  2639. * of `"top"`, `"middle"` or `"bottom"`. The default value is calculated
  2640. * at runtime and depends on orientation and whether the stack is
  2641. * positive or negative.
  2642. *
  2643. * @sample {highcharts} highcharts/yaxis/stacklabels-verticalalign-top/
  2644. * Vertically aligned top
  2645. * @sample {highcharts} highcharts/yaxis/stacklabels-verticalalign-middle/
  2646. * Vertically aligned middle
  2647. * @sample {highcharts} highcharts/yaxis/stacklabels-verticalalign-bottom/
  2648. * Vertically aligned bottom
  2649. *
  2650. * @type {Highcharts.VerticalAlignType}
  2651. * @since 2.1.5
  2652. * @product highcharts
  2653. * @apioption yAxis.stackLabels.verticalAlign
  2654. */
  2655. /**
  2656. * The x position offset of the label relative to the left of the
  2657. * stacked bar. The default value is calculated at runtime and depends
  2658. * on orientation and whether the stack is positive or negative.
  2659. *
  2660. * @sample {highcharts} highcharts/yaxis/stacklabels-x/
  2661. * Stack total labels with x offset
  2662. *
  2663. * @type {number}
  2664. * @since 2.1.5
  2665. * @product highcharts
  2666. * @apioption yAxis.stackLabels.x
  2667. */
  2668. /**
  2669. * The y position offset of the label relative to the tick position
  2670. * on the axis. The default value is calculated at runtime and depends
  2671. * on orientation and whether the stack is positive or negative.
  2672. *
  2673. * @sample {highcharts} highcharts/yaxis/stacklabels-y/
  2674. * Stack total labels with y offset
  2675. *
  2676. * @type {number}
  2677. * @since 2.1.5
  2678. * @product highcharts
  2679. * @apioption yAxis.stackLabels.y
  2680. */
  2681. /**
  2682. * Whether to force the axis to start on a tick. Use this option with
  2683. * the `maxPadding` option to control the axis start.
  2684. *
  2685. * @sample {highcharts} highcharts/xaxis/startontick-false/
  2686. * False by default
  2687. * @sample {highcharts} highcharts/xaxis/startontick-true/
  2688. * True
  2689. * @sample {highstock} stock/xaxis/endontick/
  2690. * False for Y axis
  2691. *
  2692. * @since 1.2.0
  2693. * @product highcharts highstock gantt
  2694. */
  2695. startOnTick: true,
  2696. title: {
  2697. /**
  2698. * The pixel distance between the axis labels and the title.
  2699. * Positive values are outside the axis line, negative are inside.
  2700. *
  2701. * @sample {highcharts} highcharts/xaxis/title-margin/
  2702. * Y axis title margin of 60
  2703. *
  2704. * @type {number}
  2705. * @default 40
  2706. * @apioption yAxis.title.margin
  2707. */
  2708. /**
  2709. * The rotation of the text in degrees. 0 is horizontal, 270 is
  2710. * vertical reading from bottom to top.
  2711. *
  2712. * @sample {highcharts} highcharts/yaxis/title-offset/
  2713. * Horizontal
  2714. */
  2715. rotation: 270,
  2716. /**
  2717. * The actual text of the axis title. Horizontal texts can contain
  2718. * HTML, but rotated texts are painted using vector techniques and
  2719. * must be clean text. The Y axis title is disabled by setting the
  2720. * `text` option to `undefined`.
  2721. *
  2722. * @sample {highcharts} highcharts/xaxis/title-text/
  2723. * Custom HTML
  2724. *
  2725. * @type {string|null}
  2726. * @default {highcharts} Values
  2727. * @default {highstock} undefined
  2728. * @product highcharts highstock gantt
  2729. */
  2730. text: 'Values'
  2731. },
  2732. /**
  2733. * The top position of the Y axis. If it's a number, it is interpreted
  2734. * as pixel position relative to the chart.
  2735. *
  2736. * Since Highstock 2: If it's a percentage string, it is interpreted
  2737. * as percentages of the plot height, offset from plot area top.
  2738. *
  2739. * @see [yAxis.height](#yAxis.height)
  2740. *
  2741. * @sample {highstock} stock/demo/candlestick-and-volume/
  2742. * Percentage height panes
  2743. *
  2744. * @type {number|string}
  2745. * @product highstock
  2746. * @apioption yAxis.top
  2747. */
  2748. /**
  2749. * The stack labels show the total value for each bar in a stacked
  2750. * column or bar chart. The label will be placed on top of positive
  2751. * columns and below negative columns. In case of an inverted column
  2752. * chart or a bar chart the label is placed to the right of positive
  2753. * bars and to the left of negative bars.
  2754. *
  2755. * @product highcharts
  2756. */
  2757. stackLabels: {
  2758. /**
  2759. * Allow the stack labels to overlap.
  2760. *
  2761. * @sample {highcharts} highcharts/yaxis/stacklabels-allowoverlap-false/
  2762. * Default false
  2763. *
  2764. * @since 5.0.13
  2765. * @product highcharts
  2766. */
  2767. allowOverlap: false,
  2768. /**
  2769. * Enable or disable the stack total labels.
  2770. *
  2771. * @sample {highcharts} highcharts/yaxis/stacklabels-enabled/
  2772. * Enabled stack total labels
  2773. *
  2774. * @since 2.1.5
  2775. * @product highcharts
  2776. */
  2777. enabled: false,
  2778. /**
  2779. * Callback JavaScript function to format the label. The value is
  2780. * given by `this.total`.
  2781. *
  2782. * @sample {highcharts} highcharts/yaxis/stacklabels-formatter/
  2783. * Added units to stack total value
  2784. *
  2785. * @type {Highcharts.FormatterCallbackFunction<object>}
  2786. * @since 2.1.5
  2787. * @product highcharts
  2788. */
  2789. formatter: function () {
  2790. return H.numberFormat(this.total, -1);
  2791. },
  2792. /**
  2793. * CSS styles for the label.
  2794. *
  2795. * In styled mode, the styles are set in the
  2796. * `.highcharts-stack-label` class.
  2797. *
  2798. * @sample {highcharts} highcharts/yaxis/stacklabels-style/
  2799. * Red stack total labels
  2800. *
  2801. * @type {Highcharts.CSSObject}
  2802. * @default {"color": "#666666", "fontSize": "11px", "fontWeight": "bold", "textOutline": "1px contrast"}
  2803. * @since 2.1.5
  2804. * @product highcharts
  2805. */
  2806. style: {
  2807. /** @ignore-option */
  2808. color: '#000000',
  2809. /** @ignore-option */
  2810. fontSize: '11px',
  2811. /** @ignore-option */
  2812. fontWeight: 'bold',
  2813. /** @ignore-option */
  2814. textOutline: '1px contrast'
  2815. }
  2816. },
  2817. gridLineWidth: 1,
  2818. lineWidth: 0
  2819. // tickWidth: 0
  2820. },
  2821. /**
  2822. * The Z axis or depth axis for 3D plots.
  2823. *
  2824. * See the [Axis class](/class-reference/Highcharts.Axis) for programmatic
  2825. * access to the axis.
  2826. *
  2827. * @sample {highcharts} highcharts/3d/scatter-zaxis-categories/
  2828. * Z-Axis with Categories
  2829. * @sample {highcharts} highcharts/3d/scatter-zaxis-grid/
  2830. * Z-Axis with styling
  2831. *
  2832. * @type {*|Array<*>}
  2833. * @extends xAxis
  2834. * @since 5.0.0
  2835. * @product highcharts
  2836. * @excluding breaks, crosshair, lineColor, lineWidth, nameToX, showEmpty
  2837. * @apioption zAxis
  2838. */
  2839. // This variable extends the defaultOptions for left axes.
  2840. defaultLeftAxisOptions: {
  2841. labels: {
  2842. x: -15
  2843. },
  2844. title: {
  2845. rotation: 270
  2846. }
  2847. },
  2848. // This variable extends the defaultOptions for right axes.
  2849. defaultRightAxisOptions: {
  2850. labels: {
  2851. x: 15
  2852. },
  2853. title: {
  2854. rotation: 90
  2855. }
  2856. },
  2857. // This variable extends the defaultOptions for bottom axes.
  2858. defaultBottomAxisOptions: {
  2859. labels: {
  2860. autoRotation: [-45],
  2861. x: 0
  2862. // overflow: undefined,
  2863. // staggerLines: null
  2864. },
  2865. title: {
  2866. rotation: 0
  2867. }
  2868. },
  2869. // This variable extends the defaultOptions for top axes.
  2870. defaultTopAxisOptions: {
  2871. labels: {
  2872. autoRotation: [-45],
  2873. x: 0
  2874. // overflow: undefined
  2875. // staggerLines: null
  2876. },
  2877. title: {
  2878. rotation: 0
  2879. }
  2880. },
  2881. /**
  2882. * Overrideable function to initialize the axis.
  2883. *
  2884. * @see {@link Axis}
  2885. *
  2886. * @function Highcharts.Axis#init
  2887. *
  2888. * @param {Highcharts.Chart} chart
  2889. *
  2890. * @param {Highcharts.Options} userOptions
  2891. *
  2892. * @fires Highcharts.Axis#event:afterInit
  2893. * @fires Highcharts.Axis#event:init
  2894. */
  2895. init: function (chart, userOptions) {
  2896. var isXAxis = userOptions.isX,
  2897. axis = this;
  2898. /**
  2899. * The Chart that the axis belongs to.
  2900. *
  2901. * @name Highcharts.Axis#chart
  2902. * @type {Highcharts.Chart}
  2903. */
  2904. axis.chart = chart;
  2905. /**
  2906. * Whether the axis is horizontal.
  2907. *
  2908. * @name Highcharts.Axis#horiz
  2909. * @type {boolean}
  2910. */
  2911. axis.horiz = chart.inverted && !axis.isZAxis ? !isXAxis : isXAxis;
  2912. /**
  2913. * Whether the axis is the x-axis.
  2914. *
  2915. * @name Highcharts.Axis#isXAxis
  2916. * @type {boolean|undefined}
  2917. */
  2918. axis.isXAxis = isXAxis;
  2919. /**
  2920. * The collection where the axis belongs, for example `xAxis`, `yAxis`
  2921. * or `colorAxis`. Corresponds to properties on Chart, for example
  2922. * {@link Chart.xAxis}.
  2923. *
  2924. * @name Highcharts.Axis#coll
  2925. * @type {string}
  2926. */
  2927. axis.coll = axis.coll || (isXAxis ? 'xAxis' : 'yAxis');
  2928. fireEvent(this, 'init', { userOptions: userOptions });
  2929. axis.opposite = userOptions.opposite; // needed in setOptions
  2930. /**
  2931. * The side on which the axis is rendered. 0 is top, 1 is right, 2
  2932. * is bottom and 3 is left.
  2933. *
  2934. * @name Highcharts.Axis#side
  2935. * @type {number}
  2936. */
  2937. axis.side = userOptions.side || (axis.horiz ?
  2938. (axis.opposite ? 0 : 2) : // top : bottom
  2939. (axis.opposite ? 1 : 3)); // right : left
  2940. axis.setOptions(userOptions);
  2941. var options = this.options,
  2942. type = options.type,
  2943. isDatetimeAxis = type === 'datetime';
  2944. axis.labelFormatter = options.labels.formatter ||
  2945. // can be overwritten by dynamic format
  2946. axis.defaultLabelFormatter;
  2947. // Flag, stagger lines or not
  2948. axis.userOptions = userOptions;
  2949. axis.minPixelPadding = 0;
  2950. /**
  2951. * Whether the axis is reversed. Based on the `axis.reversed`,
  2952. * option, but inverted charts have reversed xAxis by default.
  2953. *
  2954. * @name Highcharts.Axis#reversed
  2955. * @type {boolean}
  2956. */
  2957. axis.reversed = options.reversed;
  2958. axis.visible = options.visible !== false;
  2959. axis.zoomEnabled = options.zoomEnabled !== false;
  2960. // Initial categories
  2961. axis.hasNames = type === 'category' || options.categories === true;
  2962. axis.categories = options.categories || axis.hasNames;
  2963. if (!axis.names) { // Preserve on update (#3830)
  2964. axis.names = [];
  2965. axis.names.keys = {};
  2966. }
  2967. // Placeholder for plotlines and plotbands groups
  2968. axis.plotLinesAndBandsGroups = {};
  2969. // Shorthand types
  2970. axis.isLog = type === 'logarithmic';
  2971. axis.isDatetimeAxis = isDatetimeAxis;
  2972. axis.positiveValuesOnly = axis.isLog && !axis.allowNegativeLog;
  2973. // Flag, if axis is linked to another axis
  2974. axis.isLinked = defined(options.linkedTo);
  2975. /**
  2976. * List of major ticks mapped by postition on axis.
  2977. *
  2978. * @see {@link Highcharts.Tick}
  2979. *
  2980. * @private
  2981. * @name Highcharts.Axis#ticks
  2982. * @type {Highcharts.Dictionary<Highcharts.Tick>}
  2983. */
  2984. axis.ticks = {};
  2985. axis.labelEdge = [];
  2986. /**
  2987. * List of minor ticks mapped by position on the axis.
  2988. *
  2989. * @see {@link Highcharts.Tick}
  2990. *
  2991. * @private
  2992. * @name Highcharts.Axis#minorTicks
  2993. * @type {Highcharts.Dictionary<Highcharts.Tick>}
  2994. */
  2995. axis.minorTicks = {};
  2996. // List of plotLines/Bands
  2997. axis.plotLinesAndBands = [];
  2998. // Alternate bands
  2999. axis.alternateBands = {};
  3000. // Axis metrics
  3001. axis.len = 0;
  3002. axis.minRange = axis.userMinRange = options.minRange || options.maxZoom;
  3003. axis.range = options.range;
  3004. axis.offset = options.offset || 0;
  3005. // Dictionary for stacks
  3006. axis.stacks = {};
  3007. axis.oldStacks = {};
  3008. axis.stacksTouched = 0;
  3009. /**
  3010. * The maximum value of the axis. In a logarithmic axis, this is the
  3011. * logarithm of the real value, and the real value can be obtained from
  3012. * {@link Axis#getExtremes}.
  3013. *
  3014. * @name Highcharts.Axis#max
  3015. * @type {number|null}
  3016. */
  3017. axis.max = null;
  3018. /**
  3019. * The minimum value of the axis. In a logarithmic axis, this is the
  3020. * logarithm of the real value, and the real value can be obtained from
  3021. * {@link Axis#getExtremes}.
  3022. *
  3023. * @name Highcharts.Axis#min
  3024. * @type {number|null}
  3025. */
  3026. axis.min = null;
  3027. /**
  3028. * The processed crosshair options.
  3029. *
  3030. * @name Highcharts.Axis#crosshair
  3031. * @type {boolean|Highcharts.AxisCrosshairOptions}
  3032. */
  3033. axis.crosshair = pick(
  3034. options.crosshair,
  3035. splat(chart.options.tooltip.crosshairs)[isXAxis ? 0 : 1],
  3036. false
  3037. );
  3038. var events = axis.options.events;
  3039. // Register. Don't add it again on Axis.update().
  3040. if (chart.axes.indexOf(axis) === -1) { //
  3041. if (isXAxis) { // #2713
  3042. chart.axes.splice(chart.xAxis.length, 0, axis);
  3043. } else {
  3044. chart.axes.push(axis);
  3045. }
  3046. chart[axis.coll].push(axis);
  3047. }
  3048. /**
  3049. * All series associated to the axis.
  3050. *
  3051. * @name Highcharts.Axis#series
  3052. * @type {Array<Highcharts.Series>}
  3053. */
  3054. axis.series = axis.series || []; // populated by Series
  3055. // Reversed axis
  3056. if (
  3057. chart.inverted &&
  3058. !axis.isZAxis &&
  3059. isXAxis &&
  3060. axis.reversed === undefined
  3061. ) {
  3062. axis.reversed = true;
  3063. }
  3064. // register event listeners
  3065. objectEach(events, function (event, eventType) {
  3066. addEvent(axis, eventType, event);
  3067. });
  3068. // extend logarithmic axis
  3069. axis.lin2log = options.linearToLogConverter || axis.lin2log;
  3070. if (axis.isLog) {
  3071. axis.val2lin = axis.log2lin;
  3072. axis.lin2val = axis.lin2log;
  3073. }
  3074. fireEvent(this, 'afterInit');
  3075. },
  3076. /**
  3077. * Merge and set options.
  3078. *
  3079. * @private
  3080. * @function Highcharts.Axis#setOptions
  3081. *
  3082. * @param {Highcharts.AxisOptions} userOptions
  3083. *
  3084. * @fires Highcharts.Axis#event:afterSetOptions
  3085. */
  3086. setOptions: function (userOptions) {
  3087. this.options = merge(
  3088. this.defaultOptions,
  3089. this.coll === 'yAxis' && this.defaultYAxisOptions,
  3090. [
  3091. this.defaultTopAxisOptions,
  3092. this.defaultRightAxisOptions,
  3093. this.defaultBottomAxisOptions,
  3094. this.defaultLeftAxisOptions
  3095. ][this.side],
  3096. merge(
  3097. defaultOptions[this.coll], // if set in setOptions (#1053)
  3098. userOptions
  3099. )
  3100. );
  3101. fireEvent(this, 'afterSetOptions', { userOptions: userOptions });
  3102. },
  3103. /**
  3104. * The default label formatter. The context is a special config object for
  3105. * the label. In apps, use the
  3106. * [labels.formatter](https://api.highcharts.com/highcharts/xAxis.labels.formatter)
  3107. * instead except when a modification is needed.
  3108. * @private
  3109. */
  3110. defaultLabelFormatter: function () {
  3111. var axis = this.axis,
  3112. value = this.value,
  3113. time = axis.chart.time,
  3114. categories = axis.categories,
  3115. dateTimeLabelFormat = this.dateTimeLabelFormat,
  3116. lang = defaultOptions.lang,
  3117. numericSymbols = lang.numericSymbols,
  3118. numSymMagnitude = lang.numericSymbolMagnitude || 1000,
  3119. i = numericSymbols && numericSymbols.length,
  3120. multi,
  3121. ret,
  3122. formatOption = axis.options.labels.format,
  3123. // make sure the same symbol is added for all labels on a linear
  3124. // axis
  3125. numericSymbolDetector = axis.isLog ?
  3126. Math.abs(value) :
  3127. axis.tickInterval;
  3128. if (formatOption) {
  3129. ret = format(formatOption, this, time);
  3130. } else if (categories) {
  3131. ret = value;
  3132. } else if (dateTimeLabelFormat) { // datetime axis
  3133. ret = time.dateFormat(dateTimeLabelFormat, value);
  3134. } else if (i && numericSymbolDetector >= 1000) {
  3135. // Decide whether we should add a numeric symbol like k (thousands)
  3136. // or M (millions). If we are to enable this in tooltip or other
  3137. // places as well, we can move this logic to the numberFormatter and
  3138. // enable it by a parameter.
  3139. while (i-- && ret === undefined) {
  3140. multi = Math.pow(numSymMagnitude, i + 1);
  3141. if (
  3142. // Only accept a numeric symbol when the distance is more
  3143. // than a full unit. So for example if the symbol is k, we
  3144. // don't accept numbers like 0.5k.
  3145. numericSymbolDetector >= multi &&
  3146. // Accept one decimal before the symbol. Accepts 0.5k but
  3147. // not 0.25k. How does this work with the previous?
  3148. (value * 10) % multi === 0 &&
  3149. numericSymbols[i] !== null &&
  3150. value !== 0
  3151. ) { // #5480
  3152. ret = H.numberFormat(value / multi, -1) + numericSymbols[i];
  3153. }
  3154. }
  3155. }
  3156. if (ret === undefined) {
  3157. if (Math.abs(value) >= 10000) { // add thousands separators
  3158. ret = H.numberFormat(value, -1);
  3159. } else { // small numbers
  3160. ret = H.numberFormat(value, -1, undefined, ''); // #2466
  3161. }
  3162. }
  3163. return ret;
  3164. },
  3165. /**
  3166. * Get the minimum and maximum for the series of each axis. The function
  3167. * analyzes the axis series and updates `this.dataMin` and `this.dataMax`.
  3168. * @private
  3169. * @fires Highcharts.Axis#event:afterGetSeriesExtremes
  3170. * @fires Highcharts.Axis#event:getSeriesExtremes
  3171. */
  3172. getSeriesExtremes: function () {
  3173. var axis = this,
  3174. chart = axis.chart;
  3175. fireEvent(this, 'getSeriesExtremes', null, function () {
  3176. axis.hasVisibleSeries = false;
  3177. // Reset properties in case we're redrawing (#3353)
  3178. axis.dataMin = axis.dataMax = axis.threshold = null;
  3179. axis.softThreshold = !axis.isXAxis;
  3180. if (axis.buildStacks) {
  3181. axis.buildStacks();
  3182. }
  3183. // loop through this axis' series
  3184. axis.series.forEach(function (series) {
  3185. if (series.visible || !chart.options.chart.ignoreHiddenSeries) {
  3186. var seriesOptions = series.options,
  3187. xData,
  3188. threshold = seriesOptions.threshold,
  3189. seriesDataMin,
  3190. seriesDataMax;
  3191. axis.hasVisibleSeries = true;
  3192. // Validate threshold in logarithmic axes
  3193. if (axis.positiveValuesOnly && threshold <= 0) {
  3194. threshold = null;
  3195. }
  3196. // Get dataMin and dataMax for X axes
  3197. if (axis.isXAxis) {
  3198. xData = series.xData;
  3199. if (xData.length) {
  3200. // If xData contains values which is not numbers,
  3201. // then filter them out. To prevent performance hit,
  3202. // we only do this after we have already found
  3203. // seriesDataMin because in most cases all data is
  3204. // valid. #5234.
  3205. seriesDataMin = arrayMin(xData);
  3206. seriesDataMax = arrayMax(xData);
  3207. if (
  3208. !isNumber(seriesDataMin) &&
  3209. !(seriesDataMin instanceof Date) // #5010
  3210. ) {
  3211. xData = xData.filter(isNumber);
  3212. // Do it again with valid data
  3213. seriesDataMin = arrayMin(xData);
  3214. seriesDataMax = arrayMax(xData);
  3215. }
  3216. if (xData.length) {
  3217. axis.dataMin = Math.min(
  3218. pick(axis.dataMin, xData[0], seriesDataMin),
  3219. seriesDataMin
  3220. );
  3221. axis.dataMax = Math.max(
  3222. pick(axis.dataMax, xData[0], seriesDataMax),
  3223. seriesDataMax
  3224. );
  3225. }
  3226. }
  3227. // Get dataMin and dataMax for Y axes, as well as handle
  3228. // stacking and processed data
  3229. } else {
  3230. // Get this particular series extremes
  3231. series.getExtremes();
  3232. seriesDataMax = series.dataMax;
  3233. seriesDataMin = series.dataMin;
  3234. // Get the dataMin and dataMax so far. If percentage is
  3235. // used, the min and max are always 0 and 100. If
  3236. // seriesDataMin and seriesDataMax is null, then series
  3237. // doesn't have active y data, we continue with nulls
  3238. if (defined(seriesDataMin) && defined(seriesDataMax)) {
  3239. axis.dataMin = Math.min(
  3240. pick(axis.dataMin, seriesDataMin),
  3241. seriesDataMin
  3242. );
  3243. axis.dataMax = Math.max(
  3244. pick(axis.dataMax, seriesDataMax),
  3245. seriesDataMax
  3246. );
  3247. }
  3248. // Adjust to threshold
  3249. if (defined(threshold)) {
  3250. axis.threshold = threshold;
  3251. }
  3252. // If any series has a hard threshold, it takes
  3253. // precedence
  3254. if (
  3255. !seriesOptions.softThreshold ||
  3256. axis.positiveValuesOnly
  3257. ) {
  3258. axis.softThreshold = false;
  3259. }
  3260. }
  3261. }
  3262. });
  3263. });
  3264. fireEvent(this, 'afterGetSeriesExtremes');
  3265. },
  3266. /**
  3267. * Translate from axis value to pixel position on the chart, or back. Use
  3268. * the `toPixels` and `toValue` functions in applications.
  3269. * @private
  3270. */
  3271. translate: function (
  3272. val,
  3273. backwards,
  3274. cvsCoord,
  3275. old,
  3276. handleLog,
  3277. pointPlacement
  3278. ) {
  3279. var axis = this.linkedParent || this, // #1417
  3280. sign = 1,
  3281. cvsOffset = 0,
  3282. localA = old ? axis.oldTransA : axis.transA,
  3283. localMin = old ? axis.oldMin : axis.min,
  3284. returnValue,
  3285. minPixelPadding = axis.minPixelPadding,
  3286. doPostTranslate = (
  3287. axis.isOrdinal ||
  3288. axis.isBroken ||
  3289. (axis.isLog && handleLog)
  3290. ) && axis.lin2val;
  3291. if (!localA) {
  3292. localA = axis.transA;
  3293. }
  3294. // In vertical axes, the canvas coordinates start from 0 at the top like
  3295. // in SVG.
  3296. if (cvsCoord) {
  3297. sign *= -1; // canvas coordinates inverts the value
  3298. cvsOffset = axis.len;
  3299. }
  3300. // Handle reversed axis
  3301. if (axis.reversed) {
  3302. sign *= -1;
  3303. cvsOffset -= sign * (axis.sector || axis.len);
  3304. }
  3305. // From pixels to value
  3306. if (backwards) { // reverse translation
  3307. val = val * sign + cvsOffset;
  3308. val -= minPixelPadding;
  3309. returnValue = val / localA + localMin; // from chart pixel to value
  3310. if (doPostTranslate) { // log and ordinal axes
  3311. returnValue = axis.lin2val(returnValue);
  3312. }
  3313. // From value to pixels
  3314. } else {
  3315. if (doPostTranslate) { // log and ordinal axes
  3316. val = axis.val2lin(val);
  3317. }
  3318. returnValue = isNumber(localMin) ?
  3319. (
  3320. sign * (val - localMin) * localA +
  3321. cvsOffset +
  3322. (sign * minPixelPadding) +
  3323. (isNumber(pointPlacement) ? localA * pointPlacement : 0)
  3324. ) :
  3325. undefined;
  3326. }
  3327. return returnValue;
  3328. },
  3329. /**
  3330. * Translate a value in terms of axis units into pixels within the chart.
  3331. *
  3332. * @function Highcharts.Axis#toPixels
  3333. *
  3334. * @param {number} value
  3335. * A value in terms of axis units.
  3336. *
  3337. * @param {boolean} paneCoordinates
  3338. * Whether to return the pixel coordinate relative to the chart or
  3339. * just the axis/pane itself.
  3340. *
  3341. * @return {number}
  3342. * Pixel position of the value on the chart or axis.
  3343. */
  3344. toPixels: function (value, paneCoordinates) {
  3345. return this.translate(value, false, !this.horiz, null, true) +
  3346. (paneCoordinates ? 0 : this.pos);
  3347. },
  3348. /**
  3349. * Translate a pixel position along the axis to a value in terms of axis
  3350. * units.
  3351. *
  3352. * @function Highcharts.Axis#toValue
  3353. *
  3354. * @param {number} pixel
  3355. * The pixel value coordinate.
  3356. *
  3357. * @param {boolean} paneCoordiantes
  3358. * Whether the input pixel is relative to the chart or just the
  3359. * axis/pane itself.
  3360. *
  3361. * @return {number}
  3362. * The axis value.
  3363. */
  3364. toValue: function (pixel, paneCoordinates) {
  3365. return this.translate(
  3366. pixel - (paneCoordinates ? 0 : this.pos),
  3367. true,
  3368. !this.horiz,
  3369. null,
  3370. true
  3371. );
  3372. },
  3373. /**
  3374. * Create the path for a plot line that goes from the given value on
  3375. * this axis, across the plot to the opposite side. Also used internally for
  3376. * grid lines and crosshairs.
  3377. *
  3378. * @function Highcharts.Axis#getPlotLinePath
  3379. *
  3380. * @param {number} value
  3381. * Axis value.
  3382. *
  3383. * @param {number} [lineWidth=1]
  3384. * Used for calculation crisp line coordinates.
  3385. *
  3386. * @param {boolean} [old=false]
  3387. * Use old coordinates (for resizing and rescaling).
  3388. *
  3389. * @param {boolean|string} [force=false]
  3390. * If `false`, the function will return null when it falls outside
  3391. * the axis bounds. If `true`, the function will return a path
  3392. * aligned to the plot area sides if it falls outside. If `pass`, it
  3393. * will return a path outside.
  3394. *
  3395. * @param {number} [translatedValue]
  3396. * If given, return the plot line path of a pixel position on the
  3397. * axis.
  3398. *
  3399. * @return {Array<string|number>}
  3400. * The SVG path definition for the plot line.
  3401. */
  3402. getPlotLinePath: function (value, lineWidth, old, force, translatedValue) {
  3403. var axis = this,
  3404. chart = axis.chart,
  3405. axisLeft = axis.left,
  3406. axisTop = axis.top,
  3407. x1,
  3408. y1,
  3409. x2,
  3410. y2,
  3411. cHeight = (old && chart.oldChartHeight) || chart.chartHeight,
  3412. cWidth = (old && chart.oldChartWidth) || chart.chartWidth,
  3413. skip,
  3414. transB = axis.transB,
  3415. evt,
  3416. /**
  3417. * Check if x is between a and b. If not, either move to a/b
  3418. * or skip, depending on the force parameter.
  3419. */
  3420. between = function (x, a, b) {
  3421. if (force !== 'pass' && x < a || x > b) {
  3422. if (force) {
  3423. x = Math.min(Math.max(a, x), b);
  3424. } else {
  3425. skip = true;
  3426. }
  3427. }
  3428. return x;
  3429. };
  3430. evt = {
  3431. value: value,
  3432. lineWidth: lineWidth,
  3433. old: old,
  3434. force: force,
  3435. translatedValue: translatedValue
  3436. };
  3437. fireEvent(this, 'getPlotLinePath', evt, function (e) {
  3438. translatedValue = pick(
  3439. translatedValue,
  3440. axis.translate(value, null, null, old)
  3441. );
  3442. // Keep the translated value within sane bounds, and avoid Infinity
  3443. // to fail the isNumber test (#7709).
  3444. translatedValue = Math.min(Math.max(-1e5, translatedValue), 1e5);
  3445. x1 = x2 = Math.round(translatedValue + transB);
  3446. y1 = y2 = Math.round(cHeight - translatedValue - transB);
  3447. if (!isNumber(translatedValue)) { // no min or max
  3448. skip = true;
  3449. force = false; // #7175, don't force it when path is invalid
  3450. } else if (axis.horiz) {
  3451. y1 = axisTop;
  3452. y2 = cHeight - axis.bottom;
  3453. x1 = x2 = between(x1, axisLeft, axisLeft + axis.width);
  3454. } else {
  3455. x1 = axisLeft;
  3456. x2 = cWidth - axis.right;
  3457. y1 = y2 = between(y1, axisTop, axisTop + axis.height);
  3458. }
  3459. e.path = skip && !force ?
  3460. null :
  3461. chart.renderer.crispLine(
  3462. ['M', x1, y1, 'L', x2, y2],
  3463. lineWidth || 1
  3464. );
  3465. });
  3466. return evt.path;
  3467. },
  3468. /**
  3469. * Internal function to et the tick positions of a linear axis to round
  3470. * values like whole tens or every five.
  3471. *
  3472. * @function Highcharts.Axis#getLinearTickPositions
  3473. *
  3474. * @param {number} tickInterval
  3475. * The normalized tick interval.
  3476. *
  3477. * @param {number} min
  3478. * Axis minimum.
  3479. *
  3480. * @param {number} max
  3481. * Axis maximum.
  3482. *
  3483. * @return {Array<number>}
  3484. * An array of axis values where ticks should be placed.
  3485. */
  3486. getLinearTickPositions: function (tickInterval, min, max) {
  3487. var pos,
  3488. lastPos,
  3489. roundedMin =
  3490. correctFloat(Math.floor(min / tickInterval) * tickInterval),
  3491. roundedMax =
  3492. correctFloat(Math.ceil(max / tickInterval) * tickInterval),
  3493. tickPositions = [],
  3494. precision;
  3495. // When the precision is higher than what we filter out in
  3496. // correctFloat, skip it (#6183).
  3497. if (correctFloat(roundedMin + tickInterval) === roundedMin) {
  3498. precision = 20;
  3499. }
  3500. // For single points, add a tick regardless of the relative position
  3501. // (#2662, #6274)
  3502. if (this.single) {
  3503. return [min];
  3504. }
  3505. // Populate the intermediate values
  3506. pos = roundedMin;
  3507. while (pos <= roundedMax) {
  3508. // Place the tick on the rounded value
  3509. tickPositions.push(pos);
  3510. // Always add the raw tickInterval, not the corrected one.
  3511. pos = correctFloat(
  3512. pos + tickInterval,
  3513. precision
  3514. );
  3515. // If the interval is not big enough in the current min - max range
  3516. // to actually increase the loop variable, we need to break out to
  3517. // prevent endless loop. Issue #619
  3518. if (pos === lastPos) {
  3519. break;
  3520. }
  3521. // Record the last value
  3522. lastPos = pos;
  3523. }
  3524. return tickPositions;
  3525. },
  3526. /**
  3527. * Resolve the new minorTicks/minorTickInterval options into the legacy
  3528. * loosely typed minorTickInterval option.
  3529. *
  3530. * @function Highcharts.Axis#getMinorTickInterval
  3531. *
  3532. * @return {number|"auto"|null}
  3533. */
  3534. getMinorTickInterval: function () {
  3535. var options = this.options;
  3536. if (options.minorTicks === true) {
  3537. return pick(options.minorTickInterval, 'auto');
  3538. }
  3539. if (options.minorTicks === false) {
  3540. return null;
  3541. }
  3542. return options.minorTickInterval;
  3543. },
  3544. /**
  3545. * Internal function to return the minor tick positions. For logarithmic
  3546. * axes, the same logic as for major ticks is reused.
  3547. *
  3548. * @function Highcharts.Axis#getMinorTickPositions
  3549. *
  3550. * @return {Array<number>}
  3551. * An array of axis values where ticks should be placed.
  3552. */
  3553. getMinorTickPositions: function () {
  3554. var axis = this,
  3555. options = axis.options,
  3556. tickPositions = axis.tickPositions,
  3557. minorTickInterval = axis.minorTickInterval,
  3558. minorTickPositions = [],
  3559. pos,
  3560. pointRangePadding = axis.pointRangePadding || 0,
  3561. min = axis.min - pointRangePadding, // #1498
  3562. max = axis.max + pointRangePadding, // #1498
  3563. range = max - min;
  3564. // If minor ticks get too dense, they are hard to read, and may cause
  3565. // long running script. So we don't draw them.
  3566. if (range && range / minorTickInterval < axis.len / 3) { // #3875
  3567. if (axis.isLog) {
  3568. // For each interval in the major ticks, compute the minor ticks
  3569. // separately.
  3570. this.paddedTicks.forEach(function (pos, i, paddedTicks) {
  3571. if (i) {
  3572. minorTickPositions.push.apply(
  3573. minorTickPositions,
  3574. axis.getLogTickPositions(
  3575. minorTickInterval,
  3576. paddedTicks[i - 1],
  3577. paddedTicks[i],
  3578. true
  3579. )
  3580. );
  3581. }
  3582. });
  3583. } else if (
  3584. axis.isDatetimeAxis &&
  3585. this.getMinorTickInterval() === 'auto'
  3586. ) { // #1314
  3587. minorTickPositions = minorTickPositions.concat(
  3588. axis.getTimeTicks(
  3589. axis.normalizeTimeTickInterval(minorTickInterval),
  3590. min,
  3591. max,
  3592. options.startOfWeek
  3593. )
  3594. );
  3595. } else {
  3596. for (
  3597. pos = min + (tickPositions[0] - min) % minorTickInterval;
  3598. pos <= max;
  3599. pos += minorTickInterval
  3600. ) {
  3601. // Very, very, tight grid lines (#5771)
  3602. if (pos === minorTickPositions[0]) {
  3603. break;
  3604. }
  3605. minorTickPositions.push(pos);
  3606. }
  3607. }
  3608. }
  3609. if (minorTickPositions.length !== 0) {
  3610. axis.trimTicks(minorTickPositions); // #3652 #3743 #1498 #6330
  3611. }
  3612. return minorTickPositions;
  3613. },
  3614. /**
  3615. * Adjust the min and max for the minimum range. Keep in mind that the
  3616. * series data is not yet processed, so we don't have information on data
  3617. * cropping and grouping, or updated `axis.pointRange` or
  3618. * `series.pointRange`. The data can't be processed until we have finally
  3619. * established min and max.
  3620. * @private
  3621. */
  3622. adjustForMinRange: function () {
  3623. var axis = this,
  3624. options = axis.options,
  3625. min = axis.min,
  3626. max = axis.max,
  3627. zoomOffset,
  3628. spaceAvailable,
  3629. closestDataRange,
  3630. i,
  3631. distance,
  3632. xData,
  3633. loopLength,
  3634. minArgs,
  3635. maxArgs,
  3636. minRange;
  3637. // Set the automatic minimum range based on the closest point distance
  3638. if (axis.isXAxis && axis.minRange === undefined && !axis.isLog) {
  3639. if (defined(options.min) || defined(options.max)) {
  3640. axis.minRange = null; // don't do this again
  3641. } else {
  3642. // Find the closest distance between raw data points, as opposed
  3643. // to closestPointRange that applies to processed points
  3644. // (cropped and grouped)
  3645. axis.series.forEach(function (series) {
  3646. xData = series.xData;
  3647. loopLength = series.xIncrement ? 1 : xData.length - 1;
  3648. for (i = loopLength; i > 0; i--) {
  3649. distance = xData[i] - xData[i - 1];
  3650. if (
  3651. closestDataRange === undefined ||
  3652. distance < closestDataRange
  3653. ) {
  3654. closestDataRange = distance;
  3655. }
  3656. }
  3657. });
  3658. axis.minRange = Math.min(
  3659. closestDataRange * 5,
  3660. axis.dataMax - axis.dataMin
  3661. );
  3662. }
  3663. }
  3664. // if minRange is exceeded, adjust
  3665. if (max - min < axis.minRange) {
  3666. spaceAvailable = axis.dataMax - axis.dataMin >= axis.minRange;
  3667. minRange = axis.minRange;
  3668. zoomOffset = (minRange - max + min) / 2;
  3669. // if min and max options have been set, don't go beyond it
  3670. minArgs = [min - zoomOffset, pick(options.min, min - zoomOffset)];
  3671. // If space is available, stay within the data range
  3672. if (spaceAvailable) {
  3673. minArgs[2] = axis.isLog ?
  3674. axis.log2lin(axis.dataMin) :
  3675. axis.dataMin;
  3676. }
  3677. min = arrayMax(minArgs);
  3678. maxArgs = [min + minRange, pick(options.max, min + minRange)];
  3679. // If space is availabe, stay within the data range
  3680. if (spaceAvailable) {
  3681. maxArgs[2] = axis.isLog ?
  3682. axis.log2lin(axis.dataMax) :
  3683. axis.dataMax;
  3684. }
  3685. max = arrayMin(maxArgs);
  3686. // now if the max is adjusted, adjust the min back
  3687. if (max - min < minRange) {
  3688. minArgs[0] = max - minRange;
  3689. minArgs[1] = pick(options.min, max - minRange);
  3690. min = arrayMax(minArgs);
  3691. }
  3692. }
  3693. // Record modified extremes
  3694. axis.min = min;
  3695. axis.max = max;
  3696. },
  3697. // Find the closestPointRange across all series.
  3698. getClosest: function () {
  3699. var ret;
  3700. if (this.categories) {
  3701. ret = 1;
  3702. } else {
  3703. this.series.forEach(function (series) {
  3704. var seriesClosest = series.closestPointRange,
  3705. visible = series.visible ||
  3706. !series.chart.options.chart.ignoreHiddenSeries;
  3707. if (
  3708. !series.noSharedTooltip &&
  3709. defined(seriesClosest) &&
  3710. visible
  3711. ) {
  3712. ret = defined(ret) ?
  3713. Math.min(ret, seriesClosest) :
  3714. seriesClosest;
  3715. }
  3716. });
  3717. }
  3718. return ret;
  3719. },
  3720. /**
  3721. * When a point name is given and no x, search for the name in the existing
  3722. * categories, or if categories aren't provided, search names or create a
  3723. * new category (#2522).
  3724. * @private
  3725. * @param {Highcharts.Point} point The point to inspect.
  3726. * @return {number} The X value that the point is given.
  3727. */
  3728. nameToX: function (point) {
  3729. var explicitCategories = isArray(this.categories),
  3730. names = explicitCategories ? this.categories : this.names,
  3731. nameX = point.options.x,
  3732. x;
  3733. point.series.requireSorting = false;
  3734. if (!defined(nameX)) {
  3735. nameX = this.options.uniqueNames === false ?
  3736. point.series.autoIncrement() :
  3737. (
  3738. explicitCategories ?
  3739. names.indexOf(point.name) :
  3740. pick(names.keys[point.name], -1)
  3741. );
  3742. }
  3743. if (nameX === -1) { // Not found in currenct categories
  3744. if (!explicitCategories) {
  3745. x = names.length;
  3746. }
  3747. } else {
  3748. x = nameX;
  3749. }
  3750. // Write the last point's name to the names array
  3751. if (x !== undefined) {
  3752. this.names[x] = point.name;
  3753. // Backwards mapping is much faster than array searching (#7725)
  3754. this.names.keys[point.name] = x;
  3755. }
  3756. return x;
  3757. },
  3758. // When changes have been done to series data, update the axis.names.
  3759. updateNames: function () {
  3760. var axis = this,
  3761. names = this.names,
  3762. i = names.length;
  3763. if (i > 0) {
  3764. Object.keys(names.keys).forEach(function (key) {
  3765. delete names.keys[key];
  3766. });
  3767. names.length = 0;
  3768. this.minRange = this.userMinRange; // Reset
  3769. (this.series || []).forEach(function (series) {
  3770. // Reset incrementer (#5928)
  3771. series.xIncrement = null;
  3772. // When adding a series, points are not yet generated
  3773. if (!series.points || series.isDirtyData) {
  3774. // When we're updating the series with data that is longer
  3775. // than it was, and cropThreshold is passed, we need to make
  3776. // sure that the axis.max is increased _before_ running the
  3777. // premature processData. Otherwise this early iteration of
  3778. // processData will crop the points to axis.max, and the
  3779. // names array will be too short (#5857).
  3780. axis.max = Math.max(axis.max, series.xData.length - 1);
  3781. series.processData();
  3782. series.generatePoints();
  3783. }
  3784. series.data.forEach(function (point, i) { // #9487
  3785. var x;
  3786. if (
  3787. point &&
  3788. point.options &&
  3789. point.name !== undefined // #9562
  3790. ) {
  3791. x = axis.nameToX(point);
  3792. if (x !== undefined && x !== point.x) {
  3793. point.x = x;
  3794. series.xData[i] = x;
  3795. }
  3796. }
  3797. });
  3798. });
  3799. }
  3800. },
  3801. /**
  3802. * Update translation information.
  3803. * @private
  3804. * @param {boolean} saveOld
  3805. * @fires Highcharts.Axis#event:afterSetAxisTranslation
  3806. */
  3807. setAxisTranslation: function (saveOld) {
  3808. var axis = this,
  3809. range = axis.max - axis.min,
  3810. pointRange = axis.axisPointRange || 0,
  3811. closestPointRange,
  3812. minPointOffset = 0,
  3813. pointRangePadding = 0,
  3814. linkedParent = axis.linkedParent,
  3815. ordinalCorrection,
  3816. hasCategories = !!axis.categories,
  3817. transA = axis.transA,
  3818. isXAxis = axis.isXAxis;
  3819. // Adjust translation for padding. Y axis with categories need to go
  3820. // through the same (#1784).
  3821. if (isXAxis || hasCategories || pointRange) {
  3822. // Get the closest points
  3823. closestPointRange = axis.getClosest();
  3824. if (linkedParent) {
  3825. minPointOffset = linkedParent.minPointOffset;
  3826. pointRangePadding = linkedParent.pointRangePadding;
  3827. } else {
  3828. axis.series.forEach(function (series) {
  3829. var seriesPointRange = hasCategories ?
  3830. 1 :
  3831. (
  3832. isXAxis ?
  3833. pick(
  3834. series.options.pointRange,
  3835. closestPointRange,
  3836. 0
  3837. ) :
  3838. (axis.axisPointRange || 0)
  3839. ), // #2806
  3840. pointPlacement = series.options.pointPlacement;
  3841. pointRange = Math.max(pointRange, seriesPointRange);
  3842. if (!axis.single) {
  3843. // minPointOffset is the value padding to the left of
  3844. // the axis in order to make room for points with a
  3845. // pointRange, typically columns. When the
  3846. // pointPlacement option is 'between' or 'on', this
  3847. // padding does not apply.
  3848. minPointOffset = Math.max(
  3849. minPointOffset,
  3850. isXAxis && isString(pointPlacement) ?
  3851. 0 : seriesPointRange / 2
  3852. );
  3853. // Determine the total padding needed to the length of
  3854. // the axis to make room for the pointRange. If the
  3855. // series' pointPlacement is 'on', no padding is added.
  3856. pointRangePadding = Math.max(
  3857. pointRangePadding,
  3858. isXAxis && pointPlacement === 'on' ?
  3859. 0 : seriesPointRange
  3860. );
  3861. }
  3862. });
  3863. }
  3864. // Record minPointOffset and pointRangePadding
  3865. ordinalCorrection = axis.ordinalSlope && closestPointRange ?
  3866. axis.ordinalSlope / closestPointRange :
  3867. 1; // #988, #1853
  3868. axis.minPointOffset = minPointOffset =
  3869. minPointOffset * ordinalCorrection;
  3870. axis.pointRangePadding =
  3871. pointRangePadding = pointRangePadding * ordinalCorrection;
  3872. // pointRange means the width reserved for each point, like in a
  3873. // column chart
  3874. axis.pointRange = Math.min(pointRange, range);
  3875. // closestPointRange means the closest distance between points. In
  3876. // columns it is mostly equal to pointRange, but in lines pointRange
  3877. // is 0 while closestPointRange is some other value
  3878. if (isXAxis) {
  3879. axis.closestPointRange = closestPointRange;
  3880. }
  3881. }
  3882. // Secondary values
  3883. if (saveOld) {
  3884. axis.oldTransA = transA;
  3885. }
  3886. axis.translationSlope = axis.transA = transA =
  3887. axis.staticScale ||
  3888. axis.len / ((range + pointRangePadding) || 1);
  3889. // Translation addend
  3890. axis.transB = axis.horiz ? axis.left : axis.bottom;
  3891. axis.minPixelPadding = transA * minPointOffset;
  3892. fireEvent(this, 'afterSetAxisTranslation');
  3893. },
  3894. minFromRange: function () {
  3895. return this.max - this.range;
  3896. },
  3897. /**
  3898. * Set the tick positions to round values and optionally extend the extremes
  3899. * to the nearest tick.
  3900. * @private
  3901. * @param {boolean} secondPass
  3902. * @fires Highcharts.Axis#event:foundExtremes
  3903. */
  3904. setTickInterval: function (secondPass) {
  3905. var axis = this,
  3906. chart = axis.chart,
  3907. options = axis.options,
  3908. isLog = axis.isLog,
  3909. isDatetimeAxis = axis.isDatetimeAxis,
  3910. isXAxis = axis.isXAxis,
  3911. isLinked = axis.isLinked,
  3912. maxPadding = options.maxPadding,
  3913. minPadding = options.minPadding,
  3914. length,
  3915. linkedParentExtremes,
  3916. tickIntervalOption = options.tickInterval,
  3917. minTickInterval,
  3918. tickPixelIntervalOption = options.tickPixelInterval,
  3919. categories = axis.categories,
  3920. threshold = isNumber(axis.threshold) ? axis.threshold : null,
  3921. softThreshold = axis.softThreshold,
  3922. thresholdMin,
  3923. thresholdMax,
  3924. hardMin,
  3925. hardMax;
  3926. if (!isDatetimeAxis && !categories && !isLinked) {
  3927. this.getTickAmount();
  3928. }
  3929. // Min or max set either by zooming/setExtremes or initial options
  3930. hardMin = pick(axis.userMin, options.min);
  3931. hardMax = pick(axis.userMax, options.max);
  3932. // Linked axis gets the extremes from the parent axis
  3933. if (isLinked) {
  3934. axis.linkedParent = chart[axis.coll][options.linkedTo];
  3935. linkedParentExtremes = axis.linkedParent.getExtremes();
  3936. axis.min = pick(
  3937. linkedParentExtremes.min,
  3938. linkedParentExtremes.dataMin
  3939. );
  3940. axis.max = pick(
  3941. linkedParentExtremes.max,
  3942. linkedParentExtremes.dataMax
  3943. );
  3944. if (options.type !== axis.linkedParent.options.type) {
  3945. H.error(11, 1, chart); // Can't link axes of different type
  3946. }
  3947. // Initial min and max from the extreme data values
  3948. } else {
  3949. // Adjust to hard threshold
  3950. if (!softThreshold && defined(threshold)) {
  3951. if (axis.dataMin >= threshold) {
  3952. thresholdMin = threshold;
  3953. minPadding = 0;
  3954. } else if (axis.dataMax <= threshold) {
  3955. thresholdMax = threshold;
  3956. maxPadding = 0;
  3957. }
  3958. }
  3959. axis.min = pick(hardMin, thresholdMin, axis.dataMin);
  3960. axis.max = pick(hardMax, thresholdMax, axis.dataMax);
  3961. }
  3962. if (isLog) {
  3963. if (
  3964. axis.positiveValuesOnly &&
  3965. !secondPass &&
  3966. Math.min(axis.min, pick(axis.dataMin, axis.min)) <= 0
  3967. ) { // #978
  3968. H.error(10, 1, chart); // Can't plot negative values on log axis
  3969. }
  3970. // The correctFloat cures #934, float errors on full tens. But it
  3971. // was too aggressive for #4360 because of conversion back to lin,
  3972. // therefore use precision 15.
  3973. axis.min = correctFloat(axis.log2lin(axis.min), 15);
  3974. axis.max = correctFloat(axis.log2lin(axis.max), 15);
  3975. }
  3976. // handle zoomed range
  3977. if (axis.range && defined(axis.max)) {
  3978. axis.userMin = axis.min = hardMin =
  3979. Math.max(axis.dataMin, axis.minFromRange()); // #618, #6773
  3980. axis.userMax = hardMax = axis.max;
  3981. axis.range = null; // don't use it when running setExtremes
  3982. }
  3983. // Hook for Highstock Scroller. Consider combining with beforePadding.
  3984. fireEvent(axis, 'foundExtremes');
  3985. // Hook for adjusting this.min and this.max. Used by bubble series.
  3986. if (axis.beforePadding) {
  3987. axis.beforePadding();
  3988. }
  3989. // adjust min and max for the minimum range
  3990. axis.adjustForMinRange();
  3991. // Pad the values to get clear of the chart's edges. To avoid
  3992. // tickInterval taking the padding into account, we do this after
  3993. // computing tick interval (#1337).
  3994. if (
  3995. !categories &&
  3996. !axis.axisPointRange &&
  3997. !axis.usePercentage &&
  3998. !isLinked &&
  3999. defined(axis.min) &&
  4000. defined(axis.max)
  4001. ) {
  4002. length = axis.max - axis.min;
  4003. if (length) {
  4004. if (!defined(hardMin) && minPadding) {
  4005. axis.min -= length * minPadding;
  4006. }
  4007. if (!defined(hardMax) && maxPadding) {
  4008. axis.max += length * maxPadding;
  4009. }
  4010. }
  4011. }
  4012. // Handle options for floor, ceiling, softMin and softMax (#6359)
  4013. if (isNumber(options.softMin) && !isNumber(axis.userMin)) {
  4014. axis.min = Math.min(axis.min, options.softMin);
  4015. }
  4016. if (isNumber(options.softMax) && !isNumber(axis.userMax)) {
  4017. axis.max = Math.max(axis.max, options.softMax);
  4018. }
  4019. if (isNumber(options.floor)) {
  4020. axis.min = Math.min(
  4021. Math.max(axis.min, options.floor),
  4022. Number.MAX_VALUE
  4023. );
  4024. }
  4025. if (isNumber(options.ceiling)) {
  4026. axis.max = Math.max(
  4027. Math.min(axis.max, options.ceiling),
  4028. pick(axis.userMax, -Number.MAX_VALUE)
  4029. );
  4030. }
  4031. // When the threshold is soft, adjust the extreme value only if the data
  4032. // extreme and the padded extreme land on either side of the threshold.
  4033. // For example, a series of [0, 1, 2, 3] would make the yAxis add a tick
  4034. // for -1 because of the default minPadding and startOnTick options.
  4035. // This is prevented by the softThreshold option.
  4036. if (softThreshold && defined(axis.dataMin)) {
  4037. threshold = threshold || 0;
  4038. if (
  4039. !defined(hardMin) &&
  4040. axis.min < threshold &&
  4041. axis.dataMin >= threshold
  4042. ) {
  4043. axis.min = threshold;
  4044. } else if (
  4045. !defined(hardMax) &&
  4046. axis.max > threshold &&
  4047. axis.dataMax <= threshold
  4048. ) {
  4049. axis.max = threshold;
  4050. }
  4051. }
  4052. // get tickInterval
  4053. if (
  4054. axis.min === axis.max ||
  4055. axis.min === undefined ||
  4056. axis.max === undefined
  4057. ) {
  4058. axis.tickInterval = 1;
  4059. } else if (
  4060. isLinked &&
  4061. !tickIntervalOption &&
  4062. tickPixelIntervalOption ===
  4063. axis.linkedParent.options.tickPixelInterval
  4064. ) {
  4065. axis.tickInterval = tickIntervalOption =
  4066. axis.linkedParent.tickInterval;
  4067. } else {
  4068. axis.tickInterval = pick(
  4069. tickIntervalOption,
  4070. this.tickAmount ?
  4071. ((axis.max - axis.min) / Math.max(this.tickAmount - 1, 1)) :
  4072. undefined,
  4073. // For categoried axis, 1 is default, for linear axis use
  4074. // tickPix
  4075. categories ?
  4076. 1 :
  4077. // don't let it be more than the data range
  4078. (axis.max - axis.min) * tickPixelIntervalOption /
  4079. Math.max(axis.len, tickPixelIntervalOption)
  4080. );
  4081. }
  4082. // Now we're finished detecting min and max, crop and group series data.
  4083. // This is in turn needed in order to find tick positions in ordinal
  4084. // axes.
  4085. if (isXAxis && !secondPass) {
  4086. axis.series.forEach(function (series) {
  4087. series.processData(
  4088. axis.min !== axis.oldMin || axis.max !== axis.oldMax
  4089. );
  4090. });
  4091. }
  4092. // set the translation factor used in translate function
  4093. axis.setAxisTranslation(true);
  4094. // hook for ordinal axes and radial axes
  4095. if (axis.beforeSetTickPositions) {
  4096. axis.beforeSetTickPositions();
  4097. }
  4098. // hook for extensions, used in Highstock ordinal axes
  4099. if (axis.postProcessTickInterval) {
  4100. axis.tickInterval = axis.postProcessTickInterval(axis.tickInterval);
  4101. }
  4102. // In column-like charts, don't cramp in more ticks than there are
  4103. // points (#1943, #4184)
  4104. if (axis.pointRange && !tickIntervalOption) {
  4105. axis.tickInterval = Math.max(axis.pointRange, axis.tickInterval);
  4106. }
  4107. // Before normalizing the tick interval, handle minimum tick interval.
  4108. // This applies only if tickInterval is not defined.
  4109. minTickInterval = pick(
  4110. options.minTickInterval,
  4111. axis.isDatetimeAxis && axis.closestPointRange
  4112. );
  4113. if (!tickIntervalOption && axis.tickInterval < minTickInterval) {
  4114. axis.tickInterval = minTickInterval;
  4115. }
  4116. // for linear axes, get magnitude and normalize the interval
  4117. if (!isDatetimeAxis && !isLog && !tickIntervalOption) {
  4118. axis.tickInterval = normalizeTickInterval(
  4119. axis.tickInterval,
  4120. null,
  4121. getMagnitude(axis.tickInterval),
  4122. // If the tick interval is between 0.5 and 5 and the axis max is
  4123. // in the order of thousands, chances are we are dealing with
  4124. // years. Don't allow decimals. #3363.
  4125. pick(
  4126. options.allowDecimals,
  4127. !(
  4128. axis.tickInterval > 0.5 &&
  4129. axis.tickInterval < 5 &&
  4130. axis.max > 1000 &&
  4131. axis.max < 9999
  4132. )
  4133. ),
  4134. !!this.tickAmount
  4135. );
  4136. }
  4137. // Prevent ticks from getting so close that we can't draw the labels
  4138. if (!this.tickAmount) {
  4139. axis.tickInterval = axis.unsquish();
  4140. }
  4141. this.setTickPositions();
  4142. },
  4143. /**
  4144. * Now we have computed the normalized tickInterval, get the tick positions
  4145. *
  4146. * @function Highcharts.Axis#setTickPositions
  4147. *
  4148. * @fires Highcharts.Axis#event:afterSetTickPositions
  4149. */
  4150. setTickPositions: function () {
  4151. var options = this.options,
  4152. tickPositions,
  4153. tickPositionsOption = options.tickPositions,
  4154. minorTickIntervalOption = this.getMinorTickInterval(),
  4155. tickPositioner = options.tickPositioner,
  4156. startOnTick = options.startOnTick,
  4157. endOnTick = options.endOnTick;
  4158. // Set the tickmarkOffset
  4159. this.tickmarkOffset = (
  4160. this.categories &&
  4161. options.tickmarkPlacement === 'between' &&
  4162. this.tickInterval === 1
  4163. ) ? 0.5 : 0; // #3202
  4164. // get minorTickInterval
  4165. this.minorTickInterval =
  4166. minorTickIntervalOption === 'auto' &&
  4167. this.tickInterval ?
  4168. this.tickInterval / 5 :
  4169. minorTickIntervalOption;
  4170. // When there is only one point, or all points have the same value on
  4171. // this axis, then min and max are equal and tickPositions.length is 0
  4172. // or 1. In this case, add some padding in order to center the point,
  4173. // but leave it with one tick. #1337.
  4174. this.single =
  4175. this.min === this.max &&
  4176. defined(this.min) &&
  4177. !this.tickAmount &&
  4178. (
  4179. // Data is on integer (#6563)
  4180. parseInt(this.min, 10) === this.min ||
  4181. // Between integers and decimals are not allowed (#6274)
  4182. options.allowDecimals !== false
  4183. );
  4184. // Find the tick positions. Work on a copy (#1565)
  4185. this.tickPositions = tickPositions =
  4186. tickPositionsOption && tickPositionsOption.slice();
  4187. if (!tickPositions) {
  4188. // Too many ticks (#6405). Create a friendly warning and provide two
  4189. // ticks so at least we can show the data series.
  4190. if (
  4191. !this.ordinalPositions &&
  4192. (
  4193. (this.max - this.min) / this.tickInterval >
  4194. Math.max(2 * this.len, 200)
  4195. )
  4196. ) {
  4197. tickPositions = [this.min, this.max];
  4198. H.error(19, false, this.chart);
  4199. } else if (this.isDatetimeAxis) {
  4200. tickPositions = this.getTimeTicks(
  4201. this.normalizeTimeTickInterval(
  4202. this.tickInterval,
  4203. options.units
  4204. ),
  4205. this.min,
  4206. this.max,
  4207. options.startOfWeek,
  4208. this.ordinalPositions,
  4209. this.closestPointRange,
  4210. true
  4211. );
  4212. } else if (this.isLog) {
  4213. tickPositions = this.getLogTickPositions(
  4214. this.tickInterval,
  4215. this.min,
  4216. this.max
  4217. );
  4218. } else {
  4219. tickPositions = this.getLinearTickPositions(
  4220. this.tickInterval,
  4221. this.min,
  4222. this.max
  4223. );
  4224. }
  4225. // Too dense ticks, keep only the first and last (#4477)
  4226. if (tickPositions.length > this.len) {
  4227. tickPositions = [tickPositions[0], tickPositions.pop()];
  4228. // Reduce doubled value (#7339)
  4229. if (tickPositions[0] === tickPositions[1]) {
  4230. tickPositions.length = 1;
  4231. }
  4232. }
  4233. this.tickPositions = tickPositions;
  4234. // Run the tick positioner callback, that allows modifying auto tick
  4235. // positions.
  4236. if (tickPositioner) {
  4237. tickPositioner = tickPositioner.apply(
  4238. this,
  4239. [this.min, this.max]
  4240. );
  4241. if (tickPositioner) {
  4242. this.tickPositions = tickPositions = tickPositioner;
  4243. }
  4244. }
  4245. }
  4246. // Reset min/max or remove extremes based on start/end on tick
  4247. this.paddedTicks = tickPositions.slice(0); // Used for logarithmic minor
  4248. this.trimTicks(tickPositions, startOnTick, endOnTick);
  4249. if (!this.isLinked) {
  4250. // Substract half a unit (#2619, #2846, #2515, #3390),
  4251. // but not in case of multiple ticks (#6897)
  4252. if (this.single && tickPositions.length < 2) {
  4253. this.min -= 0.5;
  4254. this.max += 0.5;
  4255. }
  4256. if (!tickPositionsOption && !tickPositioner) {
  4257. this.adjustTickAmount();
  4258. }
  4259. }
  4260. fireEvent(this, 'afterSetTickPositions');
  4261. },
  4262. // Handle startOnTick and endOnTick by either adapting to padding min/max or
  4263. // rounded min/max. Also handle single data points.
  4264. trimTicks: function (tickPositions, startOnTick, endOnTick) {
  4265. var roundedMin = tickPositions[0],
  4266. roundedMax = tickPositions[tickPositions.length - 1],
  4267. minPointOffset = this.minPointOffset || 0;
  4268. fireEvent(this, 'trimTicks');
  4269. if (!this.isLinked) {
  4270. if (startOnTick && roundedMin !== -Infinity) { // #6502
  4271. this.min = roundedMin;
  4272. } else {
  4273. while (this.min - minPointOffset > tickPositions[0]) {
  4274. tickPositions.shift();
  4275. }
  4276. }
  4277. if (endOnTick) {
  4278. this.max = roundedMax;
  4279. } else {
  4280. while (this.max + minPointOffset <
  4281. tickPositions[tickPositions.length - 1]) {
  4282. tickPositions.pop();
  4283. }
  4284. }
  4285. // If no tick are left, set one tick in the middle (#3195)
  4286. if (
  4287. tickPositions.length === 0 &&
  4288. defined(roundedMin) &&
  4289. !this.options.tickPositions
  4290. ) {
  4291. tickPositions.push((roundedMax + roundedMin) / 2);
  4292. }
  4293. }
  4294. },
  4295. /**
  4296. * Check if there are multiple axes in the same pane.
  4297. * @private
  4298. * @return {boolean} True if there are other axes.
  4299. */
  4300. alignToOthers: function () {
  4301. var others = {}, // Whether there is another axis to pair with this one
  4302. hasOther,
  4303. options = this.options;
  4304. if (
  4305. // Only if alignTicks is true
  4306. this.chart.options.chart.alignTicks !== false &&
  4307. options.alignTicks !== false &&
  4308. // Disabled when startOnTick or endOnTick are false (#7604)
  4309. options.startOnTick !== false &&
  4310. options.endOnTick !== false &&
  4311. // Don't try to align ticks on a log axis, they are not evenly
  4312. // spaced (#6021)
  4313. !this.isLog
  4314. ) {
  4315. this.chart[this.coll].forEach(function (axis) {
  4316. var otherOptions = axis.options,
  4317. horiz = axis.horiz,
  4318. key = [
  4319. horiz ? otherOptions.left : otherOptions.top,
  4320. otherOptions.width,
  4321. otherOptions.height,
  4322. otherOptions.pane
  4323. ].join(',');
  4324. if (axis.series.length) { // #4442
  4325. if (others[key]) {
  4326. hasOther = true; // #4201
  4327. } else {
  4328. others[key] = 1;
  4329. }
  4330. }
  4331. });
  4332. }
  4333. return hasOther;
  4334. },
  4335. /**
  4336. * Find the max ticks of either the x and y axis collection, and record it
  4337. * in `this.tickAmount`.
  4338. * @private
  4339. */
  4340. getTickAmount: function () {
  4341. var options = this.options,
  4342. tickAmount = options.tickAmount,
  4343. tickPixelInterval = options.tickPixelInterval;
  4344. if (
  4345. !defined(options.tickInterval) &&
  4346. this.len < tickPixelInterval &&
  4347. !this.isRadial &&
  4348. !this.isLog &&
  4349. options.startOnTick &&
  4350. options.endOnTick
  4351. ) {
  4352. tickAmount = 2;
  4353. }
  4354. if (!tickAmount && this.alignToOthers()) {
  4355. // Add 1 because 4 tick intervals require 5 ticks (including first
  4356. // and last)
  4357. tickAmount = Math.ceil(this.len / tickPixelInterval) + 1;
  4358. }
  4359. // For tick amounts of 2 and 3, compute five ticks and remove the
  4360. // intermediate ones. This prevents the axis from adding ticks that are
  4361. // too far away from the data extremes.
  4362. if (tickAmount < 4) {
  4363. this.finalTickAmt = tickAmount;
  4364. tickAmount = 5;
  4365. }
  4366. this.tickAmount = tickAmount;
  4367. },
  4368. /**
  4369. * When using multiple axes, adjust the number of ticks to match the highest
  4370. * number of ticks in that group.
  4371. * @private
  4372. */
  4373. adjustTickAmount: function () {
  4374. var axis = this,
  4375. axisOptions = axis.options,
  4376. tickInterval = axis.tickInterval,
  4377. tickPositions = axis.tickPositions,
  4378. tickAmount = axis.tickAmount,
  4379. finalTickAmt = axis.finalTickAmt,
  4380. currentTickAmount = tickPositions && tickPositions.length,
  4381. threshold = pick(axis.threshold, axis.softThreshold ? 0 : null),
  4382. min,
  4383. len,
  4384. i;
  4385. if (axis.hasData()) {
  4386. if (currentTickAmount < tickAmount) {
  4387. min = axis.min;
  4388. while (tickPositions.length < tickAmount) {
  4389. // Extend evenly for both sides unless we're on the
  4390. // threshold (#3965)
  4391. if (
  4392. tickPositions.length % 2 ||
  4393. min === threshold
  4394. ) {
  4395. // to the end
  4396. tickPositions.push(correctFloat(
  4397. tickPositions[tickPositions.length - 1] +
  4398. tickInterval
  4399. ));
  4400. } else {
  4401. // to the start
  4402. tickPositions.unshift(correctFloat(
  4403. tickPositions[0] - tickInterval
  4404. ));
  4405. }
  4406. }
  4407. axis.transA *= (currentTickAmount - 1) / (tickAmount - 1);
  4408. // Do not crop when ticks are not extremes (#9841)
  4409. axis.min = axisOptions.startOnTick ?
  4410. tickPositions[0] :
  4411. Math.min(axis.min, tickPositions[0]);
  4412. axis.max = axisOptions.endOnTick ?
  4413. tickPositions[tickPositions.length - 1] :
  4414. Math.max(axis.max, tickPositions[tickPositions.length - 1]);
  4415. // We have too many ticks, run second pass to try to reduce ticks
  4416. } else if (currentTickAmount > tickAmount) {
  4417. axis.tickInterval *= 2;
  4418. axis.setTickPositions();
  4419. }
  4420. // The finalTickAmt property is set in getTickAmount
  4421. if (defined(finalTickAmt)) {
  4422. i = len = tickPositions.length;
  4423. while (i--) {
  4424. if (
  4425. // Remove every other tick
  4426. (finalTickAmt === 3 && i % 2 === 1) ||
  4427. // Remove all but first and last
  4428. (finalTickAmt <= 2 && i > 0 && i < len - 1)
  4429. ) {
  4430. tickPositions.splice(i, 1);
  4431. }
  4432. }
  4433. axis.finalTickAmt = undefined;
  4434. }
  4435. }
  4436. },
  4437. /**
  4438. * Set the scale based on data min and max, user set min and max or options.
  4439. * @private
  4440. * @fires Highcharts.Axis#event:afterSetScale
  4441. */
  4442. setScale: function () {
  4443. var axis = this,
  4444. isDirtyData,
  4445. isDirtyAxisLength;
  4446. axis.oldMin = axis.min;
  4447. axis.oldMax = axis.max;
  4448. axis.oldAxisLength = axis.len;
  4449. // set the new axisLength
  4450. axis.setAxisSize();
  4451. isDirtyAxisLength = axis.len !== axis.oldAxisLength;
  4452. // is there new data?
  4453. axis.series.forEach(function (series) {
  4454. if (
  4455. series.isDirtyData ||
  4456. series.isDirty ||
  4457. // When x axis is dirty, we need new data extremes for y as well
  4458. series.xAxis.isDirty
  4459. ) {
  4460. isDirtyData = true;
  4461. }
  4462. });
  4463. // do we really need to go through all this?
  4464. if (
  4465. isDirtyAxisLength ||
  4466. isDirtyData ||
  4467. axis.isLinked ||
  4468. axis.forceRedraw ||
  4469. axis.userMin !== axis.oldUserMin ||
  4470. axis.userMax !== axis.oldUserMax ||
  4471. axis.alignToOthers()
  4472. ) {
  4473. if (axis.resetStacks) {
  4474. axis.resetStacks();
  4475. }
  4476. axis.forceRedraw = false;
  4477. // get data extremes if needed
  4478. axis.getSeriesExtremes();
  4479. // get fixed positions based on tickInterval
  4480. axis.setTickInterval();
  4481. // record old values to decide whether a rescale is necessary later
  4482. // on (#540)
  4483. axis.oldUserMin = axis.userMin;
  4484. axis.oldUserMax = axis.userMax;
  4485. // Mark as dirty if it is not already set to dirty and extremes have
  4486. // changed. #595.
  4487. if (!axis.isDirty) {
  4488. axis.isDirty =
  4489. isDirtyAxisLength ||
  4490. axis.min !== axis.oldMin ||
  4491. axis.max !== axis.oldMax;
  4492. }
  4493. } else if (axis.cleanStacks) {
  4494. axis.cleanStacks();
  4495. }
  4496. fireEvent(this, 'afterSetScale');
  4497. },
  4498. /**
  4499. * Set the minimum and maximum of the axes after render time. If the
  4500. * `startOnTick` and `endOnTick` options are true, the minimum and maximum
  4501. * values are rounded off to the nearest tick. To prevent this, these
  4502. * options can be set to false before calling setExtremes. Also, setExtremes
  4503. * will not allow a range lower than the `minRange` option, which by default
  4504. * is the range of five points.
  4505. *
  4506. * @sample highcharts/members/axis-setextremes/
  4507. * Set extremes from a button
  4508. * @sample highcharts/members/axis-setextremes-datetime/
  4509. * Set extremes on a datetime axis
  4510. * @sample highcharts/members/axis-setextremes-off-ticks/
  4511. * Set extremes off ticks
  4512. * @sample stock/members/axis-setextremes/
  4513. * Set extremes in Highstock
  4514. * @sample maps/members/axis-setextremes/
  4515. * Set extremes in Highmaps
  4516. *
  4517. * @function Highcharts.Axis#setExtremes
  4518. *
  4519. * @param {number} [newMin]
  4520. * The new minimum value.
  4521. *
  4522. * @param {number} [newMax]
  4523. * The new maximum value.
  4524. *
  4525. * @param {boolean} [redraw=true]
  4526. * Whether to redraw the chart or wait for an explicit call to
  4527. * {@link Highcharts.Chart#redraw}
  4528. *
  4529. * @param {boolean|Highcharts.AnimationOptionsObject} [animation=true]
  4530. * Enable or modify animations.
  4531. *
  4532. * @param {*} [eventArguments]
  4533. * Arguments to be accessed in event handler.
  4534. *
  4535. * @fires Highcharts.Axis#event:setExtremes
  4536. */
  4537. setExtremes: function (newMin, newMax, redraw, animation, eventArguments) {
  4538. var axis = this,
  4539. chart = axis.chart;
  4540. redraw = pick(redraw, true); // defaults to true
  4541. axis.series.forEach(function (serie) {
  4542. delete serie.kdTree;
  4543. });
  4544. // Extend the arguments with min and max
  4545. eventArguments = extend(eventArguments, {
  4546. min: newMin,
  4547. max: newMax
  4548. });
  4549. // Fire the event
  4550. fireEvent(axis, 'setExtremes', eventArguments, function () {
  4551. axis.userMin = newMin;
  4552. axis.userMax = newMax;
  4553. axis.eventArgs = eventArguments;
  4554. if (redraw) {
  4555. chart.redraw(animation);
  4556. }
  4557. });
  4558. },
  4559. // Overridable method for zooming chart. Pulled out in a separate method to
  4560. // allow overriding in stock charts.
  4561. zoom: function (newMin, newMax) {
  4562. var dataMin = this.dataMin,
  4563. dataMax = this.dataMax,
  4564. options = this.options,
  4565. min = Math.min(dataMin, pick(options.min, dataMin)),
  4566. max = Math.max(dataMax, pick(options.max, dataMax)),
  4567. evt = { newMin: newMin, newMax: newMax };
  4568. fireEvent(this, 'zoom', evt, function (e) {
  4569. // Use e.newMin and e.newMax - event handlers may have altered them
  4570. var newMin = e.newMin,
  4571. newMax = e.newMax;
  4572. if (newMin !== this.min || newMax !== this.max) { // #5790
  4573. // Prevent pinch zooming out of range. Check for defined is for
  4574. // #1946. #1734.
  4575. if (!this.allowZoomOutside) {
  4576. // #6014, sometimes newMax will be smaller than min (or
  4577. // newMin will be larger than max).
  4578. if (defined(dataMin)) {
  4579. if (newMin < min) {
  4580. newMin = min;
  4581. }
  4582. if (newMin > max) {
  4583. newMin = max;
  4584. }
  4585. }
  4586. if (defined(dataMax)) {
  4587. if (newMax < min) {
  4588. newMax = min;
  4589. }
  4590. if (newMax > max) {
  4591. newMax = max;
  4592. }
  4593. }
  4594. }
  4595. // In full view, displaying the reset zoom button is not
  4596. // required
  4597. this.displayBtn = newMin !== undefined || newMax !== undefined;
  4598. // Do it
  4599. this.setExtremes(
  4600. newMin,
  4601. newMax,
  4602. false,
  4603. undefined,
  4604. { trigger: 'zoom' }
  4605. );
  4606. }
  4607. e.zoomed = true;
  4608. });
  4609. return evt.zoomed;
  4610. },
  4611. // Update the axis metrics.
  4612. setAxisSize: function () {
  4613. var chart = this.chart,
  4614. options = this.options,
  4615. // [top, right, bottom, left]
  4616. offsets = options.offsets || [0, 0, 0, 0],
  4617. horiz = this.horiz,
  4618. // Check for percentage based input values. Rounding fixes problems
  4619. // with column overflow and plot line filtering (#4898, #4899)
  4620. width = this.width = Math.round(H.relativeLength(
  4621. pick(
  4622. options.width,
  4623. chart.plotWidth - offsets[3] + offsets[1]
  4624. ),
  4625. chart.plotWidth
  4626. )),
  4627. height = this.height = Math.round(H.relativeLength(
  4628. pick(
  4629. options.height,
  4630. chart.plotHeight - offsets[0] + offsets[2]
  4631. ),
  4632. chart.plotHeight
  4633. )),
  4634. top = this.top = Math.round(H.relativeLength(
  4635. pick(options.top, chart.plotTop + offsets[0]),
  4636. chart.plotHeight,
  4637. chart.plotTop
  4638. )),
  4639. left = this.left = Math.round(H.relativeLength(
  4640. pick(options.left, chart.plotLeft + offsets[3]),
  4641. chart.plotWidth,
  4642. chart.plotLeft
  4643. ));
  4644. // Expose basic values to use in Series object and navigator
  4645. this.bottom = chart.chartHeight - height - top;
  4646. this.right = chart.chartWidth - width - left;
  4647. // Direction agnostic properties
  4648. this.len = Math.max(horiz ? width : height, 0); // Math.max fixes #905
  4649. this.pos = horiz ? left : top; // distance from SVG origin
  4650. },
  4651. /**
  4652. * Get the current extremes for the axis.
  4653. *
  4654. * @sample highcharts/members/axis-getextremes/
  4655. * Report extremes by click on a button
  4656. * @sample maps/members/axis-getextremes/
  4657. * Get extremes in Highmaps
  4658. *
  4659. * @function Highcharts.Axis#getExtremes
  4660. *
  4661. * @returns {Highcharts.ExtremesObject}
  4662. * An object containing extremes information.
  4663. */
  4664. getExtremes: function () {
  4665. var axis = this,
  4666. isLog = axis.isLog;
  4667. return {
  4668. min: isLog ? correctFloat(axis.lin2log(axis.min)) : axis.min,
  4669. max: isLog ? correctFloat(axis.lin2log(axis.max)) : axis.max,
  4670. dataMin: axis.dataMin,
  4671. dataMax: axis.dataMax,
  4672. userMin: axis.userMin,
  4673. userMax: axis.userMax
  4674. };
  4675. },
  4676. /**
  4677. * Get the zero plane either based on zero or on the min or max value.
  4678. * Used in bar and area plots.
  4679. *
  4680. * @function Highcharts.Axis#getThreshold
  4681. *
  4682. * @param {number} threshold
  4683. * The threshold in axis values.
  4684. *
  4685. * @return {number}
  4686. * The translated threshold position in terms of pixels, and
  4687. * corrected to stay within the axis bounds.
  4688. */
  4689. getThreshold: function (threshold) {
  4690. var axis = this,
  4691. isLog = axis.isLog,
  4692. realMin = isLog ? axis.lin2log(axis.min) : axis.min,
  4693. realMax = isLog ? axis.lin2log(axis.max) : axis.max;
  4694. if (threshold === null || threshold === -Infinity) {
  4695. threshold = realMin;
  4696. } else if (threshold === Infinity) {
  4697. threshold = realMax;
  4698. } else if (realMin > threshold) {
  4699. threshold = realMin;
  4700. } else if (realMax < threshold) {
  4701. threshold = realMax;
  4702. }
  4703. return axis.translate(threshold, 0, 1, 0, 1);
  4704. },
  4705. /**
  4706. * Compute auto alignment for the axis label based on which side the axis is
  4707. * on and the given rotation for the label.
  4708. * @private
  4709. * @param {number} rotation The rotation in degrees as set by either the
  4710. * `rotation` or `autoRotation` options.
  4711. * @return {string} Can be `center`, `left` or `right`.
  4712. */
  4713. autoLabelAlign: function (rotation) {
  4714. var angle = (pick(rotation, 0) - (this.side * 90) + 720) % 360,
  4715. evt = { align: 'center' };
  4716. fireEvent(this, 'autoLabelAlign', evt, function (e) {
  4717. if (angle > 15 && angle < 165) {
  4718. e.align = 'right';
  4719. } else if (angle > 195 && angle < 345) {
  4720. e.align = 'left';
  4721. }
  4722. });
  4723. return evt.align;
  4724. },
  4725. /**
  4726. * Get the tick length and width for the axis based on axis options.
  4727. * @private
  4728. * @param {string} prefix 'tick' or 'minorTick'
  4729. * @return {Array<number>} An array of tickLength and tickWidth
  4730. */
  4731. tickSize: function (prefix) {
  4732. var options = this.options,
  4733. tickLength = options[prefix + 'Length'],
  4734. tickWidth = pick(
  4735. options[prefix + 'Width'],
  4736. prefix === 'tick' && this.isXAxis ? 1 : 0 // X axis default 1
  4737. ),
  4738. e,
  4739. tickSize;
  4740. if (tickWidth && tickLength) {
  4741. // Negate the length
  4742. if (options[prefix + 'Position'] === 'inside') {
  4743. tickLength = -tickLength;
  4744. }
  4745. tickSize = [tickLength, tickWidth];
  4746. }
  4747. e = { tickSize: tickSize };
  4748. fireEvent(this, 'afterTickSize', e);
  4749. return e.tickSize;
  4750. },
  4751. // Return the size of the labels.
  4752. labelMetrics: function () {
  4753. var index = this.tickPositions && this.tickPositions[0] || 0;
  4754. return this.chart.renderer.fontMetrics(
  4755. this.options.labels.style && this.options.labels.style.fontSize,
  4756. this.ticks[index] && this.ticks[index].label
  4757. );
  4758. },
  4759. // Prevent the ticks from getting so close we can't draw the labels. On a
  4760. // horizontal axis, this is handled by rotating the labels, removing ticks
  4761. // and adding ellipsis. On a vertical axis remove ticks and add ellipsis.
  4762. unsquish: function () {
  4763. var labelOptions = this.options.labels,
  4764. horiz = this.horiz,
  4765. tickInterval = this.tickInterval,
  4766. newTickInterval = tickInterval,
  4767. slotSize = this.len / (
  4768. ((this.categories ? 1 : 0) + this.max - this.min) / tickInterval
  4769. ),
  4770. rotation,
  4771. rotationOption = labelOptions.rotation,
  4772. labelMetrics = this.labelMetrics(),
  4773. step,
  4774. bestScore = Number.MAX_VALUE,
  4775. autoRotation,
  4776. range = this.max - this.min,
  4777. // Return the multiple of tickInterval that is needed to avoid
  4778. // collision
  4779. getStep = function (spaceNeeded) {
  4780. var step = spaceNeeded / (slotSize || 1);
  4781. step = step > 1 ? Math.ceil(step) : 1;
  4782. // Guard for very small or negative angles (#9835)
  4783. if (
  4784. step * tickInterval > range &&
  4785. spaceNeeded !== Infinity &&
  4786. slotSize !== Infinity
  4787. ) {
  4788. step = Math.ceil(range / tickInterval);
  4789. }
  4790. return correctFloat(step * tickInterval);
  4791. };
  4792. if (horiz) {
  4793. autoRotation = !labelOptions.staggerLines &&
  4794. !labelOptions.step &&
  4795. ( // #3971
  4796. defined(rotationOption) ?
  4797. [rotationOption] :
  4798. slotSize < pick(labelOptions.autoRotationLimit, 80) &&
  4799. labelOptions.autoRotation
  4800. );
  4801. if (autoRotation) {
  4802. // Loop over the given autoRotation options, and determine
  4803. // which gives the best score. The best score is that with
  4804. // the lowest number of steps and a rotation closest
  4805. // to horizontal.
  4806. autoRotation.forEach(function (rot) {
  4807. var score;
  4808. if (
  4809. rot === rotationOption ||
  4810. (rot && rot >= -90 && rot <= 90)
  4811. ) { // #3891
  4812. step = getStep(
  4813. Math.abs(labelMetrics.h / Math.sin(deg2rad * rot))
  4814. );
  4815. score = step + Math.abs(rot / 360);
  4816. if (score < bestScore) {
  4817. bestScore = score;
  4818. rotation = rot;
  4819. newTickInterval = step;
  4820. }
  4821. }
  4822. });
  4823. }
  4824. } else if (!labelOptions.step) { // #4411
  4825. newTickInterval = getStep(labelMetrics.h);
  4826. }
  4827. this.autoRotation = autoRotation;
  4828. this.labelRotation = pick(rotation, rotationOption);
  4829. return newTickInterval;
  4830. },
  4831. /**
  4832. * Get the general slot width for labels/categories on this axis. This may
  4833. * change between the pre-render (from Axis.getOffset) and the final tick
  4834. * rendering and placement.
  4835. * @private
  4836. * @param {Highcharts.Tick} [tick] Optionally, calculate the slot width
  4837. * basing on tick label. It is used in highcharts-3d module, where the slots
  4838. * has different widths depending on perspective angles.
  4839. * @return {number} The pixel width allocated to each axis label.
  4840. */
  4841. getSlotWidth: function (tick) {
  4842. // #5086, #1580, #1931
  4843. var chart = this.chart,
  4844. horiz = this.horiz,
  4845. labelOptions = this.options.labels,
  4846. slotCount = Math.max(
  4847. this.tickPositions.length - (this.categories ? 0 : 1),
  4848. 1
  4849. ),
  4850. marginLeft = chart.margin[3];
  4851. return (
  4852. tick &&
  4853. tick.slotWidth // Used by grid axis
  4854. ) || (
  4855. horiz &&
  4856. (labelOptions.step || 0) < 2 &&
  4857. !labelOptions.rotation && // #4415
  4858. ((this.staggerLines || 1) * this.len) / slotCount
  4859. ) || (
  4860. !horiz && (
  4861. // #7028
  4862. (
  4863. labelOptions.style &&
  4864. parseInt(labelOptions.style.width, 10)
  4865. ) ||
  4866. (
  4867. marginLeft &&
  4868. (marginLeft - chart.spacing[3])
  4869. ) ||
  4870. chart.chartWidth * 0.33
  4871. )
  4872. );
  4873. },
  4874. // Render the axis labels and determine whether ellipsis or rotation need to
  4875. // be applied.
  4876. renderUnsquish: function () {
  4877. var chart = this.chart,
  4878. renderer = chart.renderer,
  4879. tickPositions = this.tickPositions,
  4880. ticks = this.ticks,
  4881. labelOptions = this.options.labels,
  4882. labelStyleOptions = (labelOptions && labelOptions.style || {}),
  4883. horiz = this.horiz,
  4884. slotWidth = this.getSlotWidth(),
  4885. innerWidth = Math.max(
  4886. 1,
  4887. Math.round(slotWidth - 2 * (labelOptions.padding || 5))
  4888. ),
  4889. attr = {},
  4890. labelMetrics = this.labelMetrics(),
  4891. textOverflowOption = labelOptions.style &&
  4892. labelOptions.style.textOverflow,
  4893. commonWidth,
  4894. commonTextOverflow,
  4895. maxLabelLength = 0,
  4896. label,
  4897. i,
  4898. pos;
  4899. // Set rotation option unless it is "auto", like in gauges
  4900. if (!isString(labelOptions.rotation)) {
  4901. attr.rotation = labelOptions.rotation || 0; // #4443
  4902. }
  4903. // Get the longest label length
  4904. tickPositions.forEach(function (tick) {
  4905. tick = ticks[tick];
  4906. if (
  4907. tick &&
  4908. tick.label &&
  4909. tick.label.textPxLength > maxLabelLength
  4910. ) {
  4911. maxLabelLength = tick.label.textPxLength;
  4912. }
  4913. });
  4914. this.maxLabelLength = maxLabelLength;
  4915. // Handle auto rotation on horizontal axis
  4916. if (this.autoRotation) {
  4917. // Apply rotation only if the label is too wide for the slot, and
  4918. // the label is wider than its height.
  4919. if (
  4920. maxLabelLength > innerWidth &&
  4921. maxLabelLength > labelMetrics.h
  4922. ) {
  4923. attr.rotation = this.labelRotation;
  4924. } else {
  4925. this.labelRotation = 0;
  4926. }
  4927. // Handle word-wrap or ellipsis on vertical axis
  4928. } else if (slotWidth) {
  4929. // For word-wrap or ellipsis
  4930. commonWidth = innerWidth;
  4931. if (!textOverflowOption) {
  4932. commonTextOverflow = 'clip';
  4933. // On vertical axis, only allow word wrap if there is room
  4934. // for more lines.
  4935. i = tickPositions.length;
  4936. while (!horiz && i--) {
  4937. pos = tickPositions[i];
  4938. label = ticks[pos].label;
  4939. if (label) {
  4940. // Reset ellipsis in order to get the correct
  4941. // bounding box (#4070)
  4942. if (
  4943. label.styles &&
  4944. label.styles.textOverflow === 'ellipsis'
  4945. ) {
  4946. label.css({ textOverflow: 'clip' });
  4947. // Set the correct width in order to read
  4948. // the bounding box height (#4678, #5034)
  4949. } else if (label.textPxLength > slotWidth) {
  4950. label.css({ width: slotWidth + 'px' });
  4951. }
  4952. if (
  4953. label.getBBox().height > (
  4954. this.len / tickPositions.length -
  4955. (labelMetrics.h - labelMetrics.f)
  4956. )
  4957. ) {
  4958. label.specificTextOverflow = 'ellipsis';
  4959. }
  4960. }
  4961. }
  4962. }
  4963. }
  4964. // Add ellipsis if the label length is significantly longer than ideal
  4965. if (attr.rotation) {
  4966. commonWidth = (
  4967. maxLabelLength > chart.chartHeight * 0.5 ?
  4968. chart.chartHeight * 0.33 :
  4969. maxLabelLength
  4970. );
  4971. if (!textOverflowOption) {
  4972. commonTextOverflow = 'ellipsis';
  4973. }
  4974. }
  4975. // Set the explicit or automatic label alignment
  4976. this.labelAlign = labelOptions.align ||
  4977. this.autoLabelAlign(this.labelRotation);
  4978. if (this.labelAlign) {
  4979. attr.align = this.labelAlign;
  4980. }
  4981. // Apply general and specific CSS
  4982. tickPositions.forEach(function (pos) {
  4983. var tick = ticks[pos],
  4984. label = tick && tick.label,
  4985. widthOption = labelStyleOptions.width,
  4986. css = {};
  4987. if (label) {
  4988. // This needs to go before the CSS in old IE (#4502)
  4989. label.attr(attr);
  4990. if (tick.shortenLabel) {
  4991. tick.shortenLabel();
  4992. } else if (
  4993. commonWidth &&
  4994. !widthOption &&
  4995. // Setting width in this case messes with the bounding box
  4996. // (#7975)
  4997. labelStyleOptions.whiteSpace !== 'nowrap' &&
  4998. (
  4999. // Speed optimizing, #7656
  5000. commonWidth < label.textPxLength ||
  5001. // Resetting CSS, #4928
  5002. label.element.tagName === 'SPAN'
  5003. )
  5004. ) {
  5005. css.width = commonWidth;
  5006. if (!textOverflowOption) {
  5007. css.textOverflow = (
  5008. label.specificTextOverflow ||
  5009. commonTextOverflow
  5010. );
  5011. }
  5012. label.css(css);
  5013. // Reset previously shortened label (#8210)
  5014. } else if (
  5015. label.styles &&
  5016. label.styles.width &&
  5017. !css.width &&
  5018. !widthOption
  5019. ) {
  5020. label.css({ width: null });
  5021. }
  5022. delete label.specificTextOverflow;
  5023. tick.rotation = attr.rotation;
  5024. }
  5025. }, this);
  5026. // Note: Why is this not part of getLabelPosition?
  5027. this.tickRotCorr = renderer.rotCorr(
  5028. labelMetrics.b,
  5029. this.labelRotation || 0,
  5030. this.side !== 0
  5031. );
  5032. },
  5033. /**
  5034. * Return true if the axis has associated data.
  5035. *
  5036. * @function Highcharts.Axis#hasData
  5037. *
  5038. * @return {boolean}
  5039. * True if the axis has associated visible series and those series
  5040. * have either valid data points or explicit `min` and `max`
  5041. * settings.
  5042. */
  5043. hasData: function () {
  5044. return (
  5045. this.hasVisibleSeries ||
  5046. (
  5047. defined(this.min) &&
  5048. defined(this.max) &&
  5049. this.tickPositions &&
  5050. this.tickPositions.length > 0
  5051. )
  5052. );
  5053. },
  5054. /**
  5055. * Adds the title defined in axis.options.title.
  5056. *
  5057. * @function Highcharts.Axis#addTitle
  5058. *
  5059. * @param {boolean} display
  5060. * Whether or not to display the title.
  5061. */
  5062. addTitle: function (display) {
  5063. var axis = this,
  5064. renderer = axis.chart.renderer,
  5065. horiz = axis.horiz,
  5066. opposite = axis.opposite,
  5067. options = axis.options,
  5068. axisTitleOptions = options.title,
  5069. textAlign,
  5070. styledMode = axis.chart.styledMode;
  5071. if (!axis.axisTitle) {
  5072. textAlign = axisTitleOptions.textAlign;
  5073. if (!textAlign) {
  5074. textAlign = (horiz ? {
  5075. low: 'left',
  5076. middle: 'center',
  5077. high: 'right'
  5078. } : {
  5079. low: opposite ? 'right' : 'left',
  5080. middle: 'center',
  5081. high: opposite ? 'left' : 'right'
  5082. })[axisTitleOptions.align];
  5083. }
  5084. axis.axisTitle = renderer.text(
  5085. axisTitleOptions.text,
  5086. 0,
  5087. 0,
  5088. axisTitleOptions.useHTML
  5089. )
  5090. .attr({
  5091. zIndex: 7,
  5092. rotation: axisTitleOptions.rotation || 0,
  5093. align: textAlign
  5094. })
  5095. .addClass('highcharts-axis-title');
  5096. // #7814, don't mutate style option
  5097. if (!styledMode) {
  5098. axis.axisTitle.css(merge(axisTitleOptions.style));
  5099. }
  5100. axis.axisTitle.add(axis.axisGroup);
  5101. axis.axisTitle.isNew = true;
  5102. }
  5103. // Max width defaults to the length of the axis
  5104. if (!styledMode && !axisTitleOptions.style.width && !axis.isRadial) {
  5105. axis.axisTitle.css({
  5106. width: axis.len
  5107. });
  5108. }
  5109. // hide or show the title depending on whether showEmpty is set
  5110. axis.axisTitle[display ? 'show' : 'hide'](true);
  5111. },
  5112. /**
  5113. * Generates a tick for initial positioning.
  5114. * @private
  5115. * @param {number} pos The tick position in axis values.
  5116. * @param {number} i The index of the tick in {@link Axis.tickPositions}.
  5117. */
  5118. generateTick: function (pos) {
  5119. var ticks = this.ticks;
  5120. if (!ticks[pos]) {
  5121. ticks[pos] = new Tick(this, pos);
  5122. } else {
  5123. ticks[pos].addLabel(); // update labels depending on tick interval
  5124. }
  5125. },
  5126. /**
  5127. * Render the tick labels to a preliminary position to get their sizes
  5128. * @private
  5129. * @fires Highcharts.Axis#event:afterGetOffset
  5130. */
  5131. getOffset: function () {
  5132. var axis = this,
  5133. chart = axis.chart,
  5134. renderer = chart.renderer,
  5135. options = axis.options,
  5136. tickPositions = axis.tickPositions,
  5137. ticks = axis.ticks,
  5138. horiz = axis.horiz,
  5139. side = axis.side,
  5140. invertedSide = chart.inverted &&
  5141. !axis.isZAxis ? [1, 0, 3, 2][side] : side,
  5142. hasData,
  5143. showAxis,
  5144. titleOffset = 0,
  5145. titleOffsetOption,
  5146. titleMargin = 0,
  5147. axisTitleOptions = options.title,
  5148. labelOptions = options.labels,
  5149. labelOffset = 0, // reset
  5150. labelOffsetPadded,
  5151. axisOffset = chart.axisOffset,
  5152. clipOffset = chart.clipOffset,
  5153. clip,
  5154. directionFactor = [-1, 1, 1, -1][side],
  5155. className = options.className,
  5156. axisParent = axis.axisParent, // Used in color axis
  5157. lineHeightCorrection,
  5158. tickSize;
  5159. // For reuse in Axis.render
  5160. hasData = axis.hasData();
  5161. axis.showAxis = showAxis = hasData || pick(options.showEmpty, true);
  5162. // Set/reset staggerLines
  5163. axis.staggerLines = axis.horiz && labelOptions.staggerLines;
  5164. // Create the axisGroup and gridGroup elements on first iteration
  5165. if (!axis.axisGroup) {
  5166. axis.gridGroup = renderer.g('grid')
  5167. .attr({ zIndex: options.gridZIndex || 1 })
  5168. .addClass(
  5169. 'highcharts-' + this.coll.toLowerCase() + '-grid ' +
  5170. (className || '')
  5171. )
  5172. .add(axisParent);
  5173. axis.axisGroup = renderer.g('axis')
  5174. .attr({ zIndex: options.zIndex || 2 })
  5175. .addClass(
  5176. 'highcharts-' + this.coll.toLowerCase() + ' ' +
  5177. (className || '')
  5178. )
  5179. .add(axisParent);
  5180. axis.labelGroup = renderer.g('axis-labels')
  5181. .attr({ zIndex: labelOptions.zIndex || 7 })
  5182. .addClass(
  5183. 'highcharts-' + axis.coll.toLowerCase() + '-labels ' +
  5184. (className || '')
  5185. )
  5186. .add(axisParent);
  5187. }
  5188. if (hasData || axis.isLinked) {
  5189. // Generate ticks
  5190. tickPositions.forEach(function (pos, i) {
  5191. // i is not used here, but may be used in overrides
  5192. axis.generateTick(pos, i);
  5193. });
  5194. axis.renderUnsquish();
  5195. // Left side must be align: right and right side must
  5196. // have align: left for labels
  5197. axis.reserveSpaceDefault = (
  5198. side === 0 ||
  5199. side === 2 ||
  5200. { 1: 'left', 3: 'right' }[side] === axis.labelAlign
  5201. );
  5202. if (pick(
  5203. labelOptions.reserveSpace,
  5204. axis.labelAlign === 'center' ? true : null,
  5205. axis.reserveSpaceDefault
  5206. )) {
  5207. tickPositions.forEach(function (pos) {
  5208. // get the highest offset
  5209. labelOffset = Math.max(
  5210. ticks[pos].getLabelSize(),
  5211. labelOffset
  5212. );
  5213. });
  5214. }
  5215. if (axis.staggerLines) {
  5216. labelOffset *= axis.staggerLines;
  5217. }
  5218. axis.labelOffset = labelOffset * (axis.opposite ? -1 : 1);
  5219. } else { // doesn't have data
  5220. objectEach(ticks, function (tick, n) {
  5221. tick.destroy();
  5222. delete ticks[n];
  5223. });
  5224. }
  5225. if (
  5226. axisTitleOptions &&
  5227. axisTitleOptions.text &&
  5228. axisTitleOptions.enabled !== false
  5229. ) {
  5230. axis.addTitle(showAxis);
  5231. if (showAxis && axisTitleOptions.reserveSpace !== false) {
  5232. axis.titleOffset = titleOffset =
  5233. axis.axisTitle.getBBox()[horiz ? 'height' : 'width'];
  5234. titleOffsetOption = axisTitleOptions.offset;
  5235. titleMargin = defined(titleOffsetOption) ?
  5236. 0 :
  5237. pick(axisTitleOptions.margin, horiz ? 5 : 10);
  5238. }
  5239. }
  5240. // Render the axis line
  5241. axis.renderLine();
  5242. // handle automatic or user set offset
  5243. axis.offset = directionFactor * pick(options.offset, axisOffset[side]);
  5244. axis.tickRotCorr = axis.tickRotCorr || { x: 0, y: 0 }; // polar
  5245. if (side === 0) {
  5246. lineHeightCorrection = -axis.labelMetrics().h;
  5247. } else if (side === 2) {
  5248. lineHeightCorrection = axis.tickRotCorr.y;
  5249. } else {
  5250. lineHeightCorrection = 0;
  5251. }
  5252. // Find the padded label offset
  5253. labelOffsetPadded = Math.abs(labelOffset) + titleMargin;
  5254. if (labelOffset) {
  5255. labelOffsetPadded -= lineHeightCorrection;
  5256. labelOffsetPadded += directionFactor * (
  5257. horiz ?
  5258. pick(
  5259. labelOptions.y,
  5260. axis.tickRotCorr.y + directionFactor * 8
  5261. ) :
  5262. labelOptions.x
  5263. );
  5264. }
  5265. axis.axisTitleMargin = pick(titleOffsetOption, labelOffsetPadded);
  5266. if (axis.getMaxLabelDimensions) {
  5267. axis.maxLabelDimensions = axis.getMaxLabelDimensions(
  5268. ticks,
  5269. tickPositions
  5270. );
  5271. }
  5272. // Due to GridAxis.tickSize, tickSize should be calculated after ticks
  5273. // has rendered.
  5274. tickSize = this.tickSize('tick');
  5275. axisOffset[side] = Math.max(
  5276. axisOffset[side],
  5277. axis.axisTitleMargin + titleOffset + directionFactor * axis.offset,
  5278. labelOffsetPadded, // #3027
  5279. hasData && tickPositions.length && tickSize ?
  5280. tickSize[0] + directionFactor * axis.offset :
  5281. 0 // #4866
  5282. );
  5283. // Decide the clipping needed to keep the graph inside
  5284. // the plot area and axis lines
  5285. clip = options.offset ?
  5286. 0 :
  5287. Math.floor(axis.axisLine.strokeWidth() / 2) * 2; // #4308, #4371
  5288. clipOffset[invertedSide] = Math.max(clipOffset[invertedSide], clip);
  5289. fireEvent(this, 'afterGetOffset');
  5290. },
  5291. /**
  5292. * Internal function to get the path for the axis line. Extended for polar
  5293. * charts.
  5294. *
  5295. * @function Highcharts.Axis#getLinePath
  5296. *
  5297. * @param {number} lineWidth
  5298. * The line width in pixels.
  5299. *
  5300. * @return {Highcharts.SVGPathArray}
  5301. * The SVG path definition in array form.
  5302. */
  5303. getLinePath: function (lineWidth) {
  5304. var chart = this.chart,
  5305. opposite = this.opposite,
  5306. offset = this.offset,
  5307. horiz = this.horiz,
  5308. lineLeft = this.left + (opposite ? this.width : 0) + offset,
  5309. lineTop = chart.chartHeight - this.bottom -
  5310. (opposite ? this.height : 0) + offset;
  5311. if (opposite) {
  5312. lineWidth *= -1; // crispify the other way - #1480, #1687
  5313. }
  5314. return chart.renderer
  5315. .crispLine([
  5316. 'M',
  5317. horiz ?
  5318. this.left :
  5319. lineLeft,
  5320. horiz ?
  5321. lineTop :
  5322. this.top,
  5323. 'L',
  5324. horiz ?
  5325. chart.chartWidth - this.right :
  5326. lineLeft,
  5327. horiz ?
  5328. lineTop :
  5329. chart.chartHeight - this.bottom
  5330. ], lineWidth);
  5331. },
  5332. /**
  5333. * Render the axis line. Called internally when rendering and redrawing the
  5334. * axis.
  5335. *
  5336. * @function Highcharts.Axis#renderLine
  5337. */
  5338. renderLine: function () {
  5339. if (!this.axisLine) {
  5340. this.axisLine = this.chart.renderer.path()
  5341. .addClass('highcharts-axis-line')
  5342. .add(this.axisGroup);
  5343. if (!this.chart.styledMode) {
  5344. this.axisLine.attr({
  5345. stroke: this.options.lineColor,
  5346. 'stroke-width': this.options.lineWidth,
  5347. zIndex: 7
  5348. });
  5349. }
  5350. }
  5351. },
  5352. /**
  5353. * Position the axis title.
  5354. * @private
  5355. * @return {Highcharts.PositionObject} X and Y positions for the title.
  5356. */
  5357. getTitlePosition: function () {
  5358. // compute anchor points for each of the title align options
  5359. var horiz = this.horiz,
  5360. axisLeft = this.left,
  5361. axisTop = this.top,
  5362. axisLength = this.len,
  5363. axisTitleOptions = this.options.title,
  5364. margin = horiz ? axisLeft : axisTop,
  5365. opposite = this.opposite,
  5366. offset = this.offset,
  5367. xOption = axisTitleOptions.x || 0,
  5368. yOption = axisTitleOptions.y || 0,
  5369. axisTitle = this.axisTitle,
  5370. fontMetrics = this.chart.renderer.fontMetrics(
  5371. axisTitleOptions.style && axisTitleOptions.style.fontSize,
  5372. axisTitle
  5373. ),
  5374. // The part of a multiline text that is below the baseline of the
  5375. // first line. Subtract 1 to preserve pixel-perfectness from the
  5376. // old behaviour (v5.0.12), where only one line was allowed.
  5377. textHeightOvershoot = Math.max(
  5378. axisTitle.getBBox(null, 0).height - fontMetrics.h - 1,
  5379. 0
  5380. ),
  5381. // the position in the length direction of the axis
  5382. alongAxis = {
  5383. low: margin + (horiz ? 0 : axisLength),
  5384. middle: margin + axisLength / 2,
  5385. high: margin + (horiz ? axisLength : 0)
  5386. }[axisTitleOptions.align],
  5387. // the position in the perpendicular direction of the axis
  5388. offAxis = (horiz ? axisTop + this.height : axisLeft) +
  5389. (horiz ? 1 : -1) * // horizontal axis reverses the margin
  5390. (opposite ? -1 : 1) * // so does opposite axes
  5391. this.axisTitleMargin +
  5392. [
  5393. -textHeightOvershoot, // top
  5394. textHeightOvershoot, // right
  5395. fontMetrics.f, // bottom
  5396. -textHeightOvershoot // left
  5397. ][this.side],
  5398. titlePosition = {
  5399. x: horiz ?
  5400. alongAxis + xOption :
  5401. offAxis + (opposite ? this.width : 0) + offset + xOption,
  5402. y: horiz ?
  5403. offAxis + yOption - (opposite ? this.height : 0) + offset :
  5404. alongAxis + yOption
  5405. };
  5406. fireEvent(
  5407. this,
  5408. 'afterGetTitlePosition',
  5409. { titlePosition: titlePosition }
  5410. );
  5411. return titlePosition;
  5412. },
  5413. /**
  5414. * Render a minor tick into the given position. If a minor tick already
  5415. * exists in this position, move it.
  5416. *
  5417. * @function Highcharts.Axis#renderMinorTick
  5418. *
  5419. * @param {number} pos
  5420. * The position in axis values.
  5421. */
  5422. renderMinorTick: function (pos) {
  5423. var slideInTicks = this.chart.hasRendered && isNumber(this.oldMin),
  5424. minorTicks = this.minorTicks;
  5425. if (!minorTicks[pos]) {
  5426. minorTicks[pos] = new Tick(this, pos, 'minor');
  5427. }
  5428. // Render new ticks in old position
  5429. if (slideInTicks && minorTicks[pos].isNew) {
  5430. minorTicks[pos].render(null, true);
  5431. }
  5432. minorTicks[pos].render(null, false, 1);
  5433. },
  5434. /**
  5435. * Render a major tick into the given position. If a tick already exists
  5436. * in this position, move it.
  5437. *
  5438. * @function Highcharts.Axis#renderTick
  5439. *
  5440. * @param {number} pos
  5441. * The position in axis values.
  5442. *
  5443. * @param {number} i
  5444. * The tick index.
  5445. */
  5446. renderTick: function (pos, i) {
  5447. var isLinked = this.isLinked,
  5448. ticks = this.ticks,
  5449. slideInTicks = this.chart.hasRendered && isNumber(this.oldMin);
  5450. // Linked axes need an extra check to find out if
  5451. if (!isLinked || (pos >= this.min && pos <= this.max)) {
  5452. if (!ticks[pos]) {
  5453. ticks[pos] = new Tick(this, pos);
  5454. }
  5455. // NOTE this seems like overkill. Could be handled in tick.render by
  5456. // setting old position in attr, then set new position in animate.
  5457. // render new ticks in old position
  5458. if (slideInTicks && ticks[pos].isNew) {
  5459. // Start with negative opacity so that it is visible from
  5460. // halfway into the animation
  5461. ticks[pos].render(i, true, -1);
  5462. }
  5463. ticks[pos].render(i);
  5464. }
  5465. },
  5466. /**
  5467. * Render the axis.
  5468. * @private
  5469. * @fires Highcharts.Axis#event:afterRender
  5470. */
  5471. render: function () {
  5472. var axis = this,
  5473. chart = axis.chart,
  5474. renderer = chart.renderer,
  5475. options = axis.options,
  5476. isLog = axis.isLog,
  5477. isLinked = axis.isLinked,
  5478. tickPositions = axis.tickPositions,
  5479. axisTitle = axis.axisTitle,
  5480. ticks = axis.ticks,
  5481. minorTicks = axis.minorTicks,
  5482. alternateBands = axis.alternateBands,
  5483. stackLabelOptions = options.stackLabels,
  5484. alternateGridColor = options.alternateGridColor,
  5485. tickmarkOffset = axis.tickmarkOffset,
  5486. axisLine = axis.axisLine,
  5487. showAxis = axis.showAxis,
  5488. animation = animObject(renderer.globalAnimation),
  5489. from,
  5490. to;
  5491. // Reset
  5492. axis.labelEdge.length = 0;
  5493. axis.overlap = false;
  5494. // Mark all elements inActive before we go over and mark the active ones
  5495. [ticks, minorTicks, alternateBands].forEach(function (coll) {
  5496. objectEach(coll, function (tick) {
  5497. tick.isActive = false;
  5498. });
  5499. });
  5500. // If the series has data draw the ticks. Else only the line and title
  5501. if (axis.hasData() || isLinked) {
  5502. // minor ticks
  5503. if (axis.minorTickInterval && !axis.categories) {
  5504. axis.getMinorTickPositions().forEach(function (pos) {
  5505. axis.renderMinorTick(pos);
  5506. });
  5507. }
  5508. // Major ticks. Pull out the first item and render it last so that
  5509. // we can get the position of the neighbour label. #808.
  5510. if (tickPositions.length) { // #1300
  5511. tickPositions.forEach(function (pos, i) {
  5512. axis.renderTick(pos, i);
  5513. });
  5514. // In a categorized axis, the tick marks are displayed
  5515. // between labels. So we need to add a tick mark and
  5516. // grid line at the left edge of the X axis.
  5517. if (tickmarkOffset && (axis.min === 0 || axis.single)) {
  5518. if (!ticks[-1]) {
  5519. ticks[-1] = new Tick(axis, -1, null, true);
  5520. }
  5521. ticks[-1].render(-1);
  5522. }
  5523. }
  5524. // alternate grid color
  5525. if (alternateGridColor) {
  5526. tickPositions.forEach(function (pos, i) {
  5527. to = tickPositions[i + 1] !== undefined ?
  5528. tickPositions[i + 1] + tickmarkOffset :
  5529. axis.max - tickmarkOffset;
  5530. if (
  5531. i % 2 === 0 &&
  5532. pos < axis.max &&
  5533. to <= axis.max + (
  5534. chart.polar ?
  5535. -tickmarkOffset :
  5536. tickmarkOffset
  5537. )
  5538. ) { // #2248, #4660
  5539. if (!alternateBands[pos]) {
  5540. alternateBands[pos] = new H.PlotLineOrBand(axis);
  5541. }
  5542. from = pos + tickmarkOffset; // #949
  5543. alternateBands[pos].options = {
  5544. from: isLog ? axis.lin2log(from) : from,
  5545. to: isLog ? axis.lin2log(to) : to,
  5546. color: alternateGridColor
  5547. };
  5548. alternateBands[pos].render();
  5549. alternateBands[pos].isActive = true;
  5550. }
  5551. });
  5552. }
  5553. // custom plot lines and bands
  5554. if (!axis._addedPlotLB) { // only first time
  5555. (
  5556. (options.plotLines || []).concat(options.plotBands || [])
  5557. ).forEach(
  5558. function (plotLineOptions) {
  5559. axis.addPlotBandOrLine(plotLineOptions);
  5560. }
  5561. );
  5562. axis._addedPlotLB = true;
  5563. }
  5564. } // end if hasData
  5565. // Remove inactive ticks
  5566. [ticks, minorTicks, alternateBands].forEach(function (coll) {
  5567. var i,
  5568. forDestruction = [],
  5569. delay = animation.duration,
  5570. destroyInactiveItems = function () {
  5571. i = forDestruction.length;
  5572. while (i--) {
  5573. // When resizing rapidly, the same items
  5574. // may be destroyed in different timeouts,
  5575. // or the may be reactivated
  5576. if (
  5577. coll[forDestruction[i]] &&
  5578. !coll[forDestruction[i]].isActive
  5579. ) {
  5580. coll[forDestruction[i]].destroy();
  5581. delete coll[forDestruction[i]];
  5582. }
  5583. }
  5584. };
  5585. objectEach(coll, function (tick, pos) {
  5586. if (!tick.isActive) {
  5587. // Render to zero opacity
  5588. tick.render(pos, false, 0);
  5589. tick.isActive = false;
  5590. forDestruction.push(pos);
  5591. }
  5592. });
  5593. // When the objects are finished fading out, destroy them
  5594. syncTimeout(
  5595. destroyInactiveItems,
  5596. coll === alternateBands ||
  5597. !chart.hasRendered ||
  5598. !delay ?
  5599. 0 :
  5600. delay
  5601. );
  5602. });
  5603. // Set the axis line path
  5604. if (axisLine) {
  5605. axisLine[axisLine.isPlaced ? 'animate' : 'attr']({
  5606. d: this.getLinePath(axisLine.strokeWidth())
  5607. });
  5608. axisLine.isPlaced = true;
  5609. // Show or hide the line depending on options.showEmpty
  5610. axisLine[showAxis ? 'show' : 'hide'](true);
  5611. }
  5612. if (axisTitle && showAxis) {
  5613. var titleXy = axis.getTitlePosition();
  5614. if (isNumber(titleXy.y)) {
  5615. axisTitle[axisTitle.isNew ? 'attr' : 'animate'](titleXy);
  5616. axisTitle.isNew = false;
  5617. } else {
  5618. axisTitle.attr('y', -9999);
  5619. axisTitle.isNew = true;
  5620. }
  5621. }
  5622. // Stacked totals:
  5623. if (stackLabelOptions && stackLabelOptions.enabled) {
  5624. axis.renderStackTotals();
  5625. }
  5626. // End stacked totals
  5627. axis.isDirty = false;
  5628. fireEvent(this, 'afterRender');
  5629. },
  5630. // Redraw the axis to reflect changes in the data or axis extremes. Called
  5631. // internally from Highcharts.Chart#redraw.
  5632. redraw: function () {
  5633. if (this.visible) {
  5634. // render the axis
  5635. this.render();
  5636. // move plot lines and bands
  5637. this.plotLinesAndBands.forEach(function (plotLine) {
  5638. plotLine.render();
  5639. });
  5640. }
  5641. // mark associated series as dirty and ready for redraw
  5642. this.series.forEach(function (series) {
  5643. series.isDirty = true;
  5644. });
  5645. },
  5646. // Properties to survive after destroy, needed for Axis.update (#4317,
  5647. // #5773, #5881).
  5648. keepProps: ['extKey', 'hcEvents', 'names', 'series', 'userMax', 'userMin'],
  5649. /**
  5650. * Destroys an Axis instance. See {@link Axis#remove} for the API endpoint
  5651. * to fully remove the axis.
  5652. * @private
  5653. * @param {boolean} keepEvents Whether to preserve events, used internally
  5654. * in Axis.update.
  5655. */
  5656. destroy: function (keepEvents) {
  5657. var axis = this,
  5658. stacks = axis.stacks,
  5659. plotLinesAndBands = axis.plotLinesAndBands,
  5660. plotGroup,
  5661. i;
  5662. fireEvent(this, 'destroy', { keepEvents: keepEvents });
  5663. // Remove the events
  5664. if (!keepEvents) {
  5665. removeEvent(axis);
  5666. }
  5667. // Destroy each stack total
  5668. objectEach(stacks, function (stack, stackKey) {
  5669. destroyObjectProperties(stack);
  5670. stacks[stackKey] = null;
  5671. });
  5672. // Destroy collections
  5673. [axis.ticks, axis.minorTicks, axis.alternateBands].forEach(
  5674. function (coll) {
  5675. destroyObjectProperties(coll);
  5676. }
  5677. );
  5678. if (plotLinesAndBands) {
  5679. i = plotLinesAndBands.length;
  5680. while (i--) { // #1975
  5681. plotLinesAndBands[i].destroy();
  5682. }
  5683. }
  5684. // Destroy elements
  5685. ['stackTotalGroup', 'axisLine', 'axisTitle', 'axisGroup',
  5686. 'gridGroup', 'labelGroup', 'cross', 'scrollbar'].forEach(
  5687. function (prop) {
  5688. if (axis[prop]) {
  5689. axis[prop] = axis[prop].destroy();
  5690. }
  5691. }
  5692. );
  5693. // Destroy each generated group for plotlines and plotbands
  5694. for (plotGroup in axis.plotLinesAndBandsGroups) {
  5695. axis.plotLinesAndBandsGroups[plotGroup] =
  5696. axis.plotLinesAndBandsGroups[plotGroup].destroy();
  5697. }
  5698. // Delete all properties and fall back to the prototype.
  5699. objectEach(axis, function (val, key) {
  5700. if (axis.keepProps.indexOf(key) === -1) {
  5701. delete axis[key];
  5702. }
  5703. });
  5704. },
  5705. /**
  5706. * Internal function to draw a crosshair.
  5707. *
  5708. * @function Highcharts.Axis#drawCrosshair
  5709. *
  5710. * @param {Highcharts.PointerEventObject} [e]
  5711. * The event arguments from the modified pointer event, extended with
  5712. * `chartX` and `chartY`
  5713. *
  5714. * @param {Highcharts.Point} [point]
  5715. * The Point object if the crosshair snaps to points.
  5716. *
  5717. * @fires Highcharts.Axis#event:afterDrawCrosshair
  5718. * @fires Highcharts.Axis#event:drawCrosshair
  5719. */
  5720. drawCrosshair: function (e, point) {
  5721. var path,
  5722. options = this.crosshair,
  5723. snap = pick(options.snap, true),
  5724. pos,
  5725. categorized,
  5726. graphic = this.cross;
  5727. fireEvent(this, 'drawCrosshair', { e: e, point: point });
  5728. // Use last available event when updating non-snapped crosshairs without
  5729. // mouse interaction (#5287)
  5730. if (!e) {
  5731. e = this.cross && this.cross.e;
  5732. }
  5733. if (
  5734. // Disabled in options
  5735. !this.crosshair ||
  5736. // Snap
  5737. ((defined(point) || !snap) === false)
  5738. ) {
  5739. this.hideCrosshair();
  5740. } else {
  5741. // Get the path
  5742. if (!snap) {
  5743. pos = e &&
  5744. (
  5745. this.horiz ?
  5746. e.chartX - this.pos :
  5747. this.len - e.chartY + this.pos
  5748. );
  5749. } else if (defined(point)) {
  5750. // #3834
  5751. pos = pick(
  5752. point.crosshairPos, // 3D axis extension
  5753. this.isXAxis ? point.plotX : this.len - point.plotY
  5754. );
  5755. }
  5756. if (defined(pos)) {
  5757. path = this.getPlotLinePath(
  5758. // First argument, value, only used on radial
  5759. point && (this.isXAxis ?
  5760. point.x :
  5761. pick(point.stackY, point.y)
  5762. ),
  5763. null,
  5764. null,
  5765. null,
  5766. pos // Translated position
  5767. ) || null; // #3189
  5768. }
  5769. if (!defined(path)) {
  5770. this.hideCrosshair();
  5771. return;
  5772. }
  5773. categorized = this.categories && !this.isRadial;
  5774. // Draw the cross
  5775. if (!graphic) {
  5776. this.cross = graphic = this.chart.renderer
  5777. .path()
  5778. .addClass(
  5779. 'highcharts-crosshair highcharts-crosshair-' +
  5780. (categorized ? 'category ' : 'thin ') +
  5781. options.className
  5782. )
  5783. .attr({
  5784. zIndex: pick(options.zIndex, 2)
  5785. })
  5786. .add();
  5787. // Presentational attributes
  5788. if (!this.chart.styledMode) {
  5789. graphic.attr({
  5790. 'stroke': options.color ||
  5791. (
  5792. categorized ?
  5793. color('#ccd6eb')
  5794. .setOpacity(0.25).get() :
  5795. '#cccccc'
  5796. ),
  5797. 'stroke-width': pick(options.width, 1)
  5798. }).css({
  5799. 'pointer-events': 'none'
  5800. });
  5801. if (options.dashStyle) {
  5802. graphic.attr({
  5803. dashstyle: options.dashStyle
  5804. });
  5805. }
  5806. }
  5807. }
  5808. graphic.show().attr({
  5809. d: path
  5810. });
  5811. if (categorized && !options.width) {
  5812. graphic.attr({
  5813. 'stroke-width': this.transA
  5814. });
  5815. }
  5816. this.cross.e = e;
  5817. }
  5818. fireEvent(this, 'afterDrawCrosshair', { e: e, point: point });
  5819. },
  5820. /**
  5821. * Hide the crosshair if visible.
  5822. *
  5823. * @function Highcharts.Axis#hideCrosshair
  5824. */
  5825. hideCrosshair: function () {
  5826. if (this.cross) {
  5827. this.cross.hide();
  5828. }
  5829. fireEvent(this, 'afterHideCrosshair');
  5830. }
  5831. }); // end Axis
  5832. H.Axis = Axis;
  5833. export default Axis;