1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470847184728473847484758476847784788479848084818482848384848485848684878488848984908491849284938494849584968497849884998500850185028503850485058506850785088509851085118512851385148515851685178518851985208521852285238524852585268527852885298530853185328533853485358536853785388539854085418542854385448545854685478548854985508551855285538554855585568557855885598560856185628563856485658566856785688569857085718572857385748575857685778578857985808581858285838584858585868587858885898590859185928593859485958596859785988599860086018602860386048605860686078608860986108611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668866986708671867286738674867586768677867886798680868186828683868486858686868786888689869086918692869386948695869686978698869987008701870287038704870587068707870887098710871187128713871487158716871787188719872087218722872387248725872687278728872987308731873287338734873587368737873887398740874187428743874487458746874787488749875087518752875387548755875687578758875987608761876287638764876587668767876887698770877187728773877487758776877787788779878087818782878387848785878687878788878987908791879287938794879587968797879887998800880188028803880488058806880788088809881088118812881388148815881688178818881988208821882288238824882588268827882888298830883188328833883488358836883788388839884088418842884388448845884688478848884988508851885288538854885588568857885888598860886188628863886488658866886788688869887088718872887388748875887688778878887988808881888288838884888588868887888888898890889188928893889488958896889788988899890089018902890389048905890689078908890989108911891289138914891589168917891889198920892189228923892489258926892789288929893089318932893389348935893689378938893989408941894289438944894589468947894889498950895189528953895489558956895789588959896089618962896389648965896689678968896989708971897289738974897589768977897889798980898189828983898489858986898789888989899089918992899389948995899689978998899990009001900290039004900590069007900890099010901190129013901490159016901790189019902090219022902390249025902690279028902990309031903290339034903590369037903890399040904190429043904490459046904790489049905090519052905390549055905690579058905990609061906290639064906590669067906890699070907190729073907490759076907790789079908090819082908390849085908690879088908990909091909290939094909590969097909890999100910191029103910491059106910791089109911091119112911391149115911691179118911991209121912291239124912591269127912891299130913191329133913491359136913791389139914091419142914391449145914691479148914991509151915291539154915591569157915891599160916191629163916491659166916791689169917091719172917391749175917691779178917991809181918291839184918591869187918891899190919191929193919491959196919791989199920092019202920392049205920692079208920992109211921292139214921592169217921892199220922192229223922492259226922792289229923092319232923392349235923692379238923992409241924292439244924592469247924892499250925192529253925492559256925792589259926092619262926392649265926692679268926992709271927292739274927592769277927892799280928192829283928492859286928792889289929092919292929392949295929692979298929993009301930293039304930593069307930893099310931193129313931493159316931793189319932093219322932393249325932693279328932993309331933293339334933593369337933893399340934193429343934493459346934793489349935093519352935393549355935693579358935993609361936293639364936593669367936893699370937193729373937493759376937793789379938093819382938393849385938693879388938993909391939293939394939593969397939893999400940194029403940494059406940794089409941094119412941394149415941694179418941994209421942294239424942594269427942894299430943194329433943494359436943794389439944094419442944394449445944694479448944994509451945294539454945594569457945894599460946194629463946494659466946794689469947094719472947394749475947694779478947994809481948294839484948594869487948894899490949194929493949494959496949794989499950095019502950395049505950695079508950995109511951295139514951595169517951895199520952195229523952495259526952795289529 |
-
- (function() {
- var doc = document,
- win = window,
- math = Math,
- mathRound = math.round,
- mathFloor = math.floor,
- mathCeil = math.ceil,
- mathMax = math.max,
- mathMin = math.min,
- mathAbs = math.abs,
- mathCos = math.cos,
- mathSin = math.sin,
- mathPI = math.PI,
- deg2rad = mathPI * 2 / 360,
-
-
-
- userAgent = navigator.userAgent,
- isIE = /msie/i.test(userAgent) && !win.opera,
- docMode8 = doc.documentMode == 8,
- isWebKit = /AppleWebKit/.test(userAgent),
- hasSVG = win.SVGAngle || doc.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1"),
- useCanVG = !hasSVG && !isIE && !!doc.createElement('canvas').getContext,
- hasTouch = 'ontouchstart' in doc.documentElement,
- colorCounter,
- symbolCounter,
- symbolSizes = {},
- idCounter = 0,
- timeFactor = 1,
- garbageBin,
- defaultOptions,
- dateFormat,
- globalAnimation,
- pathAnim,
-
-
-
- UNDEFINED,
- DIV = 'div',
- ABSOLUTE = 'absolute',
- RELATIVE = 'relative',
- HIDDEN = 'hidden',
- PREFIX = 'highcharts-',
- VISIBLE = 'visible',
- PX = 'px',
- NONE = 'none',
- M = 'M',
- L = 'L',
-
- TRACKER_FILL = 'rgba(192,192,192,'+ (hasSVG ? 0.000001 : 0.002) +')',
- NORMAL_STATE = '',
- HOVER_STATE = 'hover',
- SELECT_STATE = 'select',
-
-
- makeTime,
- getMinutes,
- getHours,
- getDay,
- getDate,
- getMonth,
- getFullYear,
- setMinutes,
- setHours,
- setDate,
- setMonth,
- setFullYear,
-
-
- globalAdapter = win.HighchartsAdapter,
- adapter = globalAdapter || {},
-
-
-
-
- each = adapter.each,
- grep = adapter.grep,
- map = adapter.map,
- merge = adapter.merge,
- hyphenate = adapter.hyphenate,
- addEvent = adapter.addEvent,
- removeEvent = adapter.removeEvent,
- fireEvent = adapter.fireEvent,
- animate = adapter.animate,
- stop = adapter.stop,
-
-
- seriesTypes = {};
-
- function extend(a, b) {
- if (!a) {
- a = {};
- }
- for (var n in b) {
- a[n] = b[n];
- }
- return a;
- }
- function pInt(s, mag) {
- return parseInt(s, mag || 10);
- }
- function isString(s) {
- return typeof s == 'string';
- }
- function isObject(obj) {
- return typeof obj == 'object';
- }
- function isNumber(n) {
- return typeof n == 'number';
- }
- function erase(arr, item) {
- var i = arr.length;
- while (i--) {
- if (arr[i] == item) {
- arr.splice(i, 1);
- break;
- }
- }
-
- }
- function defined (obj) {
- return obj !== UNDEFINED && obj !== null;
- }
- function attr(elem, prop, value) {
- var key,
- setAttribute = 'setAttribute',
- ret;
-
-
- if (isString(prop)) {
-
- if (defined(value)) {
- elem[setAttribute](prop, value);
-
-
- } else if (elem && elem.getAttribute) {
- ret = elem.getAttribute(prop);
- }
-
-
- } else if (defined(prop) && isObject(prop)) {
- for (key in prop) {
- elem[setAttribute](key, prop[key]);
- }
- }
- return ret;
- }
- function splat(obj) {
- if (!obj || obj.constructor != Array) {
- obj = [obj];
- }
- return obj;
- }
- function pick() {
- var args = arguments,
- i,
- arg;
- for (i = 0; i < args.length; i++) {
- arg = args[i];
- if (defined(arg)) {
- return arg;
- }
- }
- }
- function serializeCSS(style) {
- var s = '',
- key;
-
- for (key in style) {
- s += hyphenate(key) +':'+ style[key] + ';';
- }
- return s;
-
- }
- function css (el, styles) {
- if (isIE) {
- if (styles && styles.opacity !== UNDEFINED) {
- styles.filter = 'alpha(opacity='+ (styles.opacity * 100) +')';
- }
- }
- extend(el.style, styles);
- }
- function createElement (tag, attribs, styles, parent, nopad) {
- var el = doc.createElement(tag);
- if (attribs) {
- extend(el, attribs);
- }
- if (nopad) {
- css(el, {padding: 0, border: NONE, margin: 0});
- }
- if (styles) {
- css(el, styles);
- }
- if (parent) {
- parent.appendChild(el);
- }
- return el;
- }
- function setAnimation(animation, chart) {
- globalAnimation = pick(animation, chart.animation);
- }
- if (globalAdapter && globalAdapter.init) {
- globalAdapter.init();
- }
- if (!globalAdapter && win.jQuery) {
- var jQ = jQuery;
-
-
- each = function(arr, fn) {
- for (var i = 0, len = arr.length; i < len; i++) {
- if (fn.call(arr[i], arr[i], i, arr) === false) {
- return i;
- }
- }
- };
-
-
- grep = jQ.grep;
-
-
- map = function(arr, fn){
-
- var results = [];
- for (var i = 0, len = arr.length; i < len; i++) {
- results[i] = fn.call(arr[i], arr[i], i, arr);
- }
- return results;
-
- };
-
-
- merge = function(){
- var args = arguments;
- return jQ.extend(true, null, args[0], args[1], args[2], args[3]);
- };
-
-
- hyphenate = function (str) {
- return str.replace(/([A-Z])/g, function(a, b){ return '-'+ b.toLowerCase(); });
- };
-
-
- addEvent = function (el, event, fn){
- jQ(el).bind(event, fn);
- };
-
-
- removeEvent = function(el, eventType, handler) {
-
-
- var func = doc.removeEventListener ? 'removeEventListener' : 'detachEvent';
- if (doc[func] && !el[func]) {
- el[func] = function() {};
- }
-
- jQ(el).unbind(eventType, handler);
- };
-
-
- fireEvent = function(el, type, eventArguments, defaultFunction) {
- var m_event = jQ.Event(type),
- detachedType = 'detached'+ type;
- extend(event, eventArguments);
-
-
-
-
- if (el[type]) {
- el[detachedType] = el[type];
- el[type] = null;
- }
-
-
- jQ(el).trigger(m_event);
-
-
- if (el[detachedType]) {
- el[type] = el[detachedType];
- el[detachedType] = null;
- }
-
- if (defaultFunction && !m_event.isDefaultPrevented()) {
- defaultFunction(m_event);
- }
- };
-
- animate = function (el, params, options) {
- var $el = jQ(el);
- if (params.d) {
- el.toD = params.d;
- params.d = 1;
- }
-
- $el.stop();
- $el.animate(params, options);
-
- };
-
- stop = function (el) {
- jQ(el).stop();
- };
-
-
-
- jQ.extend( jQ.easing, {
- easeOutQuad: function (x, t, b, c, d) {
- return -c *(t/=d)*(t-2) + b;
- }
- });
-
-
- var oldStepDefault = jQuery.fx.step._default,
- oldCur = jQuery.fx.prototype.cur;
-
-
- jQ.fx.step._default = function(fx){
- var elem = fx.elem;
- if (elem.attr) {
- elem.attr(fx.prop, fx.now);
- } else {
- oldStepDefault.apply(this, arguments);
- }
- };
-
- jQ.fx.step.d = function(fx) {
- var elem = fx.elem;
-
-
-
-
-
- if (!fx.started) {
- var ends = pathAnim.init(elem, elem.d, elem.toD);
- fx.start = ends[0];
- fx.end = ends[1];
- fx.started = true;
- }
-
-
-
- elem.attr('d', pathAnim.step(fx.start, fx.end, fx.pos, elem.toD));
-
- };
-
- jQ.fx.prototype.cur = function() {
- var elem = this.elem,
- r;
- if (elem.attr) {
- r = elem.attr(this.prop);
- } else {
- r = oldCur.apply(this, arguments);
- }
- return r;
- };
- }
- pathAnim = {
-
- init: function(elem, fromD, toD) {
- fromD = fromD || '';
- var shift = elem.shift,
- bezier = fromD.indexOf('C') > -1,
- numParams = bezier ? 7 : 3,
- endLength,
- slice,
- i,
- start = fromD.split(' '),
- end = [].concat(toD),
- startBaseLine,
- endBaseLine,
- sixify = function(arr) {
- i = arr.length;
- while (i--) {
- if (arr[i] == M) {
- arr.splice(i + 1, 0, arr[i+1], arr[i+2], arr[i+1], arr[i+2]);
- }
- }
- };
-
- if (bezier) {
- sixify(start);
- sixify(end);
- }
-
-
- if (elem.isArea) {
- startBaseLine = start.splice(start.length - 6, 6);
- endBaseLine = end.splice(end.length - 6, 6);
- }
-
-
- if (shift) {
- end = [].concat(end).splice(0, numParams).concat(end);
- elem.shift = false;
- }
-
-
- endLength = end.length;
- while (start.length < endLength) {
-
-
- slice = [].concat(start).splice(start.length - numParams, numParams);
- if (bezier) {
- slice[numParams - 6] = slice[numParams - 2];
- slice[numParams - 5] = slice[numParams - 1];
- }
- start = start.concat(slice);
- }
-
- if (startBaseLine) {
- start = start.concat(startBaseLine);
- end = end.concat(endBaseLine);
- }
- return [start, end];
- },
-
-
- step: function(start, end, pos, complete) {
- var ret = [],
- i = start.length,
- startVal;
-
- if (pos == 1) {
- ret = complete;
-
- } else if (i == end.length && pos < 1) {
- while (i--) {
- startVal = parseFloat(start[i]);
- ret[i] =
- isNaN(startVal) ?
- start[i] :
- pos * (parseFloat(end[i] - startVal)) + startVal;
-
- }
- } else {
- ret = end;
- }
- return ret;
- }
- };
- function setTimeMethods() {
- var useUTC = defaultOptions.global.useUTC;
-
- makeTime = useUTC ? Date.UTC : function(year, month, date, hours, minutes, seconds) {
- return new Date(
- year,
- month,
- pick(date, 1),
- pick(hours, 0),
- pick(minutes, 0),
- pick(seconds, 0)
- ).getTime();
- };
- getMinutes = useUTC ? 'getUTCMinutes' : 'getMinutes';
- getHours = useUTC ? 'getUTCHours' : 'getHours';
- getDay = useUTC ? 'getUTCDay' : 'getDay';
- getDate = useUTC ? 'getUTCDate' : 'getDate';
- getMonth = useUTC ? 'getUTCMonth' : 'getMonth';
- getFullYear = useUTC ? 'getUTCFullYear' : 'getFullYear';
- setMinutes = useUTC ? 'setUTCMinutes' : 'setMinutes';
- setHours = useUTC ? 'setUTCHours' : 'setHours';
- setDate = useUTC ? 'setUTCDate' : 'setDate';
- setMonth = useUTC ? 'setUTCMonth' : 'setMonth';
- setFullYear = useUTC ? 'setUTCFullYear' : 'setFullYear';
-
- }
- function setOptions(options) {
- defaultOptions = merge(defaultOptions, options);
-
-
- setTimeMethods();
-
- return defaultOptions;
- }
- function getOptions() {
- return defaultOptions;
- }
- function discardElement(element) {
-
- if (!garbageBin) {
- garbageBin = createElement(DIV);
- }
-
-
- if (element) {
- garbageBin.appendChild(element);
- }
- garbageBin.innerHTML = '';
- }
- var deferredCanvases = [];
- function drawDeferredCanvases() {
- each(deferredCanvases, function(fn) {
- fn();
- erase(deferredCanvases, fn);
- });
- }
- var
- defaultLabelOptions = {
- enabled: true,
-
- align: 'center',
- x: 0,
- y: 15,
-
- style: {
- color: '#666',
- fontSize: '11px'
- }
- };
- defaultOptions = {
- colors: ['#4572A7', '#AA4643', '#89A54E', '#80699B', '#3D96AE',
- '#DB843D', '#92A8CD', '#A47D7C', '#B5CA92'],
- symbols: ['circle', 'diamond', 'square', 'triangle', 'triangle-down'],
- lang: {
- loading: 'Loading...',
- months: ['January', 'February', 'March', 'April', 'May', 'June', 'July',
- 'August', 'September', 'October', 'November', 'December'],
- weekdays: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
- decimalPoint: '.',
- resetZoom: 'Reset zoom',
- resetZoomTitle: 'Reset zoom level 1:1',
- thousandsSep: ','
- },
- global: {
- useUTC: true
- },
- chart: {
-
-
-
-
-
-
-
-
-
-
- borderColor: '#4572A7',
-
- borderRadius: 5,
- defaultSeriesType: 'line',
- ignoreHiddenSeries: true,
-
-
- spacingTop: 10,
- spacingRight: 10,
- spacingBottom: 15,
- spacingLeft: 10,
- style: {
- fontFamily: '"Lucida Grande", "Lucida Sans Unicode", Verdana, Arial, Helvetica, sans-serif',
- fontSize: '12px'
- },
- backgroundColor: '#FFFFFF',
-
- plotBorderColor: '#C0C0C0'
-
-
-
- },
- title: {
- text: 'Chart title',
- align: 'center',
-
-
-
-
- y: 15,
- style: {
- color: '#3E576F',
- fontSize: '16px'
- }
- },
- subtitle: {
- text: '',
- align: 'center',
-
-
-
- y: 30,
- style: {
- color: '#6D869F'
- }
- },
-
- plotOptions: {
- line: {
- allowPointSelect: false,
- showCheckbox: false,
- animation: {
- duration: 1000
- },
-
-
-
- events: {},
- lineWidth: 2,
- shadow: true,
-
- marker: {
- enabled: true,
-
- lineWidth: 0,
- radius: 4,
- lineColor: '#FFFFFF',
-
- states: {
- hover: {
-
- },
- select: {
- fillColor: '#FFFFFF',
- lineColor: '#000000',
- lineWidth: 2
- }
- }
- },
- point: {
- events: {}
- },
- dataLabels: merge(defaultLabelOptions, {
- enabled: false,
- y: -6,
- formatter: function() {
- return this.y;
- }
- }),
-
-
-
- showInLegend: true,
- states: {
- hover: {
-
-
- marker: {
-
-
- }
- },
- select: {
- marker: {}
- }
- },
- stickyTracking: true
-
- }
- },
- labels: {
-
- style: {
-
- position: ABSOLUTE,
- color: '#3E576F'
- }
- },
- legend: {
- enabled: true,
- align: 'center',
-
- layout: 'horizontal',
- labelFormatter: function() {
- return this.name;
- },
-
- borderWidth: 1,
- borderColor: '#909090',
- borderRadius: 5,
-
-
- shadow: false,
-
- style: {
- padding: '5px'
- },
- itemStyle: {
- cursor: 'pointer',
- color: '#3E576F'
- },
- itemHoverStyle: {
- cursor: 'pointer',
- color: '#000000'
- },
- itemHiddenStyle: {
- color: '#C0C0C0'
- },
- itemCheckboxStyle: {
- position: ABSOLUTE,
- width: '13px',
- height: '13px'
- },
-
- symbolWidth: 16,
- symbolPadding: 5,
- verticalAlign: 'bottom',
-
- x: 0,
- y: 0
- },
-
- loading: {
- hideDuration: 100,
- labelStyle: {
- fontWeight: 'bold',
- position: RELATIVE,
- top: '1em'
- },
- showDuration: 100,
- style: {
- position: ABSOLUTE,
- backgroundColor: 'white',
- opacity: 0.5,
- textAlign: 'center'
- }
- },
-
- tooltip: {
- enabled: true,
-
- backgroundColor: 'rgba(255, 255, 255, .85)',
- borderWidth: 2,
- borderRadius: 5,
-
- shadow: true,
-
- snap: hasTouch ? 25 : 10,
- style: {
- color: '#333333',
- fontSize: '12px',
- padding: '5px',
- whiteSpace: 'nowrap'
- }
- },
-
- toolbar: {
- itemStyle: {
- color: '#4572A7',
- cursor: 'pointer'
- }
- },
-
- credits: {
- enabled: true,
- text: 'Highcharts.com',
- href: 'http://www.highcharts.com',
- position: {
- align: 'right',
- x: -10,
- verticalAlign: 'bottom',
- y: -5
- },
- style: {
- cursor: 'pointer',
- color: '#909090',
- fontSize: '10px'
- }
- }
- };
- var defaultXAxisOptions = {
-
-
-
- dateTimeLabelFormats: {
- second: '%H:%M:%S',
- minute: '%H:%M',
- hour: '%H:%M',
- day: '%e. %b',
- week: '%e. %b',
- month: '%b \'%y',
- year: '%Y'
- },
- endOnTick: false,
- gridLineColor: '#C0C0C0',
-
-
-
-
- labels: defaultLabelOptions,
-
- lineColor: '#C0D0E0',
- lineWidth: 1,
-
- max: null,
- min: null,
- minPadding: 0.01,
- maxPadding: 0.01,
-
- minorGridLineColor: '#E0E0E0',
-
- minorGridLineWidth: 1,
- minorTickColor: '#A0A0A0',
-
- minorTickLength: 2,
- minorTickPosition: 'outside',
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- startOfWeek: 1,
- startOnTick: false,
- tickColor: '#C0D0E0',
-
- tickLength: 5,
- tickmarkPlacement: 'between',
- tickPixelInterval: 100,
- tickPosition: 'outside',
- tickWidth: 1,
- title: {
-
- align: 'middle',
-
-
-
- style: {
- color: '#6D869F',
-
- fontWeight: 'bold'
- }
-
-
- },
- type: 'linear'
- },
- defaultYAxisOptions = merge(defaultXAxisOptions, {
- endOnTick: true,
- gridLineWidth: 1,
- tickPixelInterval: 72,
- showLastLabel: true,
- labels: {
- align: 'right',
- x: -8,
- y: 3
- },
- lineWidth: 0,
- maxPadding: 0.05,
- minPadding: 0.05,
- startOnTick: true,
- tickWidth: 0,
- title: {
- rotation: 270,
- text: 'Y-values'
- }
- }),
- defaultLeftAxisOptions = {
- labels: {
- align: 'right',
- x: -8,
- y: 3
- },
- title: {
- rotation: 270
- }
- },
- defaultRightAxisOptions = {
- labels: {
- align: 'left',
- x: 8,
- y: 3
- },
- title: {
- rotation: 90
- }
- },
- defaultBottomAxisOptions = {
- labels: {
- align: 'center',
- x: 0,
- y: 14
-
- },
- title: {
- rotation: 0
- }
- },
- defaultTopAxisOptions = merge(defaultBottomAxisOptions, {
- labels: {
- y: -5
-
- }
- });
-
- var defaultPlotOptions = defaultOptions.plotOptions,
- defaultSeriesOptions = defaultPlotOptions.line;
- defaultPlotOptions.spline = merge(defaultSeriesOptions);
- defaultPlotOptions.scatter = merge(defaultSeriesOptions, {
- lineWidth: 0,
- states: {
- hover: {
- lineWidth: 0
- }
- }
- });
- defaultPlotOptions.area = merge(defaultSeriesOptions, {
-
-
-
-
- });
- defaultPlotOptions.areaspline = merge(defaultPlotOptions.area);
- defaultPlotOptions.column = merge(defaultSeriesOptions, {
- borderColor: '#FFFFFF',
- borderWidth: 1,
- borderRadius: 0,
-
- groupPadding: 0.2,
- marker: null,
- pointPadding: 0.1,
-
- minPointLength: 0,
- states: {
- hover: {
- brightness: 0.1,
- shadow: false
- },
- select: {
- color: '#C0C0C0',
- borderColor: '#000000',
- shadow: false
- }
- }
- });
- defaultPlotOptions.bar = merge(defaultPlotOptions.column, {
- dataLabels: {
- align: 'left',
- x: 5,
- y: 0
- }
- });
- defaultPlotOptions.pie = merge(defaultSeriesOptions, {
-
- borderColor: '#FFFFFF',
- borderWidth: 1,
- center: ['50%', '50%'],
- colorByPoint: true,
- dataLabels: {
-
-
-
-
- distance: 30,
- enabled: true,
- formatter: function() {
- return this.point.name;
- },
- y: 5
- },
-
- legendType: 'point',
- marker: null,
- size: '75%',
- showInLegend: false,
- slicedOffset: 10,
- states: {
- hover: {
- brightness: 0.1,
- shadow: false
- }
- }
-
- });
- setTimeMethods();
- function extendClass(parent, members) {
- var object = function(){};
- object.prototype = new parent();
- extend(object.prototype, members);
- return object;
- }
- var Color = function(input) {
-
- var rgba = [], result;
-
-
- function init(input) {
-
-
- if((result = /rgba\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]?(?:\.[0-9]+)?)\s*\)/.exec(input))) {
- rgba = [pInt(result[1]), pInt(result[2]), pInt(result[3]), parseFloat(result[4], 10)];
- }
-
- else if((result = /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(input))) {
- rgba = [pInt(result[1],16), pInt(result[2],16), pInt(result[3],16), 1];
- }
-
- }
-
- function get(format) {
- var ret;
-
-
- if (rgba && !isNaN(rgba[0])) {
- if (format == 'rgb') {
- ret = 'rgb('+ rgba[0] +','+ rgba[1] +','+ rgba[2] +')';
- } else if (format == 'a') {
- ret = rgba[3];
- } else {
- ret = 'rgba('+ rgba.join(',') +')';
- }
- } else {
- ret = input;
- }
- return ret;
- }
-
-
- function brighten(alpha) {
- if (isNumber(alpha) && alpha !== 0) {
- var i;
- for (i = 0; i < 3; i++) {
- rgba[i] += pInt(alpha * 255);
-
- if (rgba[i] < 0) {
- rgba[i] = 0;
- }
- if (rgba[i] > 255) {
- rgba[i] = 255;
- }
- }
- }
- return this;
- }
-
- function setOpacity(alpha) {
- rgba[3] = alpha;
- return this;
- }
-
-
- init(input);
-
-
- return {
- get: get,
- brighten: brighten,
- setOpacity: setOpacity
- };
- };
- function numberFormat (number, decimals, decPoint, thousandsSep) {
- var lang = defaultOptions.lang,
-
- n = number, c = isNaN(decimals = mathAbs(decimals)) ? 2 : decimals,
- d = decPoint === undefined ? lang.decimalPoint : decPoint,
- t = thousandsSep === undefined ? lang.thousandsSep : thousandsSep, s = n < 0 ? "-" : "",
- i = pInt(n = mathAbs(+n || 0).toFixed(c)) + "", j = (j = i.length) > 3 ? j % 3 : 0;
-
- return s + (j ? i.substr(0, j) + t : "") + i.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + t) +
- (c ? d + mathAbs(n - i).toFixed(c).slice(2) : "");
- }
- dateFormat = function (format, timestamp, capitalize) {
- function pad (number) {
- return number.toString().replace(/^([0-9])$/, '0$1');
- }
-
- if (!defined(timestamp) || isNaN(timestamp)) {
- return 'Invalid date';
- }
- format = pick(format, '%Y-%m-%d %H:%M:%S');
-
- var date = new Date(timestamp * timeFactor),
-
-
- hours = date[getHours](),
- day = date[getDay](),
- dayOfMonth = date[getDate](),
- month = date[getMonth](),
- fullYear = date[getFullYear](),
- lang = defaultOptions.lang,
- langWeekdays = lang.weekdays,
- langMonths = lang.months,
-
-
- replacements = {
-
- 'a': langWeekdays[day].substr(0, 3),
- 'A': langWeekdays[day],
- 'd': pad(dayOfMonth),
- 'e': dayOfMonth,
-
-
-
-
- 'b': langMonths[month].substr(0, 3),
- 'B': langMonths[month],
- 'm': pad(month + 1),
-
-
- 'y': fullYear.toString().substr(2, 2),
- 'Y': fullYear,
-
-
- 'H': pad(hours),
- 'I': pad((hours % 12) || 12),
- 'l': (hours % 12) || 12,
- 'M': pad(date[getMinutes]()),
- 'p': hours < 12 ? 'AM' : 'PM',
- 'P': hours < 12 ? 'am' : 'pm',
- 'S': pad(date.getSeconds())
-
- };
-
- for (var key in replacements) {
- format = format.replace('%'+ key, replacements[key]);
- }
-
-
- return capitalize ? format.substr(0, 1).toUpperCase() + format.substr(1) : format;
- };
- function getPosition (el) {
- var p = { left: el.offsetLeft, top: el.offsetTop };
- while ((el = el.offsetParent)) {
- p.left += el.offsetLeft;
- p.top += el.offsetTop;
- if (el != doc.body && el != doc.documentElement) {
- p.left -= el.scrollLeft;
- p.top -= el.scrollTop;
- }
- }
- return p;
- }
- function SVGElement () {}
- SVGElement.prototype = {
-
- init: function(renderer, nodeName) {
- this.element = doc.createElementNS('http://www.w3.org/2000/svg', nodeName);
- this.renderer = renderer;
- },
-
- animate: function(params, options, complete) {
- var animOptions = pick(options, globalAnimation, true);
- if (animOptions) {
- animOptions = merge(animOptions);
- if (complete) {
- animOptions.complete = complete;
- }
- animate(this, params, animOptions);
- } else {
- this.attr(params);
- if (complete) {
- complete();
- }
- }
- },
-
- attr: function(hash, val) {
-
- var key,
- value,
- i,
- child,
- element = this.element,
- nodeName = element.nodeName,
- renderer = this.renderer,
- skipAttr,
- shadows = this.shadows,
- hasSetSymbolSize,
- ret = this;
-
-
- if (isString(hash) && defined(val)) {
- key = hash;
- hash = {};
- hash[key] = val;
- }
-
-
- if (isString(hash)) {
- key = hash;
- if (nodeName == 'circle') {
- key = { x: 'cx', y: 'cy' }[key] || key;
- } else if (key == 'strokeWidth') {
- key = 'stroke-width';
- }
- ret = attr(element, key) || this[key] || 0;
-
- if (key != 'd' && key != 'visibility') {
- ret = parseFloat(ret);
- }
-
-
- } else {
-
- for (key in hash) {
- skipAttr = false;
- value = hash[key];
-
-
- if (key == 'd') {
- if (value && value.join) {
- value = value.join(' ');
- }
- if (/(NaN| {2}|^$)/.test(value)) {
- value = 'M 0 0';
- }
- this.d = value;
-
-
- } else if (key == 'x' && nodeName == 'text') {
- for (i = 0; i < element.childNodes.length; i++ ) {
- child = element.childNodes[i];
-
- if (attr(child, 'x') == attr(element, 'x')) {
-
- attr(child, 'x', value);
- }
- }
-
- if (this.rotation) {
- attr(element, 'transform', 'rotate('+ this.rotation +' '+ value +' '+
- pInt(hash.y || attr(element, 'y')) +')');
- }
-
-
- } else if (key == 'fill') {
- value = renderer.color(value, element, key);
-
-
- } else if (nodeName == 'circle' && (key == 'x' || key == 'y')) {
- key = { x: 'cx', y: 'cy' }[key] || key;
-
-
- } else if (key == 'translateX' || key == 'translateY' || key == 'rotation') {
- this[key] = value;
- this.updateTransform();
- skipAttr = true;
-
-
- } else if (key == 'stroke') {
- value = renderer.color(value, element, key);
-
-
- } else if (key == 'dashstyle') {
- key = 'stroke-dasharray';
- if (value) {
- value = value.toLowerCase()
- .replace('shortdashdotdot', '3,1,1,1,1,1,')
- .replace('shortdashdot', '3,1,1,1')
- .replace('shortdot', '1,1,')
- .replace('shortdash', '3,1,')
- .replace('longdash', '8,3,')
- .replace(/dot/g, '1,3,')
- .replace('dash', '4,3,')
- .replace(/,$/, '')
- .split(',');
-
- i = value.length;
- while (i--) {
- value[i] = pInt(value[i]) * hash['stroke-width'];
- }
- value = value.join(',');
- }
-
-
- } else if (key == 'isTracker') {
- this[key] = value;
-
-
-
- } else if (key == 'width') {
- value = pInt(value);
-
-
- } else if (key == 'align') {
- key = 'text-anchor';
- value = { left: 'start', center: 'middle', right: 'end' }[value];
- }
-
-
-
-
- if (key == 'strokeWidth') {
- key = 'stroke-width';
- }
-
-
- if (isWebKit && key == 'stroke-width' && value === 0) {
- value = 0.000001;
- }
-
-
- if (this.symbolName && /^(x|y|r|start|end|innerR)/.test(key)) {
-
-
- if (!hasSetSymbolSize) {
- this.symbolAttr(hash);
- hasSetSymbolSize = true;
- }
- skipAttr = true;
- }
-
-
- if (shadows && /^(width|height|visibility|x|y|d)$/.test(key)) {
- i = shadows.length;
- while (i--) {
- attr(shadows[i], key, value);
- }
- }
-
-
-
-
-
- if (key == 'text') {
-
- renderer.buildText(element, value);
- } else if (!skipAttr) {
-
- attr(element, key, value);
- }
-
- }
-
- }
- return ret;
- },
-
-
- symbolAttr: function(hash) {
- var wrapper = this;
-
- wrapper.x = pick(hash.x, wrapper.x);
- wrapper.y = parseFloat(pick(hash.y, wrapper.y));
- wrapper.r = pick(hash.r, wrapper.r);
- wrapper.start = pick(hash.start, wrapper.start);
- wrapper.end = pick(hash.end, wrapper.end);
- wrapper.setWidth(pick(hash.width, wrapper.width));
- wrapper.setHeight(parseFloat(pick(hash.height, wrapper.height)));
- wrapper.innerR = pick(hash.innerR, wrapper.innerR);
-
- wrapper.attr({
- d: wrapper.renderer.symbols[wrapper.symbolName](wrapper.x, wrapper.y, wrapper.r, {
- start: wrapper.start,
- end: wrapper.end,
- width: wrapper.width,
- height: wrapper.height,
- innerR: wrapper.innerR
- })
- });
- },
-
-
- clip: function(clipRect) {
- return this.attr('clip-path', 'url('+ this.renderer.URL +'#'+ clipRect.id +')');
- },
-
-
- css: function(styles) {
- var elemWrapper = this;
-
-
- if (styles && styles.color) {
- styles.fill = styles.color;
- }
-
-
- styles = extend(
- elemWrapper.styles,
- styles
- );
-
-
- elemWrapper.attr({
- style: serializeCSS(styles)
- });
-
-
- elemWrapper.styles = styles;
-
- return elemWrapper;
- },
-
-
- on: function(eventType, handler) {
- var fn = handler;
-
- if (hasTouch && eventType == 'click') {
- eventType = 'touchstart';
- fn = function(e) {
- e.preventDefault();
- handler();
- }
- }
-
- this.element['on'+ eventType] = fn;
- return this;
- },
-
-
-
- translate: function(x, y) {
- return this.attr({
- translateX: x,
- translateY: y
- });
- },
-
-
- invert: function() {
- var wrapper = this;
- wrapper.inverted = true;
- wrapper.updateTransform();
- return wrapper;
- },
-
-
- updateTransform: function() {
- var wrapper = this,
- translateX = wrapper.translateX || 0,
- translateY = wrapper.translateY || 0,
- inverted = wrapper.inverted,
- rotation = wrapper.rotation,
- transform = [];
-
-
- if (inverted) {
- translateX += wrapper.attr('width');
- translateY += wrapper.attr('height');
- }
-
-
- if (translateX || translateY) {
- transform.push('translate('+ translateX +','+ translateY +')');
- }
-
-
- if (inverted) {
- transform.push('rotate(90) scale(-1,1)');
- } else if (rotation) {
- transform.push('rotate('+ rotation +' '+ wrapper.x +' '+ wrapper.y +')');
- }
-
- if (transform.length) {
- attr(wrapper.element, 'transform', transform.join(' '));
- }
- },
-
- toFront: function() {
- var element = this.element;
- element.parentNode.appendChild(element);
- return this;
- },
-
-
-
- align: function(alignOptions, alignByTranslate, box) {
-
- if (!alignOptions) {
- alignOptions = this.alignOptions;
- alignByTranslate = this.alignByTranslate;
- } else {
- this.alignOptions = alignOptions;
- this.alignByTranslate = alignByTranslate;
- if (!box) {
- this.renderer.alignedObjects.push(this);
- }
- }
-
- box = pick(box, this.renderer);
-
- var align = alignOptions.align,
- vAlign = alignOptions.verticalAlign,
- x = (box.x || 0) + (alignOptions.x || 0),
- y = (box.y || 0) + (alignOptions.y || 0),
- attribs = {};
-
-
-
- if (/^(right|center)$/.test(align)) {
- x += (box.width - (alignOptions.width || 0) ) /
- { right: 1, center: 2 }[align];
- }
- attribs[alignByTranslate ? 'translateX' : 'x'] = x;
-
-
-
- if (/^(bottom|middle)$/.test(vAlign)) {
- y += (box.height - (alignOptions.height || 0)) /
- ({ bottom: 1, middle: 2 }[vAlign] || 1);
-
- }
- attribs[alignByTranslate ? 'translateY' : 'y'] = y;
-
-
- this[this.placed ? 'animate' : 'attr'](attribs);
- this.placed = true;
-
- return this;
- },
-
-
- getBBox: function() {
- var bBox,
- width,
- height,
- element = this.element,
- rotation = this.rotation,
- rad = rotation * deg2rad;
-
- try {
-
-
- bBox = element.getBBox ?
-
- extend({}, element.getBBox()) :
-
- {
- width: element.offsetWidth,
- height: element.offsetHeight
- };
-
- } catch(e) {
- bBox = { width: 0, height: 0 };
- }
- width = bBox.width;
- height = bBox.height;
-
-
- if (rotation) {
- bBox.setWidth(mathAbs(height * mathSin(rad)) + mathAbs(width * mathCos(rad)));
- bBox.setHeight(mathAbs(height * mathCos(rad)) + mathAbs(width * mathSin(rad)));
- }
-
- return bBox;
- },
-
-
-
-
- show: function() {
- return this.attr({ visibility: VISIBLE });
- },
-
-
- hide: function() {
- return this.attr({ visibility: HIDDEN });
- },
-
-
- add: function(parent) {
-
- var renderer = this.renderer,
- parentWrapper = parent || renderer,
- parentNode = parentWrapper.element || renderer.box,
- childNodes = parentNode.childNodes,
- element = this.element,
- zIndex = attr(element, 'zIndex'),
- otherElement,
- otherZIndex,
- i;
-
-
- this.parentInverted = parent && parent.inverted;
-
-
- if (zIndex) {
- parentWrapper.handleZ = true;
- zIndex = pInt(zIndex);
- }
-
- if (parentWrapper.handleZ) {
- for (i = 0; i < childNodes.length; i++) {
- otherElement = childNodes[i];
- otherZIndex = attr(otherElement, 'zIndex');
- if (otherElement != element && (
-
- pInt(otherZIndex) > zIndex ||
-
- (!defined(zIndex) && defined(otherZIndex))
-
- )) {
- parentNode.insertBefore(element, otherElement);
- return this;
- }
- }
- }
-
-
- parentNode.appendChild(element);
- return this;
- },
-
- destroy: function() {
- var wrapper = this,
- element = wrapper.element || {},
- shadows = wrapper.shadows,
- parentNode = element.parentNode,
- key;
-
-
- element.onclick = element.onmouseout = element.onmouseover = element.onmousemove = null;
- stop(wrapper);
-
-
- if (parentNode) {
- parentNode.removeChild(element);
- }
-
-
- if (shadows) {
- each(shadows, function(shadow) {
- parentNode = shadow.parentNode;
- if (parentNode) {
- parentNode.removeChild(shadow);
- }
- });
- }
-
-
- erase(wrapper.renderer.alignedObjects, wrapper);
-
- for (key in wrapper) {
- delete wrapper[key];
- }
-
- return null;
- },
-
-
- empty: function() {
- var element = this.element,
- childNodes = element.childNodes,
- i = childNodes.length;
-
- while (i--) {
- element.removeChild(childNodes[i]);
- }
- },
-
-
- shadow: function(apply) {
- var shadows = [],
- i,
- shadow,
- element = this.element,
-
-
- transform = this.parentInverted ? '(-1,-1)' : '(1,1)';
-
-
- if (apply) {
- for (i = 1; i <= 3; i++) {
- shadow = element.cloneNode(0);
- attr(shadow, {
- 'isShadow': 'true',
- 'stroke': 'rgb(0, 0, 0)',
- 'stroke-opacity': 0.05 * i,
- 'stroke-width': 7 - 2 * i,
- 'transform': 'translate'+ transform,
- 'fill': NONE
- });
-
-
- element.parentNode.insertBefore(shadow, element);
-
- shadows.push(shadow);
- }
-
- this.shadows = shadows;
- }
- return this;
-
- }
- };
- var SVGRenderer = function() {
- this.init.apply(this, arguments);
- };
- SVGRenderer.prototype = {
-
- init: function(container, width, height) {
- var renderer = this,
- loc = location,
- boxWrapper;
-
- renderer.Element = SVGElement;
- boxWrapper = renderer.createElement('svg')
- .attr({
- xmlns: 'http://www.w3.org/2000/svg',
- version: '1.1'
- });
- container.appendChild(boxWrapper.element);
-
-
- renderer.box = boxWrapper.element;
- renderer.boxWrapper = boxWrapper;
- renderer.alignedObjects = [];
- renderer.URL = isIE ? '' : loc.href.replace(/#.*?$/, '');
- renderer.defs = this.createElement('defs').add();
-
- renderer.setSize(width, height, false);
-
- },
-
-
-
- createElement: function(nodeName) {
- var wrapper = new this.Element();
- wrapper.init(this, nodeName);
- return wrapper;
- },
-
-
- draw: function() {},
-
- buildText: function(textNode, str) {
- var lines = str.toString()
- .replace(/<(b|strong)>/g, '<span style="font-weight:bold">')
- .replace(/<(i|em)>/g, '<span style="font-style:italic">')
- .replace(/<a/g, '<span')
- .replace(/<\/(b|strong|i|em|a)>/g, '</span>')
- .split(/<br[^>]?>/g),
- childNodes = textNode.childNodes,
- styleRegex = /style="([^"]+)"/,
- hrefRegex = /href="([^"]+)"/,
- parentX = attr(textNode, 'x'),
- lastLine,
- i = childNodes.length;
-
-
-
- while (i--) {
- textNode.removeChild(childNodes[i]);
- }
-
- each(lines, function(line, lineNo) {
- var spans, spanNo = 0, lineHeight;
-
- line = line.replace(/<span/g, '|||<span').replace(/<\/span>/g, '</span>|||');
- spans = line.split('|||');
-
- each(spans, function (span) {
- if (span !== '' || spans.length == 1) {
- var attributes = {},
- tspan = doc.createElementNS('http://www.w3.org/2000/svg', 'tspan');
- if (styleRegex.test(span)) {
- attr(
- tspan,
- 'style',
- span.match(styleRegex)[1].replace(/(;| |^)color([ :])/, '$1fill$2')
- );
- }
- if (hrefRegex.test(span)) {
- attr(tspan, 'onclick', 'location.href=\"'+ span.match(hrefRegex)[1] +'\"');
- css(tspan, { cursor: 'pointer' });
- }
-
- span = span.replace(/<(.|\n)*?>/g, '');
- tspan.appendChild(doc.createTextNode(span || ' '));
-
- if (!spanNo) {
- attributes.x = parentX;
- } else {
-
- attributes.dx = 3;
- }
-
-
- if (!spanNo) {
- if (lineNo) {
-
-
- lineHeight = pInt(window.getComputedStyle(lastLine, null).getPropertyValue('line-height'));
- if (isNaN(lineHeight)) {
- lineHeight = lastLine.offsetHeight || 18;
- }
- attr(tspan, 'dy', lineHeight);
- }
- lastLine = tspan;
- }
-
-
- attr(tspan, attributes);
-
-
- textNode.appendChild(tspan);
-
- spanNo++;
- }
- });
-
- });
- },
-
-
- crispLine: function(points, width) {
-
-
- if (points[1] == points[4]) {
- points[1] = points[4] = mathRound(points[1]) + (width % 2 / 2);
- }
- if (points[2] == points[5]) {
- points[2] = points[5] = mathRound(points[2]) + (width % 2 / 2);
- }
- return points;
- },
-
-
-
- path: function (path) {
- return this.createElement('path').attr({
- d: path,
- fill: NONE
- });
- },
-
-
- circle: function (x, y, r) {
- var attr = isObject(x) ?
- x :
- {
- x: x,
- y: y,
- r: r
- };
-
- return this.createElement('circle').attr(attr);
- },
-
-
- arc: function (x, y, r, innerR, start, end) {
-
-
-
- if (isObject(x)) {
- y = x.y;
- r = x.r;
- innerR = x.innerR;
- start = x.start;
- end = x.end;
- x = x.x;
- }
-
- return this.symbol('arc', x || 0, y || 0, r || 0, {
- innerR: innerR || 0,
- start: start || 0,
- end: end || 0
- });
- },
-
-
- rect: function (x, y, width, height, r, strokeWidth) {
-
- if (arguments.length > 1) {
- var normalizer = (strokeWidth || 0) % 2 / 2;
-
- x = mathRound(x || 0) + normalizer;
- y = mathRound(y || 0) + normalizer;
- width = mathRound((width || 0) - 2 * normalizer);
- height = mathRound((height || 0) - 2 * normalizer);
- }
-
- var attr = isObject(x) ?
- x :
- {
- x: x,
- y: y,
- width: mathMax(width, 0),
- height: mathMax(height, 0)
- };
-
- return this.createElement('rect').attr(extend(attr, {
- rx: r || attr.r,
- ry: r || attr.r,
- fill: NONE
- }));
- },
-
-
- setSize: function(width, height, animate) {
- var renderer = this,
- alignedObjects = renderer.alignedObjects,
- i = alignedObjects.length;
-
- renderer.setWidth(width);
- renderer.setHeight(height);
-
- renderer.boxWrapper[pick(animate, true) ? 'animate' : 'attr']({
- width: width,
- height: height
- });
-
- while (i--) {
- alignedObjects[i].align();
- }
- },
-
-
- g: function(name) {
- return this.createElement('g').attr(
- defined(name) && { 'class': PREFIX + name }
- );
- },
-
-
- image: function(src, x, y, width, height) {
- var attribs = {
- preserveAspectRatio: NONE
- },
- elemWrapper;
-
-
- if (arguments.length > 1) {
- extend(attribs, {
- x: x,
- y: y,
- width: width,
- height: height
- });
- }
-
- elemWrapper = this.createElement('image').attr(attribs);
-
-
- elemWrapper.element.setAttributeNS('http://www.w3.org/1999/xlink',
- 'href', src);
-
- return elemWrapper;
- },
-
-
- symbol: function(symbol, x, y, radius, options) {
-
- var obj,
-
-
- symbolFn = this.symbols[symbol],
-
-
- path = symbolFn && symbolFn(
- x,
- y,
- radius,
- options
- ),
-
- imageRegex = /^url\((.*?)\)$/,
- imageSrc;
-
- if (path) {
-
- obj = this.path(path);
-
- extend(obj, {
- symbolName: symbol,
- x: x,
- y: y,
- r: radius
- });
- if (options) {
- extend(obj, options);
- }
-
-
-
- } else if (imageRegex.test(symbol)) {
-
- imageSrc = symbol.match(imageRegex)[1];
-
-
- obj = this.image(imageSrc)
- .attr({
- x: x,
- y: y
- });
-
-
- createElement('img', {
- onload: function() {
- var img = this,
- size = symbolSizes[img.src] || [img.width, img.height];
- obj.attr({
- width: size[0],
- height: size[1]
- }).translate(
- -mathRound(size[0] / 2),
- -mathRound(size[1] / 2)
- );
- },
- src: imageSrc
- });
-
-
- } else {
- obj = this.circle(x, y, radius);
- }
-
- return obj;
- },
-
-
- symbols: {
- 'square': function (x, y, radius) {
- var len = 0.707 * radius;
- return [
- M, x-len, y-len,
- L, x+len, y-len,
- x+len, y+len,
- x-len, y+len,
- 'Z'
- ];
- },
-
- 'triangle': function (x, y, radius) {
- return [
- M, x, y-1.33 * radius,
- L, x+radius, y + 0.67 * radius,
- x-radius, y + 0.67 * radius,
- 'Z'
- ];
- },
-
- 'triangle-down': function (x, y, radius) {
- return [
- M, x, y + 1.33 * radius,
- L, x-radius, y-0.67 * radius,
- x+radius, y-0.67 * radius,
- 'Z'
- ];
- },
- 'diamond': function (x, y, radius) {
- return [
- M, x, y-radius,
- L, x+radius, y,
- x, y+radius,
- x-radius, y,
- 'Z'
- ];
- },
- 'arc': function (x, y, radius, options) {
- var start = options.start,
- end = options.end - 0.000001,
- innerRadius = options.innerR,
- cosStart = mathCos(start),
- sinStart = mathSin(start),
- cosEnd = mathCos(end),
- sinEnd = mathSin(end),
- longArc = options.end - start < mathPI ? 0 : 1;
-
- return [
- M,
- x + radius * cosStart,
- y + radius * sinStart,
- 'A',
- radius,
- radius,
- 0,
- longArc,
- 1,
- x + radius * cosEnd,
- y + radius * sinEnd,
- L,
- x + innerRadius * cosEnd,
- y + innerRadius * sinEnd,
- 'A',
- innerRadius,
- innerRadius,
- 0,
- longArc,
- 0,
- x + innerRadius * cosStart,
- y + innerRadius * sinStart,
-
- 'Z'
- ];
- }
- },
-
-
- clipRect: function (x, y, width, height) {
- var wrapper,
- id = PREFIX + idCounter++,
-
- clipPath = this.createElement('clipPath').attr({
- id: id
- }).add(this.defs);
-
- wrapper = this.rect(x, y, width, height, 0).add(clipPath);
- wrapper.id = id;
-
- return wrapper;
- },
-
-
-
- color: function(color, elem, prop) {
- var colorObject,
- regexRgba = /^rgba/;
- if (color && color.linearGradient) {
- var renderer = this,
- strLinearGradient = 'linearGradient',
- linearGradient = color[strLinearGradient],
- id = PREFIX + idCounter++,
- gradientObject,
- stopColor,
- stopOpacity;
- gradientObject = renderer.createElement(strLinearGradient).attr({
- id: id,
- gradientUnits: 'userSpaceOnUse',
- x1: linearGradient[0],
- y1: linearGradient[1],
- x2: linearGradient[2],
- y2: linearGradient[3]
- }).add(renderer.defs);
-
- each(color.stops, function(stop) {
- if (regexRgba.test(stop[1])) {
- colorObject = Color(stop[1]);
- stopColor = colorObject.get('rgb');
- stopOpacity = colorObject.get('a');
- } else {
- stopColor = stop[1];
- stopOpacity = 1;
- }
- renderer.createElement('stop').attr({
- offset: stop[0],
- 'stop-color': stopColor,
- 'stop-opacity': stopOpacity
- }).add(gradientObject);
- });
-
- return 'url('+ this.URL +'#'+ id +')';
-
-
- } else if (regexRgba.test(color)) {
- colorObject = Color(color);
- attr(elem, prop +'-opacity', colorObject.get('a'));
-
- return colorObject.get('rgb');
-
-
- } else {
- return color;
- }
-
- },
-
-
-
- text: function(str, x, y) {
-
-
- var defaultChartStyle = defaultOptions.chart.style,
- wrapper;
-
- x = mathRound(pick(x, 0));
- y = mathRound(pick(y, 0));
-
- wrapper = this.createElement('text')
- .attr({
- x: x,
- y: y,
- text: str
- })
- .css({
- 'font-family': defaultChartStyle.fontFamily,
- 'font-size': defaultChartStyle.fontSize
- });
-
- wrapper.x = x;
- wrapper.y = y;
- return wrapper;
- }
- };
- var VMLRenderer;
- if (!hasSVG && !useCanVG) {
- var VMLElement = extendClass( SVGElement, {
-
-
- init: function(renderer, nodeName) {
- var markup = ['<', nodeName, ' filled="f" stroked="f"'],
- style = ['position: ', ABSOLUTE, ';'];
-
-
- if (nodeName == 'shape' || nodeName == DIV) {
- style.push('left:0;top:0;width:10px;height:10px;');
- }
- if (docMode8) {
- style.push('visibility: ', nodeName == DIV ? HIDDEN : VISIBLE);
- }
-
- markup.push(' style="', style.join(''), '"/>');
-
-
- if (nodeName) {
- markup = nodeName == DIV || nodeName == 'span' || nodeName == 'img' ?
- markup.join('')
- : renderer.prepVML(markup);
- this.element = createElement(markup);
- }
-
- this.renderer = renderer;
- },
-
-
- add: function(parent) {
- var wrapper = this,
- renderer = wrapper.renderer,
- element = wrapper.element,
- box = renderer.box,
- inverted = parent && parent.inverted,
-
-
- parentNode = parent ?
- parent.element || parent :
- box;
-
-
-
- if (inverted) {
- renderer.invertChild(element, parentNode);
- }
-
-
- if (docMode8 && parentNode.gVis == HIDDEN) {
- css(element, { visibility: HIDDEN });
- }
-
-
- parentNode.appendChild(element);
-
-
- wrapper.added = true;
- if (wrapper.alignOnAdd) {
- wrapper.updateTransform();
- }
-
- return wrapper;
- },
-
-
- attr: function(hash, val) {
- var key,
- value,
- i,
- element = this.element || {},
- elemStyle = element.style,
- nodeName = element.nodeName,
- renderer = this.renderer,
- symbolName = this.symbolName,
- childNodes,
- hasSetSymbolSize,
- shadows = this.shadows,
- skipAttr,
- ret = this;
-
-
- if (isString(hash) && defined(val)) {
- key = hash;
- hash = {};
- hash[key] = val;
- }
-
-
- if (isString(hash)) {
- key = hash;
- if (key == 'strokeWidth' || key == 'stroke-width') {
- ret = this.strokeweight;
- } else {
- ret = this[key];
- }
-
-
- } else {
- for (key in hash) {
- value = hash[key];
- skipAttr = false;
-
-
-
- if (symbolName && /^(x|y|r|start|end|width|height|innerR)/.test(key)) {
-
-
-
- if (!hasSetSymbolSize) {
-
- this.symbolAttr(hash);
-
- hasSetSymbolSize = true;
- }
-
- skipAttr = true;
-
- } else if (key == 'd') {
- value = value || [];
- this.d = value.join(' ');
-
-
- i = value.length;
- var convertedPath = [];
- while (i--) {
-
-
-
-
- if (isNumber(value[i])) {
- convertedPath[i] = mathRound(value[i] * 10) - 5;
- }
-
- else if (value[i] == 'Z') {
- convertedPath[i] = 'x';
- }
- else {
- convertedPath[i] = value[i];
- }
-
- }
- value = convertedPath.join(' ') || 'x';
- element.path = value;
-
-
- if (shadows) {
- i = shadows.length;
- while (i--) {
- shadows[i].path = value;
- }
- }
- skipAttr = true;
-
-
- } else if (key == 'zIndex' || key == 'visibility') {
-
-
- if (docMode8 && key == 'visibility' && nodeName == 'DIV') {
- element.gVis = value;
- childNodes = element.childNodes;
- i = childNodes.length;
- while (i--) {
- css(childNodes[i], { visibility: value });
- }
- if (value == VISIBLE) {
- value = null;
- }
- }
-
- if (value) {
- elemStyle[key] = value;
- }
-
-
-
- skipAttr = true;
-
-
- } else if (/^(width|height)$/.test(key)) {
-
-
-
- if (this.updateClipping) {
- this[key] = value;
- this.updateClipping();
-
- } else {
-
- elemStyle[key] = value;
- }
-
- skipAttr = true;
-
-
- } else if (/^(x|y)$/.test(key)) {
- this[key] = value;
-
- if (element.tagName == 'SPAN') {
- this.updateTransform();
-
- } else {
- elemStyle[{ x: 'left', y: 'top' }[key]] = value;
- }
-
-
- } else if (key == 'class') {
-
- element.className = value;
-
-
- } else if (key == 'stroke') {
-
- value = renderer.color(value, element, key);
-
- key = 'strokecolor';
-
-
- } else if (key == 'stroke-width' || key == 'strokeWidth') {
- element.stroked = value ? true : false;
- key = 'strokeweight';
- this[key] = value;
- if (isNumber(value)) {
- value += PX;
- }
-
-
- } else if (key == 'dashstyle') {
- var strokeElem = element.getElementsByTagName('stroke')[0] ||
- createElement(renderer.prepVML(['<stroke/>']), null, null, element);
- strokeElem[key] = value || 'solid';
- this.dashstyle = value;
- skipAttr = true;
-
-
- } else if (key == 'fill') {
-
- if (nodeName == 'SPAN') {
- elemStyle.color = value;
- } else {
- element.filled = value != NONE ? true : false;
-
- value = renderer.color(value, element, key);
-
- key = 'fillcolor';
- }
-
-
- } else if (key == 'translateX' || key == 'translateY' || key == 'rotation' || key == 'align') {
- if (key == 'align') {
- key = 'textAlign';
- }
- this[key] = value;
- this.updateTransform();
-
- skipAttr = true;
- }
-
-
- else if (key == 'text') {
- element.innerHTML = value;
- skipAttr = true;
- }
-
-
-
- if (shadows && key == 'visibility') {
- i = shadows.length;
- while (i--) {
- shadows[i].style[key] = value;
- }
- }
-
-
-
- if (!skipAttr) {
- if (docMode8) {
- element[key] = value;
- } else {
- attr(element, key, value);
- }
- }
- }
- }
- return ret;
- },
-
-
- clip: function(clipRect) {
- var wrapper = this,
- clipMembers = clipRect.members,
- index = clipMembers.length;
-
- clipMembers.push(wrapper);
- wrapper.destroyClip = function() {
- clipMembers.splice(index, 1);
- };
- return wrapper.css(clipRect.getCSS(wrapper.inverted));
- },
-
-
- css: function(styles) {
- var wrapper = this;
-
- css(wrapper.element, styles);
-
- return wrapper;
- },
-
-
- destroy: function() {
- var wrapper = this;
-
- if (wrapper.destroyClip) {
- wrapper.destroyClip();
- }
-
- SVGElement.prototype.destroy.apply(this);
- },
-
-
- empty: function() {
- var element = this.element,
- childNodes = element.childNodes,
- i = childNodes.length,
- node;
-
- while (i--) {
- node = childNodes[i];
- node.parentNode.removeChild(node);
- }
- },
-
-
-
- getBBox: function() {
- var element = this.element;
-
-
- if (element.nodeName == 'text') {
- element.style.position = ABSOLUTE;
- }
-
- return {
- x: element.offsetLeft,
- y: element.offsetTop,
- width: element.offsetWidth,
- height: element.offsetHeight
- };
-
- },
-
-
- on: function(eventType, handler) {
-
- this.element['on'+ eventType] = function() {
- var evt = win.m_event;
- evt.target = evt.srcElement;
- handler(evt);
- };
- return this;
- },
-
-
-
- updateTransform: function(hash) {
-
- if (!this.added) {
- this.alignOnAdd = true;
- return;
- }
-
-
- var wrapper = this,
- elem = wrapper.element,
- translateX = wrapper.translateX || 0,
- translateY = wrapper.translateY || 0,
- x = wrapper.x || 0,
- y = wrapper.y || 0,
- rotation = wrapper.rotation || 0,
- radians = rotation * deg2rad,
- costheta = mathCos(radians),
- sintheta = mathSin(radians),
- align = wrapper.textAlign || 'left',
- alignCorrection = { right: 1, center: 2 }[align],
- nonLeft = align && align != 'left';
-
-
-
- if (translateX || translateY) {
- wrapper.css({
- marginLeft: translateX,
- marginTop: translateY
- });
- }
-
-
- if (wrapper.inverted) {
- each(elem.childNodes, function(child) {
- wrapper.renderer.invertChild(child, elem);
- });
- }
-
- if (elem.tagName == 'SPAN') {
-
-
- css(elem, {
- filter: rotation ? ['progid:DXImageTransform.Microsoft.Matrix(M11=', costheta,
- ', M12=', -sintheta, ', M21=', sintheta, ', M22=', costheta,
- ', sizingMethod=\'auto expand\')'].join('') : NONE
- });
-
- var width = elem.offsetWidth,
- height = elem.offsetHeight,
- lineHeight = mathRound(pInt(elem.style.fontSize || 12) * 1.2);
-
-
- x += width * mathMin(costheta, 0) + mathMin(sintheta, 0) * lineHeight;
- y += height * mathMin(sintheta, 0) - mathMax(costheta, 0) * lineHeight;
-
- if (nonLeft) {
- x -= width / alignCorrection * costheta;
- y -= height / alignCorrection * sintheta;
- }
-
- css(elem, {
- textAlign: align,
- left: x,
- top: y
- });
-
- }
- },
-
-
- shadow: function(apply) {
- var shadows = [],
- i,
- element = this.element,
- renderer = this.renderer,
- shadow,
- elemStyle = element.style,
- markup,
- path = element.path;
-
-
- if (''+ element.path === '') {
- path = 'x';
- }
-
- if (apply) {
- for (i = 1; i <= 3; i++) {
- markup = ['<shape isShadow="true" strokeweight="', ( 7 - 2 * i ) ,
- '" filled="false" path="', path,
- '" coordsize="100,100" style="', element.style.cssText, '" />'];
- shadow = createElement(renderer.prepVML(markup),
- null, {
- left: pInt(elemStyle.left) + 1,
- top: pInt(elemStyle.top) + 1
- }
- );
-
-
- markup = ['<stroke color="black" opacity="', (0.05 * i), '"/>'];
- createElement(renderer.prepVML(markup), null, null, shadow);
-
-
-
- element.parentNode.insertBefore(shadow, element);
-
-
- shadows.push(shadow);
-
- }
-
- this.shadows = shadows;
- }
- return this;
-
- }
- });
-
- VMLRenderer = function() {
- this.init.apply(this, arguments);
- };
- VMLRenderer.prototype = merge( SVGRenderer.prototype, {
-
- isIE8: userAgent.indexOf('MSIE 8.0') > -1,
-
-
- init: function(container, width, height) {
- var renderer = this,
- boxWrapper;
- renderer.Element = VMLElement;
- renderer.alignedObjects = [];
-
- boxWrapper = renderer.createElement(DIV);
- container.appendChild(boxWrapper.element);
-
-
-
- renderer.box = boxWrapper.element;
- renderer.boxWrapper = boxWrapper;
-
-
- renderer.setSize(width, height, false);
-
-
-
-
- if (!doc.namespaces.hcv) {
-
- doc.namespaces.add('hcv', 'urn:schemas-microsoft-com:vml');
-
-
- doc.createStyleSheet().cssText =
- 'hcv\\:fill, hcv\\:path, hcv\\:shape, hcv\\:stroke'+
- '{ behavior:url(#default#VML); display: inline-block; } ';
-
- }
- },
-
-
- clipRect: function (x, y, width, height) {
-
-
- var clipRect = this.createElement();
-
-
- return extend(clipRect, {
- members: [],
- left: x,
- top: y,
- width: width,
- height: height,
- getCSS: function(inverted) {
- var rect = this,
- top = rect.top,
- left = rect.left,
- right = left + rect.width,
- bottom = top + rect.height,
- ret = {
- clip: 'rect('+
- mathRound(inverted ? left : top) + 'px,'+
- mathRound(inverted ? bottom : right) + 'px,'+
- mathRound(inverted ? right : bottom) + 'px,'+
- mathRound(inverted ? top : left) +'px)'
- };
-
-
- if (!inverted && docMode8) {
- extend(ret, {
- width: right +PX,
- height: bottom +PX
- });
- }
- return ret;
- },
-
-
- updateClipping: function() {
- each(clipRect.members, function(member) {
- member.css(clipRect.getCSS(member.inverted));
- });
- }
- });
-
- },
-
-
-
- color: function(color, elem, prop) {
- var colorObject,
- regexRgba = /^rgba/,
- markup;
-
- if (color && color.linearGradient) {
-
- var stopColor,
- stopOpacity,
- linearGradient = color.linearGradient,
- angle,
- color1,
- opacity1,
- color2,
- opacity2;
-
- each(color.stops, function(stop, i) {
- if (regexRgba.test(stop[1])) {
- colorObject = Color(stop[1]);
- stopColor = colorObject.get('rgb');
- stopOpacity = colorObject.get('a');
- } else {
- stopColor = stop[1];
- stopOpacity = 1;
- }
-
- if (!i) {
- color1 = stopColor;
- opacity1 = stopOpacity;
- } else {
- color2 = stopColor;
- opacity2 = stopOpacity;
- }
- });
-
-
-
-
- angle = 90 - math.atan(
- (linearGradient[3] - linearGradient[1]) /
- (linearGradient[2] - linearGradient[0])
- ) * 180 / mathPI;
-
-
-
- markup = ['<', prop, ' colors="0% ', color1, ',100% ', color2, '" angle="', angle,
- '" opacity="', opacity2, '" o:opacity2="', opacity1,
- '" type="gradient" focus="100%" />'];
- createElement(this.prepVML(markup), null, null, elem);
-
-
-
-
-
- } else if (regexRgba.test(color) && elem.tagName != 'IMG') {
-
- colorObject = Color(color);
-
- markup = ['<', prop, ' opacity="', colorObject.get('a'), '"/>'];
- createElement(this.prepVML(markup), null, null, elem);
-
- return colorObject.get('rgb');
-
-
- } else {
- return color;
- }
-
- },
-
-
- prepVML: function(markup) {
- var vmlStyle = 'display:inline-block;behavior:url(#default#VML);',
- isIE8 = this.isIE8;
-
- markup = markup.join('');
-
- if (isIE8) {
- markup = markup.replace('/>', ' xmlns="urn:schemas-microsoft-com:vml" />');
- if (markup.indexOf('style="') == -1) {
- markup = markup.replace('/>', ' style="'+ vmlStyle +'" />');
- } else {
- markup = markup.replace('style="', 'style="'+ vmlStyle);
- }
- } else {
- markup = markup.replace('<', '<hcv:');
- }
- return markup;
- },
-
-
- text: function(str, x, y) {
-
- var defaultChartStyle = defaultOptions.chart.style;
-
- return this.createElement('span')
- .attr({
- text: str,
- x: mathRound(x),
- y: mathRound(y)
- })
- .css({
- whiteSpace: 'nowrap',
- fontFamily: defaultChartStyle.fontFamily,
- fontSize: defaultChartStyle.fontSize
- });
- },
-
-
- path: function (path) {
-
- return this.createElement('shape').attr({
-
- coordsize: '100 100',
- d: path
- });
- },
-
-
- circle: function(x, y, r) {
- return this.path(this.symbols.circle(x, y, r));
- },
-
-
- g: function(name) {
- var wrapper,
- attribs;
-
-
- if (name) {
- attribs = { 'className': PREFIX + name, 'class': PREFIX + name };
- }
-
-
- wrapper = this.createElement(DIV).attr(attribs);
-
- return wrapper;
- },
-
-
- image: function(src, x, y, width, height) {
- var obj = this.createElement('img')
- .attr({ src: src });
-
- if (arguments.length > 1) {
- obj.css({
- left: x,
- top: y,
- width: width,
- height: height
- });
- }
- return obj;
- },
-
-
- rect: function(x, y, width, height, r, strokeWidth) {
-
- if (arguments.length > 1) {
- var normalizer = (strokeWidth || 0) % 2 / 2;
-
- x = mathRound(x || 0) + normalizer;
- y = mathRound(y || 0) + normalizer;
- width = mathRound((width || 0) - 2 * normalizer);
- height = mathRound((height || 0) - 2 * normalizer);
- }
-
- if (isObject(x)) {
- y = x.y;
- width = x.width;
- height = x.height;
- r = x.r;
- x = x.x;
- }
-
- return this.symbol('rect', x || 0, y || 0, r || 0, {
- width: width || 0,
- height: height || 0
- });
- },
-
-
- invertChild: function(element, parentNode) {
- var parentStyle = parentNode.style;
-
- css(element, {
- flip: 'x',
- left: pInt(parentStyle.width) - 10,
- top: pInt(parentStyle.height) - 10,
- rotation: -90
- });
- },
-
-
- symbols: {
-
- arc: function (x, y, radius, options) {
- var start = options.start,
- end = options.end,
- cosStart = mathCos(start),
- sinStart = mathSin(start),
- cosEnd = mathCos(end),
- sinEnd = mathSin(end),
- innerRadius = options.innerR;
-
- if (end - start === 0) {
- return ['x'];
-
- } else if (end - start == 2 * mathPI) {
-
- cosEnd = -0.07 / radius;
- }
-
- return [
- 'wa',
- x - radius,
- y - radius,
- x + radius,
- y + radius,
- x + radius * cosStart,
- y + radius * sinStart,
- x + radius * cosEnd,
- y + radius * sinEnd,
-
-
- 'at',
- x - innerRadius,
- y - innerRadius,
- x + innerRadius,
- y + innerRadius,
- x + innerRadius * cosEnd,
- y + innerRadius * sinEnd,
- x + innerRadius * cosStart,
- y + innerRadius * sinStart,
-
- 'x',
- 'e'
- ];
-
- },
-
- circle: function (x, y, r) {
- return [
- 'wa',
- x - r,
- y - r,
- x + r,
- y + r,
- x + r,
- y,
- x + r,
- y,
-
- 'e'
- ];
- },
-
-
- rect: function (left, top, r, options) {
- var width = options.width,
- height = options.height,
- right = left + width,
- bottom = top + height;
-
- r = mathMin(r, width, height);
-
- return [
- M,
- left + r, top,
-
- L,
- right - r, top,
- 'wa',
- right - 2 * r, top,
- right, top + 2 * r,
- right - r, top,
- right, top + r,
-
- L,
- right, bottom - r,
- 'wa',
- right - 2 * r, bottom - 2 * r,
- right, bottom,
- right, bottom - r,
- right - r, bottom,
-
- L,
- left + r, bottom,
- 'wa',
- left, bottom - 2 * r,
- left + 2 * r, bottom,
- left + r, bottom,
- left, bottom - r,
-
- L,
- left, top + r,
- 'wa',
- left, top,
- left + 2 * r, top + 2 * r,
- left, top + r,
- left + r, top,
-
-
- 'x',
- 'e'
- ];
-
- }
- }
- });
- }
- var CanVGRenderer;
- if (useCanVG) {
-
- CanVGRenderer = function(container) {
- var contStyle = container.style,
- canvas;
-
- this.init.apply(this, arguments);
-
-
- canvas = createElement('canvas', {
- width: container.offsetWidth,
- height: container.offsetHeight
- }, {
- position: RELATIVE,
- left: contStyle.left,
- top: contStyle.top
- }, container.parentNode);
-
-
- css(container, {
- position: ABSOLUTE,
- visibility: HIDDEN
- });
-
- this.container = container;
- this.canvas = canvas;
- };
- CanVGRenderer.prototype = merge( SVGRenderer.prototype, {
-
- draw: function() {
- var renderer = this;
-
- if (win.canvg) {
- canvg(renderer.canvas, renderer.container.innerHTML);
- } else {
- deferredCanvases.push(function() {
- renderer.draw()
- });
- }
- }
- });
- }
-
-
- var Renderer = VMLRenderer || CanVGRenderer || SVGRenderer;
- function Chart (options, callback) {
-
- defaultXAxisOptions = merge(defaultXAxisOptions, defaultOptions.xAxis);
- defaultYAxisOptions = merge(defaultYAxisOptions, defaultOptions.yAxis);
- defaultOptions.xAxis = defaultOptions.yAxis = null;
-
-
- options = merge(defaultOptions, options);
-
-
- var optionsChart = options.chart,
- optionsMargin = optionsChart.margin,
- margin = isObject(optionsMargin) ?
- optionsMargin :
- [optionsMargin, optionsMargin, optionsMargin, optionsMargin],
- optionsMarginTop = pick(optionsChart.marginTop, margin[0]),
- optionsMarginRight = pick(optionsChart.marginRight, margin[1]),
- optionsMarginBottom = pick(optionsChart.marginBottom, margin[2]),
- optionsMarginLeft = pick(optionsChart.marginLeft, margin[3]),
- spacingTop = optionsChart.spacingTop,
- spacingRight = optionsChart.spacingRight,
- spacingBottom = optionsChart.spacingBottom,
- spacingLeft = optionsChart.spacingLeft,
- spacingBox,
- chartTitleOptions,
- chartSubtitleOptions,
- plotTop,
- marginRight,
- marginBottom,
- plotLeft,
- axisOffset,
- renderTo,
- renderToClone,
- canvas,
- container,
- containerId,
- containerWidth,
- containerHeight,
- chartWidth,
- chartHeight,
- oldChartWidth,
- oldChartHeight,
- chartBackground,
- plotBackground,
- plotBGImage,
- plotBorder,
- chart = this,
- chartEvents = optionsChart.events,
- runChartClick = chartEvents && !!chartEvents.click,
- eventType,
- isInsidePlot,
- tooltip,
- mouseIsDown,
- loadingDiv,
- loadingSpan,
- loadingShown,
- plotHeight,
- plotWidth,
- tracker,
- trackerGroup,
- placeTrackerGroup,
- legend,
- legendWidth,
- legendHeight,
- chartPosition,
- hasCartesianSeries = optionsChart.showAxes,
- isResizing = 0,
- axes = [],
- maxTicks,
- series = [],
- inverted,
- renderer,
- tooltipTick,
- tooltipInterval,
- hoverX,
- drawChartBox,
- getMargins,
- resetMargins,
- setChartSize,
- resize,
- zoom,
- zoomOut;
-
-
- function Axis (chart, options) {
-
- var isXAxis = options.isX,
- opposite = options.opposite,
- horiz = inverted ? !isXAxis : isXAxis,
- side = horiz ?
- (opposite ? 0 : 2 ) :
- (opposite ? 1 : 3 ),
- stacks = {};
-
-
- options = merge(
- isXAxis ? defaultXAxisOptions : defaultYAxisOptions,
- [defaultTopAxisOptions, defaultRightAxisOptions,
- defaultBottomAxisOptions, defaultLeftAxisOptions][side],
- options
- );
-
- var axis = this,
- isDatetimeAxis = options.type == 'datetime',
- offset = options.offset || 0,
- xOrY = isXAxis ? 'x' : 'y',
- axisLength,
- transA,
- oldTransA,
- transB = horiz ? plotLeft : marginBottom,
- translate,
- getPlotLinePath,
- axisGroup,
- gridGroup,
- axisLine,
- dataMin,
- dataMax,
- associatedSeries,
- userSetMin,
- userSetMax,
- max = null,
- min = null,
- oldMin,
- oldMax,
- minPadding = options.minPadding,
- maxPadding = options.maxPadding,
- isLinked = defined(options.linkedTo),
- ignoreMinPadding,
- ignoreMaxPadding,
- usePercentage,
- events = options.events,
- eventType,
- plotLinesAndBands = [],
- tickInterval,
- minorTickInterval,
- magnitude,
- tickPositions,
- ticks = {},
- minorTicks = {},
- alternateBands = {},
- tickAmount,
- labelOffset,
- axisTitleMargin,
- dateTimeLabelFormat,
- categories = options.categories,
- labelFormatter = options.labels.formatter ||
- function() {
- var value = this.value,
- ret;
-
- if (dateTimeLabelFormat) {
- ret = dateFormat(dateTimeLabelFormat, value);
-
- } else if (tickInterval % 1000000 === 0) {
- ret = (value / 1000000) +'M';
-
- } else if (tickInterval % 1000 === 0) {
- ret = (value / 1000) +'k';
-
- } else if (!categories && value >= 1000) {
- ret = numberFormat(value, 0);
-
- } else {
- ret = value;
- }
- return ret;
- },
-
- staggerLines = horiz && options.labels.staggerLines,
- reversed = options.reversed,
- tickmarkOffset = (categories && options.tickmarkPlacement == 'between') ? 0.5 : 0;
-
- function Tick(pos, minor) {
- var tick = this;
- tick.pos = pos;
- tick.minor = minor;
- tick.isNew = true;
-
- if (!minor) {
- tick.addLabel();
- }
- }
- Tick.prototype = {
-
- addLabel: function() {
- var pos = this.pos,
- labelOptions = options.labels,
- str,
- withLabel = !((pos == min && !pick(options.showFirstLabel, 1)) ||
- (pos == max && !pick(options.showLastLabel, 0))),
- label = this.label;
-
-
-
- str = labelFormatter.call({
- isFirst: pos == tickPositions[0],
- isLast: pos == tickPositions[tickPositions.length - 1],
- dateTimeLabelFormat: dateTimeLabelFormat,
- value: (categories && categories[pos] ? categories[pos] : pos)
- });
-
-
- if (label === UNDEFINED) {
- this.label =
- defined(str) && withLabel && labelOptions.enabled ?
- renderer.text(
- str,
- 0,
- 0
- )
- .attr({
- align: labelOptions.align,
- rotation: labelOptions.rotation
- })
-
- .css(labelOptions.style)
- .add(axisGroup):
- null;
-
-
- } else if (label) {
- label.attr({ text: str });
- }
-
- },
-
- getLabelSize: function() {
- var label = this.label;
- return label ?
- ((this.labelBBox = label.getBBox()))[horiz ? 'height' : 'width'] :
- 0;
- },
-
- render: function(index, old) {
- var tick = this,
- major = !tick.minor,
- label = tick.label,
- pos = tick.pos,
- labelOptions = options.labels,
- gridLine = tick.gridLine,
- gridLineWidth = major ? options.gridLineWidth : options.minorGridLineWidth,
- gridLineColor = major ? options.gridLineColor : options.minorGridLineColor,
- dashStyle = major ?
- options.gridLineDashStyle :
- options.minorGridLineDashStyle,
- gridLinePath,
- mark = tick.mark,
- markPath,
- tickLength = major ? options.tickLength : options.minorTickLength,
- tickWidth = major ? options.tickWidth : (options.minorTickWidth || 0),
- tickColor = major ? options.tickColor : options.minorTickColor,
- tickPosition = major ? options.tickPosition : options.minorTickPosition,
- step = labelOptions.step,
- cHeight = old && oldChartHeight || chartHeight,
- attribs,
- x,
- y;
-
-
- x = horiz ?
- translate(pos + tickmarkOffset, null, null, old) + transB :
- plotLeft + offset + (opposite ? (old && oldChartWidth || chartWidth) - marginRight - plotLeft : 0);
-
- y = horiz ?
- cHeight - marginBottom + offset - (opposite ? plotHeight : 0) :
- cHeight - translate(pos + tickmarkOffset, null, null, old) - transB;
-
-
- if (gridLineWidth) {
- gridLinePath = getPlotLinePath(pos + tickmarkOffset, gridLineWidth, old);
-
- if (gridLine === UNDEFINED) {
- attribs = {
- stroke: gridLineColor,
- 'stroke-width': gridLineWidth
- };
- if (dashStyle) {
- attribs.dashstyle = dashStyle;
- }
- tick.gridLine = gridLine =
- gridLineWidth ?
- renderer.path(gridLinePath)
- .attr(attribs).add(gridGroup) :
- null;
- }
- if (gridLine && gridLinePath) {
- gridLine.animate({
- d: gridLinePath
- });
- }
- }
-
-
- if (tickWidth) {
-
-
- if (tickPosition == 'inside') {
- tickLength = -tickLength;
- }
- if (opposite) {
- tickLength = -tickLength;
- }
-
- markPath = renderer.crispLine([
- M,
- x,
- y,
- L,
- x + (horiz ? 0 : -tickLength),
- y + (horiz ? tickLength : 0)
- ], tickWidth);
-
- if (mark) {
- mark.animate({
- d: markPath
- });
- } else {
- tick.mark = renderer.path(
- markPath
- ).attr({
- stroke: tickColor,
- 'stroke-width': tickWidth
- }).add(axisGroup);
- }
- }
-
-
- if (label) {
- x = x + labelOptions.x - (tickmarkOffset && horiz ?
- tickmarkOffset * transA * (reversed ? -1 : 1) : 0);
- y = y + labelOptions.y - (tickmarkOffset && !horiz ?
- tickmarkOffset * transA * (reversed ? 1 : -1) : 0);
-
-
- if (staggerLines) {
- y += (index % staggerLines) * 16;
- }
-
- if (step) {
-
- label[index % step ? 'hide' : 'show']();
- }
-
- label[tick.isNew ? 'attr' : 'animate']({
- x: x,
- y: y
- });
- }
-
- tick.isNew = false;
- },
-
- destroy: function() {
- var tick = this,
- n;
- for (n in tick) {
- if (tick[n] && tick[n].destroy) {
- tick[n].destroy();
- }
- }
- }
- };
-
-
- function PlotLineOrBand(options) {
- var plotLine = this;
- if (options) {
- plotLine.options = options;
- plotLine.id = options.id;
- }
-
-
- return plotLine;
- }
-
- PlotLineOrBand.prototype = {
-
- render: function () {
- var plotLine = this,
- options = plotLine.options,
- optionsLabel = options.label,
- label = plotLine.label,
- width = options.width,
- to = options.to,
- toPath,
- from = options.from,
- dashStyle = options.dashStyle,
- svgElem = plotLine.svgElem,
- path = [],
- addEvent,
- eventType,
- xs,
- ys,
- x,
- y,
- color = options.color,
- zIndex = options.zIndex,
- events = options.events,
- attribs;
-
-
- if (width) {
- path = getPlotLinePath(options.value, width);
- attribs = {
- stroke: color,
- 'stroke-width': width
- };
- if (dashStyle) {
- attribs.dashstyle = dashStyle;
- }
- }
-
-
- else if (defined(from) && defined(to)) {
-
- from = mathMax(from, min);
- to = mathMin(to, max);
-
- toPath = getPlotLinePath(to);
- path = getPlotLinePath(from);
- if (path && toPath) {
- path.push(
- toPath[4],
- toPath[5],
- toPath[1],
- toPath[2]
- );
- } else {
- path = null;
- }
- attribs = {
- fill: color
- };
- } else {
- return;
- }
-
- if (defined(zIndex)) {
- attribs.zIndex = zIndex;
- }
-
-
- if (svgElem) {
- if (path) {
- svgElem.animate({
- d: path
- }, null, svgElem.onGetPath);
- } else {
- svgElem.hide();
- svgElem.onGetPath = function() {
- svgElem.show();
- }
- }
- } else if (path && path.length) {
- plotLine.svgElem = svgElem = renderer.path(path)
- .attr(attribs).add();
-
-
- if (events) {
- addEvent = function(eventType) {
- svgElem.on(eventType, function(e) {
- events[eventType].apply(plotLine, [e]);
- });
- };
- for (eventType in events) {
- addEvent(eventType);
- }
- }
- }
-
-
- if (optionsLabel && defined(optionsLabel.text) && path && path.length && plotWidth > 0 && plotHeight > 0) {
-
- optionsLabel = merge({
- align: horiz && toPath && 'center',
- x: horiz ? !toPath && 4 : 10,
- verticalAlign : !horiz && toPath && 'middle',
- y: horiz ? toPath ? 16 : 10 : toPath ? 6 : -4,
- rotation: horiz && !toPath && 90
- }, optionsLabel);
-
-
- if (!label) {
- plotLine.label = label = renderer.text(
- optionsLabel.text,
- 0,
- 0
- )
- .attr({
- align: optionsLabel.textAlign || optionsLabel.align,
- rotation: optionsLabel.rotation,
- zIndex: zIndex
- })
- .css(optionsLabel.style)
- .add();
- }
-
-
- xs = [path[1], path[4], path[6] || path[1]];
- ys = [path[2], path[5], path[7] || path[2]];
- x = mathMin.apply(math, xs);
- y = mathMin.apply(math, ys);
-
- label.align(optionsLabel, false, {
- x: x,
- y: y,
- width: mathMax.apply(math, xs) - x,
- height: mathMax.apply(math, ys) - y
- });
- label.show();
-
- } else if (label) {
- label.hide();
- }
-
-
- return plotLine;
- },
-
-
- destroy: function() {
- var obj = this,
- n;
-
- for (n in obj) {
- if (obj[n] && obj[n].destroy) {
- obj[n].destroy();
- }
- delete obj[n];
- }
-
- erase(plotLinesAndBands, obj);
- }
- };
-
-
-
- function getSeriesExtremes() {
- var posStack = [],
- negStack = [],
- run;
-
-
- dataMin = dataMax = null;
-
-
- associatedSeries = [];
-
- each(series, function(serie) {
- run = false;
-
-
-
- each(['xAxis', 'yAxis'], function(strAxis) {
- if (
-
- serie.isCartesian &&
-
- (strAxis == 'xAxis' && isXAxis || strAxis == 'yAxis' && !isXAxis) && (
-
- (serie.options[strAxis] == options.index) ||
-
- (serie.options[strAxis] === UNDEFINED && options.index === 0)
- )
- ) {
- serie[strAxis] = axis;
- associatedSeries.push(serie);
-
-
- run = true;
- }
- });
-
- if (!serie.visible && optionsChart.ignoreHiddenSeries) {
- run = false;
- }
-
- if (run) {
-
- var stacking,
- posPointStack,
- negPointStack,
- stackKey,
- negKey;
-
- if (!isXAxis) {
- stacking = serie.options.stacking;
- usePercentage = stacking == 'percent';
-
-
- if (stacking) {
- stackKey = serie.type + pick(serie.options.stack, '');
- negKey = '-'+ stackKey;
- serie.stackKey = stackKey;
-
- posPointStack = posStack[stackKey] || [];
- posStack[stackKey] = posPointStack;
-
- negPointStack = negStack[negKey] || [];
- negStack[negKey] = negPointStack;
- }
- if (usePercentage) {
- dataMin = 0;
- dataMax = 99;
- }
- }
- if (serie.isCartesian) {
- each(serie.data, function(point, i) {
- var pointX = point.x,
- pointY = point.y,
- isNegative = pointY < 0,
- pointStack = isNegative ? negPointStack : posPointStack,
- key = isNegative ? negKey : stackKey,
- totalPos;
-
-
- if (dataMin === null) {
-
- dataMin = dataMax = point[xOrY];
- }
-
-
- if (isXAxis) {
- if (pointX > dataMax) {
- dataMax = pointX;
- } else if (pointX < dataMin) {
- dataMin = pointX;
- }
- }
-
-
- else if (defined(pointY)) {
- if (stacking) {
- pointStack[pointX] =
- defined(pointStack[pointX]) ?
- pointStack[pointX] + pointY : pointY;
- }
-
- totalPos = pointStack ? pointStack[pointX] : pointY;
- if (!usePercentage) {
- if (totalPos > dataMax) {
- dataMax = totalPos;
- } else if (totalPos < dataMin) {
- dataMin = totalPos;
- }
- }
- if (stacking) {
-
- if (!stacks[key]) {
- stacks[key] = {};
- }
- stacks[key][pointX] = {
- total: totalPos,
- cum: totalPos
- };
- }
- }
- });
-
-
-
-
- if (/(area|column|bar)/.test(serie.type) && !isXAxis) {
- if (dataMin >= 0) {
- dataMin = 0;
- ignoreMinPadding = true;
- } else if (dataMax < 0) {
- dataMax = 0;
- ignoreMaxPadding = true;
- }
- }
- }
- }
- });
-
- }
-
-
- translate = function(val, backwards, cvsCoord, old) {
- var sign = 1,
- cvsOffset = 0,
- localA = old ? oldTransA : transA,
- localMin = old ? oldMin : min,
- returnValue;
-
- if (!localA) {
- localA = transA;
- }
-
- if (cvsCoord) {
- sign *= -1;
- cvsOffset = axisLength;
- }
- if (reversed) {
- sign *= -1;
- cvsOffset -= sign * axisLength;
- }
-
- if (backwards) {
- if (reversed) {
- val = axisLength - val;
- }
- returnValue = val / localA + localMin;
-
- } else {
- returnValue = sign * (val - localMin) * localA + cvsOffset;
- }
-
- return returnValue;
- };
-
-
- getPlotLinePath = function(value, lineWidth, old) {
- var x1,
- y1,
- x2,
- y2,
- translatedValue = translate(value, null, null, old),
- cHeight = old && oldChartHeight || chartHeight,
- cWidth = old && oldChartWidth || chartWidth,
- skip;
-
- x1 = x2 = mathRound(translatedValue + transB);
- y1 = y2 = mathRound(cHeight - translatedValue - transB);
-
- if (isNaN(translatedValue)) {
- skip = true;
-
- } else if (horiz) {
- y1 = plotTop;
- y2 = cHeight - marginBottom;
- if (x1 < plotLeft || x1 > plotLeft + plotWidth) {
- skip = true;
- }
- } else {
- x1 = plotLeft;
- x2 = cWidth - marginRight;
- if (y1 < plotTop || y1 > plotTop + plotHeight) {
- skip = true;
- }
- }
- return skip ?
- null :
- renderer.crispLine([M, x1, y1, L, x2, y2], lineWidth || 0);
- };
-
-
- function normalizeTickInterval(interval, multiples) {
- var normalized;
-
-
- magnitude = multiples ? 1 : math.pow(10, mathFloor(math.log(interval) / math.LN10));
- normalized = interval / magnitude;
-
-
- if (!multiples) {
- multiples = [1, 2, 2.5, 5, 10];
-
-
-
- if (options.allowDecimals === false) {
- if (magnitude == 1) {
- multiples = [1, 2, 5, 10];
- } else if (magnitude <= 0.1) {
- multiples = [1 / magnitude];
- }
- }
- }
-
-
- for (var i = 0; i < multiples.length; i++) {
- interval = multiples[i];
- if (normalized <= (multiples[i] + (multiples[i+1] || multiples[i])) / 2) {
- break;
- }
- }
-
-
- interval *= magnitude;
-
- return interval;
- }
-
-
- function setDateTimeTickPositions() {
- tickPositions = [];
- var i,
- useUTC = defaultOptions.global.useUTC,
- oneSecond = 1000 / timeFactor,
- oneMinute = 60000 / timeFactor,
- oneHour = 3600000 / timeFactor,
- oneDay = 24 * 3600000 / timeFactor,
- oneWeek = 7 * 24 * 3600000 / timeFactor,
- oneMonth = 30 * 24 * 3600000 / timeFactor,
- oneYear = 31556952000 / timeFactor,
-
- units = [[
- 'second',
- oneSecond,
- [1, 2, 5, 10, 15, 30]
- ], [
- 'minute',
- oneMinute,
- [1, 2, 5, 10, 15, 30]
- ], [
- 'hour',
- oneHour,
- [1, 2, 3, 4, 6, 8, 12]
- ], [
- 'day',
- oneDay,
- [1, 2]
- ], [
- 'week',
- oneWeek,
- [1, 2]
- ], [
- 'month',
- oneMonth,
- [1, 2, 3, 4, 6]
- ], [
- 'year',
- oneYear,
- null
- ]],
-
- unit = units[6],
- interval = unit[1],
- multiples = unit[2];
-
-
- for (i = 0; i < units.length; i++) {
- unit = units[i];
- interval = unit[1];
- multiples = unit[2];
-
-
- if (units[i+1]) {
-
- var lessThan = (interval * multiples[multiples.length - 1] +
- units[i + 1][1]) / 2;
-
-
- if (tickInterval <= lessThan) {
- break;
- }
- }
- }
-
-
- if (interval == oneYear && tickInterval < 5 * interval) {
- multiples = [1, 2, 5];
- }
-
-
- var multitude = normalizeTickInterval(tickInterval / interval, multiples),
- minYear,
- minDate = new Date(min * timeFactor);
-
- minDate.setMilliseconds(0);
-
- if (interval >= oneSecond) {
- minDate.setSeconds(interval >= oneMinute ? 0 :
- multitude * mathFloor(minDate.getSeconds() / multitude));
- }
-
- if (interval >= oneMinute) {
- minDate[setMinutes](interval >= oneHour ? 0 :
- multitude * mathFloor(minDate[getMinutes]() / multitude));
- }
-
- if (interval >= oneHour) {
- minDate[setHours](interval >= oneDay ? 0 :
- multitude * mathFloor(minDate[getHours]() / multitude));
- }
-
- if (interval >= oneDay) {
- minDate[setDate](interval >= oneMonth ? 1 :
- multitude * mathFloor(minDate[getDate]() / multitude));
- }
-
- if (interval >= oneMonth) {
- minDate[setMonth](interval >= oneYear ? 0 :
- multitude * mathFloor(minDate[getMonth]() / multitude));
- minYear = minDate[getFullYear]();
- }
-
- if (interval >= oneYear) {
- minYear -= minYear % multitude;
- minDate[setFullYear](minYear);
- }
-
-
- if (interval == oneWeek) {
-
- minDate[setDate](minDate[getDate]() - minDate[getDay]() +
- options.startOfWeek);
- }
-
-
-
- i = 1;
- minYear = minDate[getFullYear]();
- var time = minDate.getTime() / timeFactor,
- minMonth = minDate[getMonth](),
- minDateDate = minDate[getDate]();
-
-
- while (time < max && i < plotWidth) {
- tickPositions.push(time);
-
-
- if (interval == oneYear) {
- time = makeTime(minYear + i * multitude, 0) / timeFactor;
-
-
- } else if (interval == oneMonth) {
- time = makeTime(minYear, minMonth + i * multitude) / timeFactor;
-
-
-
- } else if (!useUTC && (interval == oneDay || interval == oneWeek)) {
- time = makeTime(minYear, minMonth, minDateDate +
- i * multitude * (interval == oneDay ? 1 : 7));
-
-
- } else {
- time += interval * multitude;
- }
-
- i++;
- }
-
- tickPositions.push(time);
-
-
- dateTimeLabelFormat = options.dateTimeLabelFormats[unit[0]];
-
- }
-
-
- function correctFloat(num) {
- var invMag, ret = num;
- if (defined(magnitude)) {
- invMag = (magnitude < 1 ? mathRound(1 / magnitude) : 1) * 10;
- ret = mathRound(num * invMag) / invMag;
- }
- return ret;
- }
-
-
- function setLinearTickPositions() {
-
- var i,
- roundedMin = mathFloor(min / tickInterval) * tickInterval,
- roundedMax = mathCeil(max / tickInterval) * tickInterval;
-
- tickPositions = [];
-
-
- i = correctFloat(roundedMin);
- while (i <= roundedMax) {
- tickPositions.push(i);
- i = correctFloat(i + tickInterval);
- }
-
- }
-
-
- function setTickPositions(secondPass) {
- var length,
- catPad,
- linkedParent,
- linkedParentExtremes,
- tickIntervalOption = options.tickInterval,
- tickPixelIntervalOption = options.tickPixelInterval,
- maxZoom = options.maxZoom || (
- isXAxis ?
- mathMin(chart.smallestInterval * 5, dataMax - dataMin) :
- null
- ),
- zoomOffset;
-
-
- axisLength = horiz ? plotWidth : plotHeight;
-
-
- if (isLinked) {
- linkedParent = chart[isXAxis ? 'xAxis' : 'yAxis'][options.linkedTo];
- linkedParentExtremes = linkedParent.getExtremes();
- min = pick(linkedParentExtremes.min, linkedParentExtremes.dataMin);
- max = pick(linkedParentExtremes.max, linkedParentExtremes.dataMax);
- }
-
-
- else {
- min = pick(userSetMin, options.min, dataMin);
- max = pick(userSetMax, options.max, dataMax);
- }
-
-
- if (max - min < maxZoom) {
- zoomOffset = (maxZoom - max + min) / 2;
-
- min = mathMax(min - zoomOffset, pick(options.min, min - zoomOffset), dataMin);
- max = mathMin(min + maxZoom, pick(options.max, min + maxZoom), dataMax);
- }
-
-
- if (!categories && !usePercentage && !isLinked && defined(min) && defined(max)) {
- length = (max - min) || 1;
- if (!defined(options.min) && !defined(userSetMin) && minPadding && (dataMin < 0 || !ignoreMinPadding)) {
- min -= length * minPadding;
- }
- if (!defined(options.max) && !defined(userSetMax) && maxPadding && (dataMax > 0 || !ignoreMaxPadding)) {
- max += length * maxPadding;
- }
- }
-
- if (min == max) {
- tickInterval = 1;
- } else if (isLinked && !tickIntervalOption &&
- tickPixelIntervalOption == linkedParent.options.tickPixelInterval) {
- tickInterval = linkedParent.tickInterval;
- } else {
- tickInterval = pick(
- tickIntervalOption,
- categories ?
- 1 :
- (max - min) * tickPixelIntervalOption / axisLength
- );
- }
-
- if (!isDatetimeAxis && !defined(options.tickInterval)) {
- axis.tickInterval = tickInterval = normalizeTickInterval(tickInterval);
- }
-
-
- minorTickInterval = options.minorTickInterval === 'auto' && tickInterval ?
- tickInterval / 5 : options.minorTickInterval;
-
-
- if (isDatetimeAxis) {
- setDateTimeTickPositions();
- } else {
- setLinearTickPositions();
- }
-
- if (!isLinked) {
-
- if (categories || (isXAxis && chart.hasColumn)) {
- catPad = (categories ? 1 : tickInterval) * 0.5;
- min -= catPad;
- max += catPad;
- }
-
-
- var roundedMin = tickPositions[0],
- roundedMax = tickPositions[tickPositions.length - 1];
-
- if (options.startOnTick) {
- min = roundedMin;
- } else if (min > roundedMin) {
- tickPositions.shift();
- }
-
- if (options.endOnTick) {
- max = roundedMax;
- } else if (max < roundedMax) {
- tickPositions.pop();
- }
-
-
- if (!maxTicks) {
- maxTicks = {
- x: 0,
- y: 0
- };
- }
-
- if (!isDatetimeAxis && tickPositions.length > maxTicks[xOrY]) {
- maxTicks[xOrY] = tickPositions.length;
- }
- }
-
-
- }
-
-
- function adjustTickAmount() {
-
- if (maxTicks && !isDatetimeAxis && !categories && !isLinked) {
- var oldTickAmount = tickAmount,
- calculatedTickAmount = tickPositions.length;
-
-
- tickAmount = maxTicks[xOrY];
-
- if (calculatedTickAmount < tickAmount) {
- while (tickPositions.length < tickAmount) {
- tickPositions.push( correctFloat(
- tickPositions[tickPositions.length - 1] + tickInterval
- ));
- }
- transA *= (calculatedTickAmount - 1) / (tickAmount - 1);
- max = tickPositions[tickPositions.length - 1];
-
- }
- if (defined(oldTickAmount) && tickAmount != oldTickAmount) {
- axis.isDirty = true;
- }
- }
-
- }
-
-
- function setScale() {
- var type,
- i;
-
- oldMin = min;
- oldMax = max;
-
-
- getSeriesExtremes();
-
-
- setTickPositions();
-
-
- oldTransA = transA;
- transA = axisLength / ((max - min) || 1);
-
-
- if (!isXAxis) {
- for (type in stacks) {
- for (i in stacks[type]) {
- stacks[type][i].cum = stacks[type][i].total;
- }
- }
- }
-
- if (!axis.isDirty) {
- axis.isDirty = (min != oldMin || max != oldMax);
- }
-
- }
-
-
- function setExtremes(newMin, newMax, redraw, animation) {
-
- setAnimation(animation, chart);
- redraw = pick(redraw, true);
-
- fireEvent(axis, 'setExtremes', {
- min: newMin,
- max: newMax
- }, function() {
-
- userSetMin = newMin;
- userSetMax = newMax;
-
-
-
- if (redraw) {
- chart.redraw();
- }
- });
-
- }
-
-
- function getExtremes() {
- return {
- min: min,
- max: max,
- dataMin: dataMin,
- dataMax: dataMax
- };
- }
-
-
- function getThreshold(threshold) {
- if (min > threshold) {
- threshold = min;
- } else if (max < threshold) {
- threshold = max;
- }
-
- return translate(threshold, 0, 1);
- }
-
-
- function addPlotBandOrLine(options) {
- var obj = new PlotLineOrBand(options).render();
- plotLinesAndBands.push(obj);
- return obj;
- }
-
-
- function getOffset() {
-
- var hasData = associatedSeries.length && defined(min) && defined(max),
- titleOffset = 0,
- titleMargin = 0,
- axisTitleOptions = options.title,
- labelOptions = options.labels,
- directionFactor = [-1, 1, 1, -1][side];
-
- if (!axisGroup) {
- axisGroup = renderer.g('axis')
- .attr({ zIndex: 7 })
- .add();
- gridGroup = renderer.g('grid')
- .attr({ zIndex: 1 })
- .add();
- }
-
- labelOffset = 0;
-
- if (hasData || isLinked) {
- each(tickPositions, function(pos) {
- if (!ticks[pos]) {
- ticks[pos] = new Tick(pos);
- } else {
- ticks[pos].addLabel();
- }
-
-
- if (side === 0 || side == 2 || { 1: 'left', 3: 'right' }[side] == labelOptions.align) {
-
-
- labelOffset = mathMax(
- ticks[pos].getLabelSize(),
- labelOffset
- );
- }
-
- });
-
- if (staggerLines) {
- labelOffset += (staggerLines - 1) * 16;
- }
-
- } else {
- for (var n in ticks) {
- ticks[n].destroy();
- delete ticks[n];
- }
- }
-
- if (axisTitleOptions && axisTitleOptions.text) {
- if (!axis.axisTitle) {
- axis.axisTitle = renderer.text(
- axisTitleOptions.text,
- 0,
- 0
- )
- .attr({
- zIndex: 7,
- rotation: axisTitleOptions.rotation || 0,
- align:
- axisTitleOptions.textAlign ||
- { low: 'left', middle: 'center', high: 'right' }[axisTitleOptions.align]
- })
- .css(axisTitleOptions.style)
- .add();
- }
-
- titleOffset = axis.axisTitle.getBBox()[horiz ? 'height' : 'width'];
- titleMargin = pick(axisTitleOptions.margin, horiz ? 5 : 10);
-
- }
-
-
- offset = directionFactor * (options.offset || axisOffset[side]);
-
- axisTitleMargin =
- labelOffset +
- (side != 2 && labelOffset && directionFactor * options.labels[horiz ? 'y' : 'x']) +
- titleMargin;
-
- axisOffset[side] = mathMax(
- axisOffset[side],
- axisTitleMargin + titleOffset + directionFactor * offset
- );
- }
-
-
- function render() {
- var axisTitleOptions = options.title,
- alternateGridColor = options.alternateGridColor,
- lineWidth = options.lineWidth,
- lineLeft,
- lineTop,
- linePath,
- hasRendered = chart.hasRendered,
- slideInTicks = hasRendered && defined(oldMin) && !isNaN(oldMin),
- hasData = associatedSeries.length && defined(min) && defined(max);
-
-
- axisLength = horiz ? plotWidth : plotHeight;
- transA = axisLength / ((max - min) || 1);
- transB = horiz ? plotLeft : marginBottom;
-
-
- if (hasData || isLinked) {
-
-
- if (minorTickInterval && !categories) {
- var pos = min + (tickPositions[0] - min) % minorTickInterval;
- for (pos; pos <= max; pos += minorTickInterval) {
- if (!minorTicks[pos]) {
- minorTicks[pos] = new Tick(pos, true);
- }
-
-
- if (slideInTicks && minorTicks[pos].isNew) {
- minorTicks[pos].render(null, true);
- }
-
-
- minorTicks[pos].isActive = true;
- minorTicks[pos].render();
- }
- }
-
-
- each(tickPositions, function(pos, i) {
-
- if (!isLinked || (pos >= min && pos <= max)) {
-
-
- if (slideInTicks && ticks[pos].isNew) {
- ticks[pos].render(i, true);
- }
-
- ticks[pos].isActive = true;
- ticks[pos].render(i);
- }
- });
-
-
- if (alternateGridColor) {
- each(tickPositions, function(pos, i) {
- if (i % 2 === 0 && pos < max) {
-
-
- if (!alternateBands[pos]) {
- alternateBands[pos] = new PlotLineOrBand();
- }
- alternateBands[pos].options = {
- from: pos,
- to: tickPositions[i + 1] !== UNDEFINED ? tickPositions[i + 1] : max,
- color: alternateGridColor
- };
- alternateBands[pos].render();
- alternateBands[pos].isActive = true;
- }
- });
- }
-
-
-
-
-
-
-
-
- if (!hasRendered) {
- each((options.plotLines || []).concat(options.plotBands || []), function(plotLineOptions) {
- plotLinesAndBands.push(new PlotLineOrBand(plotLineOptions).render());
- });
- }
-
-
-
- }
-
-
- each([ticks, minorTicks, alternateBands], function(coll) {
- for (var pos in coll) {
- if (!coll[pos].isActive) {
- coll[pos].destroy();
- delete coll[pos];
- } else {
- coll[pos].isActive = false;
- }
- }
- });
-
-
-
-
-
-
-
- if (lineWidth) {
- lineLeft = plotLeft + (opposite ? plotWidth : 0) + offset;
- lineTop = chartHeight - marginBottom - (opposite ? plotHeight : 0) + offset;
-
- linePath = renderer.crispLine([
- M,
- horiz ?
- plotLeft:
- lineLeft,
- horiz ?
- lineTop:
- plotTop,
- L,
- horiz ?
- chartWidth - marginRight :
- lineLeft,
- horiz ?
- lineTop:
- chartHeight - marginBottom
- ], lineWidth);
- if (!axisLine) {
- axisLine = renderer.path(linePath)
- .attr({
- stroke: options.lineColor,
- 'stroke-width': lineWidth,
- zIndex: 7
- })
- .add();
- } else {
- axisLine.animate({ d: linePath });
- }
-
- }
-
- if (axis.axisTitle) {
-
- var margin = horiz ? plotLeft : plotTop,
- fontSize = pInt(axisTitleOptions.style.fontSize || 12),
-
- alongAxis = {
- low: margin + (horiz ? 0 : axisLength),
- middle: margin + axisLength / 2,
- high: margin + (horiz ? axisLength : 0)
- }[axisTitleOptions.align],
-
-
- offAxis = (horiz ? plotTop + plotHeight : plotLeft) +
- (horiz ? 1 : -1) *
- (opposite ? -1 : 1) *
- axisTitleMargin +
-
- (side == 2 ? fontSize : 0);
-
- axis.axisTitle[hasRendered ? 'animate' : 'attr']({
- x: horiz ?
- alongAxis:
- offAxis + (opposite ? plotWidth : 0) + offset +
- (axisTitleOptions.x || 0),
- y: horiz ?
- offAxis - (opposite ? plotHeight : 0) + offset:
- alongAxis + (axisTitleOptions.y || 0)
- });
-
- }
-
- axis.isDirty = false;
- }
-
-
- function removePlotBandOrLine(id) {
- for (var i = 0; i < plotLinesAndBands.length; i++) {
- if (plotLinesAndBands[i].id == id) {
- plotLinesAndBands[i].destroy();
- }
- }
- }
-
-
- function redraw() {
-
-
- if (tracker.resetTracker) {
- tracker.resetTracker();
- }
-
-
- render();
-
-
- each(plotLinesAndBands, function(plotLine) {
- plotLine.render();
- });
-
-
- each(associatedSeries, function(series) {
- series.isDirty = true;
- });
-
- }
-
-
- function setCategories(newCategories, doRedraw) {
-
- axis.categories = categories = newCategories;
-
-
- each(associatedSeries, function(series) {
- series.translate();
- series.setTooltipPoints(true);
- });
-
-
-
- axis.isDirty = true;
-
- if (pick(doRedraw, true)) {
- chart.redraw();
- }
- }
-
-
-
-
-
-
- if (inverted && isXAxis && reversed === UNDEFINED) {
- reversed = true;
- }
-
-
-
- extend(axis, {
- addPlotBand: addPlotBandOrLine,
- addPlotLine: addPlotBandOrLine,
- adjustTickAmount: adjustTickAmount,
- categories: categories,
- getExtremes: getExtremes,
- getPlotLinePath: getPlotLinePath,
- getThreshold: getThreshold,
- isXAxis: isXAxis,
- options: options,
- plotLinesAndBands: plotLinesAndBands,
- getOffset: getOffset,
- render: render,
- setCategories: setCategories,
- setExtremes: setExtremes,
- setScale: setScale,
- setTickPositions: setTickPositions,
- translate: translate,
- redraw: redraw,
- removePlotBand: removePlotBandOrLine,
- removePlotLine: removePlotBandOrLine,
- reversed: reversed,
- stacks: stacks
- });
-
-
- for (eventType in events) {
- addEvent(axis, eventType, events[eventType]);
- }
-
-
- setScale();
-
- }
-
-
-
- function Toolbar(chart) {
- var buttons = {};
-
- function add(id, text, title, fn) {
- if (!buttons[id]) {
- var button = renderer.text(
- text,
- 0,
- 0
- )
- .css(options.toolbar.itemStyle)
- .align({
- align: 'right',
- x: - marginRight - 20,
- y: plotTop + 30
- })
- .on('click', fn)
-
- .attr({
- align: 'right',
- zIndex: 20
- })
- .add();
- buttons[id] = button;
- }
- }
- function remove(id) {
- discardElement(buttons[id].element);
- buttons[id] = null;
- }
-
-
- return {
- add: add,
- remove: remove
- };
- }
-
-
- function Tooltip (options) {
- var currentSeries,
- borderWidth = options.borderWidth,
- crosshairsOptions = options.crosshairs,
- crosshairs = [],
- style = options.style,
- shared = options.shared,
- padding = pInt(style.padding),
- boxOffLeft = borderWidth + padding,
-
- tooltipIsHidden = true,
- boxWidth,
- boxHeight,
- currentX = 0,
- currentY = 0;
-
-
- style.padding = 0;
-
-
- var group = renderer.g('tooltip')
- .attr({
- zIndex: 8,
- translateY: -99
- })
- .add(),
-
- box = renderer.rect(boxOffLeft, boxOffLeft, 0, 0, options.borderRadius, borderWidth)
- .attr({
- fill: options.backgroundColor,
- 'stroke-width': borderWidth
- })
- .add(group)
- .shadow(options.shadow),
- label = renderer.text('', padding + boxOffLeft, pInt(style.fontSize) + padding + boxOffLeft)
- .attr({ zIndex: 1 })
- .css(style)
- .add(group);
-
- group.hide();
-
-
- function defaultFormatter() {
- var pThis = this,
- points = pThis.points || splat(pThis.point),
- xAxis = points[0].series.xAxis,
- x = pThis.x,
- isDateTime = xAxis && xAxis.options.type == 'datetime',
- useHeader = isString(x) || isDateTime,
- series,
- s;
-
-
- s = useHeader ?
- ['<span style="font-size: 10px">',
- (isDateTime ? dateFormat('%A, %b %e, %Y', x) : x),
- '</span><br/>'] : [];
-
-
- each(points, function(point) {
- series = point.series;
- s.push('<span style="color:'+ series.color +'">', (point.name || series.name), '</span>: ',
- (!useHeader ? ('<b>x = '+ (point.name || point.x) + ',</b> ') : ''),
- '<b>', (!useHeader ? 'y = ' : '' ), point.y, '</b><br/>');
- });
- return s.join('');
- }
-
-
- function move(finalX, finalY) {
- currentX = tooltipIsHidden ? finalX : (2 * currentX + finalX) / 3;
- currentY = tooltipIsHidden ? finalY : (currentY + finalY) / 2;
-
- group.translate(currentX, currentY);
-
-
-
- if (mathAbs(finalX - currentX) > 1 || mathAbs(finalY - currentY) > 1) {
- tooltipTick = function() {
- move(finalX, finalY);
- };
- } else {
- tooltipTick = null;
- }
- }
-
-
- function hide() {
- if (!tooltipIsHidden) {
- var hoverPoints = chart.hoverPoints;
-
- group.hide();
-
- each(crosshairs, function(crosshair) {
- crosshair.hide();
- });
-
-
- if (hoverPoints) {
- each (hoverPoints, function(point) {
- point.setState();
- });
- }
- chart.hoverPoints = null;
-
-
- tooltipIsHidden = true;
- }
-
- }
-
-
- function refresh(point) {
- var x,
- y,
- boxX,
- boxY,
- show,
- bBox,
- plotX,
- plotY = 0,
- textConfig = {},
- text,
- pointConfig = [],
- tooltipPos = point.tooltipPos,
- formatter = options.formatter || defaultFormatter,
- hoverPoints = chart.hoverPoints,
- getConfig = function(point) {
- return {
- series: point.series,
- point: point,
- x: point.category,
- y: point.y,
- percentage: point.percentage,
- total: point.total || point.stackTotal
- };
- };
-
-
- if (shared) {
-
-
- if (hoverPoints) {
- each (hoverPoints, function(point) {
- point.setState();
- });
- }
- chart.hoverPoints = point;
-
- each(point, function(item, i) {
-
- item.setState(HOVER_STATE);
- plotY += item.plotY;
-
- pointConfig.push(getConfig(item));
- });
-
- plotX = point[0].plotX;
- plotY = mathRound(plotY) / point.length;
-
- textConfig = {
- x: point[0].category
- };
- textConfig.points = pointConfig;
- point = point[0];
-
-
- } else {
- textConfig = getConfig(point);
- }
- text = formatter.call(textConfig);
-
-
- currentSeries = point.series;
-
-
- plotX = shared ? plotX : point.plotX;
- plotY = shared ? plotY : point.plotY;
- x = mathRound(tooltipPos ? tooltipPos[0] : (inverted ? plotWidth - plotY : plotX));
- y = mathRound(tooltipPos ? tooltipPos[1] : (inverted ? plotHeight - plotX : plotY));
-
-
-
- show = !point.series.isCartesian || isInsidePlot(x, y);
-
-
- if (text === false || !show) {
- hide();
- } else {
-
-
- if (tooltipIsHidden) {
- group.show();
- tooltipIsHidden = false;
- }
-
-
- label.attr({
- text: text
- });
-
-
- bBox = label.getBBox();
- boxWidth = bBox.width;
- boxHeight = bBox.height;
-
-
- box.attr({
- width: boxWidth + 2 * padding,
- height: boxHeight + 2 * padding,
- stroke: options.borderColor || point.color || currentSeries.color || '#606060'
- });
-
-
- boxX = x - boxWidth + plotLeft - 25;
- boxY = y - boxHeight + plotTop + 10;
-
-
- if (boxX < 7) {
- boxX = 7;
- boxY -= 30;
- }
-
-
- if (boxY < 5) {
- boxY = 5;
- } else if (boxY + boxHeight > chartHeight) {
- boxY = chartHeight - boxHeight - 5;
- }
-
-
- move(mathRound(boxX - boxOffLeft), mathRound(boxY - boxOffLeft));
-
-
- }
-
-
-
- if (crosshairsOptions) {
- crosshairsOptions = splat(crosshairsOptions);
-
- var path,
- i = crosshairsOptions.length,
- attribs,
- axis;
-
- while (i--) {
- if (crosshairsOptions[i] && (axis = point.series[i ? 'yAxis' : 'xAxis'])) {
- path = axis
- .getPlotLinePath(point[i ? 'y' : 'x'], 1);
- if (crosshairs[i]) {
- crosshairs[i].attr({ d: path, visibility: VISIBLE });
-
- } else {
- attribs = {
- 'stroke-width': crosshairsOptions[i].width || 1,
- stroke: crosshairsOptions[i].color || '#C0C0C0',
- zIndex: 2
- };
- if (crosshairsOptions[i].dashStyle) {
- attribs.dashstyle = crosshairsOptions[i].dashStyle;
- }
- crosshairs[i] = renderer.path(path)
- .attr(attribs)
- .add();
- }
- }
- }
- }
- }
-
-
-
- return {
- shared: shared,
- refresh: refresh,
- hide: hide
- };
- }
-
-
- function MouseTracker (chart, options) {
-
- var mouseDownX,
- mouseDownY,
- hasDragged,
- selectionMarker,
- zoomType = optionsChart.zoomType,
- zoomX = /x/.test(zoomType),
- zoomY = /y/.test(zoomType),
- zoomHor = zoomX && !inverted || zoomY && inverted,
- zoomVert = zoomY && !inverted || zoomX && inverted;
-
-
- function normalizeMouseEvent(e) {
- var ePos;
-
-
- e = e || win.event;
- if (!e.target) {
- e.target = e.srcElement;
- }
-
-
- ePos = e.touches ? e.touches.item(0) : e;
-
-
- if (e.type != 'mousemove' || win.opera) {
- chartPosition = getPosition(container);
- }
-
- if (isIE) {
- e.chartX = e.x;
- e.chartY = e.y;
- } else {
- if (ePos.layerX === UNDEFINED) {
- e.chartX = ePos.pageX - chartPosition.left;
- e.chartY = ePos.pageY - chartPosition.top;
- } else {
- e.chartX = e.layerX;
- e.chartY = e.layerY;
- }
- }
-
- return e;
- }
-
-
- function getMouseCoordinates(e) {
- var coordinates = {
- xAxis: [],
- yAxis: []
- };
- each(axes, function(axis, i) {
- var translate = axis.translate,
- isXAxis = axis.isXAxis,
- isHorizontal = inverted ? !isXAxis : isXAxis;
-
- coordinates[isXAxis ? 'xAxis' : 'yAxis'].push({
- axis: axis,
- value: translate(
- isHorizontal ?
- e.chartX - plotLeft :
- plotHeight - e.chartY + plotTop,
- true
- )
- });
- });
- return coordinates;
- }
-
-
- function onmousemove (e) {
- var point,
- points,
- hoverPoint = chart.hoverPoint,
- hoverSeries = chart.hoverSeries,
- i,
- j,
- distance = chartWidth,
- index = inverted ? e.chartY : e.chartX - plotLeft;
-
-
- if (tooltip && options.shared) {
- points = [];
-
-
- i = series.length;
- for (j = 0; j < i; j++) {
- if (series[j].visible && series[j].tooltipPoints.length) {
- point = series[j].tooltipPoints[index];
- point._dist = mathAbs(index - point.plotX);
- distance = mathMin(distance, point._dist);
- points.push(point);
- }
- }
-
- i = points.length;
- while (i--) {
- if (points[i]._dist > distance) {
- points.splice(i, 1);
- }
- }
-
- if (points.length && (points[0].plotX != hoverX)) {
- tooltip.refresh(points);
- hoverX = points[0].plotX;
- }
- }
-
-
- if (hoverSeries && hoverSeries.tracker) {
-
-
- point = hoverSeries.tooltipPoints[index];
-
-
- if (point && point != hoverPoint) {
-
-
- point.onMouseOver();
-
- }
- }
- }
-
-
-
-
- function resetTracker() {
- var hoverSeries = chart.hoverSeries,
- hoverPoint = chart.hoverPoint;
- if (hoverPoint) {
- hoverPoint.onMouseOut();
- }
-
- if (hoverSeries) {
- hoverSeries.onMouseOut();
- }
-
- if (tooltip) {
- tooltip.hide();
- }
-
- hoverX = null;
- }
-
-
- function drop() {
- if (selectionMarker) {
- var selectionData = {
- xAxis: [],
- yAxis: []
- },
- selectionBox = selectionMarker.getBBox(),
- selectionLeft = selectionBox.x - plotLeft,
- selectionTop = selectionBox.y - plotTop;
-
-
-
- if (hasDragged) {
-
-
- each(axes, function(axis, i) {
- var translate = axis.translate,
- isXAxis = axis.isXAxis,
- isHorizontal = inverted ? !isXAxis : isXAxis,
- selectionMin = translate(
- isHorizontal ?
- selectionLeft :
- plotHeight - selectionTop - selectionBox.height,
- true
- ),
- selectionMax = translate(
- isHorizontal ?
- selectionLeft + selectionBox.width :
- plotHeight - selectionTop,
- true
- );
-
- selectionData[isXAxis ? 'xAxis' : 'yAxis'].push({
- axis: axis,
- min: mathMin(selectionMin, selectionMax),
- max: mathMax(selectionMin, selectionMax)
- });
-
- });
- fireEvent(chart, 'selection', selectionData, zoom);
- }
- selectionMarker = selectionMarker.destroy();
- }
-
- chart.mouseIsDown = mouseIsDown = hasDragged = false;
- removeEvent(doc, hasTouch ? 'touchend' : 'mouseup', drop);
- }
-
-
- function setDOMEvents () {
- var lastWasOutsidePlot = true;
-
-
- container.onmousedown = function(e) {
- e = normalizeMouseEvent(e);
-
-
-
-
- chart.mouseIsDown = mouseIsDown = true;
- mouseDownX = e.chartX;
- mouseDownY = e.chartY;
-
- addEvent(doc, hasTouch ? 'touchend' : 'mouseup', drop);
- };
-
-
- var mouseMove = function(e) {
-
-
- if (e && e.touches && e.touches.length > 1) {
- return;
- }
-
-
- e = normalizeMouseEvent(e);
- if (!hasTouch) {
- e.returnValue = false;
- }
-
- var chartX = e.chartX,
- chartY = e.chartY,
- isOutsidePlot = !isInsidePlot(chartX - plotLeft, chartY - plotTop);
-
-
- if (hasTouch && e.type == 'touchstart') {
- if (attr(e.target, 'isTracker')) {
- if (!chart.runTrackerClick) {
- e.preventDefault();
- }
- } else if (!runChartClick && !isOutsidePlot) {
- e.preventDefault();
- }
- }
-
-
- if (isOutsidePlot) {
-
- if (!lastWasOutsidePlot) {
-
- resetTracker();
- }
-
-
-
- if (chartX < plotLeft) {
- chartX = plotLeft;
- } else if (chartX > plotLeft + plotWidth) {
- chartX = plotLeft + plotWidth;
- }
-
- if (chartY < plotTop) {
- chartY = plotTop;
- } else if (chartY > plotTop + plotHeight) {
- chartY = plotTop + plotHeight;
- }
-
- }
-
- if (mouseIsDown && e.type != 'touchstart') {
-
-
- if ((hasDragged = Math.sqrt(
- Math.pow(mouseDownX - chartX, 2) +
- Math.pow(mouseDownY - chartY, 2)
- ) > 10)) {
-
-
- if (hasCartesianSeries && (zoomX || zoomY) &&
- isInsidePlot(mouseDownX - plotLeft, mouseDownY - plotTop)) {
- if (!selectionMarker) {
- selectionMarker = renderer.rect(
- plotLeft,
- plotTop,
- zoomHor ? 1 : plotWidth,
- zoomVert ? 1 : plotHeight,
- 0
- )
- .attr({
- fill: 'rgba(69,114,167,0.25)',
- zIndex: 7
- })
- .add();
- }
- }
-
-
- if (selectionMarker && zoomHor) {
- var xSize = chartX - mouseDownX;
- selectionMarker.attr({
- width: mathAbs(xSize),
- x: (xSize > 0 ? 0 : xSize) + mouseDownX
- });
- }
-
- if (selectionMarker && zoomVert) {
- var ySize = chartY - mouseDownY;
- selectionMarker.attr({
- height: mathAbs(ySize),
- y: (ySize > 0 ? 0 : ySize) + mouseDownY
- });
- }
- }
-
- } else if (!isOutsidePlot) {
-
- onmousemove(e);
- }
-
- lastWasOutsidePlot = isOutsidePlot;
-
-
- return isOutsidePlot || !hasCartesianSeries;
- };
-
-
- container.onmousemove = mouseMove;
-
-
- addEvent(container, 'mouseleave', resetTracker);
-
-
- container.ontouchstart = function(e) {
-
- if (zoomX || zoomY) {
- container.onmousedown(e);
- }
-
- mouseMove(e);
- };
-
-
- container.ontouchmove = mouseMove;
-
-
- container.ontouchend = function() {
- if (hasDragged) {
- resetTracker();
- }
- };
-
-
-
- container.onclick = function(e) {
- var hoverPoint = chart.hoverPoint;
- e = normalizeMouseEvent(e);
-
- e.cancelBubble = true;
-
-
- if (!hasDragged) {
- if (hoverPoint && attr(e.target, 'isTracker')) {
- var plotX = hoverPoint.plotX,
- plotY = hoverPoint.plotY;
-
-
- extend(hoverPoint, {
- pageX: chartPosition.left + plotLeft +
- (inverted ? plotWidth - plotY : plotX),
- pageY: chartPosition.top + plotTop +
- (inverted ? plotHeight - plotX : plotY)
- });
-
-
- fireEvent(hoverPoint.series, 'click', extend(e, {
- point: hoverPoint
- }));
-
-
- hoverPoint.firePointEvent('click', e);
-
- } else {
- extend(e, getMouseCoordinates(e));
-
-
- if (isInsidePlot(e.chartX - plotLeft, e.chartY - plotTop)) {
- fireEvent(chart, 'click', e);
- }
- }
-
-
- }
-
- hasDragged = false;
- };
-
- }
-
-
- placeTrackerGroup = function() {
-
-
- if (!trackerGroup) {
- chart.trackerGroup = trackerGroup = renderer.g('tracker')
- .attr({ zIndex: 9 })
- .add();
-
-
-
- } else {
- trackerGroup.translate(plotLeft, plotTop);
- if (inverted) {
- trackerGroup.attr({
- width: chart.plotWidth,
- height: chart.plotHeight
- }).invert();
- }
- }
- };
-
-
-
- placeTrackerGroup();
- if (options.enabled) {
- chart.tooltip = tooltip = Tooltip(options);
- }
-
- setDOMEvents();
-
-
- tooltipInterval = setInterval(function() {
- if (tooltipTick) {
- tooltipTick();
- }
- }, 32);
-
-
- extend(this, {
- zoomX: zoomX,
- zoomY: zoomY,
- resetTracker: resetTracker
- });
- }
-
-
-
-
- var Legend = function(chart) {
- var options = chart.options.legend;
-
- if (!options.enabled) {
- return;
- }
-
- var horizontal = options.layout == 'horizontal',
- symbolWidth = options.symbolWidth,
- symbolPadding = options.symbolPadding,
- allItems,
- style = options.style,
- itemStyle = options.itemStyle,
- itemHoverStyle = options.itemHoverStyle,
- itemHiddenStyle = options.itemHiddenStyle,
- padding = pInt(style.padding),
- rightPadding = 20,
-
- y = 18,
- initialItemX = 4 + padding + symbolWidth + symbolPadding,
- itemX,
- itemY,
- lastItemY,
- lastItemHeight = 0,
- box,
- legendBorderWidth = options.borderWidth,
- legendBackgroundColor = options.backgroundColor,
- legendGroup,
- offsetWidth,
- widthOption = options.width,
- series = chart.series,
- reversedLegend = options.reversed;
-
-
-
-
- function colorizeItem(item, visible) {
- var legendItem = item.legendItem,
- legendLine = item.legendLine,
- legendSymbol = item.legendSymbol,
- hiddenColor = itemHiddenStyle.color,
- textColor = visible ? options.itemStyle.color : hiddenColor,
- symbolColor = visible ? item.color : hiddenColor;
- if (legendItem) {
- legendItem.css({ fill: textColor });
- }
- if (legendLine) {
- legendLine.attr({ stroke: symbolColor });
- }
- if (legendSymbol) {
- legendSymbol.attr({
- stroke: symbolColor,
- fill: symbolColor
- });
- }
- }
-
-
- function positionItem(item, itemX, itemY) {
- var legendItem = item.legendItem,
- legendLine = item.legendLine,
- legendSymbol = item.legendSymbol,
- checkbox = item.checkbox;
- if (legendItem) {
- legendItem.attr({
- x: itemX,
- y: itemY
- });
- }
- if (legendLine) {
- legendLine.translate(itemX, itemY - 4);
- }
- if (legendSymbol) {
- legendSymbol.attr({
- x: itemX + legendSymbol.xOff,
- y: itemY + legendSymbol.yOff
- });
- }
- if (checkbox) {
- checkbox.x = itemX;
- checkbox.y = itemY;
- }
- }
-
-
- function destroyItem(item) {
- var checkbox = item.checkbox;
-
-
-
-
-
- each(['legendItem', 'legendLine', 'legendSymbol'], function(key) {
- if (item[key]) {
- item[key].destroy();
- }
- });
-
- if (checkbox) {
- discardElement(item.checkbox);
- }
-
-
- }
-
-
-
- function positionCheckboxes() {
- each(allItems, function(item) {
- var checkbox = item.checkbox;
- if (checkbox) {
- css(checkbox, {
- left: (legendGroup.attr('translateX') + item.legendItemWidth + checkbox.x - 40) +PX,
- top: (legendGroup.attr('translateY') + checkbox.y - 11) + PX
- });
- }
- });
- }
-
-
- function renderItem(item) {
- var bBox,
- itemWidth,
- legendSymbol,
- symbolX,
- symbolY,
- attribs,
- simpleSymbol,
- li = item.legendItem,
- series = item.series || item;
-
-
- if (!li) {
-
-
- simpleSymbol = /^(bar|pie|area|column)$/.test(series.type);
-
-
- item.legendItem = li = renderer.text(
- options.labelFormatter.call(item),
- 0,
- 0
- )
- .css(item.visible ? itemStyle : itemHiddenStyle)
- .on('mouseover', function() {
- item.setState(HOVER_STATE);
- li.css(itemHoverStyle);
- })
- .on('mouseout', function() {
- li.css(item.visible ? itemStyle : itemHiddenStyle);
- item.setState();
- })
- .on('click', function(event) {
- var strLegendItemClick = 'legendItemClick',
- fnLegendItemClick = function() {
- item.setVisible();
- };
-
-
- if (item.firePointEvent) {
- item.firePointEvent(strLegendItemClick, null, fnLegendItemClick);
- } else {
- fireEvent(item, strLegendItemClick, null, fnLegendItemClick);
- }
- })
- .attr({ zIndex: 2 })
- .add(legendGroup);
-
-
- if (!simpleSymbol && item.options && item.options.lineWidth) {
- var itemOptions = item.options;
- attribs = {
- 'stroke-width': itemOptions.lineWidth,
- zIndex: 2
- };
- if (itemOptions.dashStyle) {
- attribs.dashstyle = itemOptions.dashStyle;
- }
- item.legendLine = renderer.path([
- M,
- -symbolWidth - symbolPadding,
- 0,
- L,
- -symbolPadding,
- 0
- ])
- .attr(attribs)
- .add(legendGroup);
- }
-
-
- if (simpleSymbol) {
-
- legendSymbol = renderer.rect(
- (symbolX = -symbolWidth - symbolPadding),
- (symbolY = -11),
- symbolWidth,
- 12,
- 2
- ).attr({
- 'stroke-width': 0,
- zIndex: 3
- }).add(legendGroup);
- }
-
-
- else if (item.options && item.options.marker && item.options.marker.enabled) {
- legendSymbol = renderer.symbol(
- item.symbol,
- (symbolX = -symbolWidth / 2 - symbolPadding),
- (symbolY = -4),
- item.options.marker.radius
- )
- .attr(item.pointAttr[NORMAL_STATE])
- .attr({ zIndex: 3 })
- .add(legendGroup);
-
-
- }
- if (legendSymbol) {
- legendSymbol.xOff = symbolX;
- legendSymbol.yOff = symbolY;
- }
-
- item.legendSymbol = legendSymbol;
-
-
- colorizeItem(item, item.visible);
-
-
-
- if (item.options && item.options.showCheckbox) {
- item.checkbox = createElement('input', {
- type: 'checkbox',
- checked: item.selected,
- defaultChecked: item.selected
- }, options.itemCheckboxStyle, container);
-
- addEvent(item.checkbox, 'click', function(event) {
- var target = event.target;
- fireEvent(item, 'checkboxClick', {
- checked: target.checked
- },
- function() {
- item.select();
- }
- );
- });
- }
- }
-
-
-
-
- positionItem(item, itemX, itemY);
-
-
- bBox = li.getBBox();
- lastItemY = itemY;
- lastItemHeight = bBox.height;
-
- item.legendItemWidth = itemWidth =
- options.itemWidth || symbolWidth + symbolPadding + bBox.width + rightPadding;
- if (horizontal) {
- itemX += itemWidth;
- offsetWidth = widthOption || mathMax(itemX - initialItemX, offsetWidth);
-
- if (itemX - initialItemX + itemWidth >
- (widthOption || (chartWidth - 2 * padding - initialItemX))) {
- itemX = initialItemX;
- itemY += lastItemHeight;
- }
-
- } else {
- itemY += lastItemHeight;
-
- offsetWidth = widthOption || mathMax(itemWidth, offsetWidth);
- }
-
-
- allItems.push(item);
- }
-
- function renderLegend() {
- itemX = initialItemX;
- itemY = y;
- offsetWidth = 0;
- lastItemY = 0;
-
- allItems = [];
-
- if (!legendGroup) {
- legendGroup = renderer.g('legend')
- .attr({ zIndex: 7 })
- .add();
- }
-
-
-
- if (reversedLegend) {
- series.reverse();
- }
- each(series, function(serie) {
- if (!serie.options.showInLegend) {
- return;
- }
-
-
- var items = (serie.options.legendType == 'point') ?
- serie.data : [serie];
-
-
- each(items, renderItem);
- });
- if (reversedLegend) {
- series.reverse();
- }
-
-
-
-
- legendWidth = widthOption || offsetWidth;
- legendHeight = lastItemY - y + lastItemHeight;
-
- if (legendBorderWidth || legendBackgroundColor) {
- legendWidth += 2 * padding;
- legendHeight += 2 * padding;
-
- if (!box) {
- box = renderer.rect(
- 0,
- 0,
- legendWidth,
- legendHeight,
- options.borderRadius,
- legendBorderWidth || 0
- ).attr({
- stroke: options.borderColor,
- 'stroke-width': legendBorderWidth || 0,
- fill: legendBackgroundColor || NONE
- })
- .add(legendGroup)
- .shadow(options.shadow);
-
- } else if (legendWidth > 0 && legendHeight > 0) {
- box.animate({
- width: legendWidth,
- height: legendHeight
- });
- }
-
-
- box[allItems.length ? 'show' : 'hide']();
- }
-
-
- var props = ['left', 'right', 'top', 'bottom'],
- prop,
- i = 4;
- while(i--) {
- prop = props[i];
- if (style[prop] && style[prop] != 'auto') {
- options[i < 2 ? 'align' : 'verticalAlign'] = prop;
- options[i < 2 ? 'x' : 'y'] = pInt(style[prop]) * (i % 2 ? -1 : 1);
- }
- }
-
- legendGroup.align(extend(options, {
- width: legendWidth,
- height: legendHeight
- }), true, spacingBox);
-
- if (!isResizing) {
- positionCheckboxes();
- }
- }
-
-
-
- renderLegend();
-
-
- addEvent(chart, 'endResize', positionCheckboxes);
-
-
- return {
- colorizeItem: colorizeItem,
- destroyItem: destroyItem,
- renderLegend: renderLegend
- };
- };
-
-
-
-
-
-
- function initSeries(options) {
- var type = options.type || optionsChart.type || optionsChart.defaultSeriesType,
- typeClass = seriesTypes[type],
- serie,
- hasRendered = chart.hasRendered;
-
-
- if (hasRendered) {
- if (inverted && type == 'column') {
- typeClass = seriesTypes.bar;
- } else if (!inverted && type == 'bar') {
- typeClass = seriesTypes.column;
- }
- }
-
- serie = new typeClass();
-
- serie.init(chart, options);
-
-
- if (!hasRendered && serie.inverted) {
- inverted = true;
- }
- if (serie.isCartesian) {
- hasCartesianSeries = serie.isCartesian;
- }
-
- series.push(serie);
-
- return serie;
- }
-
- function addSeries(options, redraw, animation) {
- var series;
-
- if (options) {
- setAnimation(animation, chart);
- redraw = pick(redraw, true);
-
- fireEvent(chart, 'addSeries', { options: options }, function() {
- series = initSeries(options);
- series.isDirty = true;
-
- chart.isDirtyLegend = true;
- if (redraw) {
- chart.redraw();
- }
- });
- }
-
- return series;
- }
-
-
- isInsidePlot = function(x, y) {
- return x >= 0 &&
- x <= plotWidth &&
- y >= 0 &&
- y <= plotHeight;
- };
-
-
- function adjustTickAmounts() {
- if (optionsChart.alignTicks !== false) {
- each(axes, function(axis) {
- axis.adjustTickAmount();
- });
- }
- maxTicks = null;
- }
-
- function redraw(animation) {
- var redrawLegend = chart.isDirtyLegend,
- hasStackedSeries,
- isDirtyBox = chart.isDirtyBox,
- seriesLength = series.length,
- i = seriesLength,
- clipRect = chart.clipRect,
- serie;
-
- setAnimation(animation, chart);
-
-
- while (i--) {
- serie = series[i];
- if (serie.isDirty && serie.options.stacking) {
- hasStackedSeries = true;
- break;
- }
- }
- if (hasStackedSeries) {
- i = seriesLength;
- while (i--) {
- serie = series[i];
- if (serie.options.stacking) {
- serie.isDirty = true;
- }
- }
- }
-
-
- each(series, function(serie) {
- if (serie.isDirty) {
- serie.cleanData();
- serie.getSegments();
-
- if (serie.options.legendType == 'point') {
- redrawLegend = true;
- }
- }
- });
-
-
- if (redrawLegend && legend.renderLegend) {
-
- legend.renderLegend();
-
- chart.isDirtyLegend = false;
- }
-
- if (hasCartesianSeries) {
- if (!isResizing) {
-
-
- maxTicks = null;
-
-
- each(axes, function(axis) {
- axis.setScale();
- });
- }
- adjustTickAmounts();
- getMargins();
-
-
- each(axes, function(axis) {
- if (axis.isDirty || isDirtyBox) {
- axis.redraw();
- isDirtyBox = true;
- }
- });
-
-
- }
-
-
- if (isDirtyBox) {
- drawChartBox();
- placeTrackerGroup();
-
-
- if (clipRect) {
- stop(clipRect);
- clipRect.animate({
- width: chart.plotSizeX,
- height: chart.plotSizeY
- });
- }
-
- }
-
-
-
- each(series, function(serie) {
- if (serie.isDirty && serie.visible) {
- serie.redraw();
- }
- });
-
-
-
- if (tracker && tracker.resetTracker) {
- tracker.resetTracker();
- }
-
-
- renderer.draw();
-
-
- fireEvent(chart, 'redraw');
- }
-
-
-
-
- function showLoading(str) {
- var loadingOptions = options.loading;
-
- if (!loadingDiv) {
- loadingDiv = createElement(DIV, {
- className: 'highcharts-loading'
- }, extend(loadingOptions.style, {
- left: plotLeft + PX,
- top: plotTop + PX,
- width: plotWidth + PX,
- height: plotHeight + PX,
- zIndex: 10,
- display: NONE
- }), container);
-
- loadingSpan = createElement(
- 'span',
- null,
- loadingOptions.labelStyle,
- loadingDiv
- );
- }
-
-
- loadingSpan.innerHTML = str || options.lang.loading;
-
-
- if (!loadingShown) {
- css(loadingDiv, { opacity: 0, display: '' });
- animate(loadingDiv, {
- opacity: loadingOptions.style.opacity
- }, {
- duration: loadingOptions.showDuration
- });
- loadingShown = true;
- }
- }
-
- function hideLoading() {
- animate(loadingDiv, {
- opacity: 0
- }, {
- duration: options.loading.hideDuration,
- complete: function() {
- css(loadingDiv, { display: NONE });
- }
- });
- loadingShown = false;
- }
-
-
- function get(id) {
- var i,
- j,
- data;
-
-
- for (i = 0; i < axes.length; i++) {
- if (axes[i].options.id == id) {
- return axes[i];
- }
- }
-
-
- for (i = 0; i < series.length; i++) {
- if (series[i].options.id == id) {
- return series[i];
- }
- }
-
-
- for (i = 0; i < series.length; i++) {
- data = series[i].data;
- for (j = 0; j < data.length; j++) {
- if (data[j].id == id) {
- return data[j];
- }
- }
- }
- return null;
- }
-
-
- function getAxes() {
- var xAxisOptions = options.xAxis || {},
- yAxisOptions = options.yAxis || {},
- axis;
-
-
- xAxisOptions = splat(xAxisOptions);
- each(xAxisOptions, function(axis, i) {
- axis.index = i;
- axis.isX = true;
- });
-
- yAxisOptions = splat(yAxisOptions);
- each(yAxisOptions, function(axis, i) {
- axis.index = i;
- });
-
-
- axes = xAxisOptions.concat(yAxisOptions);
-
-
- chart.xAxis = [];
- chart.yAxis = [];
- axes = map(axes, function(axisOptions) {
- axis = new Axis(chart, axisOptions);
- chart[axis.isXAxis ? 'xAxis' : 'yAxis'].push(axis);
-
- return axis;
- });
-
- adjustTickAmounts();
- }
-
-
- function getSelectedPoints() {
- var points = [];
- each(series, function(serie) {
- points = points.concat( grep( serie.data, function(point) {
- return point.selected;
- }));
- });
- return points;
- }
-
-
- function getSelectedSeries() {
- return grep(series, function (serie) {
- return serie.selected;
- });
- }
-
-
- zoomOut = function () {
- fireEvent(chart, 'selection', { resetSelection: true }, zoom);
- chart.toolbar.remove('zoom');
- };
-
- zoom = function (event) {
-
-
- var lang = defaultOptions.lang,
- animate = chart.pointCount < 100;
- chart.toolbar.add('zoom', lang.resetZoom, lang.resetZoomTitle, zoomOut);
-
-
- if (!event || event.resetSelection) {
- each(axes, function(axis) {
- axis.setExtremes(null, null, false, animate);
- });
- }
-
-
- else {
- each(event.xAxis.concat(event.yAxis), function(axisData) {
- var axis = axisData.axis;
-
-
- if (chart.tracker[axis.isXAxis ? 'zoomX' : 'zoomY']) {
- axis.setExtremes(axisData.min, axisData.max, false, animate);
- }
- });
- }
-
-
- redraw();
- };
-
-
- function setTitle (titleOptions, subtitleOptions) {
-
- chartTitleOptions = merge(options.title, titleOptions);
- chartSubtitleOptions = merge(options.subtitle, subtitleOptions);
-
-
- each([
- ['title', titleOptions, chartTitleOptions],
- ['subtitle', subtitleOptions, chartSubtitleOptions]
- ], function(arr) {
- var name = arr[0],
- title = chart[name],
- titleOptions = arr[1],
- chartTitleOptions = arr[2];
-
- if (title && titleOptions) {
- title.destroy();
- title = null;
- }
-
- if (chartTitleOptions && chartTitleOptions.text && !title) {
- chart[name] = renderer.text(
- chartTitleOptions.text,
- 0,
- 0
- )
- .attr({
- align: chartTitleOptions.align,
- 'class': 'highcharts-'+ name,
- zIndex: 1
- })
- .css(chartTitleOptions.style)
- .add()
- .align(chartTitleOptions, false, spacingBox);
- }
-
- });
-
- }
-
-
- function getChartSize() {
- containerWidth = (renderToClone || renderTo).offsetWidth;
- containerHeight = (renderToClone || renderTo).offsetHeight;
- chart.chartWidth = chartWidth = optionsChart.width || containerWidth || 600;
- chart.chartHeight = chartHeight = optionsChart.height ||
-
- (containerHeight > 19 ? containerHeight : 400);
- }
-
-
- function getContainer() {
- renderTo = optionsChart.renderTo;
- containerId = PREFIX + idCounter++;
-
- if (isString(renderTo)) {
- renderTo = doc.getElementById(renderTo);
- }
-
-
- renderTo.innerHTML = '';
-
-
-
-
-
- if (!renderTo.offsetWidth) {
- renderToClone = renderTo.cloneNode(0);
- css(renderToClone, {
- position: ABSOLUTE,
- top: '-9999px',
- display: ''
- });
- doc.body.appendChild(renderToClone);
- }
-
-
- getChartSize();
-
-
- chart.container = container = createElement(DIV, {
- className: 'highcharts-container' +
- (optionsChart.className ? ' '+ optionsChart.className : ''),
- id: containerId
- }, extend({
- position: RELATIVE,
- overflow: HIDDEN,
-
- width: chartWidth + PX,
- height: chartHeight + PX,
- textAlign: 'left'
- }, optionsChart.style),
- renderToClone || renderTo
- );
-
- chart.renderer = renderer =
- optionsChart.renderer == 'SVG' ?
- new SVGRenderer(container, chartWidth, chartHeight) :
- new Renderer(container, chartWidth, chartHeight);
-
-
-
-
-
-
-
- var subPixelFix;
- if (/Gecko/.test(userAgent)) {
- subPixelFix = function() {
- css(container, { left: 0, top: 0 });
- var rect = container.getBoundingClientRect();
- css(container, {
- left: (-rect.left % 1) + PX,
- top: (-rect.top % 1) + PX
- });
- };
-
-
- subPixelFix();
-
-
- addEvent(win, 'resize', subPixelFix);
-
-
- addEvent(chart, 'destroy', function() {
- removeEvent(win, 'resize', subPixelFix);
- });
- }
- }
-
-
- getMargins = function() {
- var legendOptions = options.legend,
- legendMargin = pick(legendOptions.margin, 10),
- legendX = legendOptions.x,
- legendY = legendOptions.y,
- align = legendOptions.align,
- verticalAlign = legendOptions.verticalAlign,
- titleOffset;
- resetMargins();
-
- if ((chart.title || chart.subtitle) && !defined(optionsMarginTop)) {
- titleOffset = mathMax(
- chart.title && !chartTitleOptions.floating && !chartTitleOptions.verticalAlign && chartTitleOptions.y || 0,
- chart.subtitle && !chartSubtitleOptions.floating && !chartSubtitleOptions.verticalAlign && chartSubtitleOptions.y || 0
- );
- if (titleOffset) {
- plotTop = mathMax(plotTop, titleOffset + pick(chartTitleOptions.margin, 15) + spacingTop);
- }
- }
-
- if (legendOptions.enabled && !legendOptions.floating) {
- if (align == 'right') {
- if (!defined(optionsMarginRight)) {
- marginRight = mathMax(
- marginRight,
- legendWidth - legendX + legendMargin + spacingRight
- );
- }
- } else if (align == 'left') {
- if (!defined(optionsMarginLeft)) {
- plotLeft = mathMax(
- plotLeft,
- legendWidth + legendX + legendMargin + spacingLeft
- );
- }
-
- } else if (verticalAlign == 'top') {
- if (!defined(optionsMarginTop)) {
- plotTop = mathMax(
- plotTop,
- legendHeight + legendY + legendMargin + spacingTop
- );
- }
-
- } else if (verticalAlign == 'bottom') {
- if (!defined(optionsMarginBottom)) {
- marginBottom = mathMax(
- marginBottom,
- legendHeight - legendY + legendMargin + spacingBottom
- );
- }
- }
- }
-
-
- if (hasCartesianSeries) {
- each(axes, function(axis) {
- axis.getOffset();
- });
- }
-
- if (!defined(optionsMarginLeft)) {
- plotLeft += axisOffset[3];
- }
- if (!defined(optionsMarginTop)) {
- plotTop += axisOffset[0];
- }
- if (!defined(optionsMarginBottom)) {
- marginBottom += axisOffset[2];
- }
- if (!defined(optionsMarginRight)) {
- marginRight += axisOffset[1];
- }
- setChartSize();
-
- };
-
-
- function initReflow() {
- var reflowTimeout;
- function reflow() {
- var width = optionsChart.width || renderTo.offsetWidth,
- height = optionsChart.height || renderTo.offsetHeight;
-
- if (width && height) {
- if (width != containerWidth || height != containerHeight) {
- clearTimeout(reflowTimeout);
- reflowTimeout = setTimeout(function() {
- resize(width, height, false);
- }, 100);
- }
- containerWidth = width;
- containerHeight = height;
- }
- }
- addEvent(window, 'resize', reflow);
- addEvent(chart, 'destroy', function() {
- removeEvent(window, 'resize', reflow);
- });
- }
-
-
- resize = function(width, height, animation) {
- var chartTitle = chart.title,
- chartSubtitle = chart.subtitle;
-
- isResizing += 1;
-
-
- setAnimation(animation, chart);
-
- oldChartHeight = chartHeight;
- oldChartWidth = chartWidth;
- chartWidth = mathRound(width);
- chartHeight = mathRound(height);
-
- css(container, {
- width: chartWidth + PX,
- height: chartHeight + PX
- });
- renderer.setSize(chartWidth, chartHeight);
-
-
- plotWidth = chartWidth - plotLeft - marginRight;
- plotHeight = chartHeight - plotTop - marginBottom;
-
-
- maxTicks = null;
- each(axes, function(axis) {
- axis.isDirty = true;
- axis.setScale();
- });
-
-
- each(series, function(serie) {
- serie.isDirty = true;
- });
-
- chart.isDirtyLegend = true;
- chart.isDirtyBox = true;
-
- getMargins();
-
-
- if (chartTitle) {
- chartTitle.align(null, null, spacingBox);
- }
- if (chartSubtitle) {
- chartSubtitle.align(null, null, spacingBox);
- }
-
- redraw();
-
-
- oldChartHeight = null;
- fireEvent(chart, 'resize');
-
-
- setTimeout(function() {
- fireEvent(chart, 'endResize', null, function() {
- isResizing -= 1;
- });
- }, globalAnimation && globalAnimation.duration || 500);
- };
-
-
- setChartSize = function() {
-
- chart.plotLeft = plotLeft = mathRound(plotLeft);
- chart.plotTop = plotTop = mathRound(plotTop);
- chart.plotWidth = plotWidth = mathRound(chartWidth - plotLeft - marginRight);
- chart.plotHeight = plotHeight = mathRound(chartHeight - plotTop - marginBottom);
-
- chart.plotSizeX = inverted ? plotHeight : plotWidth;
- chart.plotSizeY = inverted ? plotWidth : plotHeight;
-
- spacingBox = {
- x: spacingLeft,
- y: spacingTop,
- width: chartWidth - spacingLeft - spacingRight,
- height: chartHeight - spacingTop - spacingBottom
- };
- };
-
-
- resetMargins = function() {
- plotTop = pick(optionsMarginTop, spacingTop);
- marginRight = pick(optionsMarginRight, spacingRight);
- marginBottom = pick(optionsMarginBottom, spacingBottom);
- plotLeft = pick(optionsMarginLeft, spacingLeft);
- axisOffset = [0, 0, 0, 0];
- };
-
-
- drawChartBox = function() {
- var chartBorderWidth = optionsChart.borderWidth || 0,
- chartBackgroundColor = optionsChart.backgroundColor,
- plotBackgroundColor = optionsChart.plotBackgroundColor,
- plotBackgroundImage = optionsChart.plotBackgroundImage,
- mgn,
- plotSize = {
- x: plotLeft,
- y: plotTop,
- width: plotWidth,
- height: plotHeight
- };
-
- mgn = 2 * chartBorderWidth + (optionsChart.shadow ? 8 : 0);
-
- if (chartBorderWidth || chartBackgroundColor) {
- if (!chartBackground) {
- chartBackground = renderer.rect(mgn / 2, mgn / 2, chartWidth - mgn, chartHeight - mgn,
- optionsChart.borderRadius, chartBorderWidth)
- .attr({
- stroke: optionsChart.borderColor,
- 'stroke-width': chartBorderWidth,
- fill: chartBackgroundColor || NONE
- })
- .add()
- .shadow(optionsChart.shadow);
- } else {
- chartBackground.animate({
- width: chartWidth - mgn,
- height:chartHeight - mgn
- });
- }
- }
-
-
-
- if (plotBackgroundColor) {
- if (!plotBackground) {
- plotBackground = renderer.rect(plotLeft, plotTop, plotWidth, plotHeight, 0)
- .attr({
- fill: plotBackgroundColor
- })
- .add()
- .shadow(optionsChart.plotShadow);
- } else {
- plotBackground.animate(plotSize);
- }
- }
- if (plotBackgroundImage) {
- if (!plotBGImage) {
- plotBGImage = renderer.image(plotBackgroundImage, plotLeft, plotTop, plotWidth, plotHeight)
- .add();
- } else {
- plotBGImage.animate(plotSize);
- }
- }
-
-
- if (optionsChart.plotBorderWidth) {
- if (!plotBorder) {
- plotBorder = renderer.rect(plotLeft, plotTop, plotWidth, plotHeight, 0, optionsChart.plotBorderWidth)
- .attr({
- stroke: optionsChart.plotBorderColor,
- 'stroke-width': optionsChart.plotBorderWidth,
- zIndex: 4
- })
- .add();
- } else {
- plotBorder.animate(plotSize);
- }
- }
-
-
- chart.isDirtyBox = false;
- };
-
-
- function render () {
- var labels = options.labels,
- credits = options.credits,
- creditsHref;
-
-
- setTitle();
-
-
-
- legend = chart.legend = new Legend(chart);
-
-
- getMargins();
- each(axes, function(axis) {
- axis.setTickPositions(true);
- });
- adjustTickAmounts();
- getMargins();
-
-
-
- drawChartBox();
-
-
- if (hasCartesianSeries) {
- each(axes, function(axis) {
- axis.render();
- });
- }
-
-
-
- if (!chart.seriesGroup) {
- chart.seriesGroup = renderer.g('series-group')
- .attr({ zIndex: 3 })
- .add();
- }
- each(series, function(serie) {
- serie.translate();
- serie.setTooltipPoints();
- serie.render();
- });
-
-
-
- if (labels.items) {
- each(labels.items, function() {
- var style = extend(labels.style, this.style),
- x = pInt(style.left) + plotLeft,
- y = pInt(style.top) + plotTop + 12;
-
-
- delete style.left;
- delete style.top;
-
- renderer.text(
- this.html,
- x,
- y
- )
- .attr({ zIndex: 2 })
- .css(style)
- .add();
-
- });
- }
-
-
- if (!chart.toolbar) {
- chart.toolbar = Toolbar(chart);
- }
-
-
- if (credits.enabled && !chart.credits) {
- creditsHref = credits.href;
- renderer.text(
- credits.text,
- 0,
- 0
- )
- .on('click', function() {
- if (creditsHref) {
- location.href = creditsHref;
- }
- })
- .attr({
- align: credits.position.align,
- zIndex: 8
- })
- .css(credits.style)
- .add()
- .align(credits.position);
- }
-
- placeTrackerGroup();
-
- chart.hasRendered = true;
-
-
- if (renderToClone) {
- renderTo.appendChild(container);
- discardElement(renderToClone);
-
- }
- }
-
-
- function destroy() {
- var i = series.length,
- parentNode = container.parentNode;
-
-
- fireEvent(chart, 'destroy');
-
- removeEvent(win, 'unload', destroy);
- removeEvent(chart);
-
- each(axes, function(axis) {
- removeEvent(axis);
- });
-
- while (i--) {
- series[i].destroy();
- }
-
-
- container.innerHTML = '';
- removeEvent(container);
- if (parentNode) {
- parentNode.removeChild(container);
- }
-
-
- container = null;
-
- renderer.alignedObjects = null;
-
-
- clearInterval(tooltipInterval);
-
-
- for (i in chart) {
- delete chart[i];
- }
-
- }
-
- function firstRender() {
-
-
- var onreadystatechange = 'onreadystatechange';
- if (!hasSVG && !useCanVG && doc.readyState != 'complete') {
- doc.attachEvent(onreadystatechange, function() {
- doc.detachEvent(onreadystatechange, firstRender);
- firstRender();
- });
- return;
- }
-
-
- getContainer();
-
- resetMargins();
- setChartSize();
-
-
- each(options.series || [], function(serieOptions) {
- initSeries(serieOptions);
- });
-
-
- chart.inverted = inverted = pick(inverted, options.chart.inverted);
-
-
- getAxes();
-
-
- chart.render = render;
-
-
- chart.tracker = tracker = new MouseTracker(chart, options.tooltip);
-
-
- render();
-
-
-
- renderer.draw();
-
- fireEvent(chart, 'load');
-
-
-
-
- if (callback) {
- callback.apply(chart, [chart]);
- }
- each(chart.callbacks, function(fn) {
- fn.apply(chart, [chart]);
- });
- }
-
-
-
-
-
-
- colorCounter = 0;
- symbolCounter = 0;
-
-
- addEvent(win, 'unload', destroy);
-
-
- if (optionsChart.reflow !== false) {
- addEvent(chart, 'load', initReflow);
- }
-
-
- if (chartEvents) {
- for (eventType in chartEvents) {
- addEvent(chart, eventType, chartEvents[eventType]);
- }
- }
-
-
- chart.options = options;
- chart.series = series;
-
-
-
-
-
-
- chart.addSeries = addSeries;
- chart.animation = useCanVG ? false : pick(optionsChart.animation, true);
- chart.destroy = destroy;
- chart.get = get;
- chart.getSelectedPoints = getSelectedPoints;
- chart.getSelectedSeries = getSelectedSeries;
- chart.hideLoading = hideLoading;
- chart.isInsidePlot = isInsidePlot;
- chart.redraw = redraw;
- chart.setSize = resize;
- chart.setTitle = setTitle;
- chart.showLoading = showLoading;
- chart.pointCount = 0;
-
-
-
-
-
- firstRender();
-
-
- }
- Chart.prototype.callbacks = [];
- var Point = function() {};
- Point.prototype = {
-
- init: function(series, options) {
- var point = this,
- defaultColors;
- point.series = series;
- point.applyOptions(options);
- point.pointAttr = {};
-
- if (series.options.colorByPoint) {
- defaultColors = series.chart.options.colors;
- if (!point.options) {
- point.options = {};
- }
- point.color = point.options.color = point.color || defaultColors[colorCounter++];
-
-
- if (colorCounter >= defaultColors.length) {
- colorCounter = 0;
- }
- }
-
- series.chart.pointCount++;
- return point;
- },
-
- applyOptions: function(options) {
- var point = this,
- series = point.series;
-
- point.config = options;
-
-
- if (isNumber(options) || options === null) {
- point.y = options;
- }
-
-
- else if (isObject(options) && !isNumber(options.length)) {
-
-
- extend(point, options);
- point.options = options;
- }
-
-
- else if (isString(options[0])) {
- point.name = options[0];
- point.y = options[1];
- }
-
-
- else if (isNumber(options[0])) {
- point.x = options[0];
- point.y = options[1];
- }
-
-
- if (point.x === UNDEFINED) {
- point.x = series.autoIncrement();
- }
-
- },
-
-
- destroy: function() {
- var point = this,
- series = point.series,
- prop;
-
- series.chart.pointCount--;
-
- if (point == series.chart.hoverPoint) {
- point.onMouseOut();
- }
- series.chart.hoverPoints = null;
-
-
- removeEvent(point);
-
- each(['graphic', 'tracker', 'group', 'dataLabel', 'connector'], function(prop) {
- if (point[prop]) {
- point[prop].destroy();
- }
- });
-
- if (point.legendItem) {
- point.series.chart.legend.destroyItem(point);
- }
-
- for (prop in point) {
- point[prop] = null;
- }
-
-
- },
-
-
- select: function(selected, accumulate) {
- var point = this,
- series = point.series,
- chart = series.chart;
-
- point.selected = selected = pick(selected, !point.selected);
-
-
- point.firePointEvent(selected ? 'select' : 'unselect');
- point.setState(selected && SELECT_STATE);
-
-
- if (!accumulate) {
- each(chart.getSelectedPoints(), function (loopPoint) {
- if (loopPoint.selected && loopPoint != point) {
- loopPoint.selected = false;
- loopPoint.setState(NORMAL_STATE);
- loopPoint.firePointEvent('unselect');
- }
- });
- }
-
- },
-
- onMouseOver: function() {
- var point = this,
- chart = point.series.chart,
- tooltip = chart.tooltip,
- hoverPoint = chart.hoverPoint;
-
-
- if (hoverPoint && hoverPoint != point) {
- hoverPoint.onMouseOut();
- }
-
-
- point.firePointEvent('mouseOver');
-
-
- if (tooltip && !tooltip.shared) {
- tooltip.refresh(point);
- }
-
-
- point.setState(HOVER_STATE);
- chart.hoverPoint = point;
- },
-
- onMouseOut: function() {
- var point = this;
- point.firePointEvent('mouseOut');
-
- point.setState();
- point.series.chart.hoverPoint = null;
- },
-
-
- update: function(options, redraw, animation) {
- var point = this,
- series = point.series,
- chart = series.chart;
-
- setAnimation(animation, chart);
- redraw = pick(redraw, true);
-
-
- point.firePointEvent('update', { options: options }, function() {
- point.applyOptions(options);
-
-
- series.isDirty = true;
- if (redraw) {
- chart.redraw();
- }
- });
- },
-
-
- remove: function(redraw, animation) {
- var point = this,
- series = point.series,
- chart = series.chart,
- data = series.data;
-
- setAnimation(animation, chart);
- redraw = pick(redraw, true);
-
-
- point.firePointEvent('remove', null, function() {
- erase(data, point);
-
- point.destroy();
-
-
-
- series.isDirty = true;
- if (redraw) {
- chart.redraw();
- }
- });
-
-
- },
-
-
- firePointEvent: function(eventType, eventArgs, defaultFunction) {
- var point = this,
- series = this.series,
- seriesOptions = series.options;
-
-
- if (seriesOptions.point.events[eventType] || (
- point.options && point.options.events && point.options.events[eventType])) {
- this.importEvents();
- }
-
-
- if (eventType == 'click' && seriesOptions.allowPointSelect) {
- defaultFunction = function (event) {
-
- point.select(null, event.ctrlKey || event.metaKey || event.shiftKey);
- };
- }
-
- fireEvent(this, eventType, eventArgs, defaultFunction);
- },
-
- importEvents: function() {
- if (!this.hasImportedEvents) {
- var point = this,
- options = merge(point.series.options.point, point.options),
- events = options.events,
- eventType;
-
- point.events = events;
-
- for (eventType in events) {
- addEvent(point, eventType, events[eventType]);
- }
- this.hasImportedEvents = true;
-
- }
- },
-
-
- setState: function(state) {
- var point = this,
- series = point.series,
- stateOptions = series.options.states,
- markerOptions = defaultPlotOptions[series.type].marker && series.options.marker,
- normalDisabled = markerOptions && !markerOptions.enabled,
- markerStateOptions = markerOptions && markerOptions.states[state],
- stateDisabled = markerStateOptions && markerStateOptions.enabled === false,
- stateMarkerGraphic = series.stateMarkerGraphic,
- chart = series.chart,
- pointAttr = point.pointAttr;
-
- if (!state) {
- state = NORMAL_STATE;
- }
-
- if (
-
- state == point.state ||
-
- (point.selected && state != SELECT_STATE) ||
-
- (stateOptions[state] && stateOptions[state].enabled === false) ||
-
- (state && (stateDisabled || normalDisabled && !markerStateOptions.enabled))
- ) {
- return;
- }
-
-
- if (point.graphic) {
- point.graphic.attr(pointAttr[state]);
- }
-
-
- else {
- if (state) {
- if (!stateMarkerGraphic) {
- series.stateMarkerGraphic = stateMarkerGraphic = chart.renderer.circle(
- 0, 0, pointAttr[state].r
- )
- .attr(pointAttr[state])
- .add(series.group);
- }
-
- stateMarkerGraphic.translate(
- point.plotX,
- point.plotY
- );
- }
-
- if (stateMarkerGraphic) {
- stateMarkerGraphic[state ? 'show' : 'hide']();
- }
- }
-
- point.state = state;
- }
- };
- var Series = function() {};
- Series.prototype = {
-
- isCartesian: true,
- type: 'line',
- pointClass: Point,
- pointAttrToOptions: {
- stroke: 'lineColor',
- 'stroke-width': 'lineWidth',
- fill: 'fillColor',
- r: 'radius'
- },
- init: function(chart, options) {
- var series = this,
- eventType,
- events,
-
- index = chart.series.length;
-
- series.chart = chart;
- options = series.setOptions(options);
-
-
- extend(series, {
- index: index,
- options: options,
- name: options.name || 'Series '+ (index + 1),
- state: NORMAL_STATE,
- pointAttr: {},
- visible: options.visible !== false,
- selected: options.selected === true
- });
-
-
- if (useCanVG) {
- options.animation = false;
- }
-
-
- events = options.events;
- for (eventType in events) {
- addEvent(series, eventType, events[eventType]);
- }
- if (
- (events && events.click) ||
- (options.point && options.point.events && options.point.events.click) ||
- options.allowPointSelect
- ) {
- chart.runTrackerClick = true;
- }
-
- series.getColor();
- series.getSymbol();
-
-
- series.setData(options.data, false);
-
- },
-
-
-
- autoIncrement: function() {
- var series = this,
- options = series.options,
- xIncrement = series.xIncrement;
-
- xIncrement = pick(xIncrement, options.pointStart, 0);
-
- series.pointInterval = pick(series.pointInterval, options.pointInterval, 1);
-
- series.xIncrement = xIncrement + series.pointInterval;
- return xIncrement;
- },
-
-
- cleanData: function() {
- var series = this,
- chart = series.chart,
- data = series.data,
- closestPoints,
- smallestInterval,
- chartSmallestInterval = chart.smallestInterval,
- interval,
- i;
-
-
- data.sort(function(a, b){
- return (a.x - b.x);
- });
-
-
-
- for (i = data.length - 1; i >= 0; i--) {
- if (data[i - 1]) {
- if (data[i - 1].x == data[i].x) {
- data.splice(i - 1, 1);
- }
-
- }
- }
-
-
-
- for (i = data.length - 1; i >= 0; i--) {
- if (data[i - 1]) {
- interval = data[i].x - data[i - 1].x;
- if (smallestInterval === UNDEFINED || interval < smallestInterval) {
- smallestInterval = interval;
- closestPoints = i;
- }
- }
- }
-
- if (chartSmallestInterval === UNDEFINED || smallestInterval < chartSmallestInterval) {
- chart.smallestInterval = smallestInterval;
- }
- series.closestPoints = closestPoints;
- },
-
-
- getSegments: function() {
- var lastNull = -1,
- segments = [],
- data = this.data;
-
-
- each(data, function(point, i) {
- if (point.y === null) {
- if (i > lastNull + 1) {
- segments.push(data.slice(lastNull + 1, i));
- }
- lastNull = i;
- } else if (i == data.length - 1) {
- segments.push(data.slice(lastNull + 1, i + 1));
- }
- });
- this.segments = segments;
-
-
- },
-
- setOptions: function(itemOptions) {
- var plotOptions = this.chart.options.plotOptions,
- options = merge(
- plotOptions[this.type],
- plotOptions.series,
- itemOptions
- );
-
- return options;
-
- },
-
- getColor: function(){
- var defaultColors = this.chart.options.colors;
- this.color = this.options.color || defaultColors[colorCounter++] || '#0000ff';
- if (colorCounter >= defaultColors.length) {
- colorCounter = 0;
- }
- },
-
- getSymbol: function(){
- var defaultSymbols = this.chart.options.symbols,
- symbol = this.options.marker.symbol || defaultSymbols[symbolCounter++];
- this.symbol = symbol;
- if (symbolCounter >= defaultSymbols.length) {
- symbolCounter = 0;
- }
- },
-
-
- addPoint: function(options, redraw, shift, animation) {
- var series = this,
- data = series.data,
- graph = series.graph,
- area = series.area,
- chart = series.chart,
- point = (new series.pointClass()).init(series, options);
-
- setAnimation(animation, chart);
-
- if (graph && shift) {
- graph.shift = shift;
- }
- if (area) {
- area.shift = shift;
- area.isArea = true;
- }
-
- redraw = pick(redraw, true);
-
- data.push(point);
- if (shift) {
- data[0].remove(false);
- }
-
-
-
- series.isDirty = true;
- if (redraw) {
- chart.redraw();
- }
- },
-
-
- setData: function(data, redraw) {
- var series = this,
- oldData = series.data,
- initialColor = series.initialColor,
- chart = series.chart,
- i = oldData && oldData.length || 0;
-
- series.xIncrement = null;
- if (defined(initialColor)) {
- colorCounter = initialColor;
- }
-
- data = map(splat(data || []), function(pointOptions) {
- return (new series.pointClass()).init(series, pointOptions);
- });
-
-
- while (i--) {
- oldData[i].destroy();
- }
-
-
- series.data = data;
-
- series.cleanData();
- series.getSegments();
-
-
- series.isDirty = true;
- chart.isDirtyBox = true;
- if (pick(redraw, true)) {
- chart.redraw(false);
- }
- },
-
-
-
- remove: function(redraw, animation) {
- var series = this,
- chart = series.chart;
- redraw = pick(redraw, true);
-
- if (!series.isRemoving) {
- series.isRemoving = true;
-
- fireEvent(series, 'remove', null, function() {
-
-
-
- series.destroy();
-
-
-
- chart.isDirtyLegend = chart.isDirtyBox = true;
- if (redraw) {
- chart.redraw(animation);
- }
- });
-
- }
- series.isRemoving = false;
- },
-
-
- translate: function() {
- var series = this,
- chart = series.chart,
- stacking = series.options.stacking,
- categories = series.xAxis.categories,
- yAxis = series.yAxis,
- data = series.data,
- i = data.length;
-
-
- while (i--) {
- var point = data[i],
- xValue = point.x,
- yValue = point.y,
- yBottom,
- stack = yAxis.stacks[(yValue < 0 ? '-' : '') + series.stackKey],
- pointStack,
- pointStackTotal;
- point.plotX = series.xAxis.translate(xValue);
-
-
- if (stacking && series.visible && stack[xValue]) {
- pointStack = stack[xValue];
- pointStackTotal = pointStack.total;
- pointStack.cum = yBottom = pointStack.cum - yValue;
- yValue = yBottom + yValue;
-
- if (stacking == 'percent') {
- yBottom = pointStackTotal ? yBottom * 100 / pointStackTotal : 0;
- yValue = pointStackTotal ? yValue * 100 / pointStackTotal : 0;
- }
- point.percentage = pointStackTotal ? point.y * 100 / pointStackTotal : 0;
- point.stackTotal = pointStackTotal;
- point.yBottom = yAxis.translate(yBottom, 0, 1);
- }
-
-
- if (yValue !== null) {
- point.plotY = yAxis.translate(yValue, 0, 1);
- }
-
-
- point.clientX = chart.inverted ?
- chart.plotHeight - point.plotX :
- point.plotX;
-
-
- point.category = categories && categories[point.x] !== UNDEFINED ?
- categories[point.x] : point.x;
-
- }
- },
-
- setTooltipPoints: function (renew) {
- var series = this,
- chart = series.chart,
- inverted = chart.inverted,
- data = [],
- plotSize = mathRound((inverted ? chart.plotTop : chart.plotLeft) + chart.plotSizeX),
- low,
- high,
- tooltipPoints = [];
-
-
- if (renew) {
- series.tooltipPoints = null;
- }
-
-
- each(series.segments, function(segment){
- data = data.concat(segment);
- });
-
-
-
- if (series.xAxis && series.xAxis.reversed) {
- data = data.reverse();
- }
-
- each(data, function(point, i) {
-
- low = data[i - 1] ? data[i - 1].high + 1 : 0;
- high = point.high = data[i + 1] ? (
- mathFloor((point.plotX + (data[i + 1] ?
- data[i + 1].plotX : plotSize)) / 2)) :
- plotSize;
-
- while (low <= high) {
- tooltipPoints[inverted ? plotSize - low++ : low++] = point;
- }
- });
- series.tooltipPoints = tooltipPoints;
- },
-
-
-
-
- onMouseOver: function() {
- var series = this,
- chart = series.chart,
- hoverSeries = chart.hoverSeries;
-
- if (!hasTouch && chart.mouseIsDown) {
- return;
- }
-
-
- if (hoverSeries && hoverSeries != series) {
- hoverSeries.onMouseOut();
- }
-
-
-
- if (series.options.events.mouseOver) {
- fireEvent(series, 'mouseOver');
- }
-
-
-
-
-
- if (series.tracker) {
- series.tracker.toFront();
- }
-
-
- series.setState(HOVER_STATE);
- chart.hoverSeries = series;
- },
-
-
- onMouseOut: function() {
-
- var series = this,
- options = series.options,
- chart = series.chart,
- tooltip = chart.tooltip,
- hoverPoint = chart.hoverPoint;
-
-
- if (hoverPoint) {
- hoverPoint.onMouseOut();
- }
-
-
- if (series && options.events.mouseOut) {
- fireEvent(series, 'mouseOut');
- }
-
-
-
- if (tooltip && !options.stickyTracking) {
- tooltip.hide();
- }
-
-
- series.setState();
- chart.hoverSeries = null;
- },
-
-
- animate: function(init) {
- var series = this,
- chart = series.chart,
- clipRect = series.clipRect,
- animation = series.options.animation;
-
- if (animation && !isObject(animation)) {
- animation = {};
- }
-
- if (init) {
- if (!clipRect.isAnimating) {
- clipRect.attr( 'width', 0 );
- clipRect.isAnimating = true;
- }
-
- } else {
- clipRect.animate({
- width: chart.plotSizeX
- }, animation && extend(animation, {
- complete: function() {
- clipRect.isAnimating = false;
- if (clipRect != chart.clipRect) {
- series.group.clip((series.clipRect = chart.clipRect));
- clipRect.destroy();
- }
- }
- }));
-
-
- this.animate = null;
- }
- },
-
-
- drawPoints: function(){
- var series = this,
- pointAttr,
- data = series.data,
- chart = series.chart,
- plotX,
- plotY,
- i,
- point,
- radius,
- graphic;
-
- if (series.options.marker.enabled) {
- i = data.length;
- while (i--) {
- point = data[i];
- plotX = point.plotX;
- plotY = point.plotY;
- graphic = point.graphic;
-
-
- if (plotY !== UNDEFINED && !isNaN(plotY)) {
-
-
-
-
- pointAttr = point.pointAttr[point.selected ? SELECT_STATE : NORMAL_STATE];
- radius = pointAttr.r;
-
- if (graphic) {
- graphic.animate({
- x: plotX,
- y: plotY,
- r: radius
- });
- } else {
- point.graphic = chart.renderer.symbol(
- pick(point.marker && point.marker.symbol, series.symbol),
- plotX,
- plotY,
- radius
- )
- .attr(pointAttr)
- .add(series.group);
- }
- }
- }
- }
-
- },
-
-
- convertAttribs: function(options, base1, base2, base3) {
- var conversion = this.pointAttrToOptions,
- attr,
- option,
- obj = {};
-
- options = options || {};
- base1 = base1 || {};
- base2 = base2 || {};
- base3 = base3 || {};
-
- for (attr in conversion) {
- option = conversion[attr];
- obj[attr] = pick(options[option], base1[attr], base2[attr], base3[attr]);
- }
- return obj;
- },
-
-
- getAttribs: function() {
- var series = this,
- normalOptions = defaultPlotOptions[series.type].marker ? series.options.marker : series.options,
- stateOptions = normalOptions.states,
- stateOptionsHover = stateOptions[HOVER_STATE],
- pointStateOptionsHover,
- normalDefaults = {},
- seriesColor = series.color,
- data = series.data,
- i,
- point,
- seriesPointAttr = [],
- pointAttr,
- pointAttrToOptions = series.pointAttrToOptions,
- hasPointSpecificOptions;
-
-
- if (series.options.marker) {
-
-
- normalDefaults = {
- stroke: seriesColor,
- fill: seriesColor
- };
-
-
- stateOptionsHover.radius = stateOptionsHover.radius || normalOptions.radius + 2;
- stateOptionsHover.lineWidth = stateOptionsHover.lineWidth || normalOptions.lineWidth + 1;
-
- } else {
-
-
- normalDefaults = {
- fill: seriesColor
- };
-
-
- stateOptionsHover.color = stateOptionsHover.color ||
- Color(stateOptionsHover.color || seriesColor)
- .brighten(stateOptionsHover.brightness).get();
- }
-
-
- seriesPointAttr[NORMAL_STATE] = series.convertAttribs(normalOptions, normalDefaults);
-
-
- each([HOVER_STATE, SELECT_STATE], function(state) {
- seriesPointAttr[state] =
- series.convertAttribs(stateOptions[state], seriesPointAttr[NORMAL_STATE]);
- });
-
-
- series.pointAttr = seriesPointAttr;
-
-
-
-
-
- i = data.length;
- while (i--) {
- point = data[i];
- normalOptions = (point.options && point.options.marker) || point.options;
- if (normalOptions && normalOptions.enabled === false) {
- normalOptions.radius = 0;
- }
- hasPointSpecificOptions = false;
-
-
- if (point.options) {
- for (var key in pointAttrToOptions) {
- if (defined(normalOptions[pointAttrToOptions[key]])) {
- hasPointSpecificOptions = true;
- }
- }
- }
-
-
-
-
-
- if (hasPointSpecificOptions) {
- pointAttr = [];
- stateOptions = normalOptions.states || {};
- pointStateOptionsHover = stateOptions[HOVER_STATE] = stateOptions[HOVER_STATE] || {};
-
-
- if (!series.options.marker) {
- pointStateOptionsHover.color =
- Color(pointStateOptionsHover.color || point.options.color)
- .brighten(pointStateOptionsHover.brightness ||
- stateOptionsHover.brightness).get();
-
- }
-
-
- pointAttr[NORMAL_STATE] = series.convertAttribs(normalOptions, seriesPointAttr[NORMAL_STATE]);
-
-
- pointAttr[HOVER_STATE] = series.convertAttribs(
- stateOptions[HOVER_STATE],
- seriesPointAttr[HOVER_STATE],
- pointAttr[NORMAL_STATE]
- );
-
- pointAttr[SELECT_STATE] = series.convertAttribs(
- stateOptions[SELECT_STATE],
- seriesPointAttr[SELECT_STATE],
- pointAttr[NORMAL_STATE]
- );
-
-
-
-
-
- } else {
- pointAttr = seriesPointAttr;
- }
-
- point.pointAttr = pointAttr;
- }
- },
-
-
- destroy: function() {
- var series = this,
- chart = series.chart,
-
- clipRect = series.clipRect,
- issue134 = /\/5[0-9\.]+ Safari\
- destroy,
- prop;
-
-
- removeEvent(series);
-
-
- if (series.legendItem) {
- series.chart.legend.destroyItem(series);
- }
-
-
- each(series.data, function(point) {
- point.destroy();
- });
-
- each(['area', 'graph', 'dataLabelsGroup', 'group', 'tracker'], function(prop) {
- if (series[prop]) {
-
-
- destroy = issue134 && prop == 'group' ?
- 'hide' :
- 'destroy';
-
- series[prop][destroy]();
- }
- });
-
-
- if (chart.hoverSeries == series) {
- chart.hoverSeries = null;
- }
- erase(chart.series, series);
-
-
- for (prop in series) {
- delete series[prop];
- }
- },
-
-
- drawDataLabels: function() {
- if (this.options.dataLabels.enabled) {
- var series = this,
- x,
- y,
- data = series.data,
- options = series.options.dataLabels,
- str,
- dataLabelsGroup = series.dataLabelsGroup,
- chart = series.chart,
- inverted = chart.inverted,
- seriesType = series.type,
- color;
-
-
- if (!dataLabelsGroup) {
- dataLabelsGroup = series.dataLabelsGroup =
- chart.renderer.g(PREFIX +'data-labels')
- .attr({
- visibility: series.visible ? VISIBLE : HIDDEN,
- zIndex: 5
- })
- .translate(chart.plotLeft, chart.plotTop)
- .add();
- }
-
-
- color = options.color;
- if (color == 'auto') {
- color = null;
- }
- options.style.color = pick(color, series.color);
-
-
- each(data, function(point, i){
- var plotX = pick(point.barX, point.plotX, -999),
- plotY = pick(point.plotY, -999),
- dataLabel = point.dataLabel,
- align = options.align;
-
-
- str = options.formatter.call({
- x: point.x,
- y: point.y,
- series: series,
- point: point,
- percentage: point.percentage,
- total: point.total || point.stackTotal
- });
- x = (inverted ? chart.plotWidth - plotY : plotX) + options.x;
- y = (inverted ? chart.plotHeight - plotX : plotY) + options.y;
-
-
-
- if (seriesType == 'column') {
- x += {
- center: point.barW / 2,
- right: point.barW
- }[align] || 0;
- }
-
- if (dataLabel) {
- dataLabel.animate({
- x: x,
- y: y
- });
- } else if (str) {
- point.dataLabel = chart.renderer.text(
- str,
- x,
- y
- )
- .attr({
- align: align,
- rotation: options.rotation,
- zIndex: 1
- })
- .css(options.style)
- .add(dataLabelsGroup);
- }
-
-
- });
- }
- },
-
-
- drawGraph: function(state) {
- var series = this,
- options = series.options,
- chart = series.chart,
- graph = series.graph,
- graphPath = [],
- fillColor,
- area = series.area,
- group = series.group,
- color = options.lineColor || series.color,
- lineWidth = options.lineWidth,
- dashStyle = options.dashStyle,
- segmentPath,
- renderer = chart.renderer,
- translatedThreshold = series.yAxis.getThreshold(options.threshold || 0),
- useArea = /^area/.test(series.type),
- singlePoints = [],
- areaPath = [],
- attribs;
-
-
-
- each(series.segments, function(segment) {
- segmentPath = [];
-
-
- each(segment, function(point, i) {
- if (series.getPointSpline) {
- segmentPath.push.apply(segmentPath, series.getPointSpline(segment, point, i));
-
- } else {
-
-
- segmentPath.push(i ? L : M);
-
-
- if (i && options.step) {
- var lastPoint = segment[i - 1];
- segmentPath.push(
- point.plotX,
- lastPoint.plotY
- );
- }
-
-
- segmentPath.push(
- point.plotX,
- point.plotY
- );
- }
- });
-
-
- if (segment.length > 1) {
- graphPath = graphPath.concat(segmentPath);
- } else {
- singlePoints.push(segment[0]);
- }
-
-
- if (useArea) {
- var areaSegmentPath = [],
- i,
- segLength = segmentPath.length;
- for (i = 0; i < segLength; i++) {
- areaSegmentPath.push(segmentPath[i]);
- }
- if (segLength == 3) {
- areaSegmentPath.push(L, segmentPath[1], segmentPath[2]);
- }
- if (options.stacking && series.type != 'areaspline') {
-
- for (i = segment.length - 1; i >= 0; i--) {
- areaSegmentPath.push(segment[i].plotX, segment[i].yBottom);
- }
-
- } else {
- areaSegmentPath.push(
- L,
- segment[segment.length - 1].plotX,
- translatedThreshold,
- L,
- segment[0].plotX,
- translatedThreshold
- );
- }
- areaPath = areaPath.concat(areaSegmentPath);
- }
- });
-
- series.graphPath = graphPath;
- series.singlePoints = singlePoints;
-
- if (useArea) {
- fillColor = pick(
- options.fillColor,
- Color(series.color).setOpacity(options.fillOpacity || 0.75).get()
- );
- if (area) {
- area.animate({ d: areaPath });
-
- } else {
-
- series.area = series.chart.renderer.path(areaPath)
- .attr({
- fill: fillColor
- }).add(group);
- }
- }
-
-
- if (graph) {
-
- graph.animate({ d: graphPath });
-
- } else {
- if (lineWidth) {
- attribs = {
- 'stroke': color,
- 'stroke-width': lineWidth
- };
- if (dashStyle) {
- attribs.dashstyle = dashStyle;
- }
-
- series.graph = renderer.path(graphPath)
- .attr(attribs).add(group).shadow(options.shadow);
- }
- }
- },
-
-
-
- render: function() {
- var series = this,
- chart = series.chart,
- group,
- setInvert,
- options = series.options,
- doAnimation = options.animation && series.animate,
- renderer = chart.renderer;
-
-
-
-
- if (!series.clipRect) {
- series.clipRect = !chart.hasRendered && chart.clipRect ?
- chart.clipRect :
- renderer.clipRect(0, 0, chart.plotSizeX, chart.plotSizeY);
- if (!chart.clipRect) {
- chart.clipRect = series.clipRect;
- }
- }
-
-
-
- if (!series.group) {
- group = series.group = renderer.g('series');
-
- if (chart.inverted) {
- setInvert = function() {
- group.attr({
- width: chart.plotWidth,
- height: chart.plotHeight
- }).invert();
- };
-
- setInvert();
- addEvent(chart, 'resize', setInvert);
- }
- group.clip(series.clipRect)
- .attr({
- visibility: series.visible ? VISIBLE : HIDDEN,
- zIndex: options.zIndex
- })
- .translate(chart.plotLeft, chart.plotTop)
- .add(chart.seriesGroup);
- }
-
- series.drawDataLabels();
-
- if (doAnimation) {
- series.animate(true);
- }
-
-
- series.getAttribs();
-
-
- if (series.drawGraph) {
- series.drawGraph();
- }
-
-
- series.drawPoints();
-
-
- if (series.options.enableMouseTracking !== false) {
- series.drawTracker();
- }
-
-
- if (doAnimation) {
- series.animate();
- }
-
-
- series.isDirty = false;
-
- },
-
-
- redraw: function() {
- var series = this,
- chart = series.chart,
- clipRect = series.clipRect,
- group = series.group;
-
-
-
-
- if (group) {
- if (chart.inverted) {
- group.attr({
- width: chart.plotWidth,
- height: chart.plotHeight
- });
- }
-
- group.animate({
- translateX: chart.plotLeft,
- translateY: chart.plotTop
- });
- }
-
- series.translate();
- series.setTooltipPoints(true);
- series.render();
- },
-
-
- setState: function(state) {
- var series = this,
- options = series.options,
- graph = series.graph,
- stateOptions = options.states,
- lineWidth = options.lineWidth;
- state = state || NORMAL_STATE;
-
- if (series.state != state) {
- series.state = state;
-
- if (stateOptions[state] && stateOptions[state].enabled === false) {
- return;
- }
-
- if (state) {
- lineWidth = stateOptions[state].lineWidth || lineWidth + 1;
- }
-
- if (graph && !graph.dashstyle) {
- graph.attr({
- 'stroke-width': lineWidth
- }, state ? 0 : 500);
- }
- }
- },
-
-
- setVisible: function(vis, redraw) {
- var series = this,
- chart = series.chart,
- legendItem = series.legendItem,
- seriesGroup = series.group,
- seriesTracker = series.tracker,
- dataLabelsGroup = series.dataLabelsGroup,
- showOrHide,
- i,
- data = series.data,
- point,
- ignoreHiddenSeries = chart.options.chart.ignoreHiddenSeries,
- oldVisibility = series.visible;
-
-
- series.visible = vis = vis === UNDEFINED ? !oldVisibility : vis;
- showOrHide = vis ? 'show' : 'hide';
-
-
- if (seriesGroup) {
- seriesGroup[showOrHide]();
- }
-
-
- if (seriesTracker) {
- seriesTracker[showOrHide]();
- } else {
- i = data.length;
- while (i--) {
- point = data[i];
- if (point.tracker) {
- point.tracker[showOrHide]();
- }
- }
- }
-
-
- if (dataLabelsGroup) {
- dataLabelsGroup[showOrHide]();
- }
-
- if (legendItem) {
- chart.legend.colorizeItem(series, vis);
- }
-
-
-
- series.isDirty = true;
-
- if (series.options.stacking) {
- each(chart.series, function(otherSeries) {
- if (otherSeries.options.stacking && otherSeries.visible) {
- otherSeries.isDirty = true;
- }
- });
- }
-
- if (ignoreHiddenSeries) {
- chart.isDirtyBox = true;
- }
- if (redraw !== false) {
- chart.redraw();
- }
-
- fireEvent(series, showOrHide);
- },
-
-
- show: function() {
- this.setVisible(true);
- },
-
-
- hide: function() {
- this.setVisible(false);
- },
-
-
-
- select: function(selected) {
- var series = this;
-
- series.selected = selected = (selected === UNDEFINED) ? !series.selected : selected;
- if (series.checkbox) {
- series.checkbox.checked = selected;
- }
-
- fireEvent(series, selected ? 'select' : 'unselect');
- },
-
-
-
- drawTracker: function() {
- var series = this,
- options = series.options,
- trackerPath = [].concat(series.graphPath),
- trackerPathLength = trackerPath.length,
- chart = series.chart,
- snap = chart.options.tooltip.snap,
- tracker = series.tracker,
- cursor = options.cursor,
- css = cursor && { cursor: cursor },
- singlePoints = series.singlePoints,
- singlePoint,
- i;
-
-
-
- if (trackerPathLength) {
- i = trackerPathLength + 1;
- while (i--) {
- if (trackerPath[i] == M) {
- trackerPath.splice(i + 1, 0, trackerPath[i + 1] - snap, trackerPath[i + 2], L);
- }
- if ((i && trackerPath[i] == M) || i == trackerPathLength) {
- trackerPath.splice(i, 0, L, trackerPath[i - 2] + snap, trackerPath[i - 1]);
- }
- }
- }
-
-
- for (i = 0; i < singlePoints.length; i++) {
- singlePoint = singlePoints[i];
- trackerPath.push(M, singlePoint.plotX - snap, singlePoint.plotY,
- L, singlePoint.plotX + snap, singlePoint.plotY);
- }
-
-
- if (tracker) {
- tracker.attr({ d: trackerPath });
-
- } else {
- series.tracker = chart.renderer.path(trackerPath)
- .attr({
- isTracker: true,
- stroke: TRACKER_FILL,
- fill: NONE,
- 'stroke-width' : options.lineWidth + 2 * snap,
- visibility: series.visible ? VISIBLE : HIDDEN,
- zIndex: 1
- })
- .on(hasTouch ? 'touchstart' : 'mouseover', function() {
- if (chart.hoverSeries != series) {
- series.onMouseOver();
- }
- })
- .on('mouseout', function() {
- if (!options.stickyTracking) {
- series.onMouseOut();
- }
- })
- .css(css)
- .add(chart.trackerGroup);
- }
-
- }
-
- };
- var LineSeries = extendClass(Series);
- seriesTypes.line = LineSeries;
- var AreaSeries = extendClass(Series, {
- type: 'area'
- });
- seriesTypes.area = AreaSeries;
- var SplineSeries = extendClass( Series, {
- type: 'spline',
-
-
- getPointSpline: function(segment, point, i) {
- var smoothing = 1.5,
- denom = smoothing + 1,
- plotX = point.plotX,
- plotY = point.plotY,
- lastPoint = segment[i - 1],
- nextPoint = segment[i + 1],
- leftContX,
- leftContY,
- rightContX,
- rightContY,
- ret;
-
-
- if (i && i < segment.length - 1) {
- var lastX = lastPoint.plotX,
- lastY = lastPoint.plotY,
- nextX = nextPoint.plotX,
- nextY = nextPoint.plotY,
- correction;
-
- leftContX = (smoothing * plotX + lastX) / denom;
- leftContY = (smoothing * plotY + lastY) / denom;
- rightContX = (smoothing * plotX + nextX) / denom;
- rightContY = (smoothing * plotY + nextY) / denom;
-
-
- correction = ((rightContY - leftContY) * (rightContX - plotX)) /
- (rightContX - leftContX) + plotY - rightContY;
-
- leftContY += correction;
- rightContY += correction;
-
-
-
- if (leftContY > lastY && leftContY > plotY) {
- leftContY = mathMax(lastY, plotY);
- rightContY = 2 * plotY - leftContY;
- } else if (leftContY < lastY && leftContY < plotY) {
- leftContY = mathMin(lastY, plotY);
- rightContY = 2 * plotY - leftContY;
- }
- if (rightContY > nextY && rightContY > plotY) {
- rightContY = mathMax(nextY, plotY);
- leftContY = 2 * plotY - rightContY;
- } else if (rightContY < nextY && rightContY < plotY) {
- rightContY = mathMin(nextY, plotY);
- leftContY = 2 * plotY - rightContY;
- }
-
-
- point.rightContX = rightContX;
- point.rightContY = rightContY;
-
- }
-
-
- if (!i) {
- ret = [M, plotX, plotY];
- }
-
-
- else {
- ret = [
- 'C',
- lastPoint.rightContX || lastPoint.plotX,
- lastPoint.rightContY || lastPoint.plotY,
- leftContX || plotX,
- leftContY || plotY,
- plotX,
- plotY
- ];
- lastPoint.rightContX = lastPoint.rightContY = null;
- }
- return ret;
- }
- });
- seriesTypes.spline = SplineSeries;
- var AreaSplineSeries = extendClass(SplineSeries, {
- type: 'areaspline'
- });
- seriesTypes.areaspline = AreaSplineSeries;
- var ColumnSeries = extendClass(Series, {
- type: 'column',
- pointAttrToOptions: {
- stroke: 'borderColor',
- 'stroke-width': 'borderWidth',
- fill: 'color',
- r: 'borderRadius'
- },
- init: function() {
- Series.prototype.init.apply(this, arguments);
-
- var series = this,
- chart = series.chart;
-
-
- chart.hasColumn = true;
-
-
-
- if (chart.hasRendered) {
- each(chart.series, function(otherSeries) {
- if (otherSeries.type == series.type) {
- otherSeries.isDirty = true;
- }
- });
- }
- },
-
-
- translate: function() {
- var series = this,
- chart = series.chart,
- columnCount = 0,
- reversedXAxis = series.xAxis.reversed,
- categories = series.xAxis.categories,
- stackGroups = {},
- stackKey,
- columnIndex;
-
- Series.prototype.translate.apply(series);
-
-
-
-
- each(chart.series, function(otherSeries) {
- if (otherSeries.type == series.type) {
- if (otherSeries.options.stacking) {
- stackKey = otherSeries.stackKey;
- if (stackGroups[stackKey] === UNDEFINED) {
- stackGroups[stackKey] = columnCount++;
- }
- columnIndex = stackGroups[stackKey];
- } else {
- columnIndex = columnCount++;
- }
- otherSeries.columnIndex = columnIndex;
- }
- });
-
-
-
-
- var options = series.options,
- data = series.data,
- closestPoints = series.closestPoints,
- categoryWidth = mathAbs(
- data[1] ? data[closestPoints].plotX - data[closestPoints - 1].plotX :
- chart.plotSizeX / (categories ? categories.length : 1)
- ),
- groupPadding = categoryWidth * options.groupPadding,
- groupWidth = categoryWidth - 2 * groupPadding,
- pointOffsetWidth = groupWidth / columnCount,
- optionPointWidth = options.pointWidth,
- pointPadding = defined(optionPointWidth) ? (pointOffsetWidth - optionPointWidth) / 2 :
- pointOffsetWidth * options.pointPadding,
- pointWidth = pick(optionPointWidth, pointOffsetWidth - 2 * pointPadding),
- colIndex = (reversedXAxis ? columnCount -
- series.columnIndex : series.columnIndex) || 0,
- pointXOffset = pointPadding + (groupPadding + colIndex *
- pointOffsetWidth -(categoryWidth / 2)) *
- (reversedXAxis ? -1 : 1),
- threshold = options.threshold || 0,
- translatedThreshold = series.yAxis.getThreshold(threshold),
- minPointLength = pick(options.minPointLength, 5);
-
-
- each(data, function(point) {
- var plotY = point.plotY,
- yBottom = point.yBottom || translatedThreshold,
- barX = point.plotX + pointXOffset,
- barY = mathCeil(mathMin(plotY, yBottom)),
- barW = pointWidth,
- barH = mathCeil(mathMax(plotY, yBottom) - barY),
- trackerY;
-
-
- if (mathAbs(barH) < minPointLength) {
- if (minPointLength) {
- barH = minPointLength;
- barY =
- mathAbs(barY - translatedThreshold) > minPointLength ?
- yBottom - minPointLength :
- translatedThreshold - (plotY <= translatedThreshold ? minPointLength : 0);
- }
- trackerY = barY - 3;
- }
-
- extend(point, {
- barX: barX,
- barY: barY,
- barW: barW,
- barH: barH
- });
- point.shapeType = 'rect';
- point.shapeArgs = {
- x: barX,
- y: barY,
- width: barW,
- height: barH,
- r: options.borderRadius
- };
-
-
- point.trackerArgs = defined(trackerY) && merge(point.shapeArgs, {
- height: mathMax(6, barH + 3),
- y: trackerY
- });
- });
-
- },
-
- getSymbol: function(){
- },
-
-
- drawGraph: function() {},
-
-
- drawPoints: function() {
- var series = this,
- options = series.options,
- renderer = series.chart.renderer,
- graphic,
- shapeArgs;
-
-
-
- each(series.data, function(point) {
- var plotY = point.plotY;
- if (plotY !== UNDEFINED && !isNaN(plotY)) {
- graphic = point.graphic;
- shapeArgs = point.shapeArgs;
- if (graphic) {
- stop(graphic);
- graphic.animate(shapeArgs);
-
- } else {
- point.graphic = renderer[point.shapeType](shapeArgs)
- .attr(point.pointAttr[point.selected ? SELECT_STATE : NORMAL_STATE])
- .add(series.group)
- .shadow(options.shadow);
- }
-
- }
- });
- },
-
- drawTracker: function() {
- var series = this,
- chart = series.chart,
- renderer = chart.renderer,
- shapeArgs,
- tracker,
- trackerLabel = +new Date(),
- cursor = series.options.cursor,
- css = cursor && { cursor: cursor },
- rel;
-
- each(series.data, function(point) {
- tracker = point.tracker;
- shapeArgs = point.trackerArgs || point.shapeArgs;
- if (point.y !== null) {
- if (tracker) {
- tracker.attr(shapeArgs);
-
- } else {
- point.tracker =
- renderer[point.shapeType](shapeArgs)
- .attr({
- isTracker: trackerLabel,
- fill: TRACKER_FILL,
- visibility: series.visible ? VISIBLE : HIDDEN,
- zIndex: 1
- })
- .on(hasTouch ? 'touchstart' : 'mouseover', function(event) {
- rel = event.relatedTarget || event.fromElement;
- if (chart.hoverSeries != series && attr(rel, 'isTracker') != trackerLabel) {
- series.onMouseOver();
- }
- point.onMouseOver();
-
- })
- .on('mouseout', function(event) {
- if (!series.options.stickyTracking) {
- rel = event.relatedTarget || event.toElement;
- if (attr(rel, 'isTracker') != trackerLabel) {
- series.onMouseOut();
- }
- }
- })
- .css(css)
- .add(chart.trackerGroup);
- }
- }
- });
- },
-
-
-
- animate: function(init) {
- var series = this,
- data = series.data;
-
- if (!init) {
-
-
- each(data, function(point) {
- var graphic = point.graphic;
-
- if (graphic) {
-
- graphic.attr({
- height: 0,
- y: series.yAxis.translate(0, 0, 1)
- });
-
-
- graphic.animate({
- height: point.barH,
- y: point.barY
- }, series.options.animation);
- }
- });
-
-
-
- series.animate = null;
- }
-
- },
-
- remove: function() {
- var series = this,
- chart = series.chart;
-
-
-
- if (chart.hasRendered) {
- each(chart.series, function(otherSeries) {
- if (otherSeries.type == series.type) {
- otherSeries.isDirty = true;
- }
- });
- }
-
- Series.prototype.remove.apply(series, arguments);
- }
- });
- seriesTypes.column = ColumnSeries;
- var BarSeries = extendClass(ColumnSeries, {
- type: 'bar',
- init: function(chart) {
- chart.inverted = this.inverted = true;
- ColumnSeries.prototype.init.apply(this, arguments);
- }
- });
- seriesTypes.bar = BarSeries;
- var ScatterSeries = extendClass(Series, {
- type: 'scatter',
-
-
- translate: function() {
- var series = this;
- Series.prototype.translate.apply(series);
- each(series.data, function(point) {
- point.shapeType = 'circle';
- point.shapeArgs = {
- x: point.plotX,
- y: point.plotY,
- r: series.chart.options.tooltip.snap
- };
- });
- },
-
-
-
-
- drawTracker: function() {
- var series = this,
- cursor = series.options.cursor,
- css = cursor && { cursor: cursor },
- graphic;
-
- each(series.data, function(point) {
- graphic = point.graphic;
- if (graphic) {
- graphic
- .attr({ isTracker: true })
- .on('mouseover', function(event) {
- series.onMouseOver();
- point.onMouseOver();
- })
- .on('mouseout', function(event) {
- if (!series.options.stickyTracking) {
- series.onMouseOut();
- }
- })
- .css(css);
- }
- });
- },
-
-
- cleanData: function() {}
- });
- seriesTypes.scatter = ScatterSeries;
- var PiePoint = extendClass(Point, {
-
- init: function () {
-
- Point.prototype.init.apply(this, arguments);
-
- var point = this,
- toggleSlice;
-
-
- extend(point, {
- visible: point.visible !== false,
- name: pick(point.name, 'Slice')
- });
-
-
- toggleSlice = function() {
- point.slice();
- };
- addEvent(point, 'select', toggleSlice);
- addEvent(point, 'unselect', toggleSlice);
-
- return point;
- },
-
-
- setVisible: function(vis) {
- var point = this,
- chart = point.series.chart,
- tracker = point.tracker,
- dataLabel = point.dataLabel,
- connector = point.connector,
- method;
-
-
- point.visible = vis = vis === UNDEFINED ? !point.visible : vis;
-
- method = vis ? 'show' : 'hide';
-
- point.group[method]();
- if (tracker) {
- tracker[method]();
- }
- if (dataLabel) {
- dataLabel[method]();
- }
- if (connector) {
- connector[method]();
- }
- if (point.legendItem) {
- chart.legend.colorizeItem(point, vis);
- }
- },
-
-
- slice: function(sliced, redraw, animation) {
- var point = this,
- series = point.series,
- chart = series.chart,
- slicedTranslation = point.slicedTranslation;
-
- setAnimation(animation, chart);
-
-
- redraw = pick(redraw, true);
-
-
- sliced = point.sliced = defined(sliced) ? sliced : !point.sliced;
-
- point.group.animate({
- translateX: (sliced ? slicedTranslation[0] : chart.plotLeft),
- translateY: (sliced ? slicedTranslation[1] : chart.plotTop)
- });
-
- }
- });
- var PieSeries = extendClass(Series, {
- type: 'pie',
- isCartesian: false,
- pointClass: PiePoint,
- pointAttrToOptions: {
- stroke: 'borderColor',
- 'stroke-width': 'borderWidth',
- fill: 'color'
- },
-
-
- getColor: function() {
-
- this.initialColor = colorCounter;
- },
-
-
- animate: function(init) {
- var series = this,
- data = series.data;
-
- each(data, function(point) {
- var graphic = point.graphic,
- args = point.shapeArgs,
- up = -mathPI / 2;
-
- if (graphic) {
-
- graphic.attr({
- r: 0,
- start: up,
- end: up
- });
-
-
- graphic.animate({
- r: args.r,
- start: args.start,
- end: args.end
- }, series.options.animation);
- }
- });
-
-
- series.animate = null;
-
- },
-
- translate: function() {
- var total = 0,
- series = this,
- cumulative = -0.25,
- options = series.options,
- slicedOffset = options.slicedOffset,
- connectorOffset = slicedOffset + options.borderWidth,
- positions = options.center,
- chart = series.chart,
- plotWidth = chart.plotWidth,
- plotHeight = chart.plotHeight,
- start,
- end,
- angle,
- data = series.data,
- circ = 2 * mathPI,
- fraction,
- smallestSize = mathMin(plotWidth, plotHeight),
- isPercent,
- radiusX,
- radiusY,
- labelDistance = options.dataLabels.distance;
-
-
- positions.push(options.size, options.innerSize || 0);
- positions = map(positions, function(length, i) {
-
- isPercent = /%$/.test(length);
- return isPercent ?
-
-
-
- [plotWidth, plotHeight, smallestSize, smallestSize][i] *
- pInt(length) / 100:
- length;
- });
-
-
- series.getX = function(y, left) {
-
- angle = math.asin((y - positions[1]) / (positions[2] / 2 + labelDistance));
-
- return positions[0] +
- (left ? -1 : 1) *
- (mathCos(angle) * (positions[2] / 2 + labelDistance));
- };
-
-
- series.center = positions;
-
-
- each(data, function(point) {
- total += point.y;
- });
-
- each(data, function(point) {
-
- fraction = total ? point.y / total : 0;
- start = cumulative * circ;
- cumulative += fraction;
- end = cumulative * circ;
-
-
-
- point.shapeType = 'arc';
- point.shapeArgs = {
- x: positions[0],
- y: positions[1],
- r: positions[2] / 2,
- innerR: positions[3] / 2,
- start: start,
- end: end
- };
-
-
- angle = (end + start) / 2;
- point.slicedTranslation = map([
- mathCos(angle) * slicedOffset + chart.plotLeft,
- mathSin(angle) * slicedOffset + chart.plotTop
- ], mathRound);
-
-
-
- radiusX = mathCos(angle) * positions[2] / 2;
- radiusY = mathSin(angle) * positions[2] / 2;
- point.tooltipPos = [
- positions[0] + radiusX * 0.7,
- positions[1] + radiusY * 0.7
- ];
-
-
- point.labelPos = [
- positions[0] + radiusX + mathCos(angle) * labelDistance,
- positions[1] + radiusY + mathSin(angle) * labelDistance,
- positions[0] + radiusX + mathCos(angle) * connectorOffset,
- positions[1] + radiusY + mathSin(angle) * connectorOffset,
- positions[0] + radiusX,
- positions[1] + radiusY,
- labelDistance < 0 ?
- 'center' :
- angle < circ / 4 ? 'left' : 'right',
- angle
- ];
-
-
-
- point.percentage = fraction * 100;
- point.total = total;
-
- });
-
- this.setTooltipPoints();
- },
-
-
- render: function() {
- var series = this;
-
-
- series.getAttribs();
- this.drawPoints();
-
-
- if (series.options.enableMouseTracking !== false) {
- series.drawTracker();
- }
-
- this.drawDataLabels();
-
- if (series.options.animation && series.animate) {
- series.animate();
- }
-
- series.isDirty = false;
- },
-
-
- drawPoints: function() {
- var series = this,
- chart = series.chart,
- renderer = chart.renderer,
- groupTranslation,
-
- graphic,
- shapeArgs;
-
-
- each(series.data, function(point) {
- graphic = point.graphic;
- shapeArgs = point.shapeArgs;
-
- if (!point.group) {
-
- groupTranslation = point.sliced ? point.slicedTranslation : [chart.plotLeft, chart.plotTop];
- point.group = renderer.g('point')
- .attr({ zIndex: 5 })
- .add()
- .translate(groupTranslation[0], groupTranslation[1]);
- }
-
-
- if (graphic) {
- graphic.animate(shapeArgs);
- } else {
- point.graphic =
- renderer.arc(shapeArgs)
- .attr(point.pointAttr[NORMAL_STATE])
- .add(point.group);
- }
-
-
- if (point.visible === false) {
- point.setVisible(false);
- }
-
- });
-
- },
-
-
- drawDataLabels: function() {
- var series = this,
- data = series.data,
- point,
- chart = series.chart,
- options = series.options.dataLabels,
- connectorPadding = pick(options.connectorPadding, 10),
- connectorWidth = pick(options.connectorWidth, 1),
- connector,
- connectorPath,
- outside = options.distance > 0,
- dataLabel,
- labelPos,
- labelHeight,
- lastY,
- centerY = series.center[1],
- quarters = [
- [],
- [],
- [],
- []
- ],
- x,
- y,
- visibility,
- overlapping,
- rankArr,
- secondPass,
- sign,
- lowerHalf,
- sort,
- i = 4,
- j;
-
-
- Series.prototype.drawDataLabels.apply(series);
-
-
- each(data, function(point) {
- var angle = point.labelPos[7],
- quarter;
- if (angle < 0) {
- quarter = 0;
- } else if (angle < mathPI / 2) {
- quarter = 1;
- } else if (angle < mathPI) {
- quarter = 2;
- } else {
- quarter = 3;
- }
- quarters[quarter].push(point);
- });
- quarters[1].reverse();
- quarters[3].reverse();
-
-
- sort = function(a,b) {
- return a.y > b.y;
- };
-
- while (i--) {
- overlapping = 0;
-
-
- rankArr = [].concat(quarters[i]);
- rankArr.sort(sort);
- j = rankArr.length;
- while (j--) {
- rankArr[j].rank = j;
- }
-
-
- for (secondPass = 0; secondPass < 2; secondPass++) {
- lowerHalf = i % 3;
- lastY = lowerHalf ? 9999 : -9999;
- sign = lowerHalf ? -1 : 1;
-
- for (j = 0; j < quarters[i].length; j++) {
- point = quarters[i][j];
-
- if ((dataLabel = point.dataLabel)) {
- labelPos = point.labelPos;
- visibility = VISIBLE;
- x = labelPos[0];
- y = labelPos[1];
-
-
-
- if (!labelHeight) {
- labelHeight = dataLabel && dataLabel.getBBox().height;
- }
-
-
- if (outside) {
- if (secondPass && point.rank < overlapping) {
- visibility = HIDDEN;
- } else if ((!lowerHalf && y < lastY + labelHeight) ||
- (lowerHalf && y > lastY - labelHeight)) {
- y = lastY + sign * labelHeight;
- x = series.getX(y, i > 1);
- if ((!lowerHalf && y + labelHeight > centerY) ||
- (lowerHalf && y -labelHeight < centerY)) {
- if (secondPass) {
- visibility = HIDDEN;
- } else {
- overlapping++;
- }
- }
- }
- }
-
- if (point.visible === false) {
- visibility = HIDDEN;
- }
-
- if (visibility == VISIBLE) {
- lastY = y;
- }
-
- if (secondPass) {
-
-
- dataLabel
- .attr({
- visibility: visibility,
- align: labelPos[6]
- })
- [dataLabel.moved ? 'animate' : 'attr']({
- x: x + options.x +
- ({ left: connectorPadding, right: -connectorPadding }[labelPos[6]] || 0),
- y: y + options.y
- });
- dataLabel.moved = true;
-
-
- if (outside && connectorWidth) {
- connector = point.connector;
-
- connectorPath = [
- M,
- x + (labelPos[6] == 'left' ? 5 : -5), y,
- L,
- x, y,
- L,
- labelPos[2], labelPos[3],
- L,
- labelPos[4], labelPos[5]
- ];
-
- if (connector) {
- connector.animate({ d: connectorPath });
- connector.attr('visibility', visibility);
-
- } else {
- point.connector = connector = series.chart.renderer.path(connectorPath).attr({
- 'stroke-width': connectorWidth,
- stroke: options.connectorColor || '#606060',
- visibility: visibility,
- zIndex: 3
- })
- .translate(chart.plotLeft, chart.plotTop)
- .add();
- }
- }
- }
- }
- }
- }
- }
- },
-
-
- drawTracker: ColumnSeries.prototype.drawTracker,
-
-
- getSymbol: function() {}
-
- });
- seriesTypes.pie = PieSeries;
- if (useCanVG) {
- var head = doc.getElementsByTagName('head')[0];
- createElement('script', {
- type: 'text/javascript',
- src: 'http://highcharts.com/js/canvg.js',
- onload: function() {
- drawDeferredCanvases();
- }
- }, null, head);
- }
- win.Highcharts = {
- Chart: Chart,
- dateFormat: dateFormat,
- pathAnim: pathAnim,
- getOptions: getOptions,
- numberFormat: numberFormat,
- Point: Point,
- Renderer: Renderer,
- seriesTypes: seriesTypes,
- setOptions: setOptions,
- Series: Series,
-
-
- addEvent: addEvent,
- createElement: createElement,
- discardElement: discardElement,
- css: css,
- each: each,
- extend: extend,
- map: map,
- merge: merge,
- pick: pick,
- extendClass: extendClass,
- version: '2.1.1'
- };
- })();
|