f2-all.js 617 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568756975707571757275737574757575767577757875797580758175827583758475857586758775887589759075917592759375947595759675977598759976007601760276037604760576067607760876097610761176127613761476157616761776187619762076217622762376247625762676277628762976307631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700770177027703770477057706770777087709771077117712771377147715771677177718771977207721772277237724772577267727772877297730773177327733773477357736773777387739774077417742774377447745774677477748774977507751775277537754775577567757775877597760776177627763776477657766776777687769777077717772777377747775777677777778777977807781778277837784778577867787778877897790779177927793779477957796779777987799780078017802780378047805780678077808780978107811781278137814781578167817781878197820782178227823782478257826782778287829783078317832783378347835783678377838783978407841784278437844784578467847784878497850785178527853785478557856785778587859786078617862786378647865786678677868786978707871787278737874787578767877787878797880788178827883788478857886788778887889789078917892789378947895789678977898789979007901790279037904790579067907790879097910791179127913791479157916791779187919792079217922792379247925792679277928792979307931793279337934793579367937793879397940794179427943794479457946794779487949795079517952795379547955795679577958795979607961796279637964796579667967796879697970797179727973797479757976797779787979798079817982798379847985798679877988798979907991799279937994799579967997799879998000800180028003800480058006800780088009801080118012801380148015801680178018801980208021802280238024802580268027802880298030803180328033803480358036803780388039804080418042804380448045804680478048804980508051805280538054805580568057805880598060806180628063806480658066806780688069807080718072807380748075807680778078807980808081808280838084808580868087808880898090809180928093809480958096809780988099810081018102810381048105810681078108810981108111811281138114811581168117811881198120812181228123812481258126812781288129813081318132813381348135813681378138813981408141814281438144814581468147814881498150815181528153815481558156815781588159816081618162816381648165816681678168816981708171817281738174817581768177817881798180818181828183818481858186818781888189819081918192819381948195819681978198819982008201820282038204820582068207820882098210821182128213821482158216821782188219822082218222822382248225822682278228822982308231823282338234823582368237823882398240824182428243824482458246824782488249825082518252825382548255825682578258825982608261826282638264826582668267826882698270827182728273827482758276827782788279828082818282828382848285828682878288828982908291829282938294829582968297829882998300830183028303830483058306830783088309831083118312831383148315831683178318831983208321832283238324832583268327832883298330833183328333833483358336833783388339834083418342834383448345834683478348834983508351835283538354835583568357835883598360836183628363836483658366836783688369837083718372837383748375837683778378837983808381838283838384838583868387838883898390839183928393839483958396839783988399840084018402840384048405840684078408840984108411841284138414841584168417841884198420842184228423842484258426842784288429843084318432843384348435843684378438843984408441844284438444844584468447844884498450845184528453845484558456845784588459846084618462846384648465846684678468846984708471847284738474847584768477847884798480848184828483848484858486848784888489849084918492849384948495849684978498849985008501850285038504850585068507850885098510851185128513851485158516851785188519852085218522852385248525852685278528852985308531853285338534853585368537853885398540854185428543854485458546854785488549855085518552855385548555855685578558855985608561856285638564856585668567856885698570857185728573857485758576857785788579858085818582858385848585858685878588858985908591859285938594859585968597859885998600860186028603860486058606860786088609861086118612861386148615861686178618861986208621862286238624862586268627862886298630863186328633863486358636863786388639864086418642864386448645864686478648864986508651865286538654865586568657865886598660866186628663866486658666866786688669867086718672867386748675867686778678867986808681868286838684868586868687868886898690869186928693869486958696869786988699870087018702870387048705870687078708870987108711871287138714871587168717871887198720872187228723872487258726872787288729873087318732873387348735873687378738873987408741874287438744874587468747874887498750875187528753875487558756875787588759876087618762876387648765876687678768876987708771877287738774877587768777877887798780878187828783878487858786878787888789879087918792879387948795879687978798879988008801880288038804880588068807880888098810881188128813881488158816881788188819882088218822882388248825882688278828882988308831883288338834883588368837883888398840884188428843884488458846884788488849885088518852885388548855885688578858885988608861886288638864886588668867886888698870887188728873887488758876887788788879888088818882888388848885888688878888888988908891889288938894889588968897889888998900890189028903890489058906890789088909891089118912891389148915891689178918891989208921892289238924892589268927892889298930893189328933893489358936893789388939894089418942894389448945894689478948894989508951895289538954895589568957895889598960896189628963896489658966896789688969897089718972897389748975897689778978897989808981898289838984898589868987898889898990899189928993899489958996899789988999900090019002900390049005900690079008900990109011901290139014901590169017901890199020902190229023902490259026902790289029903090319032903390349035903690379038903990409041904290439044904590469047904890499050905190529053905490559056905790589059906090619062906390649065906690679068906990709071907290739074907590769077907890799080908190829083908490859086908790889089909090919092909390949095909690979098909991009101910291039104910591069107910891099110911191129113911491159116911791189119912091219122912391249125912691279128912991309131913291339134913591369137913891399140914191429143914491459146914791489149915091519152915391549155915691579158915991609161916291639164916591669167916891699170917191729173917491759176917791789179918091819182918391849185918691879188918991909191919291939194919591969197919891999200920192029203920492059206920792089209921092119212921392149215921692179218921992209221922292239224922592269227922892299230923192329233923492359236923792389239924092419242924392449245924692479248924992509251925292539254925592569257925892599260926192629263926492659266926792689269927092719272927392749275927692779278927992809281928292839284928592869287928892899290929192929293929492959296929792989299930093019302930393049305930693079308930993109311931293139314931593169317931893199320932193229323932493259326932793289329933093319332933393349335933693379338933993409341934293439344934593469347934893499350935193529353935493559356935793589359936093619362936393649365936693679368936993709371937293739374937593769377937893799380938193829383938493859386938793889389939093919392939393949395939693979398939994009401940294039404940594069407940894099410941194129413941494159416941794189419942094219422942394249425942694279428942994309431943294339434943594369437943894399440944194429443944494459446944794489449945094519452945394549455945694579458945994609461946294639464946594669467946894699470947194729473947494759476947794789479948094819482948394849485948694879488948994909491949294939494949594969497949894999500950195029503950495059506950795089509951095119512951395149515951695179518951995209521952295239524952595269527952895299530953195329533953495359536953795389539954095419542954395449545954695479548954995509551955295539554955595569557955895599560956195629563956495659566956795689569957095719572957395749575957695779578957995809581958295839584958595869587958895899590959195929593959495959596959795989599960096019602960396049605960696079608960996109611961296139614961596169617961896199620962196229623962496259626962796289629963096319632963396349635963696379638963996409641964296439644964596469647964896499650965196529653965496559656965796589659966096619662966396649665966696679668966996709671967296739674967596769677967896799680968196829683968496859686968796889689969096919692969396949695969696979698969997009701970297039704970597069707970897099710971197129713971497159716971797189719972097219722972397249725972697279728972997309731973297339734973597369737973897399740974197429743974497459746974797489749975097519752975397549755975697579758975997609761976297639764976597669767976897699770977197729773977497759776977797789779978097819782978397849785978697879788978997909791979297939794979597969797979897999800980198029803980498059806980798089809981098119812981398149815981698179818981998209821982298239824982598269827982898299830983198329833983498359836983798389839984098419842984398449845984698479848984998509851985298539854985598569857985898599860986198629863986498659866986798689869987098719872987398749875987698779878987998809881988298839884988598869887988898899890989198929893989498959896989798989899990099019902990399049905990699079908990999109911991299139914991599169917991899199920992199229923992499259926992799289929993099319932993399349935993699379938993999409941994299439944994599469947994899499950995199529953995499559956995799589959996099619962996399649965996699679968996999709971997299739974997599769977997899799980998199829983998499859986998799889989999099919992999399949995999699979998999910000100011000210003100041000510006100071000810009100101001110012100131001410015100161001710018100191002010021100221002310024100251002610027100281002910030100311003210033100341003510036100371003810039100401004110042100431004410045100461004710048100491005010051100521005310054100551005610057100581005910060100611006210063100641006510066100671006810069100701007110072100731007410075100761007710078100791008010081100821008310084100851008610087100881008910090100911009210093100941009510096100971009810099101001010110102101031010410105101061010710108101091011010111101121011310114101151011610117101181011910120101211012210123101241012510126101271012810129101301013110132101331013410135101361013710138101391014010141101421014310144101451014610147101481014910150101511015210153101541015510156101571015810159101601016110162101631016410165101661016710168101691017010171101721017310174101751017610177101781017910180101811018210183101841018510186101871018810189101901019110192101931019410195101961019710198101991020010201102021020310204102051020610207102081020910210102111021210213102141021510216102171021810219102201022110222102231022410225102261022710228102291023010231102321023310234102351023610237102381023910240102411024210243102441024510246102471024810249102501025110252102531025410255102561025710258102591026010261102621026310264102651026610267102681026910270102711027210273102741027510276102771027810279102801028110282102831028410285102861028710288102891029010291102921029310294102951029610297102981029910300103011030210303103041030510306103071030810309103101031110312103131031410315103161031710318103191032010321103221032310324103251032610327103281032910330103311033210333103341033510336103371033810339103401034110342103431034410345103461034710348103491035010351103521035310354103551035610357103581035910360103611036210363103641036510366103671036810369103701037110372103731037410375103761037710378103791038010381103821038310384103851038610387103881038910390103911039210393103941039510396103971039810399104001040110402104031040410405104061040710408104091041010411104121041310414104151041610417104181041910420104211042210423104241042510426104271042810429104301043110432104331043410435104361043710438104391044010441104421044310444104451044610447104481044910450104511045210453104541045510456104571045810459104601046110462104631046410465104661046710468104691047010471104721047310474104751047610477104781047910480104811048210483104841048510486104871048810489104901049110492104931049410495104961049710498104991050010501105021050310504105051050610507105081050910510105111051210513105141051510516105171051810519105201052110522105231052410525105261052710528105291053010531105321053310534105351053610537105381053910540105411054210543105441054510546105471054810549105501055110552105531055410555105561055710558105591056010561105621056310564105651056610567105681056910570105711057210573105741057510576105771057810579105801058110582105831058410585105861058710588105891059010591105921059310594105951059610597105981059910600106011060210603106041060510606106071060810609106101061110612106131061410615106161061710618106191062010621106221062310624106251062610627106281062910630106311063210633106341063510636106371063810639106401064110642106431064410645106461064710648106491065010651106521065310654106551065610657106581065910660106611066210663106641066510666106671066810669106701067110672106731067410675106761067710678106791068010681106821068310684106851068610687106881068910690106911069210693106941069510696106971069810699107001070110702107031070410705107061070710708107091071010711107121071310714107151071610717107181071910720107211072210723107241072510726107271072810729107301073110732107331073410735107361073710738107391074010741107421074310744107451074610747107481074910750107511075210753107541075510756107571075810759107601076110762107631076410765107661076710768107691077010771107721077310774107751077610777107781077910780107811078210783107841078510786107871078810789107901079110792107931079410795107961079710798107991080010801108021080310804108051080610807108081080910810108111081210813108141081510816108171081810819108201082110822108231082410825108261082710828108291083010831108321083310834108351083610837108381083910840108411084210843108441084510846108471084810849108501085110852108531085410855108561085710858108591086010861108621086310864108651086610867108681086910870108711087210873108741087510876108771087810879108801088110882108831088410885108861088710888108891089010891108921089310894108951089610897108981089910900109011090210903109041090510906109071090810909109101091110912109131091410915109161091710918109191092010921109221092310924109251092610927109281092910930109311093210933109341093510936109371093810939109401094110942109431094410945109461094710948109491095010951109521095310954109551095610957109581095910960109611096210963109641096510966109671096810969109701097110972109731097410975109761097710978109791098010981109821098310984109851098610987109881098910990109911099210993109941099510996109971099810999110001100111002110031100411005110061100711008110091101011011110121101311014110151101611017110181101911020110211102211023110241102511026110271102811029110301103111032110331103411035110361103711038110391104011041110421104311044110451104611047110481104911050110511105211053110541105511056110571105811059110601106111062110631106411065110661106711068110691107011071110721107311074110751107611077110781107911080110811108211083110841108511086110871108811089110901109111092110931109411095110961109711098110991110011101111021110311104111051110611107111081110911110111111111211113111141111511116111171111811119111201112111122111231112411125111261112711128111291113011131111321113311134111351113611137111381113911140111411114211143111441114511146111471114811149111501115111152111531115411155111561115711158111591116011161111621116311164111651116611167111681116911170111711117211173111741117511176111771117811179111801118111182111831118411185111861118711188111891119011191111921119311194111951119611197111981119911200112011120211203112041120511206112071120811209112101121111212112131121411215112161121711218112191122011221112221122311224112251122611227112281122911230112311123211233112341123511236112371123811239112401124111242112431124411245112461124711248112491125011251112521125311254112551125611257112581125911260112611126211263112641126511266112671126811269112701127111272112731127411275112761127711278112791128011281112821128311284112851128611287112881128911290112911129211293112941129511296112971129811299113001130111302113031130411305113061130711308113091131011311113121131311314113151131611317113181131911320113211132211323113241132511326113271132811329113301133111332113331133411335113361133711338113391134011341113421134311344113451134611347113481134911350113511135211353113541135511356113571135811359113601136111362113631136411365113661136711368113691137011371113721137311374113751137611377113781137911380113811138211383113841138511386113871138811389113901139111392113931139411395113961139711398113991140011401114021140311404114051140611407114081140911410114111141211413114141141511416114171141811419114201142111422114231142411425114261142711428114291143011431114321143311434114351143611437114381143911440114411144211443114441144511446114471144811449114501145111452114531145411455114561145711458114591146011461114621146311464114651146611467114681146911470114711147211473114741147511476114771147811479114801148111482114831148411485114861148711488114891149011491114921149311494114951149611497114981149911500115011150211503115041150511506115071150811509115101151111512115131151411515115161151711518115191152011521115221152311524115251152611527115281152911530115311153211533115341153511536115371153811539115401154111542115431154411545115461154711548115491155011551115521155311554115551155611557115581155911560115611156211563115641156511566115671156811569115701157111572115731157411575115761157711578115791158011581115821158311584115851158611587115881158911590115911159211593115941159511596115971159811599116001160111602116031160411605116061160711608116091161011611116121161311614116151161611617116181161911620116211162211623116241162511626116271162811629116301163111632116331163411635116361163711638116391164011641116421164311644116451164611647116481164911650116511165211653116541165511656116571165811659116601166111662116631166411665116661166711668116691167011671116721167311674116751167611677116781167911680116811168211683116841168511686116871168811689116901169111692116931169411695116961169711698116991170011701117021170311704117051170611707117081170911710117111171211713117141171511716117171171811719117201172111722117231172411725117261172711728117291173011731117321173311734117351173611737117381173911740117411174211743117441174511746117471174811749117501175111752117531175411755117561175711758117591176011761117621176311764117651176611767117681176911770117711177211773117741177511776117771177811779117801178111782117831178411785117861178711788117891179011791117921179311794117951179611797117981179911800118011180211803118041180511806118071180811809118101181111812118131181411815118161181711818118191182011821118221182311824118251182611827118281182911830118311183211833118341183511836118371183811839118401184111842118431184411845118461184711848118491185011851118521185311854118551185611857118581185911860118611186211863118641186511866118671186811869118701187111872118731187411875118761187711878118791188011881118821188311884118851188611887118881188911890118911189211893118941189511896118971189811899119001190111902119031190411905119061190711908119091191011911119121191311914119151191611917119181191911920119211192211923119241192511926119271192811929119301193111932119331193411935119361193711938119391194011941119421194311944119451194611947119481194911950119511195211953119541195511956119571195811959119601196111962119631196411965119661196711968119691197011971119721197311974119751197611977119781197911980119811198211983119841198511986119871198811989119901199111992119931199411995119961199711998119991200012001120021200312004120051200612007120081200912010120111201212013120141201512016120171201812019120201202112022120231202412025120261202712028120291203012031120321203312034120351203612037120381203912040120411204212043120441204512046120471204812049120501205112052120531205412055120561205712058120591206012061120621206312064120651206612067120681206912070120711207212073120741207512076120771207812079120801208112082120831208412085120861208712088120891209012091120921209312094120951209612097120981209912100121011210212103121041210512106121071210812109121101211112112121131211412115121161211712118121191212012121121221212312124121251212612127121281212912130121311213212133121341213512136121371213812139121401214112142121431214412145121461214712148121491215012151121521215312154121551215612157121581215912160121611216212163121641216512166121671216812169121701217112172121731217412175121761217712178121791218012181121821218312184121851218612187121881218912190121911219212193121941219512196121971219812199122001220112202122031220412205122061220712208122091221012211122121221312214122151221612217122181221912220122211222212223122241222512226122271222812229122301223112232122331223412235122361223712238122391224012241122421224312244122451224612247122481224912250122511225212253122541225512256122571225812259122601226112262122631226412265122661226712268122691227012271122721227312274122751227612277122781227912280122811228212283122841228512286122871228812289122901229112292122931229412295122961229712298122991230012301123021230312304123051230612307123081230912310123111231212313123141231512316123171231812319123201232112322123231232412325123261232712328123291233012331123321233312334123351233612337123381233912340123411234212343123441234512346123471234812349123501235112352123531235412355123561235712358123591236012361123621236312364123651236612367123681236912370123711237212373123741237512376123771237812379123801238112382123831238412385123861238712388123891239012391123921239312394123951239612397123981239912400124011240212403124041240512406124071240812409124101241112412124131241412415124161241712418124191242012421124221242312424124251242612427124281242912430124311243212433124341243512436124371243812439124401244112442124431244412445124461244712448124491245012451124521245312454124551245612457124581245912460124611246212463124641246512466124671246812469124701247112472124731247412475124761247712478124791248012481124821248312484124851248612487124881248912490124911249212493124941249512496124971249812499125001250112502125031250412505125061250712508125091251012511125121251312514125151251612517125181251912520125211252212523125241252512526125271252812529125301253112532125331253412535125361253712538125391254012541125421254312544125451254612547125481254912550125511255212553125541255512556125571255812559125601256112562125631256412565125661256712568125691257012571125721257312574125751257612577125781257912580125811258212583125841258512586125871258812589125901259112592125931259412595125961259712598125991260012601126021260312604126051260612607126081260912610126111261212613126141261512616126171261812619126201262112622126231262412625126261262712628126291263012631126321263312634126351263612637126381263912640126411264212643126441264512646126471264812649126501265112652126531265412655126561265712658126591266012661126621266312664126651266612667126681266912670126711267212673126741267512676126771267812679126801268112682126831268412685126861268712688126891269012691126921269312694126951269612697126981269912700127011270212703127041270512706127071270812709127101271112712127131271412715127161271712718127191272012721127221272312724127251272612727127281272912730127311273212733127341273512736127371273812739127401274112742127431274412745127461274712748127491275012751127521275312754127551275612757127581275912760127611276212763127641276512766127671276812769127701277112772127731277412775127761277712778127791278012781127821278312784127851278612787127881278912790127911279212793127941279512796127971279812799128001280112802128031280412805128061280712808128091281012811128121281312814128151281612817128181281912820128211282212823128241282512826128271282812829128301283112832128331283412835128361283712838128391284012841128421284312844128451284612847128481284912850128511285212853128541285512856128571285812859128601286112862128631286412865128661286712868128691287012871128721287312874128751287612877128781287912880128811288212883128841288512886128871288812889128901289112892128931289412895128961289712898128991290012901129021290312904129051290612907129081290912910129111291212913129141291512916129171291812919129201292112922129231292412925129261292712928129291293012931129321293312934129351293612937129381293912940129411294212943129441294512946129471294812949129501295112952129531295412955129561295712958129591296012961129621296312964129651296612967129681296912970129711297212973129741297512976129771297812979129801298112982129831298412985129861298712988129891299012991129921299312994129951299612997129981299913000130011300213003130041300513006130071300813009130101301113012130131301413015130161301713018130191302013021130221302313024130251302613027130281302913030130311303213033130341303513036130371303813039130401304113042130431304413045130461304713048130491305013051130521305313054130551305613057130581305913060130611306213063130641306513066130671306813069130701307113072130731307413075130761307713078130791308013081130821308313084130851308613087130881308913090130911309213093130941309513096130971309813099131001310113102131031310413105131061310713108131091311013111131121311313114131151311613117131181311913120131211312213123131241312513126131271312813129131301313113132131331313413135131361313713138131391314013141131421314313144131451314613147131481314913150131511315213153131541315513156131571315813159131601316113162131631316413165131661316713168131691317013171131721317313174131751317613177131781317913180131811318213183131841318513186131871318813189131901319113192131931319413195131961319713198131991320013201132021320313204132051320613207132081320913210132111321213213132141321513216132171321813219132201322113222132231322413225132261322713228132291323013231132321323313234132351323613237132381323913240132411324213243132441324513246132471324813249132501325113252132531325413255132561325713258132591326013261132621326313264132651326613267132681326913270132711327213273132741327513276132771327813279132801328113282132831328413285132861328713288132891329013291132921329313294132951329613297132981329913300133011330213303133041330513306133071330813309133101331113312133131331413315133161331713318133191332013321133221332313324133251332613327133281332913330133311333213333133341333513336133371333813339133401334113342133431334413345133461334713348133491335013351133521335313354133551335613357133581335913360133611336213363133641336513366133671336813369133701337113372133731337413375133761337713378133791338013381133821338313384133851338613387133881338913390133911339213393133941339513396133971339813399134001340113402134031340413405134061340713408134091341013411134121341313414134151341613417134181341913420134211342213423134241342513426134271342813429134301343113432134331343413435134361343713438134391344013441134421344313444134451344613447134481344913450134511345213453134541345513456134571345813459134601346113462134631346413465134661346713468134691347013471134721347313474134751347613477134781347913480134811348213483134841348513486134871348813489134901349113492134931349413495134961349713498134991350013501135021350313504135051350613507135081350913510135111351213513135141351513516135171351813519135201352113522135231352413525135261352713528135291353013531135321353313534135351353613537135381353913540135411354213543135441354513546135471354813549135501355113552135531355413555135561355713558135591356013561135621356313564135651356613567135681356913570135711357213573135741357513576135771357813579135801358113582135831358413585135861358713588135891359013591135921359313594135951359613597135981359913600136011360213603136041360513606136071360813609136101361113612136131361413615136161361713618136191362013621136221362313624136251362613627136281362913630136311363213633136341363513636136371363813639136401364113642136431364413645136461364713648136491365013651136521365313654136551365613657136581365913660136611366213663136641366513666136671366813669136701367113672136731367413675136761367713678136791368013681136821368313684136851368613687136881368913690136911369213693136941369513696136971369813699137001370113702137031370413705137061370713708137091371013711137121371313714137151371613717137181371913720137211372213723137241372513726137271372813729137301373113732137331373413735137361373713738137391374013741137421374313744137451374613747137481374913750137511375213753137541375513756137571375813759137601376113762137631376413765137661376713768137691377013771137721377313774137751377613777137781377913780137811378213783137841378513786137871378813789137901379113792137931379413795137961379713798137991380013801138021380313804138051380613807138081380913810138111381213813138141381513816138171381813819138201382113822138231382413825138261382713828138291383013831138321383313834138351383613837138381383913840138411384213843138441384513846138471384813849138501385113852138531385413855138561385713858138591386013861138621386313864138651386613867138681386913870138711387213873138741387513876138771387813879138801388113882138831388413885138861388713888138891389013891138921389313894138951389613897138981389913900139011390213903139041390513906139071390813909139101391113912139131391413915139161391713918139191392013921139221392313924139251392613927139281392913930139311393213933139341393513936139371393813939139401394113942139431394413945139461394713948139491395013951139521395313954139551395613957139581395913960139611396213963139641396513966139671396813969139701397113972139731397413975139761397713978139791398013981139821398313984139851398613987139881398913990139911399213993139941399513996139971399813999140001400114002140031400414005140061400714008140091401014011140121401314014140151401614017140181401914020140211402214023140241402514026140271402814029140301403114032140331403414035140361403714038140391404014041140421404314044140451404614047140481404914050140511405214053140541405514056140571405814059140601406114062140631406414065140661406714068140691407014071140721407314074140751407614077140781407914080140811408214083140841408514086140871408814089140901409114092140931409414095140961409714098140991410014101141021410314104141051410614107141081410914110141111411214113141141411514116141171411814119141201412114122141231412414125141261412714128141291413014131141321413314134141351413614137141381413914140141411414214143141441414514146141471414814149141501415114152141531415414155141561415714158141591416014161141621416314164141651416614167141681416914170141711417214173141741417514176141771417814179141801418114182141831418414185141861418714188141891419014191141921419314194141951419614197141981419914200142011420214203142041420514206142071420814209142101421114212142131421414215142161421714218142191422014221142221422314224142251422614227142281422914230142311423214233142341423514236142371423814239142401424114242142431424414245142461424714248142491425014251142521425314254142551425614257142581425914260142611426214263142641426514266142671426814269142701427114272142731427414275142761427714278142791428014281142821428314284142851428614287142881428914290142911429214293142941429514296142971429814299143001430114302143031430414305143061430714308143091431014311143121431314314143151431614317143181431914320143211432214323143241432514326143271432814329143301433114332143331433414335143361433714338143391434014341143421434314344143451434614347143481434914350143511435214353143541435514356143571435814359143601436114362143631436414365143661436714368143691437014371143721437314374143751437614377143781437914380143811438214383143841438514386143871438814389143901439114392143931439414395143961439714398143991440014401144021440314404144051440614407144081440914410144111441214413144141441514416144171441814419144201442114422144231442414425144261442714428144291443014431144321443314434144351443614437144381443914440144411444214443144441444514446144471444814449144501445114452144531445414455144561445714458144591446014461144621446314464144651446614467144681446914470144711447214473144741447514476144771447814479144801448114482144831448414485144861448714488144891449014491144921449314494144951449614497144981449914500145011450214503145041450514506145071450814509145101451114512145131451414515145161451714518145191452014521145221452314524145251452614527145281452914530145311453214533145341453514536145371453814539145401454114542145431454414545145461454714548145491455014551145521455314554145551455614557145581455914560145611456214563145641456514566145671456814569145701457114572145731457414575145761457714578145791458014581145821458314584145851458614587145881458914590145911459214593145941459514596145971459814599146001460114602146031460414605146061460714608146091461014611146121461314614146151461614617146181461914620146211462214623146241462514626146271462814629146301463114632146331463414635146361463714638146391464014641146421464314644146451464614647146481464914650146511465214653146541465514656146571465814659146601466114662146631466414665146661466714668146691467014671146721467314674146751467614677146781467914680146811468214683146841468514686146871468814689146901469114692146931469414695146961469714698146991470014701147021470314704147051470614707147081470914710147111471214713147141471514716147171471814719147201472114722147231472414725147261472714728147291473014731147321473314734147351473614737147381473914740147411474214743147441474514746147471474814749147501475114752147531475414755147561475714758147591476014761147621476314764147651476614767147681476914770147711477214773147741477514776147771477814779147801478114782147831478414785147861478714788147891479014791147921479314794147951479614797147981479914800148011480214803148041480514806148071480814809148101481114812148131481414815148161481714818148191482014821148221482314824148251482614827148281482914830148311483214833148341483514836148371483814839148401484114842148431484414845148461484714848148491485014851148521485314854148551485614857148581485914860148611486214863148641486514866148671486814869148701487114872148731487414875148761487714878148791488014881148821488314884148851488614887148881488914890148911489214893148941489514896148971489814899149001490114902149031490414905149061490714908149091491014911149121491314914149151491614917149181491914920149211492214923149241492514926149271492814929149301493114932149331493414935149361493714938149391494014941149421494314944149451494614947149481494914950149511495214953149541495514956149571495814959149601496114962149631496414965149661496714968149691497014971149721497314974149751497614977149781497914980149811498214983149841498514986149871498814989149901499114992149931499414995149961499714998149991500015001150021500315004150051500615007150081500915010150111501215013150141501515016150171501815019150201502115022150231502415025150261502715028150291503015031150321503315034150351503615037150381503915040150411504215043150441504515046150471504815049150501505115052150531505415055150561505715058150591506015061150621506315064150651506615067150681506915070150711507215073150741507515076150771507815079150801508115082150831508415085150861508715088150891509015091150921509315094150951509615097150981509915100151011510215103151041510515106151071510815109151101511115112151131511415115151161511715118151191512015121151221512315124151251512615127151281512915130151311513215133151341513515136151371513815139151401514115142151431514415145151461514715148151491515015151151521515315154151551515615157151581515915160151611516215163151641516515166151671516815169151701517115172151731517415175151761517715178151791518015181151821518315184151851518615187151881518915190151911519215193151941519515196151971519815199152001520115202152031520415205152061520715208152091521015211152121521315214152151521615217152181521915220152211522215223152241522515226152271522815229152301523115232152331523415235152361523715238152391524015241152421524315244152451524615247152481524915250152511525215253152541525515256152571525815259152601526115262152631526415265152661526715268152691527015271152721527315274152751527615277152781527915280152811528215283152841528515286152871528815289152901529115292152931529415295152961529715298152991530015301153021530315304153051530615307153081530915310153111531215313153141531515316153171531815319153201532115322153231532415325153261532715328153291533015331153321533315334153351533615337153381533915340153411534215343153441534515346153471534815349153501535115352153531535415355153561535715358153591536015361153621536315364153651536615367153681536915370153711537215373153741537515376153771537815379153801538115382153831538415385153861538715388153891539015391153921539315394153951539615397153981539915400154011540215403154041540515406154071540815409154101541115412154131541415415154161541715418154191542015421154221542315424154251542615427154281542915430154311543215433154341543515436154371543815439154401544115442154431544415445154461544715448154491545015451154521545315454154551545615457154581545915460154611546215463154641546515466154671546815469154701547115472154731547415475154761547715478154791548015481154821548315484154851548615487154881548915490154911549215493154941549515496154971549815499155001550115502155031550415505155061550715508155091551015511155121551315514155151551615517155181551915520155211552215523155241552515526155271552815529155301553115532155331553415535155361553715538155391554015541155421554315544155451554615547155481554915550155511555215553155541555515556155571555815559155601556115562155631556415565155661556715568155691557015571155721557315574155751557615577155781557915580155811558215583155841558515586155871558815589155901559115592155931559415595155961559715598155991560015601156021560315604156051560615607156081560915610156111561215613156141561515616156171561815619156201562115622156231562415625156261562715628156291563015631156321563315634156351563615637156381563915640156411564215643156441564515646156471564815649156501565115652156531565415655156561565715658156591566015661156621566315664156651566615667156681566915670156711567215673156741567515676156771567815679156801568115682156831568415685156861568715688156891569015691156921569315694156951569615697156981569915700157011570215703157041570515706157071570815709157101571115712157131571415715157161571715718157191572015721157221572315724157251572615727157281572915730157311573215733157341573515736157371573815739157401574115742157431574415745157461574715748157491575015751157521575315754157551575615757157581575915760157611576215763157641576515766157671576815769157701577115772157731577415775157761577715778157791578015781157821578315784157851578615787157881578915790157911579215793157941579515796157971579815799158001580115802158031580415805158061580715808158091581015811158121581315814158151581615817158181581915820158211582215823158241582515826158271582815829158301583115832158331583415835158361583715838158391584015841158421584315844158451584615847158481584915850158511585215853158541585515856158571585815859158601586115862158631586415865158661586715868158691587015871158721587315874158751587615877158781587915880158811588215883158841588515886158871588815889158901589115892158931589415895158961589715898158991590015901159021590315904159051590615907159081590915910159111591215913159141591515916159171591815919159201592115922159231592415925159261592715928159291593015931159321593315934159351593615937159381593915940159411594215943159441594515946159471594815949159501595115952159531595415955159561595715958159591596015961159621596315964159651596615967159681596915970159711597215973159741597515976159771597815979159801598115982159831598415985159861598715988159891599015991159921599315994159951599615997159981599916000160011600216003160041600516006160071600816009160101601116012160131601416015160161601716018160191602016021160221602316024160251602616027160281602916030160311603216033160341603516036160371603816039160401604116042160431604416045160461604716048160491605016051160521605316054160551605616057160581605916060160611606216063160641606516066160671606816069160701607116072160731607416075160761607716078160791608016081160821608316084160851608616087160881608916090160911609216093160941609516096160971609816099161001610116102161031610416105161061610716108161091611016111161121611316114161151611616117161181611916120161211612216123161241612516126161271612816129161301613116132161331613416135161361613716138161391614016141161421614316144161451614616147161481614916150161511615216153161541615516156161571615816159161601616116162161631616416165161661616716168161691617016171161721617316174161751617616177161781617916180161811618216183161841618516186161871618816189161901619116192161931619416195161961619716198161991620016201162021620316204162051620616207162081620916210162111621216213162141621516216162171621816219162201622116222162231622416225162261622716228162291623016231162321623316234162351623616237162381623916240162411624216243162441624516246162471624816249162501625116252162531625416255162561625716258162591626016261162621626316264162651626616267162681626916270162711627216273162741627516276162771627816279162801628116282162831628416285162861628716288162891629016291162921629316294162951629616297162981629916300163011630216303163041630516306163071630816309163101631116312163131631416315163161631716318163191632016321163221632316324163251632616327163281632916330163311633216333163341633516336163371633816339163401634116342163431634416345163461634716348163491635016351163521635316354163551635616357163581635916360163611636216363163641636516366163671636816369163701637116372163731637416375163761637716378163791638016381163821638316384163851638616387163881638916390163911639216393163941639516396163971639816399164001640116402164031640416405164061640716408164091641016411164121641316414164151641616417164181641916420164211642216423164241642516426164271642816429164301643116432164331643416435164361643716438164391644016441164421644316444164451644616447164481644916450164511645216453164541645516456164571645816459164601646116462164631646416465164661646716468164691647016471164721647316474164751647616477164781647916480164811648216483164841648516486164871648816489164901649116492164931649416495164961649716498164991650016501165021650316504165051650616507165081650916510165111651216513165141651516516165171651816519165201652116522165231652416525165261652716528165291653016531165321653316534165351653616537165381653916540165411654216543165441654516546165471654816549165501655116552165531655416555165561655716558165591656016561165621656316564165651656616567165681656916570165711657216573165741657516576165771657816579165801658116582165831658416585165861658716588165891659016591165921659316594165951659616597165981659916600166011660216603166041660516606166071660816609166101661116612166131661416615166161661716618166191662016621166221662316624166251662616627166281662916630166311663216633166341663516636166371663816639166401664116642166431664416645166461664716648166491665016651166521665316654166551665616657166581665916660166611666216663166641666516666166671666816669166701667116672166731667416675166761667716678166791668016681166821668316684166851668616687166881668916690166911669216693166941669516696166971669816699167001670116702167031670416705167061670716708167091671016711167121671316714167151671616717167181671916720167211672216723167241672516726167271672816729167301673116732167331673416735167361673716738167391674016741167421674316744167451674616747167481674916750167511675216753167541675516756167571675816759167601676116762167631676416765167661676716768167691677016771167721677316774167751677616777167781677916780167811678216783167841678516786167871678816789167901679116792167931679416795167961679716798167991680016801168021680316804168051680616807168081680916810168111681216813168141681516816168171681816819168201682116822168231682416825168261682716828168291683016831168321683316834168351683616837168381683916840168411684216843168441684516846168471684816849168501685116852168531685416855168561685716858168591686016861168621686316864168651686616867168681686916870168711687216873168741687516876168771687816879168801688116882168831688416885168861688716888168891689016891168921689316894168951689616897168981689916900169011690216903169041690516906169071690816909169101691116912169131691416915169161691716918169191692016921169221692316924169251692616927169281692916930169311693216933169341693516936169371693816939169401694116942169431694416945169461694716948169491695016951169521695316954169551695616957169581695916960169611696216963169641696516966169671696816969169701697116972169731697416975169761697716978169791698016981169821698316984169851698616987169881698916990169911699216993169941699516996169971699816999170001700117002170031700417005170061700717008170091701017011170121701317014170151701617017170181701917020170211702217023170241702517026170271702817029170301703117032170331703417035170361703717038170391704017041170421704317044170451704617047170481704917050170511705217053170541705517056170571705817059170601706117062170631706417065170661706717068170691707017071170721707317074170751707617077170781707917080170811708217083170841708517086170871708817089170901709117092170931709417095170961709717098170991710017101171021710317104171051710617107171081710917110171111711217113171141711517116171171711817119171201712117122171231712417125171261712717128171291713017131171321713317134171351713617137171381713917140171411714217143171441714517146171471714817149171501715117152171531715417155171561715717158171591716017161171621716317164171651716617167171681716917170171711717217173171741717517176171771717817179171801718117182171831718417185171861718717188171891719017191171921719317194171951719617197171981719917200172011720217203172041720517206172071720817209172101721117212172131721417215172161721717218172191722017221172221722317224172251722617227172281722917230172311723217233172341723517236172371723817239172401724117242172431724417245172461724717248172491725017251172521725317254172551725617257172581725917260172611726217263172641726517266172671726817269172701727117272172731727417275172761727717278172791728017281172821728317284172851728617287172881728917290172911729217293172941729517296172971729817299173001730117302173031730417305173061730717308173091731017311173121731317314173151731617317173181731917320173211732217323173241732517326173271732817329173301733117332173331733417335173361733717338173391734017341173421734317344173451734617347173481734917350173511735217353173541735517356173571735817359173601736117362173631736417365173661736717368173691737017371173721737317374173751737617377173781737917380173811738217383173841738517386173871738817389173901739117392173931739417395173961739717398173991740017401174021740317404174051740617407174081740917410174111741217413174141741517416174171741817419174201742117422174231742417425174261742717428174291743017431174321743317434174351743617437174381743917440174411744217443174441744517446174471744817449174501745117452174531745417455174561745717458174591746017461174621746317464174651746617467174681746917470174711747217473174741747517476174771747817479174801748117482174831748417485174861748717488174891749017491174921749317494174951749617497174981749917500175011750217503175041750517506175071750817509175101751117512175131751417515175161751717518175191752017521175221752317524175251752617527175281752917530175311753217533175341753517536175371753817539175401754117542175431754417545175461754717548175491755017551175521755317554175551755617557175581755917560175611756217563175641756517566175671756817569175701757117572175731757417575175761757717578175791758017581175821758317584175851758617587175881758917590175911759217593175941759517596175971759817599176001760117602176031760417605176061760717608176091761017611176121761317614176151761617617176181761917620176211762217623176241762517626176271762817629176301763117632176331763417635176361763717638176391764017641176421764317644176451764617647176481764917650176511765217653176541765517656176571765817659176601766117662176631766417665176661766717668176691767017671176721767317674176751767617677176781767917680176811768217683176841768517686176871768817689176901769117692176931769417695176961769717698176991770017701177021770317704177051770617707177081770917710177111771217713177141771517716177171771817719177201772117722177231772417725177261772717728177291773017731177321773317734177351773617737177381773917740177411774217743177441774517746177471774817749177501775117752177531775417755177561775717758177591776017761177621776317764177651776617767177681776917770177711777217773177741777517776177771777817779177801778117782177831778417785177861778717788177891779017791177921779317794177951779617797177981779917800178011780217803178041780517806178071780817809178101781117812178131781417815178161781717818178191782017821178221782317824178251782617827178281782917830178311783217833178341783517836178371783817839178401784117842178431784417845178461784717848178491785017851178521785317854178551785617857178581785917860178611786217863178641786517866178671786817869178701787117872178731787417875178761787717878178791788017881178821788317884178851788617887178881788917890178911789217893178941789517896178971789817899179001790117902179031790417905179061790717908179091791017911179121791317914179151791617917179181791917920179211792217923179241792517926179271792817929179301793117932179331793417935179361793717938179391794017941179421794317944179451794617947179481794917950179511795217953179541795517956179571795817959179601796117962179631796417965179661796717968179691797017971179721797317974179751797617977179781797917980179811798217983179841798517986179871798817989179901799117992179931799417995179961799717998179991800018001180021800318004180051800618007180081800918010180111801218013180141801518016180171801818019180201802118022180231802418025180261802718028180291803018031180321803318034180351803618037180381803918040180411804218043180441804518046180471804818049180501805118052180531805418055180561805718058180591806018061180621806318064180651806618067180681806918070180711807218073180741807518076180771807818079180801808118082180831808418085180861808718088180891809018091180921809318094180951809618097180981809918100181011810218103181041810518106181071810818109181101811118112181131811418115181161811718118181191812018121181221812318124181251812618127181281812918130181311813218133181341813518136181371813818139181401814118142181431814418145181461814718148181491815018151181521815318154181551815618157181581815918160181611816218163181641816518166181671816818169181701817118172181731817418175181761817718178181791818018181181821818318184181851818618187181881818918190181911819218193181941819518196181971819818199182001820118202182031820418205182061820718208182091821018211182121821318214182151821618217182181821918220182211822218223182241822518226182271822818229182301823118232182331823418235182361823718238182391824018241182421824318244182451824618247182481824918250182511825218253182541825518256182571825818259182601826118262182631826418265182661826718268182691827018271182721827318274182751827618277182781827918280182811828218283182841828518286182871828818289182901829118292182931829418295182961829718298182991830018301183021830318304183051830618307183081830918310183111831218313183141831518316183171831818319183201832118322183231832418325183261832718328183291833018331183321833318334183351833618337183381833918340183411834218343183441834518346183471834818349183501835118352183531835418355183561835718358183591836018361183621836318364183651836618367183681836918370183711837218373183741837518376183771837818379183801838118382183831838418385183861838718388183891839018391183921839318394183951839618397183981839918400184011840218403184041840518406184071840818409184101841118412184131841418415184161841718418184191842018421184221842318424184251842618427184281842918430184311843218433184341843518436184371843818439184401844118442184431844418445184461844718448184491845018451184521845318454184551845618457184581845918460184611846218463184641846518466184671846818469184701847118472184731847418475184761847718478184791848018481184821848318484184851848618487184881848918490184911849218493184941849518496184971849818499185001850118502185031850418505185061850718508185091851018511185121851318514185151851618517185181851918520185211852218523185241852518526185271852818529185301853118532185331853418535185361853718538185391854018541185421854318544185451854618547185481854918550185511855218553185541855518556185571855818559185601856118562185631856418565185661856718568185691857018571185721857318574185751857618577185781857918580185811858218583185841858518586185871858818589185901859118592185931859418595185961859718598185991860018601186021860318604186051860618607186081860918610186111861218613186141861518616186171861818619186201862118622186231862418625186261862718628186291863018631186321863318634186351863618637186381863918640186411864218643186441864518646186471864818649186501865118652186531865418655186561865718658186591866018661186621866318664186651866618667186681866918670186711867218673186741867518676186771867818679186801868118682186831868418685186861868718688186891869018691186921869318694186951869618697186981869918700187011870218703187041870518706187071870818709187101871118712187131871418715187161871718718187191872018721187221872318724187251872618727187281872918730187311873218733187341873518736187371873818739187401874118742187431874418745187461874718748187491875018751187521875318754187551875618757187581875918760187611876218763187641876518766187671876818769187701877118772187731877418775187761877718778187791878018781187821878318784187851878618787187881878918790187911879218793187941879518796187971879818799188001880118802188031880418805188061880718808188091881018811188121881318814188151881618817188181881918820188211882218823188241882518826188271882818829188301883118832188331883418835188361883718838188391884018841188421884318844188451884618847188481884918850188511885218853188541885518856188571885818859188601886118862188631886418865188661886718868188691887018871188721887318874188751887618877188781887918880188811888218883188841888518886188871888818889188901889118892188931889418895188961889718898188991890018901189021890318904189051890618907189081890918910189111891218913189141891518916189171891818919189201892118922189231892418925189261892718928189291893018931189321893318934189351893618937189381893918940189411894218943189441894518946189471894818949189501895118952189531895418955189561895718958189591896018961189621896318964189651896618967189681896918970189711897218973189741897518976189771897818979189801898118982189831898418985189861898718988189891899018991189921899318994189951899618997189981899919000190011900219003190041900519006190071900819009190101901119012190131901419015190161901719018190191902019021190221902319024190251902619027190281902919030190311903219033190341903519036190371903819039190401904119042190431904419045190461904719048190491905019051190521905319054190551905619057190581905919060190611906219063190641906519066190671906819069190701907119072190731907419075190761907719078190791908019081190821908319084190851908619087190881908919090190911909219093190941909519096190971909819099191001910119102191031910419105191061910719108191091911019111191121911319114191151911619117191181911919120191211912219123191241912519126191271912819129191301913119132191331913419135191361913719138191391914019141191421914319144191451914619147191481914919150191511915219153191541915519156191571915819159191601916119162191631916419165191661916719168191691917019171191721917319174191751917619177191781917919180191811918219183191841918519186191871918819189191901919119192191931919419195191961919719198191991920019201192021920319204192051920619207192081920919210192111921219213192141921519216192171921819219192201922119222192231922419225192261922719228192291923019231192321923319234192351923619237192381923919240192411924219243192441924519246192471924819249192501925119252192531925419255192561925719258192591926019261192621926319264192651926619267192681926919270192711927219273192741927519276192771927819279192801928119282192831928419285192861928719288192891929019291192921929319294192951929619297192981929919300193011930219303193041930519306193071930819309193101931119312193131931419315193161931719318193191932019321193221932319324193251932619327193281932919330193311933219333193341933519336193371933819339193401934119342193431934419345193461934719348193491935019351193521935319354193551935619357193581935919360193611936219363193641936519366193671936819369193701937119372193731937419375193761937719378193791938019381193821938319384193851938619387193881938919390193911939219393193941939519396193971939819399194001940119402194031940419405194061940719408194091941019411194121941319414194151941619417194181941919420194211942219423194241942519426194271942819429194301943119432194331943419435194361943719438194391944019441194421944319444194451944619447194481944919450194511945219453194541945519456194571945819459194601946119462194631946419465194661946719468194691947019471194721947319474194751947619477194781947919480194811948219483194841948519486194871948819489194901949119492194931949419495194961949719498194991950019501195021950319504195051950619507195081950919510195111951219513195141951519516195171951819519195201952119522195231952419525195261952719528195291953019531195321953319534195351953619537195381953919540195411954219543195441954519546195471954819549195501955119552195531955419555195561955719558195591956019561195621956319564195651956619567195681956919570195711957219573195741957519576195771957819579195801958119582195831958419585195861958719588195891959019591195921959319594195951959619597195981959919600196011960219603196041960519606196071960819609196101961119612196131961419615196161961719618196191962019621196221962319624196251962619627196281962919630196311963219633196341963519636196371963819639196401964119642196431964419645196461964719648196491965019651196521965319654196551965619657196581965919660196611966219663196641966519666196671966819669196701967119672196731967419675196761967719678196791968019681196821968319684196851968619687196881968919690196911969219693196941969519696196971969819699197001970119702197031970419705197061970719708197091971019711197121971319714197151971619717197181971919720197211972219723197241972519726197271972819729197301973119732197331973419735197361973719738197391974019741197421974319744197451974619747197481974919750197511975219753197541975519756197571975819759197601976119762197631976419765197661976719768197691977019771197721977319774197751977619777197781977919780197811978219783197841978519786197871978819789197901979119792197931979419795197961979719798197991980019801198021980319804198051980619807198081980919810198111981219813198141981519816198171981819819198201982119822198231982419825198261982719828198291983019831198321983319834198351983619837198381983919840198411984219843198441984519846198471984819849198501985119852198531985419855198561985719858198591986019861198621986319864198651986619867198681986919870198711987219873198741987519876198771987819879198801988119882198831988419885198861988719888198891989019891198921989319894198951989619897198981989919900199011990219903199041990519906199071990819909199101991119912199131991419915199161991719918199191992019921199221992319924199251992619927199281992919930199311993219933199341993519936199371993819939199401994119942199431994419945199461994719948199491995019951199521995319954199551995619957199581995919960199611996219963199641996519966199671996819969199701997119972199731997419975199761997719978199791998019981199821998319984199851998619987199881998919990199911999219993199941999519996199971999819999200002000120002200032000420005200062000720008200092001020011200122001320014200152001620017200182001920020200212002220023200242002520026200272002820029200302003120032200332003420035200362003720038200392004020041200422004320044200452004620047200482004920050200512005220053200542005520056200572005820059200602006120062200632006420065200662006720068200692007020071200722007320074200752007620077200782007920080200812008220083200842008520086200872008820089200902009120092200932009420095200962009720098200992010020101201022010320104201052010620107201082010920110201112011220113201142011520116201172011820119201202012120122201232012420125201262012720128201292013020131201322013320134201352013620137201382013920140201412014220143201442014520146201472014820149201502015120152201532015420155201562015720158201592016020161201622016320164201652016620167201682016920170201712017220173201742017520176201772017820179201802018120182201832018420185201862018720188201892019020191201922019320194201952019620197201982019920200202012020220203202042020520206202072020820209202102021120212202132021420215202162021720218202192022020221202222022320224202252022620227202282022920230202312023220233202342023520236202372023820239202402024120242202432024420245202462024720248202492025020251202522025320254202552025620257202582025920260202612026220263202642026520266202672026820269202702027120272202732027420275202762027720278202792028020281202822028320284202852028620287202882028920290202912029220293202942029520296202972029820299203002030120302203032030420305203062030720308203092031020311203122031320314203152031620317203182031920320203212032220323203242032520326203272032820329203302033120332203332033420335203362033720338203392034020341203422034320344203452034620347203482034920350203512035220353203542035520356203572035820359203602036120362203632036420365203662036720368203692037020371203722037320374203752037620377203782037920380203812038220383203842038520386203872038820389203902039120392203932039420395203962039720398203992040020401204022040320404204052040620407204082040920410204112041220413204142041520416204172041820419204202042120422204232042420425204262042720428204292043020431204322043320434204352043620437204382043920440204412044220443204442044520446204472044820449204502045120452204532045420455204562045720458204592046020461204622046320464204652046620467204682046920470204712047220473204742047520476204772047820479204802048120482204832048420485204862048720488204892049020491204922049320494204952049620497204982049920500205012050220503205042050520506205072050820509205102051120512205132051420515205162051720518205192052020521205222052320524205252052620527205282052920530205312053220533205342053520536205372053820539205402054120542205432054420545205462054720548205492055020551205522055320554205552055620557205582055920560205612056220563205642056520566205672056820569205702057120572205732057420575205762057720578205792058020581205822058320584205852058620587205882058920590205912059220593205942059520596205972059820599206002060120602206032060420605206062060720608206092061020611206122061320614206152061620617206182061920620206212062220623206242062520626206272062820629206302063120632206332063420635206362063720638206392064020641206422064320644206452064620647206482064920650206512065220653206542065520656206572065820659206602066120662206632066420665206662066720668206692067020671206722067320674206752067620677206782067920680206812068220683206842068520686206872068820689206902069120692206932069420695206962069720698206992070020701207022070320704207052070620707207082070920710207112071220713207142071520716207172071820719207202072120722207232072420725207262072720728207292073020731207322073320734207352073620737207382073920740207412074220743207442074520746207472074820749207502075120752207532075420755207562075720758207592076020761207622076320764207652076620767207682076920770207712077220773207742077520776207772077820779207802078120782207832078420785207862078720788207892079020791207922079320794207952079620797207982079920800208012080220803208042080520806208072080820809208102081120812208132081420815208162081720818208192082020821208222082320824208252082620827208282082920830208312083220833208342083520836208372083820839208402084120842208432084420845208462084720848208492085020851208522085320854208552085620857208582085920860208612086220863208642086520866208672086820869208702087120872208732087420875208762087720878208792088020881208822088320884208852088620887208882088920890208912089220893208942089520896208972089820899209002090120902209032090420905209062090720908209092091020911209122091320914209152091620917209182091920920209212092220923209242092520926209272092820929209302093120932209332093420935209362093720938209392094020941209422094320944209452094620947209482094920950209512095220953209542095520956209572095820959209602096120962209632096420965209662096720968209692097020971209722097320974209752097620977209782097920980209812098220983209842098520986209872098820989209902099120992209932099420995209962099720998209992100021001210022100321004210052100621007210082100921010210112101221013210142101521016210172101821019210202102121022210232102421025210262102721028210292103021031210322103321034210352103621037210382103921040210412104221043210442104521046210472104821049210502105121052210532105421055210562105721058210592106021061210622106321064210652106621067210682106921070210712107221073210742107521076210772107821079210802108121082210832108421085210862108721088210892109021091210922109321094210952109621097210982109921100211012110221103211042110521106211072110821109211102111121112211132111421115211162111721118211192112021121211222112321124211252112621127211282112921130211312113221133211342113521136211372113821139211402114121142211432114421145211462114721148211492115021151211522115321154211552115621157211582115921160211612116221163211642116521166211672116821169211702117121172211732117421175211762117721178211792118021181211822118321184211852118621187211882118921190211912119221193211942119521196211972119821199212002120121202212032120421205212062120721208212092121021211212122121321214212152121621217212182121921220212212122221223212242122521226212272122821229212302123121232212332123421235212362123721238212392124021241212422124321244212452124621247212482124921250212512125221253212542125521256212572125821259212602126121262212632126421265212662126721268212692127021271212722127321274212752127621277212782127921280212812128221283212842128521286212872128821289212902129121292212932129421295212962129721298212992130021301213022130321304213052130621307213082130921310213112131221313213142131521316213172131821319213202132121322213232132421325213262132721328213292133021331213322133321334213352133621337213382133921340213412134221343213442134521346213472134821349213502135121352213532135421355213562135721358213592136021361213622136321364213652136621367213682136921370213712137221373213742137521376213772137821379213802138121382213832138421385213862138721388213892139021391213922139321394213952139621397213982139921400214012140221403214042140521406214072140821409214102141121412214132141421415214162141721418214192142021421214222142321424214252142621427214282142921430214312143221433214342143521436214372143821439214402144121442214432144421445214462144721448214492145021451214522145321454214552145621457214582145921460214612146221463214642146521466214672146821469214702147121472214732147421475214762147721478214792148021481214822148321484214852148621487214882148921490214912149221493214942149521496214972149821499215002150121502215032150421505215062150721508215092151021511215122151321514215152151621517215182151921520215212152221523215242152521526215272152821529215302153121532215332153421535215362153721538215392154021541215422154321544215452154621547215482154921550215512155221553215542155521556215572155821559215602156121562215632156421565215662156721568215692157021571215722157321574215752157621577215782157921580215812158221583215842158521586215872158821589215902159121592215932159421595215962159721598215992160021601216022160321604216052160621607216082160921610216112161221613216142161521616216172161821619216202162121622216232162421625216262162721628216292163021631216322163321634216352163621637216382163921640216412164221643216442164521646216472164821649216502165121652216532165421655216562165721658216592166021661216622166321664216652166621667216682166921670216712167221673216742167521676216772167821679216802168121682216832168421685216862168721688216892169021691216922169321694216952169621697216982169921700217012170221703217042170521706217072170821709217102171121712217132171421715217162171721718217192172021721217222172321724217252172621727217282172921730217312173221733217342173521736217372173821739217402174121742217432174421745217462174721748217492175021751217522175321754217552175621757217582175921760217612176221763217642176521766217672176821769217702177121772217732177421775217762177721778217792178021781217822178321784217852178621787217882178921790217912179221793217942179521796217972179821799218002180121802218032180421805218062180721808218092181021811218122181321814218152181621817218182181921820218212182221823218242182521826218272182821829218302183121832218332183421835218362183721838218392184021841218422184321844218452184621847218482184921850218512185221853218542185521856218572185821859218602186121862218632186421865218662186721868218692187021871218722187321874218752187621877218782187921880218812188221883218842188521886218872188821889218902189121892218932189421895218962189721898218992190021901219022190321904219052190621907219082190921910219112191221913219142191521916219172191821919219202192121922219232192421925219262192721928219292193021931219322193321934219352193621937219382193921940219412194221943219442194521946219472194821949219502195121952219532195421955219562195721958219592196021961219622196321964219652196621967219682196921970219712197221973219742197521976219772197821979219802198121982219832198421985219862198721988219892199021991219922199321994219952199621997219982199922000220012200222003220042200522006220072200822009220102201122012220132201422015220162201722018220192202022021220222202322024220252202622027220282202922030220312203222033220342203522036220372203822039220402204122042220432204422045220462204722048220492205022051220522205322054220552205622057220582205922060220612206222063220642206522066220672206822069220702207122072220732207422075220762207722078220792208022081220822208322084220852208622087220882208922090220912209222093220942209522096220972209822099221002210122102221032210422105221062210722108221092211022111221122211322114221152211622117221182211922120221212212222123221242212522126221272212822129221302213122132221332213422135221362213722138221392214022141221422214322144221452214622147221482214922150221512215222153221542215522156221572215822159221602216122162221632216422165221662216722168221692217022171221722217322174221752217622177221782217922180221812218222183221842218522186221872218822189221902219122192221932219422195221962219722198221992220022201222022220322204222052220622207222082220922210222112221222213222142221522216222172221822219222202222122222222232222422225222262222722228222292223022231222322223322234222352223622237222382223922240222412224222243222442224522246222472224822249222502225122252222532225422255222562225722258222592226022261222622226322264222652226622267222682226922270222712227222273222742227522276222772227822279222802228122282222832228422285222862228722288222892229022291222922229322294222952229622297222982229922300223012230222303223042230522306223072230822309223102231122312223132231422315223162231722318223192232022321223222232322324223252232622327223282232922330223312233222333223342233522336223372233822339223402234122342223432234422345223462234722348223492235022351223522235322354223552235622357223582235922360223612236222363223642236522366223672236822369223702237122372223732237422375223762237722378223792238022381223822238322384223852238622387223882238922390223912239222393223942239522396223972239822399224002240122402224032240422405224062240722408224092241022411224122241322414224152241622417224182241922420224212242222423224242242522426224272242822429224302243122432224332243422435224362243722438224392244022441224422244322444224452244622447224482244922450224512245222453224542245522456224572245822459224602246122462224632246422465224662246722468224692247022471224722247322474224752247622477224782247922480224812248222483224842248522486224872248822489224902249122492224932249422495224962249722498224992250022501225022250322504225052250622507225082250922510225112251222513225142251522516225172251822519225202252122522225232252422525225262252722528225292253022531225322253322534225352253622537225382253922540225412254222543225442254522546225472254822549225502255122552225532255422555225562255722558225592256022561225622256322564225652256622567225682256922570225712257222573225742257522576225772257822579225802258122582225832258422585225862258722588225892259022591225922259322594225952259622597225982259922600226012260222603226042260522606226072260822609226102261122612226132261422615226162261722618226192262022621226222262322624226252262622627226282262922630226312263222633226342263522636226372263822639226402264122642226432264422645226462264722648226492265022651226522265322654226552265622657226582265922660226612266222663226642266522666226672266822669226702267122672226732267422675226762267722678
  1. (function (global, factory) {
  2. typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
  3. typeof define === 'function' && define.amd ? define(['exports'], factory) :
  4. (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.F2 = {}));
  5. }(this, (function (exports) { 'use strict';
  6. var isArrayLike = function (value) {
  7. /**
  8. * isArrayLike([1, 2, 3]) => true
  9. * isArrayLike(document.body.children) => true
  10. * isArrayLike('abc') => true
  11. * isArrayLike(Function) => false
  12. */
  13. return value !== null && typeof value !== 'function' && isFinite(value.length);
  14. };
  15. var contains = function (arr, value) {
  16. if (!isArrayLike(arr)) {
  17. return false;
  18. }
  19. return arr.indexOf(value) > -1;
  20. };
  21. var filter = function (arr, func) {
  22. if (!isArrayLike(arr)) {
  23. return arr;
  24. }
  25. var result = [];
  26. for (var index = 0; index < arr.length; index++) {
  27. var value = arr[index];
  28. if (func(value, index)) {
  29. result.push(value);
  30. }
  31. }
  32. return result;
  33. };
  34. var toString = {}.toString;
  35. var isType = function (value, type) {
  36. return toString.call(value) === '[object ' + type + ']';
  37. };
  38. /**
  39. * 是否为函数
  40. * @param {*} fn 对象
  41. * @return {Boolean} 是否函数
  42. */
  43. var isFunction = (function (value) {
  44. return isType(value, 'Function');
  45. });
  46. // isFinite,
  47. var isNil = function (value) {
  48. /**
  49. * isNil(null) => true
  50. * isNil() => true
  51. */
  52. return value === null || value === undefined;
  53. };
  54. var isArray = (function (value) {
  55. return Array.isArray ? Array.isArray(value) : isType(value, 'Array');
  56. });
  57. var isObject = (function (value) {
  58. /**
  59. * isObject({}) => true
  60. * isObject([1, 2, 3]) => true
  61. * isObject(Function) => true
  62. * isObject(null) => false
  63. */
  64. var type = typeof value;
  65. return value !== null && type === 'object' || type === 'function';
  66. });
  67. function each(elements, func) {
  68. if (!elements) {
  69. return;
  70. }
  71. var rst;
  72. if (isArray(elements)) {
  73. for (var i = 0, len = elements.length; i < len; i++) {
  74. rst = func(elements[i], i);
  75. if (rst === false) {
  76. break;
  77. }
  78. }
  79. } else if (isObject(elements)) {
  80. for (var k in elements) {
  81. if (elements.hasOwnProperty(k)) {
  82. rst = func(elements[k], k);
  83. if (rst === false) {
  84. break;
  85. }
  86. }
  87. }
  88. }
  89. }
  90. var keys = Object.keys ? function (obj) {
  91. return Object.keys(obj);
  92. } : function (obj) {
  93. var result = [];
  94. each(obj, function (value, key) {
  95. if (!(isFunction(obj) && key === 'prototype')) {
  96. result.push(key);
  97. }
  98. });
  99. return result;
  100. };
  101. function isMatch(obj, attrs) {
  102. var _keys = keys(attrs);
  103. var length = _keys.length;
  104. if (isNil(obj)) return !length;
  105. for (var i = 0; i < length; i += 1) {
  106. var key = _keys[i];
  107. if (attrs[key] !== obj[key] || !(key in obj)) {
  108. return false;
  109. }
  110. }
  111. return true;
  112. }
  113. var isObjectLike = function (value) {
  114. /**
  115. * isObjectLike({}) => true
  116. * isObjectLike([1, 2, 3]) => true
  117. * isObjectLike(Function) => false
  118. * isObjectLike(null) => false
  119. */
  120. return typeof value === 'object' && value !== null;
  121. };
  122. var isPlainObject = function (value) {
  123. /**
  124. * isObjectLike(new Foo) => false
  125. * isObjectLike([1, 2, 3]) => false
  126. * isObjectLike({ x: 0, y: 0 }) => true
  127. * isObjectLike(Object.create(null)) => true
  128. */
  129. if (!isObjectLike(value) || !isType(value, 'Object')) {
  130. return false;
  131. }
  132. if (Object.getPrototypeOf(value) === null) {
  133. return true;
  134. }
  135. var proto = value;
  136. while (Object.getPrototypeOf(proto) !== null) {
  137. proto = Object.getPrototypeOf(proto);
  138. }
  139. return Object.getPrototypeOf(value) === proto;
  140. };
  141. function find(arr, predicate) {
  142. if (!isArray(arr)) return null;
  143. var _predicate;
  144. if (isFunction(predicate)) {
  145. _predicate = predicate;
  146. }
  147. if (isPlainObject(predicate)) {
  148. _predicate = function (a) {
  149. return isMatch(a, predicate);
  150. };
  151. }
  152. if (_predicate) {
  153. for (var i = 0; i < arr.length; i += 1) {
  154. if (_predicate(arr[i])) {
  155. return arr[i];
  156. }
  157. }
  158. }
  159. return null;
  160. }
  161. var getRange = function (values) {
  162. // 存在 NaN 时,min,max 判定会出问题
  163. var filterValues = values.filter(function (v) {
  164. return !isNaN(v);
  165. });
  166. if (!filterValues.length) {
  167. // 如果没有数值则直接返回0
  168. return {
  169. min: 0,
  170. max: 0
  171. };
  172. }
  173. if (isArray(values[0])) {
  174. var tmp = [];
  175. for (var i = 0; i < values.length; i++) {
  176. tmp = tmp.concat(values[i]);
  177. }
  178. filterValues = tmp;
  179. }
  180. var max = Math.max.apply(null, filterValues);
  181. var min = Math.min.apply(null, filterValues);
  182. return {
  183. min: min,
  184. max: max
  185. };
  186. };
  187. var isString = (function (str) {
  188. return isType(str, 'String');
  189. });
  190. var uniq = function (arr) {
  191. var resultArr = [];
  192. each(arr, function (item) {
  193. if (!contains(resultArr, item)) {
  194. resultArr.push(item);
  195. }
  196. });
  197. return resultArr;
  198. };
  199. function head(o) {
  200. if (isArrayLike(o)) {
  201. return o[0];
  202. }
  203. return undefined;
  204. }
  205. function last(o) {
  206. if (isArrayLike(o)) {
  207. var arr = o;
  208. return arr[arr.length - 1];
  209. }
  210. return undefined;
  211. }
  212. var fixedBase = function (v, base) {
  213. var str = base.toString();
  214. var index = str.indexOf('.');
  215. if (index === -1) {
  216. return Math.round(v);
  217. }
  218. var length = str.substr(index + 1).length;
  219. if (length > 20) {
  220. length = 20;
  221. }
  222. return parseFloat(v.toFixed(length));
  223. };
  224. /**
  225. * 判断是否数字
  226. * @return {Boolean} 是否数字
  227. */
  228. var isNumber = function (value) {
  229. return isType(value, 'Number');
  230. };
  231. var toString$1 = (function (value) {
  232. if (isNil(value)) return '';
  233. return value.toString();
  234. });
  235. var lowerFirst = function (value) {
  236. var str = toString$1(value);
  237. return str.charAt(0).toLowerCase() + str.substring(1);
  238. };
  239. function substitute(str, o) {
  240. if (!str || !o) {
  241. return str;
  242. }
  243. return str.replace(/\\?\{([^{}]+)\}/g, function (match, name) {
  244. if (match.charAt(0) === '\\') {
  245. return match.slice(1);
  246. }
  247. return o[name] === undefined ? '' : o[name];
  248. });
  249. }
  250. var upperFirst = function (value) {
  251. var str = toString$1(value);
  252. return str.charAt(0).toUpperCase() + str.substring(1);
  253. };
  254. var toString$2 = {}.toString;
  255. var getType = function (value) {
  256. return toString$2.call(value).replace(/^\[object /, '').replace(/]$/, '');
  257. };
  258. /**
  259. * 是否是布尔类型
  260. *
  261. * @param {Object} value 测试的值
  262. * @return {Boolean}
  263. */
  264. var isBoolean = function (value) {
  265. return isType(value, 'Boolean');
  266. };
  267. var isDate = function (value) {
  268. return isType(value, 'Date');
  269. };
  270. var objectProto = Object.prototype;
  271. var isPrototype = function (value) {
  272. var Ctor = value && value.constructor;
  273. var proto = typeof Ctor === 'function' && Ctor.prototype || objectProto;
  274. return value === proto;
  275. };
  276. // FIXME: Mutable param should be forbidden in static lang.
  277. function _mix(dist, obj) {
  278. for (var key in obj) {
  279. if (obj.hasOwnProperty(key) && key !== 'constructor' && obj[key] !== undefined) {
  280. dist[key] = obj[key];
  281. }
  282. }
  283. }
  284. function mix(dist, src1, src2, src3) {
  285. if (src1) _mix(dist, src1);
  286. if (src2) _mix(dist, src2);
  287. if (src3) _mix(dist, src3);
  288. return dist;
  289. }
  290. var MAX_MIX_LEVEL = 5;
  291. function _deepMix(dist, src, level, maxLevel) {
  292. level = level || 0;
  293. maxLevel = maxLevel || MAX_MIX_LEVEL;
  294. for (var key in src) {
  295. if (src.hasOwnProperty(key)) {
  296. var value = src[key];
  297. if (value !== null && isPlainObject(value)) {
  298. if (!isPlainObject(dist[key])) {
  299. dist[key] = {};
  300. }
  301. if (level < maxLevel) {
  302. _deepMix(dist[key], value, level + 1, maxLevel);
  303. } else {
  304. dist[key] = src[key];
  305. }
  306. } else if (isArray(value)) {
  307. dist[key] = [];
  308. dist[key] = dist[key].concat(value);
  309. } else if (value !== undefined) {
  310. dist[key] = value;
  311. }
  312. }
  313. }
  314. } // todo 重写
  315. var deepMix = function (rst) {
  316. var args = [];
  317. for (var _i = 1; _i < arguments.length; _i++) {
  318. args[_i - 1] = arguments[_i];
  319. }
  320. for (var i = 0; i < args.length; i += 1) {
  321. _deepMix(rst, args[i]);
  322. }
  323. return rst;
  324. };
  325. var indexOf = function (arr, obj) {
  326. if (!isArrayLike(arr)) {
  327. return -1;
  328. }
  329. var m = Array.prototype.indexOf;
  330. if (m) {
  331. return m.call(arr, obj);
  332. }
  333. var index = -1;
  334. for (var i = 0; i < arr.length; i++) {
  335. if (arr[i] === obj) {
  336. index = i;
  337. break;
  338. }
  339. }
  340. return index;
  341. };
  342. var hasOwnProperty = Object.prototype.hasOwnProperty;
  343. function isEmpty(value) {
  344. /**
  345. * isEmpty(null) => true
  346. * isEmpty() => true
  347. * isEmpty(true) => true
  348. * isEmpty(1) => true
  349. * isEmpty([1, 2, 3]) => false
  350. * isEmpty('abc') => false
  351. * isEmpty({ a: 1 }) => false
  352. */
  353. if (isNil(value)) {
  354. return true;
  355. }
  356. if (isArrayLike(value)) {
  357. return !value.length;
  358. }
  359. var type = getType(value);
  360. if (type === 'Map' || type === 'Set') {
  361. return !value.size;
  362. }
  363. if (isPrototype(value)) {
  364. return !Object.keys(value).length;
  365. }
  366. for (var key in value) {
  367. if (hasOwnProperty.call(value, key)) {
  368. return false;
  369. }
  370. }
  371. return true;
  372. }
  373. var isEqual = function (value, other) {
  374. if (value === other) {
  375. return true;
  376. }
  377. if (!value || !other) {
  378. return false;
  379. }
  380. if (isString(value) || isString(other)) {
  381. return false;
  382. }
  383. if (isArrayLike(value) || isArrayLike(other)) {
  384. if (value.length !== other.length) {
  385. return false;
  386. }
  387. var rst = true;
  388. for (var i = 0; i < value.length; i++) {
  389. rst = isEqual(value[i], other[i]);
  390. if (!rst) {
  391. break;
  392. }
  393. }
  394. return rst;
  395. }
  396. if (isObjectLike(value) || isObjectLike(other)) {
  397. var valueKeys = Object.keys(value);
  398. var otherKeys = Object.keys(other);
  399. if (valueKeys.length !== otherKeys.length) {
  400. return false;
  401. }
  402. var rst = true;
  403. for (var i = 0; i < valueKeys.length; i++) {
  404. rst = isEqual(value[valueKeys[i]], other[valueKeys[i]]);
  405. if (!rst) {
  406. break;
  407. }
  408. }
  409. return rst;
  410. }
  411. return false;
  412. };
  413. var map = function (arr, func) {
  414. if (!isArrayLike(arr)) {
  415. // @ts-ignore
  416. return arr;
  417. }
  418. var result = [];
  419. for (var index = 0; index < arr.length; index++) {
  420. var value = arr[index];
  421. result.push(func(value, index));
  422. }
  423. return result;
  424. };
  425. function size(o) {
  426. if (isNil(o)) {
  427. return 0;
  428. }
  429. if (isArrayLike(o)) {
  430. return o.length;
  431. }
  432. return Object.keys(o).length;
  433. }
  434. function merge(dataArray) {
  435. var rst = [];
  436. for (var i = 0, len = dataArray.length; i < len; i++) {
  437. rst = rst.concat(dataArray[i]);
  438. }
  439. return rst;
  440. }
  441. function values(data, name) {
  442. var rst = [];
  443. var tmpMap = {};
  444. for (var i = 0, len = data.length; i < len; i++) {
  445. var obj = data[i];
  446. var value = obj[name];
  447. if (!isNil(value)) {
  448. if (!isArray(value)) {
  449. if (!tmpMap[value]) {
  450. rst.push(value);
  451. tmpMap[value] = true;
  452. }
  453. } else {
  454. each(value, function (val) {
  455. if (!tmpMap[val]) {
  456. rst.push(val);
  457. tmpMap[val] = true;
  458. }
  459. });
  460. }
  461. }
  462. }
  463. return rst;
  464. }
  465. function firstValue(data, name) {
  466. var rst = null;
  467. for (var i = 0, len = data.length; i < len; i++) {
  468. var obj = data[i];
  469. var value = obj[name];
  470. if (!isNil(value)) {
  471. if (isArray(value)) {
  472. rst = value[0];
  473. } else {
  474. rst = value;
  475. }
  476. break;
  477. }
  478. }
  479. return rst;
  480. }
  481. function groupToMap(data, fields) {
  482. if (!fields) {
  483. return {
  484. 0: data
  485. };
  486. }
  487. var callback = function callback(row) {
  488. var unique = '_';
  489. for (var i = 0, l = fields.length; i < l; i++) {
  490. unique += row[fields[i]] && row[fields[i]].toString();
  491. }
  492. return unique;
  493. };
  494. var groups = {};
  495. for (var i = 0, len = data.length; i < len; i++) {
  496. var row = data[i];
  497. var key = callback(row);
  498. if (groups[key]) {
  499. groups[key].push(row);
  500. } else {
  501. groups[key] = [row];
  502. }
  503. }
  504. return groups;
  505. }
  506. function group(data, fields, appendConditions) {
  507. if (appendConditions === void 0) {
  508. appendConditions = {};
  509. }
  510. if (!fields) {
  511. return [data];
  512. }
  513. var groups = groupToMap(data, fields);
  514. var array = [];
  515. if (fields.length === 1 && appendConditions[fields[0]]) {
  516. var _values = appendConditions[fields[0]];
  517. each(_values, function (value) {
  518. value = '_' + value;
  519. array.push(groups[value]);
  520. });
  521. } else {
  522. for (var i in groups) {
  523. array.push(groups[i]);
  524. }
  525. }
  526. return array;
  527. }
  528. function remove(arr, obj) {
  529. if (!arr) {
  530. return;
  531. }
  532. var index = arr.indexOf(obj);
  533. if (index !== -1) {
  534. arr.splice(index, 1);
  535. }
  536. }
  537. function getRange$1(values) {
  538. if (!values.length) {
  539. return {
  540. min: 0,
  541. max: 0
  542. };
  543. }
  544. var max = Math.max.apply(null, values);
  545. var min = Math.min.apply(null, values);
  546. return {
  547. min: min,
  548. max: max
  549. };
  550. }
  551. var array = /*#__PURE__*/Object.freeze({
  552. __proto__: null,
  553. merge: merge,
  554. values: values,
  555. firstValue: firstValue,
  556. group: group,
  557. groupToMap: groupToMap,
  558. remove: remove,
  559. getRange: getRange$1
  560. });
  561. /**
  562. * Detects support for options object argument in addEventListener.
  563. * https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#Safely_detecting_option_support
  564. * @private
  565. */
  566. var supportsEventListenerOptions = function () {
  567. var supports = false;
  568. try {
  569. var options = Object.defineProperty({}, 'passive', {
  570. get: function get() {
  571. supports = true;
  572. }
  573. });
  574. window.addEventListener('e', null, options);
  575. } catch (e) {// continue regardless of error
  576. }
  577. return supports;
  578. }(); // Default passive to true as expected by Chrome for 'touchstart' and 'touchend' events.
  579. // https://github.com/chartjs/Chart.js/issues/4287
  580. var eventListenerOptions = supportsEventListenerOptions ? {
  581. passive: true
  582. } : false;
  583. /* global wx, my */
  584. // weixin miniprogram
  585. var isWx = typeof wx === 'object' && typeof wx.getSystemInfoSync === 'function'; // ant miniprogram
  586. var isMy = typeof my === 'object' && typeof my.getSystemInfoSync === 'function'; // in node
  587. var isNode = typeof global && !typeof window; // in browser
  588. var isBrowser = typeof window !== 'undefined' && typeof window.document !== 'undefined' && typeof window.sessionStorage !== 'undefined';
  589. function isCanvasElement(el) {
  590. if (!el || typeof el !== 'object') return false;
  591. if (el.nodeType === 1 && el.nodeName) {
  592. // HTMLCanvasElement
  593. return true;
  594. } // CanvasElement
  595. return !!el.isCanvasElement;
  596. }
  597. function getPixelRatio() {
  598. return window && window.devicePixelRatio || 1;
  599. }
  600. function getStyle(el, property) {
  601. return el.currentStyle ? el.currentStyle[property] : document.defaultView.getComputedStyle(el, null).getPropertyValue(property);
  602. }
  603. function getWidth(el) {
  604. var width = getStyle(el, 'width');
  605. if (width === 'auto') {
  606. width = el.offsetWidth;
  607. }
  608. return parseFloat(width);
  609. }
  610. function getHeight(el) {
  611. var height = getStyle(el, 'height');
  612. if (height === 'auto') {
  613. height = el.offsetHeight;
  614. }
  615. return parseFloat(height);
  616. }
  617. function getDomById(id) {
  618. if (!id) {
  619. return null;
  620. }
  621. return document.getElementById(id);
  622. }
  623. function getRelativePosition(point, canvas) {
  624. var canvasDom = canvas.get('el');
  625. if (!canvasDom) return point;
  626. var _canvasDom$getBoundin = canvasDom.getBoundingClientRect(),
  627. top = _canvasDom$getBoundin.top,
  628. left = _canvasDom$getBoundin.left;
  629. var paddingLeft = parseFloat(getStyle(canvasDom, 'padding-left'));
  630. var paddingTop = parseFloat(getStyle(canvasDom, 'padding-top'));
  631. var mouseX = point.x - left - paddingLeft;
  632. var mouseY = point.y - top - paddingTop;
  633. return {
  634. x: mouseX,
  635. y: mouseY
  636. };
  637. }
  638. function addEventListener(source, type, listener) {
  639. source.addEventListener(type, listener, eventListenerOptions);
  640. }
  641. function removeEventListener(source, type, listener) {
  642. source.removeEventListener(type, listener, eventListenerOptions);
  643. }
  644. function landscapePoint(point, canvas) {
  645. var landscape = canvas.get('landscape');
  646. if (!landscape) {
  647. return point;
  648. }
  649. if (isFunction(landscape)) {
  650. return landscape(point, canvas);
  651. } // 默认顺时针旋转90度
  652. var height = canvas.get('height');
  653. var x = point.y;
  654. var y = height - point.x;
  655. return {
  656. x: x,
  657. y: y
  658. };
  659. }
  660. function convertPoints(ev, canvas) {
  661. var touches = ev.touches; // 认为是mouse事件
  662. if (!touches) {
  663. var point = getRelativePosition({
  664. x: ev.clientX,
  665. y: ev.clientY
  666. }, canvas);
  667. return [landscapePoint(point, canvas)];
  668. } // 单指 touchend 后,touchs 会变空,最后的触点要从changedTouches里拿
  669. if (!touches.length) {
  670. // 为了防止万一,加个空逻辑
  671. touches = ev.changedTouches || [];
  672. }
  673. var points = [];
  674. for (var i = 0, len = touches.length; i < len; i++) {
  675. var touch = touches[i]; // x, y: 相对canvas原点的位置,clientX, clientY 相对于可视窗口的位置
  676. var x = touch.x,
  677. y = touch.y,
  678. clientX = touch.clientX,
  679. clientY = touch.clientY;
  680. var _point = void 0; // 小程序环境会有x,y
  681. if (isNumber(x) || isNumber(y)) {
  682. _point = {
  683. x: x,
  684. y: y
  685. };
  686. } else {
  687. // 浏览器环境再计算下canvas的相对位置
  688. _point = getRelativePosition({
  689. x: clientX,
  690. y: clientY
  691. }, canvas);
  692. }
  693. points.push(landscapePoint(_point, canvas));
  694. }
  695. return points;
  696. }
  697. function createEvent(event, chart) {
  698. var canvas = chart.get('canvas');
  699. var points = convertPoints(event, canvas); // touchend会没有points
  700. var point = points[0] || {};
  701. return {
  702. type: event.type,
  703. chart: chart,
  704. "native": event,
  705. x: point.x,
  706. y: point.y
  707. };
  708. }
  709. function measureText(text, font, ctx) {
  710. if (!ctx) {
  711. ctx = document.createElement('canvas').getContext('2d');
  712. }
  713. ctx.font = font || '12px sans-serif';
  714. return ctx.measureText(text);
  715. }
  716. /**
  717. * @fileOverview Utility for F2
  718. * @author dxq613 @gmail.com
  719. * @author sima.zhang1990@gmail.com
  720. */
  721. function isObjectValueEqual(a, b) {
  722. // for vue.js
  723. a = Object.assign({}, a);
  724. b = Object.assign({}, b);
  725. var aProps = Object.getOwnPropertyNames(a);
  726. var bProps = Object.getOwnPropertyNames(b);
  727. if (aProps.length !== bProps.length) {
  728. return false;
  729. }
  730. for (var i = 0, len = aProps.length; i < len; i++) {
  731. var propName = aProps[i];
  732. if (a[propName] !== b[propName]) {
  733. return false;
  734. }
  735. }
  736. return true;
  737. }
  738. function parsePadding(padding) {
  739. var top;
  740. var right;
  741. var bottom;
  742. var left;
  743. if (isNumber(padding) || isString(padding)) {
  744. top = bottom = left = right = padding;
  745. } else if (isArray(padding)) {
  746. top = padding[0];
  747. right = !isNil(padding[1]) ? padding[1] : padding[0];
  748. bottom = !isNil(padding[2]) ? padding[2] : padding[0];
  749. left = !isNil(padding[3]) ? padding[3] : right;
  750. }
  751. return [top, right, bottom, left];
  752. }
  753. function directionEnabled(mode, dir) {
  754. if (mode === undefined) {
  755. return true;
  756. } else if (typeof mode === 'string') {
  757. return mode.indexOf(dir) !== -1;
  758. }
  759. return false;
  760. }
  761. function toTimeStamp(value) {
  762. if (isString(value)) {
  763. if (value.indexOf('T') > 0) {
  764. value = new Date(value).getTime();
  765. } else {
  766. // new Date('2010/01/10') 和 new Date('2010-01-10') 的差别在于:
  767. // 如果仅有年月日时,前者是带有时区的: Fri Jan 10 2020 02:40:13 GMT+0800 (中国标准时间)
  768. // 后者会格式化成 Sun Jan 10 2010 08:00:00 GMT+0800 (中国标准时间)
  769. value = new Date(value.replace(/-/gi, '/')).getTime();
  770. }
  771. }
  772. if (isDate(value)) {
  773. value = value.getTime();
  774. }
  775. return value;
  776. }
  777. var Util = /*#__PURE__*/Object.freeze({
  778. __proto__: null,
  779. Array: array,
  780. upperFirst: upperFirst,
  781. lowerFirst: lowerFirst,
  782. isString: isString,
  783. isNumber: isNumber,
  784. isBoolean: isBoolean,
  785. isFunction: isFunction,
  786. isDate: isDate,
  787. isArray: isArray,
  788. isNil: isNil,
  789. isObject: isObject,
  790. isPlainObject: isPlainObject,
  791. isEqual: isEqual,
  792. deepMix: deepMix,
  793. mix: mix,
  794. each: each,
  795. uniq: uniq,
  796. find: find,
  797. isObjectValueEqual: isObjectValueEqual,
  798. parsePadding: parsePadding,
  799. directionEnabled: directionEnabled,
  800. toTimeStamp: toTimeStamp,
  801. substitute: substitute,
  802. isWx: isWx,
  803. isMy: isMy,
  804. isNode: isNode,
  805. isBrowser: isBrowser,
  806. isCanvasElement: isCanvasElement,
  807. getPixelRatio: getPixelRatio,
  808. getStyle: getStyle,
  809. getWidth: getWidth,
  810. getHeight: getHeight,
  811. getDomById: getDomById,
  812. getRelativePosition: getRelativePosition,
  813. addEventListener: addEventListener,
  814. removeEventListener: removeEventListener,
  815. createEvent: createEvent,
  816. convertPoints: convertPoints,
  817. measureText: measureText
  818. });
  819. /**
  820. * @fileOverview default theme
  821. * @author dxq613@gail.com
  822. */
  823. var color1 = '#E8E8E8'; // color of axis-line and axis-grid
  824. var color2 = '#808080'; // color of axis label
  825. var defaultAxis = {
  826. label: {
  827. fill: color2,
  828. fontSize: 10
  829. },
  830. line: {
  831. stroke: color1,
  832. lineWidth: 1
  833. },
  834. grid: {
  835. type: 'line',
  836. stroke: color1,
  837. lineWidth: 1,
  838. lineDash: [2]
  839. },
  840. tickLine: null,
  841. labelOffset: 7.5
  842. };
  843. var Theme = {
  844. fontFamily: '"Helvetica Neue", "San Francisco", Helvetica, Tahoma, Arial, "PingFang SC", "Hiragino Sans GB", "Heiti SC", "Microsoft YaHei", sans-serif',
  845. defaultColor: '#1890FF',
  846. pixelRatio: 1,
  847. padding: 'auto',
  848. appendPadding: 15,
  849. colors: ['#1890FF', '#2FC25B', '#FACC14', '#223273', '#8543E0', '#13C2C2', '#3436C7', '#F04864'],
  850. shapes: {
  851. line: ['line', 'dash'],
  852. point: ['circle', 'hollowCircle']
  853. },
  854. sizes: [4, 10],
  855. axis: {
  856. common: defaultAxis,
  857. // common axis configuration
  858. bottom: mix({}, defaultAxis, {
  859. grid: null
  860. }),
  861. left: mix({}, defaultAxis, {
  862. line: null
  863. }),
  864. right: mix({}, defaultAxis, {
  865. line: null
  866. }),
  867. circle: mix({}, defaultAxis, {
  868. line: null
  869. }),
  870. radius: mix({}, defaultAxis, {
  871. labelOffset: 4
  872. })
  873. },
  874. shape: {
  875. line: {
  876. lineWidth: 2,
  877. lineJoin: 'round',
  878. lineCap: 'round'
  879. },
  880. point: {
  881. lineWidth: 0,
  882. size: 3
  883. },
  884. area: {
  885. fillOpacity: 0.1
  886. }
  887. },
  888. _defaultAxis: defaultAxis
  889. };
  890. var lang = {
  891. general: {
  892. title: '这是一个图表,',
  893. withTitle: '这是一个关于“{title}”的图表。'
  894. },
  895. coord: {
  896. cartesian: 'X轴是{xLabel}Y轴是{yLabel}' // polar: '弧度是{xLabel}半径是{yLabel}'
  897. },
  898. scale: {
  899. linear: '数值型,数据最小值为{min},最大值为{max};',
  900. cat: '分类型, 分类类型有:{values};',
  901. timeCat: '时间型,时间范围从{start}到{end};'
  902. },
  903. geometry: {
  904. prefix: '共有{count}种分类组成,',
  905. oneData: '第{index}类是{name},数据是{values};',
  906. partData: '第{index}类是{name},共有{count}项数据,前{part}项是{values};',
  907. allData: '第{index}类是{name},有{count}项数据,分别是{values};'
  908. },
  909. legend: {
  910. prefix: '图例分类有:'
  911. }
  912. };
  913. var Global = {
  914. version: '3.8.9',
  915. scales: {},
  916. widthRatio: {
  917. column: 1 / 2,
  918. rose: 0.999999,
  919. multiplePie: 3 / 4
  920. },
  921. lineDash: [4, 4],
  922. lang: lang
  923. };
  924. Global.setTheme = function (theme) {
  925. deepMix(Global, theme);
  926. };
  927. Global.setTheme(Theme);
  928. function _defineProperty(obj, key, value) {
  929. if (key in obj) {
  930. Object.defineProperty(obj, key, {
  931. value: value,
  932. enumerable: true,
  933. configurable: true,
  934. writable: true
  935. });
  936. } else {
  937. obj[key] = value;
  938. }
  939. return obj;
  940. }
  941. function _extends() {
  942. _extends = Object.assign || function (target) {
  943. for (var i = 1; i < arguments.length; i++) {
  944. var source = arguments[i];
  945. for (var key in source) {
  946. if (Object.prototype.hasOwnProperty.call(source, key)) {
  947. target[key] = source[key];
  948. }
  949. }
  950. }
  951. return target;
  952. };
  953. return _extends.apply(this, arguments);
  954. }
  955. function _inheritsLoose(subClass, superClass) {
  956. subClass.prototype = Object.create(superClass.prototype);
  957. subClass.prototype.constructor = subClass;
  958. subClass.__proto__ = superClass;
  959. }
  960. function _assertThisInitialized(self) {
  961. if (self === void 0) {
  962. throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
  963. }
  964. return self;
  965. }
  966. var EVENT_AFTER_INIT = 'afterinit';
  967. var EVENT_BEFORE_RENDER = 'beforerender';
  968. var EVENT_AFTER_RENDER = 'afterrender';
  969. var EVENT_BEFORE_DATA_CHANGE = 'beforedatachange';
  970. var EVENT_AFTER_DATA_CHANGE = 'afterdatachange';
  971. var EVENT_AFTER_SIZE_CHANGE = '_aftersizechange';
  972. var EVENT_AFTER_GEOM_INIT = '_aftergeominit';
  973. var EVENT_BEFORE_GEOM_DRAW = 'beforegeomdraw';
  974. var EVENT_AFTER_GEOM_DRAW = 'aftergeomdraw';
  975. var EVENT_CLEAR = 'clear';
  976. var EVENT_CLEAR_INNER = 'clearinner';
  977. var EVENT_REPAINT = 'repaint';
  978. // 实现简单的事件机制
  979. var EventEmit = /*#__PURE__*/function () {
  980. function EventEmit() {
  981. this.__events = {};
  982. }
  983. var _proto = EventEmit.prototype;
  984. _proto.on = function on(type, listener) {
  985. if (!type || !listener) {
  986. return;
  987. }
  988. var events = this.__events[type] || [];
  989. events.push(listener);
  990. this.__events[type] = events;
  991. };
  992. _proto.emit = function emit(type, e) {
  993. var _this = this;
  994. if (isObject(type)) {
  995. e = type;
  996. type = e && e.type;
  997. }
  998. if (!type) {
  999. return;
  1000. }
  1001. var events = this.__events[type];
  1002. if (!events || !events.length) {
  1003. return;
  1004. }
  1005. events.forEach(function (listener) {
  1006. listener.call(_this, e);
  1007. });
  1008. };
  1009. _proto.off = function off(type, listener) {
  1010. var __events = this.__events;
  1011. var events = __events[type];
  1012. if (!events || !events.length) {
  1013. return;
  1014. } // 如果没有指定方法,则删除所有项
  1015. if (!listener) {
  1016. delete __events[type];
  1017. return;
  1018. } // 删除指定的 listener
  1019. for (var i = 0, len = events.length; i < len; i++) {
  1020. if (events[i] === listener) {
  1021. events.splice(i, 1);
  1022. i--;
  1023. }
  1024. }
  1025. };
  1026. return EventEmit;
  1027. }();
  1028. var Base = /*#__PURE__*/function (_Emit) {
  1029. _inheritsLoose(Base, _Emit);
  1030. var _proto = Base.prototype;
  1031. _proto.getDefaultCfg = function getDefaultCfg() {
  1032. return {};
  1033. };
  1034. function Base(cfg) {
  1035. var _this;
  1036. _this = _Emit.call(this) || this;
  1037. var attrs = {};
  1038. var defaultCfg = _this.getDefaultCfg();
  1039. _this._attrs = attrs;
  1040. mix(attrs, defaultCfg, cfg);
  1041. return _this;
  1042. }
  1043. _proto.get = function get(name) {
  1044. return this._attrs[name];
  1045. };
  1046. _proto.set = function set(name, value) {
  1047. this._attrs[name] = value;
  1048. };
  1049. _proto.destroy = function destroy() {
  1050. this._attrs = {};
  1051. this.destroyed = true;
  1052. };
  1053. return Base;
  1054. }(EventEmit);
  1055. var Plot = /*#__PURE__*/function () {
  1056. function Plot(cfg) {
  1057. mix(this, cfg);
  1058. this._init();
  1059. }
  1060. var _proto = Plot.prototype;
  1061. _proto._init = function _init() {
  1062. var self = this;
  1063. var start = self.start;
  1064. var end = self.end;
  1065. var xMin = Math.min(start.x, end.x);
  1066. var xMax = Math.max(start.x, end.x);
  1067. var yMin = Math.min(start.y, end.y);
  1068. var yMax = Math.max(start.y, end.y);
  1069. this.tl = {
  1070. x: xMin,
  1071. y: yMin
  1072. };
  1073. this.tr = {
  1074. x: xMax,
  1075. y: yMin
  1076. };
  1077. this.bl = {
  1078. x: xMin,
  1079. y: yMax
  1080. };
  1081. this.br = {
  1082. x: xMax,
  1083. y: yMax
  1084. };
  1085. this.width = xMax - xMin;
  1086. this.height = yMax - yMin;
  1087. }
  1088. /**
  1089. * reset
  1090. * @param {Object} start start point
  1091. * @param {Object} end end point
  1092. */
  1093. ;
  1094. _proto.reset = function reset(start, end) {
  1095. this.start = start;
  1096. this.end = end;
  1097. this._init();
  1098. }
  1099. /**
  1100. * check the point is in the range of plot
  1101. * @param {Number} x x value
  1102. * @param {[type]} y y value
  1103. * @return {Boolean} return the result
  1104. */
  1105. ;
  1106. _proto.isInRange = function isInRange(x, y) {
  1107. if (isObject(x)) {
  1108. y = x.y;
  1109. x = x.x;
  1110. }
  1111. var tl = this.tl;
  1112. var br = this.br;
  1113. return tl.x <= x && x <= br.x && tl.y <= y && y <= br.y;
  1114. };
  1115. return Plot;
  1116. }();
  1117. var Matrix = {
  1118. generateDefault: function generateDefault() {
  1119. return [1, 0, 0, 1, 0, 0];
  1120. },
  1121. isChanged: function isChanged(m) {
  1122. return m[0] !== 1 || m[1] !== 0 || m[2] !== 0 || m[3] !== 1 || m[4] !== 0 || m[5] !== 0;
  1123. },
  1124. multiply: function multiply(m1, m2) {
  1125. var m11 = m1[0] * m2[0] + m1[2] * m2[1];
  1126. var m12 = m1[1] * m2[0] + m1[3] * m2[1];
  1127. var m21 = m1[0] * m2[2] + m1[2] * m2[3];
  1128. var m22 = m1[1] * m2[2] + m1[3] * m2[3];
  1129. var dx = m1[0] * m2[4] + m1[2] * m2[5] + m1[4];
  1130. var dy = m1[1] * m2[4] + m1[3] * m2[5] + m1[5];
  1131. return [m11, m12, m21, m22, dx, dy];
  1132. },
  1133. scale: function scale(out, m, v) {
  1134. out[0] = m[0] * v[0];
  1135. out[1] = m[1] * v[0];
  1136. out[2] = m[2] * v[1];
  1137. out[3] = m[3] * v[1];
  1138. out[4] = m[4];
  1139. out[5] = m[5];
  1140. return out;
  1141. },
  1142. rotate: function rotate(out, m, radian) {
  1143. var c = Math.cos(radian);
  1144. var s = Math.sin(radian);
  1145. var m11 = m[0] * c + m[2] * s;
  1146. var m12 = m[1] * c + m[3] * s;
  1147. var m21 = m[0] * -s + m[2] * c;
  1148. var m22 = m[1] * -s + m[3] * c;
  1149. out[0] = m11;
  1150. out[1] = m12;
  1151. out[2] = m21;
  1152. out[3] = m22;
  1153. out[4] = m[4];
  1154. out[5] = m[5];
  1155. return out;
  1156. },
  1157. translate: function translate(out, m, v) {
  1158. out[0] = m[0];
  1159. out[1] = m[1];
  1160. out[2] = m[2];
  1161. out[3] = m[3];
  1162. out[4] = m[4] + m[0] * v[0] + m[2] * v[1];
  1163. out[5] = m[5] + m[1] * v[0] + m[3] * v[1];
  1164. return out;
  1165. },
  1166. transform: function transform(m, actions) {
  1167. var out = [].concat(m);
  1168. for (var i = 0, len = actions.length; i < len; i++) {
  1169. var action = actions[i];
  1170. switch (action[0]) {
  1171. case 't':
  1172. Matrix.translate(out, out, [action[1], action[2]]);
  1173. break;
  1174. case 's':
  1175. Matrix.scale(out, out, [action[1], action[2]]);
  1176. break;
  1177. case 'r':
  1178. Matrix.rotate(out, out, action[1]);
  1179. break;
  1180. }
  1181. }
  1182. return out;
  1183. }
  1184. };
  1185. /**
  1186. * 2 Dimensional Vector
  1187. * @module vector2
  1188. */
  1189. var Vector2 = {
  1190. /**
  1191. * Creates a new, empty vector2
  1192. *
  1193. * @return {vector2} a new 2D vector
  1194. */
  1195. create: function create() {
  1196. return [0, 0];
  1197. },
  1198. /**
  1199. * Calculates the length of a vector2
  1200. *
  1201. * @param {vector2} v vector to calculate length of
  1202. * @return {Number} length of v
  1203. */
  1204. length: function length(v) {
  1205. var x = v[0];
  1206. var y = v[1];
  1207. return Math.sqrt(x * x + y * y);
  1208. },
  1209. /**
  1210. * Normalize a vector2
  1211. *
  1212. * @param {vector2} out the receiving vector
  1213. * @param {vector2} v vector to normalize
  1214. * @return {vector2} out
  1215. */
  1216. normalize: function normalize(out, v) {
  1217. var len = this.length(v);
  1218. if (len === 0) {
  1219. out[0] = 0;
  1220. out[1] = 0;
  1221. } else {
  1222. out[0] = v[0] / len;
  1223. out[1] = v[1] / len;
  1224. }
  1225. return out;
  1226. },
  1227. /**
  1228. * Adds two vector2's
  1229. *
  1230. * @param {vector2} out the receiving vector
  1231. * @param {vector2} v1 the first operand
  1232. * @param {vector2} v2 the second operand
  1233. * @return {vector2} out
  1234. */
  1235. add: function add(out, v1, v2) {
  1236. out[0] = v1[0] + v2[0];
  1237. out[1] = v1[1] + v2[1];
  1238. return out;
  1239. },
  1240. /**
  1241. * Subtracts vector v2 from vector v1
  1242. *
  1243. * @param {vector2} out the receiving vector
  1244. * @param {vector2} v1 the first operand
  1245. * @param {vector2} v2 the second operand
  1246. * @return {vector2} out
  1247. */
  1248. sub: function sub(out, v1, v2) {
  1249. out[0] = v1[0] - v2[0];
  1250. out[1] = v1[1] - v2[1];
  1251. return out;
  1252. },
  1253. /**
  1254. * Scales a vector2 by a scalar number
  1255. *
  1256. * @param {vector2} out the receiving vector
  1257. * @param {vector2} v the vector to scale
  1258. * @param {Number} s amount to scale the vector by
  1259. * @return {vector2} out
  1260. */
  1261. scale: function scale(out, v, s) {
  1262. out[0] = v[0] * s;
  1263. out[1] = v[1] * s;
  1264. return out;
  1265. },
  1266. /**
  1267. * Calculates the dot product of two vector2's
  1268. *
  1269. * @param {vector2} v1 the first operand
  1270. * @param {vector2} v2 the second operand
  1271. * @return {Number} dot product of v1 and v2
  1272. */
  1273. dot: function dot(v1, v2) {
  1274. return v1[0] * v2[0] + v1[1] * v2[1];
  1275. },
  1276. /**
  1277. * Calculates the direction of two vector2's
  1278. *
  1279. * @param {vector2} v1 the first operand
  1280. * @param {vector2} v2 the second operand
  1281. * @return {Boolean} the direction of v1 and v2
  1282. */
  1283. direction: function direction(v1, v2) {
  1284. return v1[0] * v2[1] - v2[0] * v1[1];
  1285. },
  1286. /**
  1287. * Calculates the angle of two vector2's
  1288. *
  1289. * @param {vector2} v1 the first operand
  1290. * @param {vector2} v2 the second operand
  1291. * @return {Number} angle of v1 and v2
  1292. */
  1293. angle: function angle(v1, v2) {
  1294. var theta = this.dot(v1, v2) / (this.length(v1) * this.length(v2));
  1295. return Math.acos(theta);
  1296. },
  1297. /**
  1298. * Calculates the angle of two vector2's with direction
  1299. *
  1300. * @param {vector2} v1 the first operand
  1301. * @param {vector2} v2 the second operand
  1302. * @param {Boolean} direction the direction of two vector2's
  1303. * @return {Number} angle of v1 and v2
  1304. */
  1305. angleTo: function angleTo(v1, v2, direction) {
  1306. var angle = this.angle(v1, v2);
  1307. var angleLargeThanPI = this.direction(v1, v2) >= 0;
  1308. if (direction) {
  1309. if (angleLargeThanPI) {
  1310. return Math.PI * 2 - angle;
  1311. }
  1312. return angle;
  1313. }
  1314. if (angleLargeThanPI) {
  1315. return angle;
  1316. }
  1317. return Math.PI * 2 - angle;
  1318. },
  1319. /**
  1320. * whether a vector2 is zero vector
  1321. *
  1322. * @param {vector2} v vector to calculate
  1323. * @return {Boolean} is or not a zero vector
  1324. */
  1325. zero: function zero(v) {
  1326. return v[0] === 0 && v[1] === 0;
  1327. },
  1328. /**
  1329. * Calculates the euclidian distance between two vector2's
  1330. *
  1331. * @param {vector2} v1 the first operand
  1332. * @param {vector2} v2 the second operand
  1333. * @return {Number} distance between a and b
  1334. */
  1335. distance: function distance(v1, v2) {
  1336. var x = v2[0] - v1[0];
  1337. var y = v2[1] - v1[1];
  1338. return Math.sqrt(x * x + y * y);
  1339. },
  1340. /**
  1341. * Creates a new vector2 initialized with values from an existing vector
  1342. *
  1343. * @param {vector2} v vector to clone
  1344. * @return {Array} a new 2D vector
  1345. */
  1346. clone: function clone(v) {
  1347. return [v[0], v[1]];
  1348. },
  1349. /**
  1350. * Return the minimum of two vector2's
  1351. *
  1352. * @param {vector2} out the receiving vector
  1353. * @param {vector2} v1 the first operand
  1354. * @param {vector2} v2 the second operand
  1355. * @return {vector2} out
  1356. */
  1357. min: function min(out, v1, v2) {
  1358. out[0] = Math.min(v1[0], v2[0]);
  1359. out[1] = Math.min(v1[1], v2[1]);
  1360. return out;
  1361. },
  1362. /**
  1363. * Return the maximum of two vector2's
  1364. *
  1365. * @param {vector2} out the receiving vector
  1366. * @param {vector2} v1 the first operand
  1367. * @param {vector2} v2 the second operand
  1368. * @return {vector2} out
  1369. */
  1370. max: function max(out, v1, v2) {
  1371. out[0] = Math.max(v1[0], v2[0]);
  1372. out[1] = Math.max(v1[1], v2[1]);
  1373. return out;
  1374. },
  1375. /**
  1376. * Transforms the vector2 with a mat2d
  1377. *
  1378. * @param {vector2} out the receiving vector
  1379. * @param {vector2} v the vector to transform
  1380. * @param {mat2d} m matrix to transform with
  1381. * @return {vector2} out
  1382. */
  1383. transformMat2d: function transformMat2d(out, v, m) {
  1384. var x = v[0];
  1385. var y = v[1];
  1386. out[0] = m[0] * x + m[2] * y + m[4];
  1387. out[1] = m[1] * x + m[3] * y + m[5];
  1388. return out;
  1389. }
  1390. };
  1391. var defaultMatrix = [1, 0, 0, 1, 0, 0];
  1392. var Base$1 = /*#__PURE__*/function () {
  1393. var _proto = Base.prototype;
  1394. _proto._initDefaultCfg = function _initDefaultCfg() {};
  1395. function Base(cfg) {
  1396. this._initDefaultCfg();
  1397. mix(this, cfg);
  1398. var start;
  1399. var end;
  1400. if (this.plot) {
  1401. start = this.plot.bl;
  1402. end = this.plot.tr;
  1403. this.start = start;
  1404. this.end = end;
  1405. } else {
  1406. start = this.start;
  1407. end = this.end;
  1408. }
  1409. this.init(start, end);
  1410. }
  1411. _proto._scale = function _scale(s1, s2) {
  1412. var matrix = this.matrix;
  1413. var center = this.center;
  1414. Matrix.translate(matrix, matrix, [center.x, center.y]);
  1415. Matrix.scale(matrix, matrix, [s1, s2]);
  1416. Matrix.translate(matrix, matrix, [-center.x, -center.y]);
  1417. };
  1418. _proto.init = function init(start, end) {
  1419. this.matrix = [].concat(defaultMatrix); // 设置中心点
  1420. this.center = {
  1421. x: (end.x - start.x) / 2 + start.x,
  1422. y: (end.y - start.y) / 2 + start.y
  1423. };
  1424. if (this.scale) {
  1425. this._scale(this.scale[0], this.scale[1]);
  1426. }
  1427. };
  1428. _proto.convertPoint = function convertPoint(point) {
  1429. var _this$_convertPoint = this._convertPoint(point),
  1430. x = _this$_convertPoint.x,
  1431. y = _this$_convertPoint.y;
  1432. if (!Matrix.isChanged(this.matrix)) {
  1433. return {
  1434. x: x,
  1435. y: y
  1436. };
  1437. }
  1438. var vector = [x, y];
  1439. Vector2.transformMat2d(vector, vector, this.matrix);
  1440. return {
  1441. x: vector[0],
  1442. y: vector[1]
  1443. };
  1444. };
  1445. _proto.invertPoint = function invertPoint(point) {
  1446. return this._invertPoint(point);
  1447. };
  1448. _proto._convertPoint = function _convertPoint(point) {
  1449. return point;
  1450. };
  1451. _proto._invertPoint = function _invertPoint(point) {
  1452. return point;
  1453. };
  1454. _proto.reset = function reset(plot) {
  1455. this.plot = plot;
  1456. var bl = plot.bl,
  1457. tr = plot.tr;
  1458. this.start = bl;
  1459. this.end = tr;
  1460. this.init(bl, tr);
  1461. };
  1462. return Base;
  1463. }();
  1464. var Cartesian = /*#__PURE__*/function (_Base) {
  1465. _inheritsLoose(Cartesian, _Base);
  1466. function Cartesian() {
  1467. return _Base.apply(this, arguments) || this;
  1468. }
  1469. var _proto = Cartesian.prototype;
  1470. _proto._initDefaultCfg = function _initDefaultCfg() {
  1471. this.type = 'cartesian';
  1472. this.transposed = false;
  1473. this.isRect = true;
  1474. };
  1475. _proto.init = function init(start, end) {
  1476. _Base.prototype.init.call(this, start, end);
  1477. this.x = {
  1478. start: start.x,
  1479. end: end.x
  1480. };
  1481. this.y = {
  1482. start: start.y,
  1483. end: end.y
  1484. };
  1485. };
  1486. _proto._convertPoint = function _convertPoint(point) {
  1487. var self = this;
  1488. var transposed = self.transposed;
  1489. var xDim = transposed ? 'y' : 'x';
  1490. var yDim = transposed ? 'x' : 'y';
  1491. var x = self.x;
  1492. var y = self.y;
  1493. return {
  1494. x: x.start + (x.end - x.start) * point[xDim],
  1495. y: y.start + (y.end - y.start) * point[yDim]
  1496. };
  1497. };
  1498. _proto._invertPoint = function _invertPoint(point) {
  1499. var self = this;
  1500. var transposed = self.transposed;
  1501. var xDim = transposed ? 'y' : 'x';
  1502. var yDim = transposed ? 'x' : 'y';
  1503. var x = self.x;
  1504. var y = self.y;
  1505. var rst = {};
  1506. rst[xDim] = (point.x - x.start) / (x.end - x.start);
  1507. rst[yDim] = (point.y - y.start) / (y.end - y.start);
  1508. return rst;
  1509. };
  1510. return Cartesian;
  1511. }(Base$1);
  1512. Base$1.Cartesian = Cartesian;
  1513. Base$1.Rect = Cartesian;
  1514. /**
  1515. * @fileOverview the Attribute base class
  1516. */
  1517. function toScaleString(scale, value) {
  1518. if (isString(value)) {
  1519. return value;
  1520. }
  1521. return scale.invert(scale.scale(value));
  1522. }
  1523. /**
  1524. * 所有视觉通道属性的基类
  1525. * @class Attr
  1526. */
  1527. var AttributeBase = /*#__PURE__*/function () {
  1528. function AttributeBase(cfg) {
  1529. var _this = this;
  1530. /**
  1531. * 属性的类型
  1532. * @type {String}
  1533. */
  1534. this.type = 'base';
  1535. /**
  1536. * 属性的名称
  1537. * @type {String}
  1538. */
  1539. this.name = null;
  1540. /**
  1541. * 回调函数
  1542. * @type {Function}
  1543. */
  1544. this.method = null;
  1545. /**
  1546. * 备选的值数组
  1547. * @type {Array}
  1548. */
  1549. this.values = [];
  1550. /**
  1551. * 属性内部的度量
  1552. * @type {Array}
  1553. */
  1554. this.scales = [];
  1555. /**
  1556. * 是否通过线性取值, 如果未指定,则根据数值的类型判定
  1557. * @type {Boolean}
  1558. */
  1559. this.linear = null;
  1560. /**
  1561. * 当用户设置的 callback 返回 null 时, 应该返回默认 callback 中的值
  1562. */
  1563. var mixedCallback = null;
  1564. var defaultCallback = this.callback;
  1565. if (cfg.callback) {
  1566. var userCallback = cfg.callback;
  1567. mixedCallback = function mixedCallback() {
  1568. for (var _len = arguments.length, params = new Array(_len), _key = 0; _key < _len; _key++) {
  1569. params[_key] = arguments[_key];
  1570. }
  1571. var ret = userCallback.apply(void 0, params);
  1572. if (isNil(ret)) {
  1573. ret = defaultCallback.apply(_this, params);
  1574. }
  1575. return ret;
  1576. };
  1577. }
  1578. mix(this, cfg);
  1579. if (mixedCallback) {
  1580. mix(this, {
  1581. callback: mixedCallback
  1582. });
  1583. }
  1584. } // 获取属性值,将值映射到视觉通道
  1585. var _proto = AttributeBase.prototype;
  1586. _proto._getAttrValue = function _getAttrValue(scale, value) {
  1587. var values = this.values;
  1588. if (scale.isCategory && !this.linear) {
  1589. var index = scale.translate(value);
  1590. return values[index % values.length];
  1591. }
  1592. var percent = scale.scale(value);
  1593. return this.getLinearValue(percent);
  1594. }
  1595. /**
  1596. * 如果进行线性映射,返回对应的映射值
  1597. * @protected
  1598. * @param {Number} percent 百分比
  1599. * @return {*} 颜色值、形状、大小等
  1600. */
  1601. ;
  1602. _proto.getLinearValue = function getLinearValue(percent) {
  1603. var values = this.values;
  1604. var steps = values.length - 1;
  1605. var step = Math.floor(steps * percent);
  1606. var leftPercent = steps * percent - step;
  1607. var start = values[step];
  1608. var end = step === steps ? start : values[step + 1];
  1609. var rstValue = start + (end - start) * leftPercent;
  1610. return rstValue;
  1611. }
  1612. /**
  1613. * 默认的回调函数
  1614. * @param {*} value 回调函数的值
  1615. * @type {Function}
  1616. * @return {Array} 返回映射后的值
  1617. */
  1618. ;
  1619. _proto.callback = function callback(value) {
  1620. var self = this;
  1621. var scale = self.scales[0];
  1622. var rstValue = null;
  1623. if (scale.type === 'identity') {
  1624. rstValue = scale.value;
  1625. } else {
  1626. rstValue = self._getAttrValue(scale, value);
  1627. }
  1628. return rstValue;
  1629. }
  1630. /**
  1631. * 根据度量获取属性名
  1632. * @return {Array} dims of this Attribute
  1633. */
  1634. ;
  1635. _proto.getNames = function getNames() {
  1636. var scales = this.scales;
  1637. var names = this.names;
  1638. var length = Math.min(scales.length, names.length);
  1639. var rst = [];
  1640. for (var i = 0; i < length; i++) {
  1641. rst.push(names[i]);
  1642. }
  1643. return rst;
  1644. }
  1645. /**
  1646. * 根据度量获取维度名
  1647. * @return {Array} dims of this Attribute
  1648. */
  1649. ;
  1650. _proto.getFields = function getFields() {
  1651. var scales = this.scales;
  1652. var rst = [];
  1653. each(scales, function (scale) {
  1654. rst.push(scale.field);
  1655. });
  1656. return rst;
  1657. }
  1658. /**
  1659. * 根据名称获取度量
  1660. * @param {String} name the name of scale
  1661. * @return {Scale} scale
  1662. */
  1663. ;
  1664. _proto.getScale = function getScale(name) {
  1665. var scales = this.scales;
  1666. var names = this.names;
  1667. var index = names.indexOf(name);
  1668. return scales[index];
  1669. }
  1670. /**
  1671. * 映射数据
  1672. * @param {*} param1...paramn 多个数值
  1673. * @return {Array} 映射的值组成的数组
  1674. */
  1675. ;
  1676. _proto.mapping = function mapping() {
  1677. var scales = this.scales;
  1678. var callback = this.callback;
  1679. for (var _len2 = arguments.length, params = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
  1680. params[_key2] = arguments[_key2];
  1681. }
  1682. var values = params;
  1683. if (callback) {
  1684. for (var i = 0, len = params.length; i < len; i++) {
  1685. params[i] = this._toOriginParam(params[i], scales[i]);
  1686. }
  1687. values = callback.apply(this, params);
  1688. }
  1689. values = [].concat(values);
  1690. return values;
  1691. } // 原始的参数
  1692. ;
  1693. _proto._toOriginParam = function _toOriginParam(param, scale) {
  1694. var rst = param;
  1695. if (!scale.isLinear) {
  1696. if (isArray(param)) {
  1697. rst = [];
  1698. for (var i = 0, len = param.length; i < len; i++) {
  1699. rst.push(toScaleString(scale, param[i]));
  1700. }
  1701. } else {
  1702. rst = toScaleString(scale, param);
  1703. }
  1704. }
  1705. return rst;
  1706. };
  1707. return AttributeBase;
  1708. }();
  1709. var Position = /*#__PURE__*/function (_Base) {
  1710. _inheritsLoose(Position, _Base);
  1711. function Position(cfg) {
  1712. var _this;
  1713. _this = _Base.call(this, cfg) || this;
  1714. _this.names = ['x', 'y'];
  1715. _this.type = 'position';
  1716. return _this;
  1717. }
  1718. var _proto = Position.prototype;
  1719. _proto.mapping = function mapping(x, y) {
  1720. var scales = this.scales;
  1721. var coord = this.coord;
  1722. var scaleX = scales[0];
  1723. var scaleY = scales[1];
  1724. var rstX;
  1725. var rstY;
  1726. var obj;
  1727. if (isNil(x) || isNil(y)) {
  1728. return [];
  1729. }
  1730. if (isArray(y) && isArray(x)) {
  1731. rstX = [];
  1732. rstY = [];
  1733. for (var i = 0, j = 0, xLen = x.length, yLen = y.length; i < xLen && j < yLen; i++, j++) {
  1734. obj = coord.convertPoint({
  1735. x: scaleX.scale(x[i]),
  1736. y: scaleY.scale(y[j])
  1737. });
  1738. rstX.push(obj.x);
  1739. rstY.push(obj.y);
  1740. }
  1741. } else if (isArray(y)) {
  1742. x = scaleX.scale(x);
  1743. rstY = [];
  1744. each(y, function (yVal) {
  1745. yVal = scaleY.scale(yVal);
  1746. obj = coord.convertPoint({
  1747. x: x,
  1748. y: yVal
  1749. });
  1750. if (rstX && rstX !== obj.x) {
  1751. if (!isArray(rstX)) {
  1752. rstX = [rstX];
  1753. }
  1754. rstX.push(obj.x);
  1755. } else {
  1756. rstX = obj.x;
  1757. }
  1758. rstY.push(obj.y);
  1759. });
  1760. } else if (isArray(x)) {
  1761. y = scaleY.scale(y);
  1762. rstX = [];
  1763. each(x, function (xVal) {
  1764. xVal = scaleX.scale(xVal);
  1765. obj = coord.convertPoint({
  1766. x: xVal,
  1767. y: y
  1768. });
  1769. if (rstY && rstY !== obj.y) {
  1770. if (!isArray(rstY)) {
  1771. rstY = [rstY];
  1772. }
  1773. rstY.push(obj.y);
  1774. } else {
  1775. rstY = obj.y;
  1776. }
  1777. rstX.push(obj.x);
  1778. });
  1779. } else {
  1780. x = scaleX.scale(x);
  1781. y = scaleY.scale(y);
  1782. var point = coord.convertPoint({
  1783. x: x,
  1784. y: y
  1785. });
  1786. rstX = point.x;
  1787. rstY = point.y;
  1788. }
  1789. return [rstX, rstY];
  1790. };
  1791. return Position;
  1792. }(AttributeBase);
  1793. var Shape = /*#__PURE__*/function (_Base) {
  1794. _inheritsLoose(Shape, _Base);
  1795. function Shape(cfg) {
  1796. var _this;
  1797. _this = _Base.call(this, cfg) || this;
  1798. _this.names = ['shape'];
  1799. _this.type = 'shape';
  1800. _this.gradient = null;
  1801. return _this;
  1802. }
  1803. /**
  1804. * @override
  1805. */
  1806. var _proto = Shape.prototype;
  1807. _proto.getLinearValue = function getLinearValue(percent) {
  1808. var values = this.values;
  1809. var index = Math.round((values.length - 1) * percent);
  1810. return values[index];
  1811. };
  1812. return Shape;
  1813. }(AttributeBase);
  1814. var Size = /*#__PURE__*/function (_Base) {
  1815. _inheritsLoose(Size, _Base);
  1816. function Size(cfg) {
  1817. var _this;
  1818. _this = _Base.call(this, cfg) || this;
  1819. _this.names = ['size'];
  1820. _this.type = 'size';
  1821. _this.gradient = null;
  1822. return _this;
  1823. }
  1824. return Size;
  1825. }(AttributeBase);
  1826. function getValue(start, end, percent, index) {
  1827. var value = start[index] + (end[index] - start[index]) * percent;
  1828. return value;
  1829. } // convert to hex
  1830. function arr2hex(arr) {
  1831. return '#' + toRGBValue(arr[0]) + toRGBValue(arr[1]) + toRGBValue(arr[2]);
  1832. }
  1833. function toRGBValue(value) {
  1834. value = Math.round(value);
  1835. value = value.toString(16);
  1836. if (value.length === 1) {
  1837. value = '0' + value;
  1838. }
  1839. return value;
  1840. }
  1841. function calColor(colors, percent) {
  1842. var steps = colors.length - 1;
  1843. var step = Math.floor(steps * percent);
  1844. var left = steps * percent - step;
  1845. var start = colors[step];
  1846. var end = step === steps ? start : colors[step + 1];
  1847. var rgb = arr2hex([getValue(start, end, left, 0), getValue(start, end, left, 1), getValue(start, end, left, 2)]);
  1848. return rgb;
  1849. }
  1850. function hex2arr(str) {
  1851. var arr = [];
  1852. arr.push(parseInt(str.substr(1, 2), 16));
  1853. arr.push(parseInt(str.substr(3, 2), 16));
  1854. arr.push(parseInt(str.substr(5, 2), 16));
  1855. return arr;
  1856. }
  1857. var colorCache = {
  1858. black: '#000000',
  1859. blue: '#0000ff',
  1860. grey: '#808080',
  1861. green: '#008000',
  1862. orange: '#ffa500',
  1863. pink: '#ffc0cb',
  1864. purple: '#800080',
  1865. red: '#ff0000',
  1866. white: '#ffffff',
  1867. yellow: '#ffff00'
  1868. };
  1869. /**
  1870. * Returns a hexadecimal string representing this color in RGB space, such as #f7eaba.
  1871. * @param {String} color color value
  1872. * @return {String} Returns a hexadecimal string
  1873. */
  1874. function toHex(color) {
  1875. if (colorCache[color]) {
  1876. return colorCache[color];
  1877. }
  1878. if (color[0] === '#') {
  1879. if (color.length === 7) {
  1880. return color;
  1881. }
  1882. var hex = color.replace(/^#?([a-f\d])([a-f\d])([a-f\d])$/i, function (m, r, g, b) {
  1883. return '#' + r + r + g + g + b + b;
  1884. }); // hex3 to hex6
  1885. colorCache[color] = hex;
  1886. return hex;
  1887. } // rgb/rgba to hex
  1888. var rst = color.match(/^rgba?[\s+]?\([\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?/i);
  1889. rst.shift();
  1890. rst = arr2hex(rst);
  1891. colorCache[color] = rst;
  1892. return rst;
  1893. }
  1894. /**
  1895. * handle the gradient color
  1896. * @param {Array} colors the colors
  1897. * @return {String} return the color value
  1898. */
  1899. function gradient(colors) {
  1900. var points = [];
  1901. if (isString(colors)) {
  1902. colors = colors.split('-');
  1903. }
  1904. each(colors, function (color) {
  1905. if (color.indexOf('#') === -1) {
  1906. color = toHex(color);
  1907. }
  1908. points.push(hex2arr(color));
  1909. });
  1910. return function (percent) {
  1911. return calColor(points, percent);
  1912. };
  1913. }
  1914. var Color = /*#__PURE__*/function (_Base) {
  1915. _inheritsLoose(Color, _Base);
  1916. function Color(cfg) {
  1917. var _this;
  1918. _this = _Base.call(this, cfg) || this;
  1919. _this.names = ['color'];
  1920. _this.type = 'color';
  1921. _this.gradient = null;
  1922. if (isString(_this.values)) {
  1923. _this.linear = true;
  1924. }
  1925. return _this;
  1926. }
  1927. /**
  1928. * @override
  1929. */
  1930. var _proto = Color.prototype;
  1931. _proto.getLinearValue = function getLinearValue(percent) {
  1932. var gradient$1 = this.gradient;
  1933. if (!gradient$1) {
  1934. var values = this.values;
  1935. gradient$1 = gradient(values);
  1936. this.gradient = gradient$1;
  1937. }
  1938. return gradient$1(percent);
  1939. };
  1940. return Color;
  1941. }(AttributeBase);
  1942. var Attr = /*#__PURE__*/Object.freeze({
  1943. __proto__: null,
  1944. Position: Position,
  1945. Shape: Shape,
  1946. Size: Size,
  1947. Color: Color
  1948. });
  1949. var Shape$1 = {};
  1950. var ShapeBase = {
  1951. _coord: null,
  1952. /**
  1953. * draw the shape
  1954. * @param {Object} cfg options
  1955. * @param {Object} container container to store the shapes
  1956. */
  1957. draw: function draw(cfg, container) {
  1958. if (this.drawShape) {
  1959. this.drawShape(cfg, container);
  1960. }
  1961. },
  1962. /**
  1963. * set the coordinate instance
  1964. * @param {Coord} coord coordinate instance
  1965. */
  1966. setCoord: function setCoord(coord) {
  1967. this._coord = coord;
  1968. },
  1969. /**
  1970. * convert the normalized value to the canvas position
  1971. * @param {point} point the point to convert
  1972. * @return {point} point return the result
  1973. */
  1974. parsePoint: function parsePoint(point) {
  1975. var coord = this._coord;
  1976. if (coord.isPolar) {
  1977. if (point.x === 1) point.x = 0.9999999;
  1978. if (point.y === 1) point.y = 0.9999999;
  1979. }
  1980. return coord.convertPoint(point);
  1981. },
  1982. /**
  1983. * convert the normalized value to the canvas position
  1984. * @param {points} points the array that store the points
  1985. * @return {points} points return the result
  1986. */
  1987. parsePoints: function parsePoints(points) {
  1988. if (!points) return false;
  1989. var self = this;
  1990. var rst = [];
  1991. points.forEach(function (point) {
  1992. rst.push(self.parsePoint(point));
  1993. });
  1994. return rst;
  1995. }
  1996. };
  1997. var ShapeFactoryBase = {
  1998. defaultShapeType: null,
  1999. setCoord: function setCoord(coord) {
  2000. this._coord = coord;
  2001. },
  2002. getShape: function getShape(type) {
  2003. var self = this;
  2004. if (isArray(type)) {
  2005. type = type[0];
  2006. }
  2007. var shape = self[type] || self[self.defaultShapeType];
  2008. shape._coord = self._coord;
  2009. return shape;
  2010. },
  2011. getShapePoints: function getShapePoints(type, cfg) {
  2012. var shape = this.getShape(type);
  2013. var fn = shape.getPoints || shape.getShapePoints || this.getDefaultPoints;
  2014. var points = fn(cfg);
  2015. return points;
  2016. },
  2017. getDefaultPoints: function getDefaultPoints()
  2018. /* cfg */
  2019. {
  2020. return [];
  2021. },
  2022. drawShape: function drawShape(type, cfg, container) {
  2023. var shape = this.getShape(type);
  2024. if (!cfg.color) {
  2025. cfg.color = Global.colors[0];
  2026. }
  2027. return shape.draw(cfg, container);
  2028. }
  2029. };
  2030. Shape$1.registerFactory = function (factoryName, cfg) {
  2031. var className = upperFirst(factoryName);
  2032. var geomObj = mix({}, ShapeFactoryBase, cfg);
  2033. Shape$1[className] = geomObj;
  2034. geomObj.name = factoryName;
  2035. return geomObj;
  2036. };
  2037. Shape$1.registerShape = function (factoryName, shapeType, cfg) {
  2038. var className = upperFirst(factoryName);
  2039. var factory = Shape$1[className];
  2040. var shapeObj = mix({}, ShapeBase, cfg);
  2041. factory[shapeType] = shapeObj;
  2042. return shapeObj;
  2043. };
  2044. Shape$1.registShape = Shape$1.registerShape;
  2045. Shape$1.getShapeFactory = function (factoryName) {
  2046. var self = this;
  2047. factoryName = factoryName || 'point';
  2048. var className = upperFirst(factoryName);
  2049. return self[className];
  2050. };
  2051. function _mix$1(dist, obj) {
  2052. for (var key in obj) {
  2053. if (obj.hasOwnProperty(key) && key !== 'constructor' && obj[key] !== undefined) {
  2054. dist[key] = obj[key];
  2055. }
  2056. }
  2057. }
  2058. var mix$1 = function mix(dist, src1, src2, src3) {
  2059. if (src1) _mix$1(dist, src1);
  2060. if (src2) _mix$1(dist, src2);
  2061. if (src3) _mix$1(dist, src3);
  2062. return dist;
  2063. };
  2064. var mix_1 = mix$1;
  2065. var Adjust = /*#__PURE__*/function () {
  2066. var _proto = Adjust.prototype;
  2067. _proto._initDefaultCfg = function _initDefaultCfg() {
  2068. this.adjustNames = ['x', 'y']; // 调整的维度,默认,x,y都做调整
  2069. };
  2070. function Adjust(cfg) {
  2071. this._initDefaultCfg();
  2072. mix_1(this, cfg);
  2073. }
  2074. /**
  2075. * @override
  2076. */
  2077. _proto.processAdjust = function processAdjust()
  2078. /* dataArray */
  2079. {};
  2080. return Adjust;
  2081. }();
  2082. var base = Adjust;
  2083. function generateScaleAria(scale) {
  2084. var type = scale.type,
  2085. values = scale.values;
  2086. if (type === 'linear') {
  2087. return substitute(lang.scale.linear, scale);
  2088. }
  2089. if (type === 'cat') {
  2090. return substitute(lang.scale.cat, {
  2091. values: values.slice(0, 10).join(' ')
  2092. });
  2093. }
  2094. if (type === 'timeCat') {
  2095. var start = scale.getText(values[0]);
  2096. var end = scale.getText(values[values.length - 1]);
  2097. return substitute(lang.scale.timeCat, {
  2098. start: start,
  2099. end: end
  2100. });
  2101. }
  2102. return '';
  2103. }
  2104. function generateCoordAria(coord, xScale, yScale) {
  2105. var type = coord.type;
  2106. if (!lang.coord[type]) {
  2107. return '';
  2108. }
  2109. return substitute(lang.coord[type], {
  2110. xLabel: generateScaleAria(xScale),
  2111. yLabel: generateScaleAria(yScale)
  2112. });
  2113. }
  2114. var GROUP_ATTRS = ['color', 'size', 'shape'];
  2115. var FIELD_ORIGIN = '_origin';
  2116. var FIELD_ORIGIN_Y = '_originY';
  2117. function parseFields(field) {
  2118. if (isArray(field)) {
  2119. return field;
  2120. }
  2121. if (isString(field)) {
  2122. return field.split('*');
  2123. }
  2124. return [field];
  2125. }
  2126. /**
  2127. * The parent class for Geometry
  2128. * @class Geom
  2129. */
  2130. var Geom = /*#__PURE__*/function (_Base) {
  2131. _inheritsLoose(Geom, _Base);
  2132. function Geom() {
  2133. return _Base.apply(this, arguments) || this;
  2134. }
  2135. var _proto = Geom.prototype;
  2136. _proto.getDefaultCfg = function getDefaultCfg() {
  2137. return {
  2138. /**
  2139. * geometry type
  2140. * @type {String}
  2141. */
  2142. type: null,
  2143. /**
  2144. * the data of geometry
  2145. * @type {Array}
  2146. */
  2147. data: null,
  2148. /**
  2149. * the attrs of geo,etry
  2150. * @type {Object}
  2151. */
  2152. attrs: {},
  2153. scales: {},
  2154. /**
  2155. * group for storing the shapes
  2156. * @type {Canvas}
  2157. */
  2158. container: null,
  2159. /**
  2160. * style options
  2161. * @type {Object}
  2162. */
  2163. styleOptions: null,
  2164. chart: null,
  2165. shapeType: '',
  2166. /**
  2167. * wether to generate key points for each shape
  2168. * @protected
  2169. * @type {Boolean}
  2170. */
  2171. generatePoints: false,
  2172. attrOptions: {},
  2173. sortable: false,
  2174. startOnZero: true,
  2175. visible: true,
  2176. connectNulls: false,
  2177. // 是否丢弃没有值的分组。
  2178. ignoreEmptyGroup: false,
  2179. // 是否已经初始化
  2180. isInit: false
  2181. };
  2182. };
  2183. _proto.init = function init() {
  2184. var self = this;
  2185. var isInit = self.get('isInit');
  2186. if (isInit) {
  2187. return;
  2188. }
  2189. self._initAttrs();
  2190. self._processData();
  2191. self.set('isInit', true);
  2192. };
  2193. _proto._getGroupScales = function _getGroupScales() {
  2194. var self = this;
  2195. var scales = [];
  2196. each(GROUP_ATTRS, function (attrName) {
  2197. var attr = self.getAttr(attrName);
  2198. if (attr) {
  2199. var attrScales = attr.scales;
  2200. each(attrScales, function (scale) {
  2201. if (scale && scale.isCategory && scales.indexOf(scale) === -1) {
  2202. scales.push(scale);
  2203. }
  2204. });
  2205. }
  2206. });
  2207. return scales;
  2208. };
  2209. _proto._groupData = function _groupData(data) {
  2210. var self = this;
  2211. var colDefs = self.get('colDefs');
  2212. var groupScales = self._getGroupScales();
  2213. if (groupScales.length) {
  2214. var appendConditions = {};
  2215. var names = [];
  2216. each(groupScales, function (scale) {
  2217. var field = scale.field;
  2218. names.push(field);
  2219. if (colDefs && colDefs[field] && colDefs[field].values) {
  2220. // users have defined
  2221. appendConditions[scale.field] = colDefs[field].values;
  2222. }
  2223. });
  2224. return group(data, names, appendConditions);
  2225. }
  2226. return [data];
  2227. };
  2228. _proto._setAttrOptions = function _setAttrOptions(attrName, attrCfg) {
  2229. var options = this.get('attrOptions');
  2230. options[attrName] = attrCfg;
  2231. var attrs = this.get('attrs'); // 说明已经初始化过了
  2232. if (Object.keys(attrs).length) {
  2233. this._createAttr(attrName, attrCfg);
  2234. }
  2235. };
  2236. _proto._createAttrOption = function _createAttrOption(attrName, field, cfg, defaultValues) {
  2237. var attrCfg = {};
  2238. attrCfg.field = field;
  2239. if (cfg) {
  2240. if (isFunction(cfg)) {
  2241. attrCfg.callback = cfg;
  2242. } else {
  2243. attrCfg.values = cfg;
  2244. }
  2245. } else {
  2246. attrCfg.values = defaultValues;
  2247. }
  2248. this._setAttrOptions(attrName, attrCfg);
  2249. };
  2250. _proto._createAttr = function _createAttr(type, option) {
  2251. var self = this;
  2252. var attrs = self.get('attrs');
  2253. var coord = self.get('coord');
  2254. var className = upperFirst(type);
  2255. var fields = parseFields(option.field);
  2256. if (type === 'position') {
  2257. option.coord = coord;
  2258. }
  2259. var scales = [];
  2260. for (var i = 0, len = fields.length; i < len; i++) {
  2261. var field = fields[i];
  2262. var scale = self._createScale(field);
  2263. scales.push(scale);
  2264. }
  2265. if (type === 'position') {
  2266. var yScale = scales[1]; // 饼图的处理,但是还不知道为啥
  2267. if (coord.type === 'polar' && coord.transposed && self.hasAdjust('stack')) {
  2268. if (yScale.values.length) {
  2269. yScale.change({
  2270. nice: false,
  2271. min: 0,
  2272. max: Math.max.apply(null, yScale.values)
  2273. });
  2274. }
  2275. }
  2276. }
  2277. option.scales = scales;
  2278. var attr = new Attr[className](option);
  2279. attrs[type] = attr;
  2280. return attr;
  2281. };
  2282. _proto._initAttrs = function _initAttrs() {
  2283. var self = this;
  2284. var attrOptions = self.get('attrOptions');
  2285. for (var type in attrOptions) {
  2286. if (attrOptions.hasOwnProperty(type)) {
  2287. this._createAttr(type, attrOptions[type]);
  2288. }
  2289. }
  2290. };
  2291. _proto._createScale = function _createScale(field) {
  2292. var scales = this.get('scales');
  2293. var scale = scales[field];
  2294. if (!scale) {
  2295. scale = this.get('chart').createScale(field);
  2296. scales[field] = scale;
  2297. }
  2298. return scale;
  2299. };
  2300. _proto._processData = function _processData() {
  2301. var self = this;
  2302. var data = this.get('data');
  2303. var dataArray = [];
  2304. var groupedArray = this._groupData(data);
  2305. if (this.get('ignoreEmptyGroup')) {
  2306. var yScale = this.getYScale();
  2307. groupedArray = groupedArray.filter(function (group) {
  2308. return group.some(function (item) {
  2309. return typeof item[yScale.field] !== 'undefined';
  2310. });
  2311. });
  2312. }
  2313. for (var i = 0, len = groupedArray.length; i < len; i++) {
  2314. var subData = groupedArray[i];
  2315. var tempData = self._saveOrigin(subData);
  2316. if (this.hasAdjust('dodge')) {
  2317. self._numberic(tempData);
  2318. }
  2319. dataArray.push(tempData);
  2320. }
  2321. if (self.get('adjust')) {
  2322. self._adjustData(dataArray);
  2323. }
  2324. if (self.get('sortable')) {
  2325. self._sort(dataArray);
  2326. }
  2327. self.emit('afterprocessdata', {
  2328. dataArray: dataArray
  2329. });
  2330. self.set('mappingData', dataArray);
  2331. self.set('dataArray', dataArray);
  2332. return dataArray;
  2333. };
  2334. _proto._saveOrigin = function _saveOrigin(data) {
  2335. var rst = [];
  2336. for (var i = 0, len = data.length; i < len; i++) {
  2337. var origin = data[i];
  2338. var obj = {};
  2339. for (var k in origin) {
  2340. obj[k] = origin[k];
  2341. }
  2342. obj[FIELD_ORIGIN] = origin;
  2343. rst.push(obj);
  2344. }
  2345. return rst;
  2346. };
  2347. _proto._numberic = function _numberic(data) {
  2348. var positionAttr = this.getAttr('position');
  2349. var scales = positionAttr.scales;
  2350. for (var j = 0, len = data.length; j < len; j++) {
  2351. var obj = data[j];
  2352. var count = Math.min(2, scales.length);
  2353. for (var i = 0; i < count; i++) {
  2354. var scale = scales[i];
  2355. if (scale.isCategory) {
  2356. var field = scale.field;
  2357. obj[field] = scale.translate(obj[field]);
  2358. }
  2359. }
  2360. }
  2361. };
  2362. _proto._adjustData = function _adjustData(dataArray) {
  2363. var self = this;
  2364. var adjust = self.get('adjust');
  2365. if (adjust) {
  2366. var adjustType = upperFirst(adjust.type);
  2367. if (!base[adjustType]) {
  2368. throw new Error('not support such adjust : ' + adjust);
  2369. }
  2370. var xScale = self.getXScale();
  2371. var yScale = self.getYScale();
  2372. var cfg = mix({
  2373. xField: xScale.field,
  2374. yField: yScale.field
  2375. }, adjust);
  2376. var adjustObject = new base[adjustType](cfg);
  2377. adjustObject.processAdjust(dataArray);
  2378. if (adjustType === 'Stack') {
  2379. self._updateStackRange(yScale.field, yScale, dataArray);
  2380. }
  2381. }
  2382. };
  2383. _proto._updateStackRange = function _updateStackRange(field, scale, dataArray) {
  2384. var mergeArray = merge(dataArray);
  2385. var min = scale.min;
  2386. var max = scale.max;
  2387. for (var i = 0, len = mergeArray.length; i < len; i++) {
  2388. var obj = mergeArray[i];
  2389. var tmpMin = Math.min.apply(null, obj[field]);
  2390. var tmpMax = Math.max.apply(null, obj[field]);
  2391. if (tmpMin < min) {
  2392. min = tmpMin;
  2393. }
  2394. if (tmpMax > max) {
  2395. max = tmpMax;
  2396. }
  2397. }
  2398. if (min < scale.min || max > scale.max) {
  2399. scale.change({
  2400. min: min,
  2401. max: max
  2402. });
  2403. }
  2404. };
  2405. _proto._sort = function _sort(mappedArray) {
  2406. var self = this;
  2407. var xScale = self.getXScale();
  2408. var field = xScale.field,
  2409. type = xScale.type;
  2410. if (type !== 'identity' && xScale.values.length > 1) {
  2411. each(mappedArray, function (itemArr) {
  2412. itemArr.sort(function (obj1, obj2) {
  2413. if (type === 'timeCat') {
  2414. return toTimeStamp(obj1[FIELD_ORIGIN][field]) - toTimeStamp(obj2[FIELD_ORIGIN][field]);
  2415. }
  2416. return xScale.translate(obj1[FIELD_ORIGIN][field]) - xScale.translate(obj2[FIELD_ORIGIN][field]);
  2417. });
  2418. });
  2419. }
  2420. self.set('hasSorted', true);
  2421. self.set('dataArray', mappedArray);
  2422. };
  2423. _proto.paint = function paint() {
  2424. var self = this;
  2425. var dataArray = self.get('mappingData');
  2426. var mappedArray = [];
  2427. var shapeFactory = self.getShapeFactory();
  2428. shapeFactory.setCoord(self.get('coord'));
  2429. self._beforeMapping(dataArray);
  2430. for (var i = 0, len = dataArray.length; i < len; i++) {
  2431. var data = dataArray[i];
  2432. if (data.length) {
  2433. var mappedData = self._mapping(data);
  2434. mappedArray.push(mappedData);
  2435. self.draw(mappedData, shapeFactory);
  2436. }
  2437. }
  2438. self.set('dataArray', mappedArray);
  2439. this.generateAria();
  2440. };
  2441. _proto.getShapeFactory = function getShapeFactory() {
  2442. var shapeFactory = this.get('shapeFactory');
  2443. if (!shapeFactory) {
  2444. var shapeType = this.get('shapeType');
  2445. shapeFactory = Shape$1.getShapeFactory(shapeType);
  2446. this.set('shapeFactory', shapeFactory);
  2447. }
  2448. return shapeFactory;
  2449. };
  2450. _proto._mapping = function _mapping(data) {
  2451. var self = this;
  2452. var attrs = self.get('attrs');
  2453. var yField = self.getYScale().field; // 用来缓存转换的值,减少mapping耗时
  2454. var mappedCache = {};
  2455. var mappedData = new Array(data.length);
  2456. for (var k in attrs) {
  2457. if (attrs.hasOwnProperty(k)) {
  2458. var attr = attrs[k];
  2459. var names = attr.names;
  2460. var scales = attr.scales;
  2461. for (var i = 0, len = data.length; i < len; i++) {
  2462. var record = data[i];
  2463. var mappedRecord = _extends({}, record, mappedData[i]);
  2464. mappedRecord[FIELD_ORIGIN_Y] = record[yField]; // 获取视觉属性对应的value值
  2465. // 位置的缓存命中率低,还是每次单独计算
  2466. if (attr.type === 'position') {
  2467. var values = self._getAttrValues(attr, record);
  2468. for (var j = 0, _len = values.length; j < _len; j++) {
  2469. var val = values[j];
  2470. var name = names[j];
  2471. mappedRecord[name] = isArray(val) && val.length === 1 ? val[0] : val;
  2472. }
  2473. } else {
  2474. // 除了position其他都只有一项
  2475. var _name = names[0];
  2476. var field = scales[0].field;
  2477. var value = record[field];
  2478. var key = "" + _name + value;
  2479. var _values = mappedCache[key];
  2480. if (!_values) {
  2481. _values = self._getAttrValues(attr, record);
  2482. mappedCache[key] = _values;
  2483. }
  2484. mappedRecord[_name] = _values[0];
  2485. } // 设置新数组
  2486. mappedData[i] = mappedRecord;
  2487. }
  2488. }
  2489. }
  2490. return mappedData;
  2491. };
  2492. _proto._getAttrValues = function _getAttrValues(attr, record) {
  2493. var scales = attr.scales;
  2494. var params = [];
  2495. for (var i = 0, len = scales.length; i < len; i++) {
  2496. var scale = scales[i];
  2497. var field = scale.field;
  2498. if (scale.type === 'identity') {
  2499. params.push(scale.value);
  2500. } else {
  2501. params.push(record[field]);
  2502. }
  2503. }
  2504. var values = attr.mapping.apply(attr, params);
  2505. return values;
  2506. };
  2507. _proto.getAttrValue = function getAttrValue(attrName, record) {
  2508. var attr = this.getAttr(attrName);
  2509. var rst = null;
  2510. if (attr) {
  2511. var values = this._getAttrValues(attr, record);
  2512. rst = values[0];
  2513. }
  2514. return rst;
  2515. };
  2516. _proto._beforeMapping = function _beforeMapping(dataArray) {
  2517. var self = this;
  2518. if (self.get('generatePoints')) {
  2519. self._generatePoints(dataArray);
  2520. }
  2521. };
  2522. _proto.isInCircle = function isInCircle() {
  2523. var coord = this.get('coord');
  2524. return coord && coord.isPolar;
  2525. };
  2526. _proto.getCallbackCfg = function getCallbackCfg(fields, cfg, origin) {
  2527. if (!fields) {
  2528. return cfg;
  2529. }
  2530. var tmpCfg = {};
  2531. var params = fields.map(function (field) {
  2532. return origin[field];
  2533. });
  2534. each(cfg, function (v, k) {
  2535. if (isFunction(v)) {
  2536. tmpCfg[k] = v.apply(null, params);
  2537. } else {
  2538. tmpCfg[k] = v;
  2539. }
  2540. });
  2541. return tmpCfg;
  2542. };
  2543. _proto.getDrawCfg = function getDrawCfg(obj) {
  2544. var self = this;
  2545. var isInCircle = self.isInCircle();
  2546. var cfg = {
  2547. origin: obj,
  2548. x: obj.x,
  2549. y: obj.y,
  2550. color: obj.color,
  2551. size: obj.size,
  2552. shape: obj.shape,
  2553. isInCircle: isInCircle,
  2554. opacity: obj.opacity
  2555. };
  2556. var styleOptions = self.get('styleOptions');
  2557. if (styleOptions && styleOptions.style) {
  2558. cfg.style = self.getCallbackCfg(styleOptions.fields, styleOptions.style, obj[FIELD_ORIGIN]);
  2559. }
  2560. if (self.get('generatePoints')) {
  2561. cfg.points = obj.points;
  2562. cfg.nextPoints = obj.nextPoints;
  2563. }
  2564. if (isInCircle) {
  2565. cfg.center = self.get('coord').center;
  2566. }
  2567. return cfg;
  2568. };
  2569. _proto.draw = function draw(data, shapeFactory) {
  2570. var self = this;
  2571. var container = self.get('container');
  2572. var yScale = self.getYScale();
  2573. each(data, function (obj, index) {
  2574. if (yScale && isNil(obj._origin[yScale.field])) {
  2575. return;
  2576. }
  2577. obj.index = index;
  2578. var cfg = self.getDrawCfg(obj);
  2579. var shape = obj.shape;
  2580. self.drawShape(shape, obj, cfg, container, shapeFactory);
  2581. });
  2582. };
  2583. _proto.drawShape = function drawShape(shape, shapeData, cfg, container, shapeFactory) {
  2584. var gShape = shapeFactory.drawShape(shape, cfg, container);
  2585. if (gShape) {
  2586. each([].concat(gShape), function (s) {
  2587. s.set('origin', shapeData);
  2588. });
  2589. }
  2590. };
  2591. _proto._generatePoints = function _generatePoints(dataArray) {
  2592. var self = this;
  2593. var shapeFactory = self.getShapeFactory();
  2594. var shapeAttr = self.getAttr('shape');
  2595. each(dataArray, function (data) {
  2596. for (var i = 0, len = data.length; i < len; i++) {
  2597. var obj = data[i];
  2598. var cfg = self.createShapePointsCfg(obj);
  2599. var shape = shapeAttr ? self._getAttrValues(shapeAttr, obj) : null;
  2600. var points = shapeFactory.getShapePoints(shape, cfg);
  2601. obj.points = points;
  2602. }
  2603. }); // 添加nextPoints
  2604. each(dataArray, function (data, index) {
  2605. var nextData = dataArray[index + 1];
  2606. if (nextData) {
  2607. data[0].nextPoints = nextData[0].points;
  2608. }
  2609. });
  2610. } // 生成无障碍文本
  2611. ;
  2612. _proto.generateAria = function generateAria() {
  2613. var container = this.get('container');
  2614. var aria = container.get('aria');
  2615. if (!aria) {
  2616. return;
  2617. }
  2618. var ariaLables = [];
  2619. var coord = this.get('coord');
  2620. var xScale = this.getXScale();
  2621. var yScale = this.getYScale();
  2622. var coordAriaLabel = generateCoordAria(coord, xScale, yScale);
  2623. ariaLables.push(coordAriaLabel);
  2624. var _lang$geometry = lang.geometry,
  2625. prefix = _lang$geometry.prefix,
  2626. oneData = _lang$geometry.oneData,
  2627. partData = _lang$geometry.partData,
  2628. allData = _lang$geometry.allData;
  2629. var dataArray = this.get('dataArray');
  2630. var count = dataArray.length; // 只处理一个,不然太复杂
  2631. var groupScale = this._getGroupScales()[0];
  2632. if (groupScale) {
  2633. var prefixLabel = substitute(prefix, {
  2634. count: count
  2635. });
  2636. ariaLables.push(prefixLabel);
  2637. each(dataArray, function (data, index) {
  2638. var len = data.length;
  2639. if (!len) return;
  2640. var firstObj = data[0]._origin;
  2641. if (len === 1) {
  2642. ariaLables.push(substitute(oneData, {
  2643. index: index + 1,
  2644. count: len,
  2645. name: firstObj[groupScale.field],
  2646. values: firstObj[yScale.field]
  2647. }));
  2648. } else {
  2649. var template = len > 5 ? partData : allData;
  2650. var values = data.slice(0, 5).map(function (record) {
  2651. var _origin = record._origin;
  2652. var xValue = xScale.getText(_origin[xScale.field]);
  2653. var yValue = yScale.getText(_origin[yScale.field]);
  2654. return xValue + ":" + yValue;
  2655. });
  2656. ariaLables.push(substitute(template, {
  2657. index: index + 1,
  2658. count: len,
  2659. part: 3,
  2660. name: firstObj[groupScale.field],
  2661. values: values.join(' ')
  2662. }));
  2663. }
  2664. });
  2665. }
  2666. container.set('ariaLabel', ariaLables.join(''));
  2667. }
  2668. /**
  2669. * get the info of each shape
  2670. * @protected
  2671. * @param {Object} obj the data item
  2672. * @return {Object} cfg return the result
  2673. */
  2674. ;
  2675. _proto.createShapePointsCfg = function createShapePointsCfg(obj) {
  2676. var xScale = this.getXScale();
  2677. var yScale = this.getYScale();
  2678. var x = this._normalizeValues(obj[xScale.field], xScale);
  2679. var y;
  2680. if (yScale) {
  2681. y = this._normalizeValues(obj[yScale.field], yScale);
  2682. } else {
  2683. y = obj.y ? obj.y : 0.1;
  2684. }
  2685. return {
  2686. x: x,
  2687. y: y,
  2688. y0: yScale ? yScale.scale(this.getYMinValue()) : undefined
  2689. };
  2690. };
  2691. _proto.getYMinValue = function getYMinValue() {
  2692. var yScale = this.getYScale();
  2693. var min = yScale.min,
  2694. max = yScale.max;
  2695. var value;
  2696. if (this.get('startOnZero')) {
  2697. if (max <= 0 && min <= 0) {
  2698. value = max;
  2699. } else {
  2700. value = min >= 0 ? min : 0;
  2701. }
  2702. } else {
  2703. value = min;
  2704. }
  2705. return value;
  2706. };
  2707. _proto._normalizeValues = function _normalizeValues(values, scale) {
  2708. var rst = [];
  2709. if (isArray(values)) {
  2710. for (var i = 0, len = values.length; i < len; i++) {
  2711. var v = values[i];
  2712. rst.push(scale.scale(v));
  2713. }
  2714. } else {
  2715. rst = scale.scale(values);
  2716. }
  2717. return rst;
  2718. };
  2719. _proto.getAttr = function getAttr(name) {
  2720. return this.get('attrs')[name];
  2721. };
  2722. _proto.getXScale = function getXScale() {
  2723. return this.getAttr('position').scales[0];
  2724. };
  2725. _proto.getYScale = function getYScale() {
  2726. return this.getAttr('position').scales[1];
  2727. };
  2728. _proto.hasAdjust = function hasAdjust(adjust) {
  2729. return this.get('adjust') && this.get('adjust').type === adjust;
  2730. };
  2731. _proto._getSnap = function _getSnap(scale, item, arr) {
  2732. var i = 0;
  2733. var values;
  2734. var yField = this.getYScale().field; // 叠加的维度
  2735. if (this.hasAdjust('stack') && scale.field === yField) {
  2736. values = [];
  2737. arr.forEach(function (obj) {
  2738. values.push(obj[FIELD_ORIGIN_Y]);
  2739. });
  2740. for (var len = values.length; i < len; i++) {
  2741. if (values[0][0] > item) {
  2742. break;
  2743. }
  2744. if (values[values.length - 1][1] <= item) {
  2745. i = values.length - 1;
  2746. break;
  2747. }
  2748. if (values[i][0] <= item && values[i][1] > item) {
  2749. break;
  2750. }
  2751. }
  2752. } else {
  2753. values = scale.values;
  2754. values.sort(function (a, b) {
  2755. return a - b;
  2756. });
  2757. for (var _len2 = values.length; i < _len2; i++) {
  2758. // 如果只有1个点直接返回第1个点
  2759. if (_len2 <= 1) {
  2760. break;
  2761. } // 第1个点和第2个点之间
  2762. if ((values[0] + values[1]) / 2 > item) {
  2763. break;
  2764. } // 中间的点
  2765. if ((values[i - 1] + values[i]) / 2 <= item && (values[i + 1] + values[i]) / 2 > item) {
  2766. break;
  2767. } // 最后2个点
  2768. if ((values[values.length - 2] + values[values.length - 1]) / 2 <= item) {
  2769. i = values.length - 1;
  2770. break;
  2771. }
  2772. }
  2773. }
  2774. var result = values[i];
  2775. return result;
  2776. };
  2777. _proto.getSnapRecords = function getSnapRecords(point) {
  2778. var self = this;
  2779. var coord = self.get('coord');
  2780. var xScale = self.getXScale();
  2781. var yScale = self.getYScale();
  2782. var xfield = xScale.field;
  2783. var dataArray = self.get('dataArray');
  2784. if (!this.get('hasSorted')) {
  2785. this._sort(dataArray);
  2786. }
  2787. var rst = [];
  2788. var invertPoint = coord.invertPoint(point);
  2789. var invertPointX = invertPoint.x;
  2790. if (self.isInCircle() && !coord.transposed && invertPointX > (1 + xScale.rangeMax()) / 2) {
  2791. invertPointX = xScale.rangeMin();
  2792. }
  2793. var xValue = xScale.invert(invertPointX);
  2794. if (!xScale.isCategory) {
  2795. xValue = self._getSnap(xScale, xValue);
  2796. }
  2797. var tmp = [];
  2798. dataArray.forEach(function (data) {
  2799. data.forEach(function (obj) {
  2800. var originValue = isNil(obj[FIELD_ORIGIN]) ? obj[xfield] : obj[FIELD_ORIGIN][xfield];
  2801. if (self._isEqual(originValue, xValue, xScale)) {
  2802. tmp.push(obj);
  2803. }
  2804. });
  2805. }); // special for pie chart
  2806. if (this.hasAdjust('stack') && coord.isPolar && coord.transposed) {
  2807. if (invertPointX >= 0 && invertPointX <= 1) {
  2808. var yValue = yScale.invert(invertPoint.y);
  2809. yValue = self._getSnap(yScale, yValue, tmp);
  2810. tmp.forEach(function (obj) {
  2811. if (isArray(yValue) ? obj[FIELD_ORIGIN_Y].toString() === yValue.toString() : obj[FIELD_ORIGIN_Y] === yValue) {
  2812. rst.push(obj);
  2813. }
  2814. });
  2815. }
  2816. } else {
  2817. rst = tmp;
  2818. }
  2819. return rst;
  2820. };
  2821. _proto.getRecords = function getRecords(value) {
  2822. var _this = this;
  2823. var xScale = this.getXScale();
  2824. var dataArray = this.get('dataArray');
  2825. var xfield = xScale.field;
  2826. return dataArray.map(function (data) {
  2827. for (var len = data.length, i = len - 1; i >= 0; i--) {
  2828. var obj = data[i];
  2829. var originValue = isNil(obj[FIELD_ORIGIN]) ? obj[xfield] : obj[FIELD_ORIGIN][xfield];
  2830. if (_this._isEqual(originValue, value, xScale)) {
  2831. return obj;
  2832. }
  2833. }
  2834. return null;
  2835. });
  2836. };
  2837. _proto._isEqual = function _isEqual(originValue, value, scale) {
  2838. if (scale.type === 'timeCat') {
  2839. return toTimeStamp(originValue) === value;
  2840. }
  2841. return value === originValue;
  2842. };
  2843. _proto.position = function position(field) {
  2844. this._setAttrOptions('position', {
  2845. field: field
  2846. });
  2847. return this;
  2848. };
  2849. _proto.color = function color(field, values) {
  2850. this._createAttrOption('color', field, values, Global.colors);
  2851. return this;
  2852. };
  2853. _proto.size = function size(field, values) {
  2854. this._createAttrOption('size', field, values, Global.sizes);
  2855. return this;
  2856. };
  2857. _proto.shape = function shape(field, values) {
  2858. var type = this.get('type');
  2859. var shapes = Global.shapes[type] || [];
  2860. this._createAttrOption('shape', field, values, shapes);
  2861. return this;
  2862. };
  2863. _proto.style = function style(field, cfg) {
  2864. var styleOptions = this.get('styleOptions');
  2865. if (!styleOptions) {
  2866. styleOptions = {};
  2867. this.set('styleOptions', styleOptions);
  2868. }
  2869. if (isObject(field)) {
  2870. cfg = field;
  2871. field = null;
  2872. }
  2873. var fields;
  2874. if (field) {
  2875. fields = parseFields(field);
  2876. }
  2877. styleOptions.fields = fields;
  2878. styleOptions.style = cfg;
  2879. return this;
  2880. };
  2881. _proto.adjust = function adjust(type) {
  2882. if (isString(type)) {
  2883. type = {
  2884. type: type
  2885. };
  2886. }
  2887. this.set('adjust', type);
  2888. return this;
  2889. };
  2890. _proto.animate = function animate(cfg) {
  2891. this.set('animateCfg', cfg);
  2892. return this;
  2893. };
  2894. _proto.changeData = function changeData(data) {
  2895. this.set('data', data); // 改变数据后,情况度量,因为需要重新实例化
  2896. this.set('scales', {});
  2897. if (!this.get('isInit')) return;
  2898. this.set('isInit', false);
  2899. this.init();
  2900. };
  2901. _proto.clearInner = function clearInner() {
  2902. var container = this.get('container');
  2903. if (container) {
  2904. container.clear(); // container.setMatrix([ 1, 0, 0, 1, 0, 0 ]);
  2905. }
  2906. };
  2907. _proto.reset = function reset() {
  2908. this.set('isInit', false);
  2909. this.set('attrs', {});
  2910. this.set('attrOptions', {});
  2911. this.set('adjust', null);
  2912. this.clearInner();
  2913. };
  2914. _proto.clear = function clear() {
  2915. this.clearInner();
  2916. };
  2917. _proto.destroy = function destroy() {
  2918. this.set('isInit', false);
  2919. this.clear();
  2920. _Base.prototype.destroy.call(this);
  2921. };
  2922. _proto._display = function _display(visible) {
  2923. this.set('visible', visible);
  2924. var container = this.get('container');
  2925. var canvas = container.get('canvas');
  2926. container.set('visible', visible);
  2927. canvas.draw();
  2928. };
  2929. _proto.show = function show() {
  2930. this._display(true);
  2931. };
  2932. _proto.hide = function hide() {
  2933. this._display(false);
  2934. };
  2935. return Geom;
  2936. }(Base);
  2937. var methodCache = {};
  2938. /**
  2939. * 获取计算 ticks 的方法
  2940. * @param key 键值
  2941. * @returns 计算 ticks 的方法
  2942. */
  2943. function getTickMethod(key) {
  2944. return methodCache[key];
  2945. }
  2946. /**
  2947. * 注册计算 ticks 的方法
  2948. * @param key 键值
  2949. * @param method 方法
  2950. */
  2951. function registerTickMethod(key, method) {
  2952. methodCache[key] = method;
  2953. }
  2954. var Scale =
  2955. /** @class */
  2956. function () {
  2957. function Scale(cfg) {
  2958. /**
  2959. * 度量的类型
  2960. */
  2961. this.type = 'base';
  2962. /**
  2963. * 是否分类类型的度量
  2964. */
  2965. this.isCategory = false;
  2966. /**
  2967. * 是否线性度量,有linear, time 度量
  2968. */
  2969. this.isLinear = false;
  2970. /**
  2971. * 是否连续类型的度量,linear,time,log, pow, quantile, quantize 都支持
  2972. */
  2973. this.isContinuous = false;
  2974. /**
  2975. * 是否是常量的度量,传入和传出一致
  2976. */
  2977. this.isIdentity = false;
  2978. this.values = [];
  2979. this.range = [0, 1];
  2980. this.ticks = [];
  2981. this.__cfg__ = cfg;
  2982. this.initCfg();
  2983. this.init();
  2984. } // 对于原始值的必要转换,如分类、时间字段需转换成数值,用transform/map命名可能更好
  2985. Scale.prototype.translate = function (v) {
  2986. return v;
  2987. };
  2988. /** 重新初始化 */
  2989. Scale.prototype.change = function (cfg) {
  2990. // 覆盖配置项,而不替代
  2991. mix(this.__cfg__, cfg);
  2992. this.init();
  2993. };
  2994. Scale.prototype.clone = function () {
  2995. return this.constructor(this.__cfg__);
  2996. };
  2997. /** 获取坐标轴需要的ticks */
  2998. Scale.prototype.getTicks = function () {
  2999. var _this = this;
  3000. return map(this.ticks, function (tick, idx) {
  3001. if (isObject(tick)) {
  3002. // 仅当符合Tick类型时才有意义
  3003. return tick;
  3004. }
  3005. return {
  3006. text: _this.getText(tick, idx),
  3007. tickValue: tick,
  3008. value: _this.scale(tick)
  3009. };
  3010. });
  3011. };
  3012. /** 获取Tick的格式化结果 */
  3013. Scale.prototype.getText = function (value, key) {
  3014. var formatter = this.formatter;
  3015. var res = formatter ? formatter(value, key) : value;
  3016. if (isNil(res) || !isFunction(res.toString)) {
  3017. return '';
  3018. }
  3019. return res.toString();
  3020. }; // 获取配置项中的值,当前 scale 上的值可能会被修改
  3021. Scale.prototype.getConfig = function (key) {
  3022. return this.__cfg__[key];
  3023. }; // scale初始化
  3024. Scale.prototype.init = function () {
  3025. mix(this, this.__cfg__);
  3026. this.setDomain();
  3027. if (isEmpty(this.getConfig('ticks'))) {
  3028. this.ticks = this.calculateTicks();
  3029. }
  3030. }; // 子类上覆盖某些属性,不能直接在类上声明,否则会被覆盖
  3031. Scale.prototype.initCfg = function () {};
  3032. Scale.prototype.setDomain = function () {};
  3033. Scale.prototype.calculateTicks = function () {
  3034. var tickMethod = this.tickMethod;
  3035. var ticks = [];
  3036. if (isString(tickMethod)) {
  3037. var method = getTickMethod(tickMethod);
  3038. if (!method) {
  3039. throw new Error('There is no method to to calculate ticks!');
  3040. }
  3041. ticks = method(this);
  3042. } else if (isFunction(tickMethod)) {
  3043. ticks = tickMethod(this);
  3044. }
  3045. return ticks;
  3046. }; // range 的最小值
  3047. Scale.prototype.rangeMin = function () {
  3048. return head(this.range);
  3049. }; // range 的最大值
  3050. Scale.prototype.rangeMax = function () {
  3051. return last(this.range);
  3052. };
  3053. /** 定义域转 0~1 */
  3054. Scale.prototype.calcPercent = function (value, min, max) {
  3055. if (isNumber(value)) {
  3056. return (value - min) / (max - min);
  3057. }
  3058. return NaN;
  3059. };
  3060. /** 0~1转定义域 */
  3061. Scale.prototype.calcValue = function (percent, min, max) {
  3062. return min + percent * (max - min);
  3063. };
  3064. return Scale;
  3065. }();
  3066. /*! *****************************************************************************
  3067. Copyright (c) Microsoft Corporation.
  3068. Permission to use, copy, modify, and/or distribute this software for any
  3069. purpose with or without fee is hereby granted.
  3070. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
  3071. REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  3072. AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
  3073. INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  3074. LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
  3075. OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  3076. PERFORMANCE OF THIS SOFTWARE.
  3077. ***************************************************************************** */
  3078. /* global Reflect, Promise */
  3079. var extendStatics = function (d, b) {
  3080. extendStatics = Object.setPrototypeOf || {
  3081. __proto__: []
  3082. } instanceof Array && function (d, b) {
  3083. d.__proto__ = b;
  3084. } || function (d, b) {
  3085. for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];
  3086. };
  3087. return extendStatics(d, b);
  3088. };
  3089. function __extends(d, b) {
  3090. extendStatics(d, b);
  3091. function __() {
  3092. this.constructor = d;
  3093. }
  3094. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  3095. }
  3096. function __spreadArrays() {
  3097. for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
  3098. for (var r = Array(s), k = 0, i = 0; i < il; i++) for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) r[k] = a[j];
  3099. return r;
  3100. }
  3101. /**
  3102. * 分类度量
  3103. * @class
  3104. */
  3105. var Category =
  3106. /** @class */
  3107. function (_super) {
  3108. __extends(Category, _super);
  3109. function Category() {
  3110. var _this = _super !== null && _super.apply(this, arguments) || this;
  3111. _this.type = 'cat';
  3112. _this.isCategory = true;
  3113. return _this;
  3114. }
  3115. Category.prototype.translate = function (value) {
  3116. var index = indexOf(this.values, value);
  3117. if (index === -1) {
  3118. return isNumber(value) ? value : NaN;
  3119. }
  3120. return index;
  3121. };
  3122. Category.prototype.scale = function (value) {
  3123. var order = this.translate(value); // 分类数据允许 0.5 范围内调整
  3124. // if (order < this.min - 0.5 || order > this.max + 0.5) {
  3125. // return NaN;
  3126. // }
  3127. var percent = this.calcPercent(order, this.min, this.max);
  3128. return this.calcValue(percent, this.rangeMin(), this.rangeMax());
  3129. };
  3130. Category.prototype.invert = function (scaledValue) {
  3131. var domainRange = this.max - this.min;
  3132. var percent = this.calcPercent(scaledValue, this.rangeMin(), this.rangeMax());
  3133. var idx = Math.round(domainRange * percent) + this.min;
  3134. if (idx < this.min || idx > this.max) {
  3135. return NaN;
  3136. }
  3137. return this.values[idx];
  3138. };
  3139. Category.prototype.getText = function (value) {
  3140. var args = [];
  3141. for (var _i = 1; _i < arguments.length; _i++) {
  3142. args[_i - 1] = arguments[_i];
  3143. }
  3144. var v = value; // value为index
  3145. if (isNumber(value) && !this.values.includes(value)) {
  3146. v = this.values[v];
  3147. }
  3148. return _super.prototype.getText.apply(this, __spreadArrays([v], args));
  3149. }; // 复写属性
  3150. Category.prototype.initCfg = function () {
  3151. this.tickMethod = 'cat';
  3152. }; // 设置 min, max
  3153. Category.prototype.setDomain = function () {
  3154. // 用户有可能设置 min
  3155. if (isNil(this.getConfig('min'))) {
  3156. this.min = 0;
  3157. }
  3158. if (isNil(this.getConfig('max'))) {
  3159. var size = this.values.length;
  3160. this.max = size > 1 ? size - 1 : size;
  3161. }
  3162. };
  3163. return Category;
  3164. }(Scale);
  3165. var token = /d{1,4}|M{1,4}|YY(?:YY)?|S{1,3}|Do|ZZ|Z|([HhMsDm])\1?|[aA]|"[^"]*"|'[^']*'/g;
  3166. var twoDigitsOptional = "[1-9]\\d?";
  3167. var twoDigits = "\\d\\d";
  3168. var threeDigits = "\\d{3}";
  3169. var fourDigits = "\\d{4}";
  3170. var word = "[^\\s]+";
  3171. var literal = /\[([^]*?)\]/gm;
  3172. function shorten(arr, sLen) {
  3173. var newArr = [];
  3174. for (var i = 0, len = arr.length; i < len; i++) {
  3175. newArr.push(arr[i].substr(0, sLen));
  3176. }
  3177. return newArr;
  3178. }
  3179. var monthUpdate = function (arrName) {
  3180. return function (v, i18n) {
  3181. var lowerCaseArr = i18n[arrName].map(function (v) {
  3182. return v.toLowerCase();
  3183. });
  3184. var index = lowerCaseArr.indexOf(v.toLowerCase());
  3185. if (index > -1) {
  3186. return index;
  3187. }
  3188. return null;
  3189. };
  3190. };
  3191. function assign(origObj) {
  3192. var args = [];
  3193. for (var _i = 1; _i < arguments.length; _i++) {
  3194. args[_i - 1] = arguments[_i];
  3195. }
  3196. for (var _a = 0, args_1 = args; _a < args_1.length; _a++) {
  3197. var obj = args_1[_a];
  3198. for (var key in obj) {
  3199. // @ts-ignore ex
  3200. origObj[key] = obj[key];
  3201. }
  3202. }
  3203. return origObj;
  3204. }
  3205. var dayNames = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
  3206. var monthNames = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
  3207. var monthNamesShort = shorten(monthNames, 3);
  3208. var dayNamesShort = shorten(dayNames, 3);
  3209. var defaultI18n = {
  3210. dayNamesShort: dayNamesShort,
  3211. dayNames: dayNames,
  3212. monthNamesShort: monthNamesShort,
  3213. monthNames: monthNames,
  3214. amPm: ["am", "pm"],
  3215. DoFn: function (dayOfMonth) {
  3216. return dayOfMonth + ["th", "st", "nd", "rd"][dayOfMonth % 10 > 3 ? 0 : (dayOfMonth - dayOfMonth % 10 !== 10 ? 1 : 0) * dayOfMonth % 10];
  3217. }
  3218. };
  3219. var globalI18n = assign({}, defaultI18n);
  3220. var setGlobalDateI18n = function (i18n) {
  3221. return globalI18n = assign(globalI18n, i18n);
  3222. };
  3223. var regexEscape = function (str) {
  3224. return str.replace(/[|\\{()[^$+*?.-]/g, "\\$&");
  3225. };
  3226. var pad = function (val, len) {
  3227. if (len === void 0) {
  3228. len = 2;
  3229. }
  3230. val = String(val);
  3231. while (val.length < len) {
  3232. val = "0" + val;
  3233. }
  3234. return val;
  3235. };
  3236. var formatFlags = {
  3237. D: function (dateObj) {
  3238. return String(dateObj.getDate());
  3239. },
  3240. DD: function (dateObj) {
  3241. return pad(dateObj.getDate());
  3242. },
  3243. Do: function (dateObj, i18n) {
  3244. return i18n.DoFn(dateObj.getDate());
  3245. },
  3246. d: function (dateObj) {
  3247. return String(dateObj.getDay());
  3248. },
  3249. dd: function (dateObj) {
  3250. return pad(dateObj.getDay());
  3251. },
  3252. ddd: function (dateObj, i18n) {
  3253. return i18n.dayNamesShort[dateObj.getDay()];
  3254. },
  3255. dddd: function (dateObj, i18n) {
  3256. return i18n.dayNames[dateObj.getDay()];
  3257. },
  3258. M: function (dateObj) {
  3259. return String(dateObj.getMonth() + 1);
  3260. },
  3261. MM: function (dateObj) {
  3262. return pad(dateObj.getMonth() + 1);
  3263. },
  3264. MMM: function (dateObj, i18n) {
  3265. return i18n.monthNamesShort[dateObj.getMonth()];
  3266. },
  3267. MMMM: function (dateObj, i18n) {
  3268. return i18n.monthNames[dateObj.getMonth()];
  3269. },
  3270. YY: function (dateObj) {
  3271. return pad(String(dateObj.getFullYear()), 4).substr(2);
  3272. },
  3273. YYYY: function (dateObj) {
  3274. return pad(dateObj.getFullYear(), 4);
  3275. },
  3276. h: function (dateObj) {
  3277. return String(dateObj.getHours() % 12 || 12);
  3278. },
  3279. hh: function (dateObj) {
  3280. return pad(dateObj.getHours() % 12 || 12);
  3281. },
  3282. H: function (dateObj) {
  3283. return String(dateObj.getHours());
  3284. },
  3285. HH: function (dateObj) {
  3286. return pad(dateObj.getHours());
  3287. },
  3288. m: function (dateObj) {
  3289. return String(dateObj.getMinutes());
  3290. },
  3291. mm: function (dateObj) {
  3292. return pad(dateObj.getMinutes());
  3293. },
  3294. s: function (dateObj) {
  3295. return String(dateObj.getSeconds());
  3296. },
  3297. ss: function (dateObj) {
  3298. return pad(dateObj.getSeconds());
  3299. },
  3300. S: function (dateObj) {
  3301. return String(Math.round(dateObj.getMilliseconds() / 100));
  3302. },
  3303. SS: function (dateObj) {
  3304. return pad(Math.round(dateObj.getMilliseconds() / 10), 2);
  3305. },
  3306. SSS: function (dateObj) {
  3307. return pad(dateObj.getMilliseconds(), 3);
  3308. },
  3309. a: function (dateObj, i18n) {
  3310. return dateObj.getHours() < 12 ? i18n.amPm[0] : i18n.amPm[1];
  3311. },
  3312. A: function (dateObj, i18n) {
  3313. return dateObj.getHours() < 12 ? i18n.amPm[0].toUpperCase() : i18n.amPm[1].toUpperCase();
  3314. },
  3315. ZZ: function (dateObj) {
  3316. var offset = dateObj.getTimezoneOffset();
  3317. return (offset > 0 ? "-" : "+") + pad(Math.floor(Math.abs(offset) / 60) * 100 + Math.abs(offset) % 60, 4);
  3318. },
  3319. Z: function (dateObj) {
  3320. var offset = dateObj.getTimezoneOffset();
  3321. return (offset > 0 ? "-" : "+") + pad(Math.floor(Math.abs(offset) / 60), 2) + ":" + pad(Math.abs(offset) % 60, 2);
  3322. }
  3323. };
  3324. var monthParse = function (v) {
  3325. return +v - 1;
  3326. };
  3327. var emptyDigits = [null, twoDigitsOptional];
  3328. var emptyWord = [null, word];
  3329. var amPm = ["isPm", word, function (v, i18n) {
  3330. var val = v.toLowerCase();
  3331. if (val === i18n.amPm[0]) {
  3332. return 0;
  3333. } else if (val === i18n.amPm[1]) {
  3334. return 1;
  3335. }
  3336. return null;
  3337. }];
  3338. var timezoneOffset = ["timezoneOffset", "[^\\s]*?[\\+\\-]\\d\\d:?\\d\\d|[^\\s]*?Z?", function (v) {
  3339. var parts = (v + "").match(/([+-]|\d\d)/gi);
  3340. if (parts) {
  3341. var minutes = +parts[1] * 60 + parseInt(parts[2], 10);
  3342. return parts[0] === "+" ? minutes : -minutes;
  3343. }
  3344. return 0;
  3345. }];
  3346. var parseFlags = {
  3347. D: ["day", twoDigitsOptional],
  3348. DD: ["day", twoDigits],
  3349. Do: ["day", twoDigitsOptional + word, function (v) {
  3350. return parseInt(v, 10);
  3351. }],
  3352. M: ["month", twoDigitsOptional, monthParse],
  3353. MM: ["month", twoDigits, monthParse],
  3354. YY: ["year", twoDigits, function (v) {
  3355. var now = new Date();
  3356. var cent = +("" + now.getFullYear()).substr(0, 2);
  3357. return +("" + (+v > 68 ? cent - 1 : cent) + v);
  3358. }],
  3359. h: ["hour", twoDigitsOptional, undefined, "isPm"],
  3360. hh: ["hour", twoDigits, undefined, "isPm"],
  3361. H: ["hour", twoDigitsOptional],
  3362. HH: ["hour", twoDigits],
  3363. m: ["minute", twoDigitsOptional],
  3364. mm: ["minute", twoDigits],
  3365. s: ["second", twoDigitsOptional],
  3366. ss: ["second", twoDigits],
  3367. YYYY: ["year", fourDigits],
  3368. S: ["millisecond", "\\d", function (v) {
  3369. return +v * 100;
  3370. }],
  3371. SS: ["millisecond", twoDigits, function (v) {
  3372. return +v * 10;
  3373. }],
  3374. SSS: ["millisecond", threeDigits],
  3375. d: emptyDigits,
  3376. dd: emptyDigits,
  3377. ddd: emptyWord,
  3378. dddd: emptyWord,
  3379. MMM: ["month", word, monthUpdate("monthNamesShort")],
  3380. MMMM: ["month", word, monthUpdate("monthNames")],
  3381. a: amPm,
  3382. A: amPm,
  3383. ZZ: timezoneOffset,
  3384. Z: timezoneOffset
  3385. }; // Some common format strings
  3386. var globalMasks = {
  3387. default: "ddd MMM DD YYYY HH:mm:ss",
  3388. shortDate: "M/D/YY",
  3389. mediumDate: "MMM D, YYYY",
  3390. longDate: "MMMM D, YYYY",
  3391. fullDate: "dddd, MMMM D, YYYY",
  3392. isoDate: "YYYY-MM-DD",
  3393. isoDateTime: "YYYY-MM-DDTHH:mm:ssZ",
  3394. shortTime: "HH:mm",
  3395. mediumTime: "HH:mm:ss",
  3396. longTime: "HH:mm:ss.SSS"
  3397. };
  3398. var setGlobalDateMasks = function (masks) {
  3399. return assign(globalMasks, masks);
  3400. };
  3401. /***
  3402. * Format a date
  3403. * @method format
  3404. * @param {Date|number} dateObj
  3405. * @param {string} mask Format of the date, i.e. 'mm-dd-yy' or 'shortDate'
  3406. * @returns {string} Formatted date string
  3407. */
  3408. var format = function (dateObj, mask, i18n) {
  3409. if (mask === void 0) {
  3410. mask = globalMasks["default"];
  3411. }
  3412. if (i18n === void 0) {
  3413. i18n = {};
  3414. }
  3415. if (typeof dateObj === "number") {
  3416. dateObj = new Date(dateObj);
  3417. }
  3418. if (Object.prototype.toString.call(dateObj) !== "[object Date]" || isNaN(dateObj.getTime())) {
  3419. throw new Error("Invalid Date pass to format");
  3420. }
  3421. mask = globalMasks[mask] || mask;
  3422. var literals = []; // Make literals inactive by replacing them with @@@
  3423. mask = mask.replace(literal, function ($0, $1) {
  3424. literals.push($1);
  3425. return "@@@";
  3426. });
  3427. var combinedI18nSettings = assign(assign({}, globalI18n), i18n); // Apply formatting rules
  3428. mask = mask.replace(token, function ($0) {
  3429. return formatFlags[$0](dateObj, combinedI18nSettings);
  3430. }); // Inline literal values back into the formatted value
  3431. return mask.replace(/@@@/g, function () {
  3432. return literals.shift();
  3433. });
  3434. };
  3435. /**
  3436. * Parse a date string into a Javascript Date object /
  3437. * @method parse
  3438. * @param {string} dateStr Date string
  3439. * @param {string} format Date parse format
  3440. * @param {i18n} I18nSettingsOptional Full or subset of I18N settings
  3441. * @returns {Date|null} Returns Date object. Returns null what date string is invalid or doesn't match format
  3442. */
  3443. function parse(dateStr, format, i18n) {
  3444. if (i18n === void 0) {
  3445. i18n = {};
  3446. }
  3447. if (typeof format !== "string") {
  3448. throw new Error("Invalid format in fecha parse");
  3449. } // Check to see if the format is actually a mask
  3450. format = globalMasks[format] || format; // Avoid regular expression denial of service, fail early for really long strings
  3451. // https://www.owasp.org/index.php/Regular_expression_Denial_of_Service_-_ReDoS
  3452. if (dateStr.length > 1000) {
  3453. return null;
  3454. } // Default to the beginning of the year.
  3455. var today = new Date();
  3456. var dateInfo = {
  3457. year: today.getFullYear(),
  3458. month: 0,
  3459. day: 1,
  3460. hour: 0,
  3461. minute: 0,
  3462. second: 0,
  3463. millisecond: 0,
  3464. isPm: null,
  3465. timezoneOffset: null
  3466. };
  3467. var parseInfo = [];
  3468. var literals = []; // Replace all the literals with @@@. Hopefully a string that won't exist in the format
  3469. var newFormat = format.replace(literal, function ($0, $1) {
  3470. literals.push(regexEscape($1));
  3471. return "@@@";
  3472. });
  3473. var specifiedFields = {};
  3474. var requiredFields = {}; // Change every token that we find into the correct regex
  3475. newFormat = regexEscape(newFormat).replace(token, function ($0) {
  3476. var info = parseFlags[$0];
  3477. var field = info[0],
  3478. regex = info[1],
  3479. requiredField = info[3]; // Check if the person has specified the same field twice. This will lead to confusing results.
  3480. if (specifiedFields[field]) {
  3481. throw new Error("Invalid format. " + field + " specified twice in format");
  3482. }
  3483. specifiedFields[field] = true; // Check if there are any required fields. For instance, 12 hour time requires AM/PM specified
  3484. if (requiredField) {
  3485. requiredFields[requiredField] = true;
  3486. }
  3487. parseInfo.push(info);
  3488. return "(" + regex + ")";
  3489. }); // Check all the required fields are present
  3490. Object.keys(requiredFields).forEach(function (field) {
  3491. if (!specifiedFields[field]) {
  3492. throw new Error("Invalid format. " + field + " is required in specified format");
  3493. }
  3494. }); // Add back all the literals after
  3495. newFormat = newFormat.replace(/@@@/g, function () {
  3496. return literals.shift();
  3497. }); // Check if the date string matches the format. If it doesn't return null
  3498. var matches = dateStr.match(new RegExp(newFormat, "i"));
  3499. if (!matches) {
  3500. return null;
  3501. }
  3502. var combinedI18nSettings = assign(assign({}, globalI18n), i18n); // For each match, call the parser function for that date part
  3503. for (var i = 1; i < matches.length; i++) {
  3504. var _a = parseInfo[i - 1],
  3505. field = _a[0],
  3506. parser = _a[2];
  3507. var value = parser ? parser(matches[i], combinedI18nSettings) : +matches[i]; // If the parser can't make sense of the value, return null
  3508. if (value == null) {
  3509. return null;
  3510. }
  3511. dateInfo[field] = value;
  3512. }
  3513. if (dateInfo.isPm === 1 && dateInfo.hour != null && +dateInfo.hour !== 12) {
  3514. dateInfo.hour = +dateInfo.hour + 12;
  3515. } else if (dateInfo.isPm === 0 && +dateInfo.hour === 12) {
  3516. dateInfo.hour = 0;
  3517. }
  3518. var dateWithoutTZ = new Date(dateInfo.year, dateInfo.month, dateInfo.day, dateInfo.hour, dateInfo.minute, dateInfo.second, dateInfo.millisecond);
  3519. var validateFields = [["month", "getMonth"], ["day", "getDate"], ["hour", "getHours"], ["minute", "getMinutes"], ["second", "getSeconds"]];
  3520. for (var i = 0, len = validateFields.length; i < len; i++) {
  3521. // Check to make sure the date field is within the allowed range. Javascript dates allows values
  3522. // outside the allowed range. If the values don't match the value was invalid
  3523. if (specifiedFields[validateFields[i][0]] && dateInfo[validateFields[i][0]] !== dateWithoutTZ[validateFields[i][1]]()) {
  3524. return null;
  3525. }
  3526. }
  3527. if (dateInfo.timezoneOffset == null) {
  3528. return dateWithoutTZ;
  3529. }
  3530. return new Date(Date.UTC(dateInfo.year, dateInfo.month, dateInfo.day, dateInfo.hour, dateInfo.minute - dateInfo.timezoneOffset, dateInfo.second, dateInfo.millisecond));
  3531. }
  3532. var fecha = {
  3533. format: format,
  3534. parse: parse,
  3535. defaultI18n: defaultI18n,
  3536. setGlobalDateI18n: setGlobalDateI18n,
  3537. setGlobalDateMasks: setGlobalDateMasks
  3538. };
  3539. var fecha1 = /*#__PURE__*/Object.freeze({
  3540. __proto__: null,
  3541. 'default': fecha,
  3542. assign: assign,
  3543. format: format,
  3544. parse: parse,
  3545. defaultI18n: defaultI18n,
  3546. setGlobalDateI18n: setGlobalDateI18n,
  3547. setGlobalDateMasks: setGlobalDateMasks
  3548. });
  3549. /**
  3550. * 二分右侧查找
  3551. * https://github.com/d3/d3-array/blob/master/src/bisector.js
  3552. */
  3553. function bisector (getter) {
  3554. /**
  3555. * x: 目标值
  3556. * lo: 起始位置
  3557. * hi: 结束位置
  3558. */
  3559. return function (a, x, _lo, _hi) {
  3560. var lo = isNil(_lo) ? 0 : _lo;
  3561. var hi = isNil(_hi) ? a.length : _hi;
  3562. while (lo < hi) {
  3563. var mid = lo + hi >>> 1;
  3564. if (getter(a[mid]) > x) {
  3565. hi = mid;
  3566. } else {
  3567. lo = mid + 1;
  3568. }
  3569. }
  3570. return lo;
  3571. };
  3572. }
  3573. var FORMAT_METHOD = 'format';
  3574. function timeFormat(time, mask) {
  3575. var method = fecha1[FORMAT_METHOD] || fecha[FORMAT_METHOD];
  3576. return method(time, mask);
  3577. }
  3578. /**
  3579. * 转换成时间戳
  3580. * @param value 时间值
  3581. */
  3582. function toTimeStamp$1(value) {
  3583. if (isString(value)) {
  3584. if (value.indexOf('T') > 0) {
  3585. value = new Date(value).getTime();
  3586. } else {
  3587. // new Date('2010/01/10') 和 new Date('2010-01-10') 的差别在于:
  3588. // 如果仅有年月日时,前者是带有时区的: Fri Jan 10 2020 02:40:13 GMT+0800 (中国标准时间)
  3589. // 后者会格式化成 Sun Jan 10 2010 08:00:00 GMT+0800 (中国标准时间)
  3590. value = new Date(value.replace(/-/gi, '/')).getTime();
  3591. }
  3592. }
  3593. if (isDate(value)) {
  3594. value = value.getTime();
  3595. }
  3596. return value;
  3597. }
  3598. var SECOND = 1000;
  3599. var MINUTE = 60 * SECOND;
  3600. var HOUR = 60 * MINUTE;
  3601. var DAY = 24 * HOUR;
  3602. var MONTH = DAY * 31;
  3603. var YEAR = DAY * 365;
  3604. var intervals = [['HH:mm:ss', SECOND], ['HH:mm:ss', SECOND * 10], ['HH:mm:ss', SECOND * 30], ['HH:mm', MINUTE], ['HH:mm', MINUTE * 10], ['HH:mm', MINUTE * 30], ['HH', HOUR], ['HH', HOUR * 6], ['HH', HOUR * 12], ['YYYY-MM-DD', DAY], ['YYYY-MM-DD', DAY * 4], ['YYYY-WW', DAY * 7], ['YYYY-MM', MONTH], ['YYYY-MM', MONTH * 4], ['YYYY-MM', MONTH * 6], ['YYYY', DAY * 380]];
  3605. function getTickInterval(min, max, tickCount) {
  3606. var target = (max - min) / tickCount;
  3607. var idx = bisector(function (o) {
  3608. return o[1];
  3609. })(intervals, target) - 1;
  3610. var interval = intervals[idx];
  3611. if (idx < 0) {
  3612. interval = intervals[0];
  3613. } else if (idx >= intervals.length) {
  3614. interval = last(intervals);
  3615. }
  3616. return interval;
  3617. }
  3618. /**
  3619. * 时间分类度量
  3620. * @class
  3621. */
  3622. var TimeCat =
  3623. /** @class */
  3624. function (_super) {
  3625. __extends(TimeCat, _super);
  3626. function TimeCat() {
  3627. var _this = _super !== null && _super.apply(this, arguments) || this;
  3628. _this.type = 'timeCat';
  3629. return _this;
  3630. }
  3631. /**
  3632. * @override
  3633. */
  3634. TimeCat.prototype.translate = function (value) {
  3635. value = toTimeStamp$1(value);
  3636. var index = this.values.indexOf(value);
  3637. if (index === -1) {
  3638. if (isNumber(value) && value < this.values.length) {
  3639. index = value;
  3640. } else {
  3641. index = NaN;
  3642. }
  3643. }
  3644. return index;
  3645. };
  3646. /**
  3647. * 由于时间类型数据需要转换一下,所以复写 getText
  3648. * @override
  3649. */
  3650. TimeCat.prototype.getText = function (value, tickIndex) {
  3651. var index = this.translate(value);
  3652. if (index > -1) {
  3653. var result = this.values[index];
  3654. var formatter = this.formatter;
  3655. result = formatter ? formatter(result, tickIndex) : timeFormat(result, this.mask);
  3656. return result;
  3657. }
  3658. return value;
  3659. };
  3660. TimeCat.prototype.initCfg = function () {
  3661. this.tickMethod = 'time-cat';
  3662. this.mask = 'YYYY-MM-DD';
  3663. this.tickCount = 7; // 一般时间数据会显示 7, 14, 30 天的数字
  3664. };
  3665. TimeCat.prototype.setDomain = function () {
  3666. var values = this.values; // 针对时间分类类型,会将时间统一转换为时间戳
  3667. each(values, function (v, i) {
  3668. values[i] = toTimeStamp$1(v);
  3669. });
  3670. values.sort(function (v1, v2) {
  3671. return v1 - v2;
  3672. });
  3673. _super.prototype.setDomain.call(this);
  3674. };
  3675. return TimeCat;
  3676. }(Category);
  3677. /**
  3678. * 连续度量的基类
  3679. * @class
  3680. */
  3681. var Continuous =
  3682. /** @class */
  3683. function (_super) {
  3684. __extends(Continuous, _super);
  3685. function Continuous() {
  3686. var _this = _super !== null && _super.apply(this, arguments) || this;
  3687. _this.isContinuous = true;
  3688. return _this;
  3689. }
  3690. Continuous.prototype.scale = function (value) {
  3691. if (isNil(value)) {
  3692. return NaN;
  3693. }
  3694. var rangeMin = this.rangeMin();
  3695. var rangeMax = this.rangeMax();
  3696. var max = this.max;
  3697. var min = this.min;
  3698. if (max === min) {
  3699. return rangeMin;
  3700. }
  3701. var percent = this.getScalePercent(value);
  3702. return rangeMin + percent * (rangeMax - rangeMin);
  3703. };
  3704. Continuous.prototype.init = function () {
  3705. _super.prototype.init.call(this); // init 完成后保证 min, max 包含 ticks 的范围
  3706. var ticks = this.ticks;
  3707. var firstTick = head(ticks);
  3708. var lastTick = last(ticks);
  3709. if (firstTick < this.min) {
  3710. this.min = firstTick;
  3711. }
  3712. if (lastTick > this.max) {
  3713. this.max = lastTick;
  3714. } // strict-limit 方式
  3715. if (!isNil(this.minLimit)) {
  3716. this.min = firstTick;
  3717. }
  3718. if (!isNil(this.maxLimit)) {
  3719. this.max = lastTick;
  3720. }
  3721. };
  3722. Continuous.prototype.setDomain = function () {
  3723. var _a = getRange(this.values),
  3724. min = _a.min,
  3725. max = _a.max;
  3726. if (isNil(this.min)) {
  3727. this.min = min;
  3728. }
  3729. if (isNil(this.max)) {
  3730. this.max = max;
  3731. }
  3732. if (this.min > this.max) {
  3733. this.min = min;
  3734. this.max = max;
  3735. }
  3736. };
  3737. Continuous.prototype.calculateTicks = function () {
  3738. var _this = this;
  3739. var ticks = _super.prototype.calculateTicks.call(this);
  3740. if (!this.nice) {
  3741. ticks = filter(ticks, function (tick) {
  3742. return tick >= _this.min && tick <= _this.max;
  3743. });
  3744. }
  3745. return ticks;
  3746. }; // 计算原始值值占的百分比
  3747. Continuous.prototype.getScalePercent = function (value) {
  3748. var max = this.max;
  3749. var min = this.min;
  3750. return (value - min) / (max - min);
  3751. };
  3752. Continuous.prototype.getInvertPercent = function (value) {
  3753. return (value - this.rangeMin()) / (this.rangeMax() - this.rangeMin());
  3754. };
  3755. return Continuous;
  3756. }(Scale);
  3757. /**
  3758. * 线性度量
  3759. * @class
  3760. */
  3761. var Linear =
  3762. /** @class */
  3763. function (_super) {
  3764. __extends(Linear, _super);
  3765. function Linear() {
  3766. var _this = _super !== null && _super.apply(this, arguments) || this;
  3767. _this.type = 'linear';
  3768. _this.isLinear = true;
  3769. return _this;
  3770. }
  3771. Linear.prototype.invert = function (value) {
  3772. var percent = this.getInvertPercent(value);
  3773. return this.min + percent * (this.max - this.min);
  3774. };
  3775. Linear.prototype.initCfg = function () {
  3776. this.tickMethod = 'wilkinson-extended';
  3777. this.nice = false;
  3778. };
  3779. return Linear;
  3780. }(Continuous);
  3781. // 虽然数学上 b 不支持负数,但是这里需要支持 负数
  3782. function calBase(a, b) {
  3783. var e = Math.E;
  3784. var value;
  3785. if (b >= 0) {
  3786. value = Math.pow(e, Math.log(b) / a); // 使用换底公式求底
  3787. } else {
  3788. value = Math.pow(e, Math.log(-b) / a) * -1; // 使用换底公式求底
  3789. }
  3790. return value;
  3791. }
  3792. function log(a, b) {
  3793. if (a === 1) {
  3794. return 1;
  3795. }
  3796. return Math.log(b) / Math.log(a);
  3797. }
  3798. function getLogPositiveMin(values, base, max) {
  3799. if (isNil(max)) {
  3800. max = Math.max.apply(null, values);
  3801. }
  3802. var positiveMin = max;
  3803. each(values, function (value) {
  3804. if (value > 0 && value < positiveMin) {
  3805. positiveMin = value;
  3806. }
  3807. });
  3808. if (positiveMin === max) {
  3809. positiveMin = max / base;
  3810. }
  3811. if (positiveMin > 1) {
  3812. positiveMin = 1;
  3813. }
  3814. return positiveMin;
  3815. }
  3816. /**
  3817. * Log 度量,处理非均匀分布
  3818. */
  3819. var Log =
  3820. /** @class */
  3821. function (_super) {
  3822. __extends(Log, _super);
  3823. function Log() {
  3824. var _this = _super !== null && _super.apply(this, arguments) || this;
  3825. _this.type = 'log';
  3826. return _this;
  3827. }
  3828. /**
  3829. * @override
  3830. */
  3831. Log.prototype.invert = function (value) {
  3832. var base = this.base;
  3833. var max = log(base, this.max);
  3834. var rangeMin = this.rangeMin();
  3835. var range = this.rangeMax() - rangeMin;
  3836. var min;
  3837. var positiveMin = this.positiveMin;
  3838. if (positiveMin) {
  3839. if (value === 0) {
  3840. return 0;
  3841. }
  3842. min = log(base, positiveMin / base);
  3843. var appendPercent = 1 / (max - min) * range; // 0 到 positiveMin的占比
  3844. if (value < appendPercent) {
  3845. // 落到 0 - positiveMin 之间
  3846. return value / appendPercent * positiveMin;
  3847. }
  3848. } else {
  3849. min = log(base, this.min);
  3850. }
  3851. var percent = (value - rangeMin) / range;
  3852. var tmp = percent * (max - min) + min;
  3853. return Math.pow(base, tmp);
  3854. };
  3855. Log.prototype.initCfg = function () {
  3856. this.tickMethod = 'log';
  3857. this.base = 10;
  3858. this.tickCount = 6;
  3859. this.nice = true;
  3860. }; // 设置
  3861. Log.prototype.setDomain = function () {
  3862. _super.prototype.setDomain.call(this);
  3863. var min = this.min;
  3864. if (min < 0) {
  3865. throw new Error('When you use log scale, the minimum value must be greater than zero!');
  3866. }
  3867. if (min === 0) {
  3868. this.positiveMin = getLogPositiveMin(this.values, this.base, this.max);
  3869. }
  3870. }; // 根据当前值获取占比
  3871. Log.prototype.getScalePercent = function (value) {
  3872. var max = this.max;
  3873. var min = this.min;
  3874. if (max === min) {
  3875. return 0;
  3876. } // 如果值小于等于0,则按照0处理
  3877. if (value <= 0) {
  3878. return 0;
  3879. }
  3880. var base = this.base;
  3881. var positiveMin = this.positiveMin; // 如果min == 0, 则根据比0大的最小值,计算比例关系。这个最小值作为坐标轴上的第二个tick,第一个是0但是不显示
  3882. if (positiveMin) {
  3883. min = positiveMin * 1 / base;
  3884. }
  3885. var percent; // 如果数值小于次小值,那么就计算 value / 次小值 占整体的比例
  3886. if (value < positiveMin) {
  3887. percent = value / positiveMin / (log(base, max) - log(base, min));
  3888. } else {
  3889. percent = (log(base, value) - log(base, min)) / (log(base, max) - log(base, min));
  3890. }
  3891. return percent;
  3892. };
  3893. return Log;
  3894. }(Continuous);
  3895. /**
  3896. * Pow 度量,处理非均匀分布
  3897. */
  3898. var Pow =
  3899. /** @class */
  3900. function (_super) {
  3901. __extends(Pow, _super);
  3902. function Pow() {
  3903. var _this = _super !== null && _super.apply(this, arguments) || this;
  3904. _this.type = 'pow';
  3905. return _this;
  3906. }
  3907. /**
  3908. * @override
  3909. */
  3910. Pow.prototype.invert = function (value) {
  3911. var percent = this.getInvertPercent(value);
  3912. var exponent = this.exponent;
  3913. var max = calBase(exponent, this.max);
  3914. var min = calBase(exponent, this.min);
  3915. var tmp = percent * (max - min) + min;
  3916. var factor = tmp >= 0 ? 1 : -1;
  3917. return Math.pow(tmp, exponent) * factor;
  3918. };
  3919. Pow.prototype.initCfg = function () {
  3920. this.tickMethod = 'pow';
  3921. this.exponent = 2;
  3922. this.tickCount = 5;
  3923. this.nice = true;
  3924. }; // 获取度量计算时,value占的定义域百分比
  3925. Pow.prototype.getScalePercent = function (value) {
  3926. var max = this.max;
  3927. var min = this.min;
  3928. if (max === min) {
  3929. return 0;
  3930. }
  3931. var exponent = this.exponent;
  3932. var percent = (calBase(exponent, value) - calBase(exponent, min)) / (calBase(exponent, max) - calBase(exponent, min));
  3933. return percent;
  3934. };
  3935. return Pow;
  3936. }(Continuous);
  3937. /**
  3938. * 时间度量
  3939. * @class
  3940. */
  3941. var Time =
  3942. /** @class */
  3943. function (_super) {
  3944. __extends(Time, _super);
  3945. function Time() {
  3946. var _this = _super !== null && _super.apply(this, arguments) || this;
  3947. _this.type = 'time';
  3948. return _this;
  3949. }
  3950. /**
  3951. * @override
  3952. */
  3953. Time.prototype.getText = function (value, index) {
  3954. var numberValue = this.translate(value);
  3955. var formatter = this.formatter;
  3956. return formatter ? formatter(numberValue, index) : timeFormat(numberValue, this.mask);
  3957. };
  3958. /**
  3959. * @override
  3960. */
  3961. Time.prototype.scale = function (value) {
  3962. var v = value;
  3963. if (isString(v) || isDate(v)) {
  3964. v = this.translate(v);
  3965. }
  3966. return _super.prototype.scale.call(this, v);
  3967. };
  3968. /**
  3969. * 将时间转换成数字
  3970. * @override
  3971. */
  3972. Time.prototype.translate = function (v) {
  3973. return toTimeStamp$1(v);
  3974. };
  3975. Time.prototype.initCfg = function () {
  3976. this.tickMethod = 'time-pretty';
  3977. this.mask = 'YYYY-MM-DD';
  3978. this.tickCount = 7;
  3979. this.nice = false;
  3980. };
  3981. Time.prototype.setDomain = function () {
  3982. var values = this.values; // 是否设置了 min, max,而不是直接取 this.min, this.max
  3983. var minConfig = this.getConfig('min');
  3984. var maxConfig = this.getConfig('max'); // 如果设置了 min,max 则转换成时间戳
  3985. if (!isNil(minConfig) || !isNumber(minConfig)) {
  3986. this.min = this.translate(this.min);
  3987. }
  3988. if (!isNil(maxConfig) || !isNumber(maxConfig)) {
  3989. this.max = this.translate(this.max);
  3990. } // 没有设置 min, max 时
  3991. if (values && values.length) {
  3992. // 重新计算最大最小值
  3993. var timeStamps_1 = [];
  3994. var min_1 = Infinity; // 最小值
  3995. var secondMin_1 = min_1; // 次小值
  3996. var max_1 = 0; // 使用一个循环,计算min,max,secondMin
  3997. each(values, function (v) {
  3998. var timeStamp = toTimeStamp$1(v);
  3999. if (isNaN(timeStamp)) {
  4000. throw new TypeError("Invalid Time: " + v + " in time scale!");
  4001. }
  4002. if (min_1 > timeStamp) {
  4003. secondMin_1 = min_1;
  4004. min_1 = timeStamp;
  4005. } else if (secondMin_1 > timeStamp) {
  4006. secondMin_1 = timeStamp;
  4007. }
  4008. if (max_1 < timeStamp) {
  4009. max_1 = timeStamp;
  4010. }
  4011. timeStamps_1.push(timeStamp);
  4012. }); // 存在多个值时,设置最小间距
  4013. if (values.length > 1) {
  4014. this.minTickInterval = secondMin_1 - min_1;
  4015. }
  4016. if (isNil(minConfig)) {
  4017. this.min = min_1;
  4018. }
  4019. if (isNil(maxConfig)) {
  4020. this.max = max_1;
  4021. }
  4022. }
  4023. };
  4024. return Time;
  4025. }(Linear);
  4026. /**
  4027. * 分段度量
  4028. */
  4029. var Quantize =
  4030. /** @class */
  4031. function (_super) {
  4032. __extends(Quantize, _super);
  4033. function Quantize() {
  4034. var _this = _super !== null && _super.apply(this, arguments) || this;
  4035. _this.type = 'quantize';
  4036. return _this;
  4037. }
  4038. Quantize.prototype.invert = function (value) {
  4039. var ticks = this.ticks;
  4040. var length = ticks.length;
  4041. var percent = this.getInvertPercent(value);
  4042. var minIndex = Math.floor(percent * (length - 1)); // 最后一个
  4043. if (minIndex >= length - 1) {
  4044. return last(ticks);
  4045. } // 超出左边界, 则取第一个
  4046. if (minIndex < 0) {
  4047. return head(ticks);
  4048. }
  4049. var minTick = ticks[minIndex];
  4050. var nextTick = ticks[minIndex + 1]; // 比当前值小的 tick 在度量上的占比
  4051. var minIndexPercent = minIndex / (length - 1);
  4052. var maxIndexPercent = (minIndex + 1) / (length - 1);
  4053. return minTick + (percent - minIndexPercent) / (maxIndexPercent - minIndexPercent) * (nextTick - minTick);
  4054. };
  4055. Quantize.prototype.initCfg = function () {
  4056. this.tickMethod = 'r-pretty';
  4057. this.tickCount = 5;
  4058. this.nice = true;
  4059. };
  4060. Quantize.prototype.calculateTicks = function () {
  4061. var ticks = _super.prototype.calculateTicks.call(this);
  4062. if (!this.nice) {
  4063. // 如果 nice = false ,补充 min, max
  4064. if (last(ticks) !== this.max) {
  4065. ticks.push(this.max);
  4066. }
  4067. if (head(ticks) !== this.min) {
  4068. ticks.unshift(this.min);
  4069. }
  4070. }
  4071. return ticks;
  4072. }; // 计算当前值在刻度中的占比
  4073. Quantize.prototype.getScalePercent = function (value) {
  4074. var ticks = this.ticks; // 超出左边界
  4075. if (value < head(ticks)) {
  4076. return 0;
  4077. } // 超出右边界
  4078. if (value > last(ticks)) {
  4079. return 1;
  4080. }
  4081. var minIndex = 0;
  4082. each(ticks, function (tick, index) {
  4083. if (value >= tick) {
  4084. minIndex = index;
  4085. } else {
  4086. return false;
  4087. }
  4088. });
  4089. return minIndex / (ticks.length - 1);
  4090. };
  4091. return Quantize;
  4092. }(Continuous);
  4093. var Quantile =
  4094. /** @class */
  4095. function (_super) {
  4096. __extends(Quantile, _super);
  4097. function Quantile() {
  4098. var _this = _super !== null && _super.apply(this, arguments) || this;
  4099. _this.type = 'quantile';
  4100. return _this;
  4101. }
  4102. Quantile.prototype.initCfg = function () {
  4103. this.tickMethod = 'quantile';
  4104. this.tickCount = 5;
  4105. this.nice = true;
  4106. };
  4107. return Quantile;
  4108. }(Quantize);
  4109. var map$1 = {};
  4110. function getClass(key) {
  4111. return map$1[key];
  4112. }
  4113. function registerClass(key, cls) {
  4114. if (getClass(key)) {
  4115. throw new Error("type '" + key + "' existed.");
  4116. }
  4117. map$1[key] = cls;
  4118. }
  4119. /**
  4120. * identity scale原则上是定义域和值域一致,scale/invert方法也是一致的
  4121. * 参考R的实现:https://github.com/r-lib/scales/blob/master/R/pal-identity.r
  4122. * 参考d3的实现(做了下转型):https://github.com/d3/d3-scale/blob/master/src/identity.js
  4123. */
  4124. var Identity =
  4125. /** @class */
  4126. function (_super) {
  4127. __extends(Identity, _super);
  4128. function Identity() {
  4129. var _this = _super !== null && _super.apply(this, arguments) || this;
  4130. _this.type = 'identity';
  4131. _this.isIdentity = true;
  4132. return _this;
  4133. }
  4134. Identity.prototype.calculateTicks = function () {
  4135. return this.values;
  4136. };
  4137. Identity.prototype.scale = function (value) {
  4138. // 如果传入的值不等于 identity 的值,则直接返回,用于一维图时的 dodge
  4139. if (this.values[0] !== value && isNumber(value)) {
  4140. return value;
  4141. }
  4142. return this.range[0];
  4143. };
  4144. Identity.prototype.invert = function (value) {
  4145. var range = this.range;
  4146. if (value < range[0] || value > range[1]) {
  4147. return NaN;
  4148. }
  4149. return this.values[0];
  4150. };
  4151. return Identity;
  4152. }(Scale);
  4153. var DEFAULT_Q = [1, 5, 2, 2.5, 4, 3];
  4154. var eps = Number.EPSILON * 100; // https://stackoverflow.com/questions/4467539/javascript-modulo-gives-a-negative-result-for-negative-numbers
  4155. function mod(n, m) {
  4156. return (n % m + m) % m;
  4157. }
  4158. function simplicity(q, Q, j, lmin, lmax, lstep) {
  4159. var n = size(Q);
  4160. var i = indexOf(Q, q);
  4161. var v = 0;
  4162. var m = mod(lmin, lstep);
  4163. if ((m < eps || lstep - m < eps) && lmin <= 0 && lmax >= 0) {
  4164. v = 1;
  4165. }
  4166. return 1 - i / (n - 1) - j + v;
  4167. }
  4168. function simplicityMax(q, Q, j) {
  4169. var n = size(Q);
  4170. var i = indexOf(Q, q);
  4171. var v = 1;
  4172. return 1 - i / (n - 1) - j + v;
  4173. }
  4174. function density(k, m, dmin, dmax, lmin, lmax) {
  4175. var r = (k - 1) / (lmax - lmin);
  4176. var rt = (m - 1) / (Math.max(lmax, dmax) - Math.min(dmin, lmin));
  4177. return 2 - Math.max(r / rt, rt / r);
  4178. }
  4179. function densityMax(k, m) {
  4180. if (k >= m) {
  4181. return 2 - (k - 1) / (m - 1);
  4182. }
  4183. return 1;
  4184. }
  4185. function coverage(dmin, dmax, lmin, lmax) {
  4186. var range = dmax - dmin;
  4187. return 1 - 0.5 * (Math.pow(dmax - lmax, 2) + Math.pow(dmin - lmin, 2)) / Math.pow(0.1 * range, 2);
  4188. }
  4189. function coverageMax(dmin, dmax, span) {
  4190. var range = dmax - dmin;
  4191. if (span > range) {
  4192. var half = (span - range) / 2;
  4193. return 1 - Math.pow(half, 2) / Math.pow(0.1 * range, 2);
  4194. }
  4195. return 1;
  4196. }
  4197. function legibility() {
  4198. return 1;
  4199. }
  4200. /**
  4201. * An Extension of Wilkinson's Algorithm for Position Tick Labels on Axes
  4202. * https://www.yuque.com/preview/yuque/0/2019/pdf/185317/1546999150858-45c3b9c2-4e86-4223-bf1a-8a732e8195ed.pdf
  4203. * @param dmin 最小值
  4204. * @param dmax 最大值
  4205. * @param m tick个数
  4206. * @param onlyLoose 是否允许扩展min、max,不绝对强制,例如[3, 97]
  4207. * @param Q nice numbers集合
  4208. * @param w 四个优化组件的权重
  4209. */
  4210. function extended(dmin, dmax, m, onlyLoose, Q, w) {
  4211. if (m === void 0) {
  4212. m = 5;
  4213. }
  4214. if (onlyLoose === void 0) {
  4215. onlyLoose = true;
  4216. }
  4217. if (Q === void 0) {
  4218. Q = DEFAULT_Q;
  4219. }
  4220. if (w === void 0) {
  4221. w = [0.25, 0.2, 0.5, 0.05];
  4222. } // 异常数据情况下,直接返回,防止 oom
  4223. if (typeof dmin !== 'number' || typeof dmax !== 'number') {
  4224. return {
  4225. min: 0,
  4226. max: 0,
  4227. ticks: []
  4228. };
  4229. }
  4230. if (dmin === dmax || m === 1) {
  4231. return {
  4232. min: dmin,
  4233. max: dmax,
  4234. ticks: [dmin]
  4235. };
  4236. }
  4237. var best = {
  4238. score: -2,
  4239. lmin: 0,
  4240. lmax: 0,
  4241. lstep: 0
  4242. };
  4243. var j = 1;
  4244. while (j < Infinity) {
  4245. for (var _i = 0, Q_1 = Q; _i < Q_1.length; _i++) {
  4246. var q = Q_1[_i];
  4247. var sm = simplicityMax(q, Q, j);
  4248. if (Number.isNaN(sm)) {
  4249. throw new Error('NaN');
  4250. }
  4251. if (w[0] * sm + w[1] + w[2] + w[3] < best.score) {
  4252. j = Infinity;
  4253. break;
  4254. }
  4255. var k = 2;
  4256. while (k < Infinity) {
  4257. var dm = densityMax(k, m);
  4258. if (w[0] * sm + w[1] + w[2] * dm + w[3] < best.score) {
  4259. break;
  4260. }
  4261. var delta = (dmax - dmin) / (k + 1) / j / q;
  4262. var z = Math.ceil(Math.log10(delta));
  4263. while (z < Infinity) {
  4264. var step = j * q * Math.pow(10, z);
  4265. var cm = coverageMax(dmin, dmax, step * (k - 1));
  4266. if (w[0] * sm + w[1] * cm + w[2] * dm + w[3] < best.score) {
  4267. break;
  4268. }
  4269. var minStart = Math.floor(dmax / step) * j - (k - 1) * j;
  4270. var maxStart = Math.ceil(dmin / step) * j;
  4271. if (minStart > maxStart) {
  4272. z = z + 1;
  4273. continue;
  4274. }
  4275. for (var start = minStart; start <= maxStart; start = start + 1) {
  4276. var lmin = start * (step / j);
  4277. var lmax = lmin + step * (k - 1);
  4278. var lstep = step;
  4279. var s = simplicity(q, Q, j, lmin, lmax, lstep);
  4280. var c = coverage(dmin, dmax, lmin, lmax);
  4281. var g = density(k, m, dmin, dmax, lmin, lmax);
  4282. var l = legibility();
  4283. var score = w[0] * s + w[1] * c + w[2] * g + w[3] * l;
  4284. if (score > best.score && (!onlyLoose || lmin <= dmin && lmax >= dmax)) {
  4285. best.lmin = lmin;
  4286. best.lmax = lmax;
  4287. best.lstep = lstep;
  4288. best.score = score;
  4289. }
  4290. }
  4291. z = z + 1;
  4292. }
  4293. k = k + 1;
  4294. }
  4295. }
  4296. j = j + 1;
  4297. } // 步长为浮点数时处理精度
  4298. var toFixed = Number.isInteger(best.lstep) ? 0 : Math.ceil(Math.abs(Math.log10(best.lstep)));
  4299. var range = [];
  4300. for (var tick = best.lmin; tick <= best.lmax; tick += best.lstep) {
  4301. range.push(tick);
  4302. }
  4303. var ticks = toFixed ? map(range, function (x) {
  4304. return Number.parseFloat(x.toFixed(toFixed));
  4305. }) : range;
  4306. return {
  4307. min: Math.min(dmin, head(ticks)),
  4308. max: Math.max(dmax, last(ticks)),
  4309. ticks: ticks
  4310. };
  4311. }
  4312. /**
  4313. * 计算分类 ticks
  4314. * @param cfg 度量的配置项
  4315. * @returns 计算后的 ticks
  4316. */
  4317. function calculateCatTicks(cfg) {
  4318. var values = cfg.values,
  4319. tickInterval = cfg.tickInterval,
  4320. tickCount = cfg.tickCount;
  4321. var ticks = values;
  4322. if (isNumber(tickInterval)) {
  4323. return filter(ticks, function (__, i) {
  4324. return i % tickInterval === 0;
  4325. });
  4326. }
  4327. var min = cfg.min,
  4328. max = cfg.max;
  4329. if (isNil(min)) {
  4330. min = 0;
  4331. }
  4332. if (isNil(max)) {
  4333. max = values.length - 1;
  4334. }
  4335. if (isNumber(tickCount) && tickCount < max - min) {
  4336. // 简单过滤,部分情况下小数的倍数也可以是整数
  4337. // tslint:disable-next-line: no-shadowed-variable
  4338. var ticks_1 = extended(min, max, tickCount, false, [1, 2, 5, 3, 4, 7, 6, 8, 9]).ticks;
  4339. var valid = filter(ticks_1, function (tick) {
  4340. return tick >= min && tick <= max;
  4341. });
  4342. return valid.map(function (index) {
  4343. return values[index];
  4344. });
  4345. }
  4346. return values.slice(min, max + 1);
  4347. }
  4348. function d3Linear(cfg) {
  4349. var min = cfg.min,
  4350. max = cfg.max,
  4351. nice = cfg.nice,
  4352. tickCount = cfg.tickCount;
  4353. var linear = new D3Linear();
  4354. linear.domain([min, max]);
  4355. if (nice) {
  4356. linear.nice(tickCount);
  4357. }
  4358. return linear.ticks(tickCount);
  4359. }
  4360. var DEFAULT_COUNT = 5;
  4361. var e10 = Math.sqrt(50);
  4362. var e5 = Math.sqrt(10);
  4363. var e2 = Math.sqrt(2); // https://github.com/d3/d3-scale
  4364. var D3Linear =
  4365. /** @class */
  4366. function () {
  4367. function D3Linear() {
  4368. this._domain = [0, 1];
  4369. }
  4370. D3Linear.prototype.domain = function (domain) {
  4371. if (domain) {
  4372. this._domain = Array.from(domain, Number);
  4373. return this;
  4374. }
  4375. return this._domain.slice();
  4376. };
  4377. D3Linear.prototype.nice = function (count) {
  4378. var _a, _b;
  4379. if (count === void 0) {
  4380. count = DEFAULT_COUNT;
  4381. }
  4382. var d = this._domain.slice();
  4383. var i0 = 0;
  4384. var i1 = this._domain.length - 1;
  4385. var start = this._domain[i0];
  4386. var stop = this._domain[i1];
  4387. var step;
  4388. if (stop < start) {
  4389. _a = [stop, start], start = _a[0], stop = _a[1];
  4390. _b = [i1, i0], i0 = _b[0], i1 = _b[1];
  4391. }
  4392. step = tickIncrement(start, stop, count);
  4393. if (step > 0) {
  4394. start = Math.floor(start / step) * step;
  4395. stop = Math.ceil(stop / step) * step;
  4396. step = tickIncrement(start, stop, count);
  4397. } else if (step < 0) {
  4398. start = Math.ceil(start * step) / step;
  4399. stop = Math.floor(stop * step) / step;
  4400. step = tickIncrement(start, stop, count);
  4401. }
  4402. if (step > 0) {
  4403. d[i0] = Math.floor(start / step) * step;
  4404. d[i1] = Math.ceil(stop / step) * step;
  4405. this.domain(d);
  4406. } else if (step < 0) {
  4407. d[i0] = Math.ceil(start * step) / step;
  4408. d[i1] = Math.floor(stop * step) / step;
  4409. this.domain(d);
  4410. }
  4411. return this;
  4412. };
  4413. D3Linear.prototype.ticks = function (count) {
  4414. if (count === void 0) {
  4415. count = DEFAULT_COUNT;
  4416. }
  4417. return d3ArrayTicks(this._domain[0], this._domain[this._domain.length - 1], count || DEFAULT_COUNT);
  4418. };
  4419. return D3Linear;
  4420. }();
  4421. function d3ArrayTicks(start, stop, count) {
  4422. var reverse;
  4423. var i = -1;
  4424. var n;
  4425. var ticks;
  4426. var step;
  4427. stop = +stop, start = +start, count = +count;
  4428. if (start === stop && count > 0) {
  4429. return [start];
  4430. } // tslint:disable-next-line
  4431. if (reverse = stop < start) {
  4432. n = start, start = stop, stop = n;
  4433. } // tslint:disable-next-line
  4434. if ((step = tickIncrement(start, stop, count)) === 0 || !isFinite(step)) {
  4435. return [];
  4436. }
  4437. if (step > 0) {
  4438. start = Math.ceil(start / step);
  4439. stop = Math.floor(stop / step);
  4440. ticks = new Array(n = Math.ceil(stop - start + 1));
  4441. while (++i < n) {
  4442. ticks[i] = (start + i) * step;
  4443. }
  4444. } else {
  4445. start = Math.floor(start * step);
  4446. stop = Math.ceil(stop * step);
  4447. ticks = new Array(n = Math.ceil(start - stop + 1));
  4448. while (++i < n) {
  4449. ticks[i] = (start - i) / step;
  4450. }
  4451. }
  4452. if (reverse) {
  4453. ticks.reverse();
  4454. }
  4455. return ticks;
  4456. }
  4457. function tickIncrement(start, stop, count) {
  4458. var step = (stop - start) / Math.max(0, count);
  4459. var power = Math.floor(Math.log(step) / Math.LN10);
  4460. var error = step / Math.pow(10, power);
  4461. return power >= 0 ? (error >= e10 ? 10 : error >= e5 ? 5 : error >= e2 ? 2 : 1) * Math.pow(10, power) : -Math.pow(10, -power) / (error >= e10 ? 10 : error >= e5 ? 5 : error >= e2 ? 2 : 1);
  4462. }
  4463. function snapMultiple(v, base, snapType) {
  4464. var div;
  4465. if (snapType === 'ceil') {
  4466. div = Math.ceil(v / base);
  4467. } else if (snapType === 'floor') {
  4468. div = Math.floor(v / base);
  4469. } else {
  4470. div = Math.round(v / base);
  4471. }
  4472. return div * base;
  4473. }
  4474. function intervalTicks(min, max, interval) {
  4475. // 变成 interval 的倍数
  4476. var minTick = snapMultiple(min, interval, 'floor');
  4477. var maxTick = snapMultiple(max, interval, 'ceil'); // 统一小数位数
  4478. minTick = fixedBase(minTick, interval);
  4479. maxTick = fixedBase(maxTick, interval);
  4480. var ticks = [];
  4481. for (var i = minTick; i <= maxTick; i = i + interval) {
  4482. var tickValue = fixedBase(i, interval); // 防止浮点数加法出现问题
  4483. ticks.push(tickValue);
  4484. }
  4485. return {
  4486. min: minTick,
  4487. max: maxTick,
  4488. ticks: ticks
  4489. };
  4490. }
  4491. /**
  4492. * 按照给定的 minLimit/maxLimit/tickCount 均匀计算出刻度 ticks
  4493. *
  4494. * @param cfg Scale 配置项
  4495. * @return ticks
  4496. */
  4497. function strictLimit(cfg, defaultMin, defaultMax) {
  4498. var _a;
  4499. var minLimit = cfg.minLimit,
  4500. maxLimit = cfg.maxLimit,
  4501. min = cfg.min,
  4502. max = cfg.max,
  4503. _b = cfg.tickCount,
  4504. tickCount = _b === void 0 ? 5 : _b;
  4505. var tickMin = isNil(minLimit) ? isNil(defaultMin) ? min : defaultMin : minLimit;
  4506. var tickMax = isNil(maxLimit) ? isNil(defaultMax) ? max : defaultMax : maxLimit;
  4507. if (tickMin > tickMax) {
  4508. _a = [tickMin, tickMax], tickMax = _a[0], tickMin = _a[1];
  4509. }
  4510. if (tickCount <= 2) {
  4511. return [tickMin, tickMax];
  4512. }
  4513. var step = (tickMax - tickMin) / (tickCount - 1);
  4514. var ticks = [];
  4515. for (var i = 0; i < tickCount; i++) {
  4516. ticks.push(tickMin + step * i);
  4517. }
  4518. return ticks;
  4519. }
  4520. function d3LinearTickMethod(cfg) {
  4521. var min = cfg.min,
  4522. max = cfg.max,
  4523. tickInterval = cfg.tickInterval,
  4524. minLimit = cfg.minLimit,
  4525. maxLimit = cfg.maxLimit;
  4526. var ticks = d3Linear(cfg);
  4527. if (!isNil(minLimit) || !isNil(maxLimit)) {
  4528. return strictLimit(cfg, head(ticks), last(ticks));
  4529. }
  4530. if (tickInterval) {
  4531. return intervalTicks(min, max, tickInterval).ticks;
  4532. }
  4533. return ticks;
  4534. }
  4535. /**
  4536. * 计算线性的 ticks,使用 wilkinson extended 方法
  4537. * @param cfg 度量的配置项
  4538. * @returns 计算后的 ticks
  4539. */
  4540. function linear(cfg) {
  4541. var min = cfg.min,
  4542. max = cfg.max,
  4543. tickCount = cfg.tickCount,
  4544. nice = cfg.nice,
  4545. tickInterval = cfg.tickInterval,
  4546. minLimit = cfg.minLimit,
  4547. maxLimit = cfg.maxLimit;
  4548. var ticks = extended(min, max, tickCount, nice).ticks;
  4549. if (!isNil(minLimit) || !isNil(maxLimit)) {
  4550. return strictLimit(cfg, head(ticks), last(ticks));
  4551. }
  4552. if (tickInterval) {
  4553. return intervalTicks(min, max, tickInterval).ticks;
  4554. }
  4555. return ticks;
  4556. }
  4557. /**
  4558. * 计算 log 的 ticks,考虑 min = 0 的场景
  4559. * @param cfg 度量的配置项
  4560. * @returns 计算后的 ticks
  4561. */
  4562. function calculateLogTicks(cfg) {
  4563. var base = cfg.base,
  4564. tickCount = cfg.tickCount,
  4565. min = cfg.min,
  4566. max = cfg.max,
  4567. values = cfg.values;
  4568. var minTick;
  4569. var maxTick = log(base, max);
  4570. if (min > 0) {
  4571. minTick = Math.floor(log(base, min));
  4572. } else {
  4573. var positiveMin = getLogPositiveMin(values, base, max);
  4574. minTick = Math.floor(log(base, positiveMin));
  4575. }
  4576. var count = maxTick - minTick;
  4577. var avg = Math.ceil(count / tickCount);
  4578. var ticks = [];
  4579. for (var i = minTick; i < maxTick + avg; i = i + avg) {
  4580. ticks.push(Math.pow(base, i));
  4581. }
  4582. if (min <= 0) {
  4583. // 最小值 <= 0 时显示 0
  4584. ticks.unshift(0);
  4585. }
  4586. return ticks;
  4587. }
  4588. function pretty(min, max, n) {
  4589. if (n === void 0) {
  4590. n = 5;
  4591. }
  4592. var res = {
  4593. max: 0,
  4594. min: 0,
  4595. ticks: []
  4596. };
  4597. if (min === max) {
  4598. return {
  4599. max: max,
  4600. min: min,
  4601. ticks: [min]
  4602. };
  4603. }
  4604. /*
  4605. R pretty:
  4606. https://svn.r-project.org/R/trunk/src/appl/pretty.c
  4607. https://www.rdocumentation.org/packages/base/versions/3.5.2/topics/pretty
  4608. */
  4609. var h = 1.5; // high.u.bias
  4610. var h5 = 0.5 + 1.5 * h; // u5.bias
  4611. // 反正我也不会调参,跳过所有判断步骤
  4612. var d = max - min;
  4613. var c = d / n; // 当d非常小的时候触发,但似乎没什么用
  4614. // const min_n = Math.floor(n / 3);
  4615. // const shrink_sml = Math.pow(2, 5);
  4616. // if (Math.log10(d) < -2) {
  4617. // c = (_.max([ Math.abs(max), Math.abs(min) ]) * shrink_sml) / min_n;
  4618. // }
  4619. var base = Math.pow(10, Math.floor(Math.log10(c)));
  4620. var toFixed = base < 1 ? Math.ceil(Math.abs(Math.log10(base))) : 0;
  4621. var unit = base;
  4622. if (2 * base - c < h * (c - unit)) {
  4623. unit = 2 * base;
  4624. if (5 * base - c < h5 * (c - unit)) {
  4625. unit = 5 * base;
  4626. if (10 * base - c < h * (c - unit)) {
  4627. unit = 10 * base;
  4628. }
  4629. }
  4630. }
  4631. var nu = Math.ceil(max / unit);
  4632. var ns = Math.floor(min / unit);
  4633. res.max = Math.max(nu * unit, max);
  4634. res.min = Math.min(ns * unit, min);
  4635. var x = Number.parseFloat((ns * unit).toFixed(toFixed));
  4636. while (x < max) {
  4637. res.ticks.push(x);
  4638. x += unit;
  4639. if (toFixed) {
  4640. x = Number.parseFloat(x.toFixed(toFixed));
  4641. }
  4642. }
  4643. res.ticks.push(x);
  4644. return res;
  4645. }
  4646. /**
  4647. * 计算 Pow 的 ticks
  4648. * @param cfg 度量的配置项
  4649. * @returns 计算后的 ticks
  4650. */
  4651. function calculatePowTicks(cfg) {
  4652. var exponent = cfg.exponent,
  4653. tickCount = cfg.tickCount;
  4654. var max = Math.ceil(calBase(exponent, cfg.max));
  4655. var min = Math.floor(calBase(exponent, cfg.min));
  4656. var ticks = pretty(min, max, tickCount).ticks;
  4657. return ticks.map(function (tick) {
  4658. var factor = tick >= 0 ? 1 : -1;
  4659. return Math.pow(tick, exponent) * factor;
  4660. });
  4661. }
  4662. /**
  4663. * 计算几分位 https://github.com/simple-statistics/simple-statistics/blob/master/src/quantile_sorted.js
  4664. * @param x 数组
  4665. * @param p 百分比
  4666. */
  4667. function quantileSorted(x, p) {
  4668. var idx = x.length * p;
  4669. /*if (x.length === 0) { // 当前场景这些条件不可能命中
  4670. throw new Error('quantile requires at least one value.');
  4671. } else if (p < 0 || p > 1) {
  4672. throw new Error('quantiles must be between 0 and 1');
  4673. } else */
  4674. if (p === 1) {
  4675. // If p is 1, directly return the last element
  4676. return x[x.length - 1];
  4677. } else if (p === 0) {
  4678. // If p is 0, directly return the first element
  4679. return x[0];
  4680. } else if (idx % 1 !== 0) {
  4681. // If p is not integer, return the next element in array
  4682. return x[Math.ceil(idx) - 1];
  4683. } else if (x.length % 2 === 0) {
  4684. // If the list has even-length, we'll take the average of this number
  4685. // and the next value, if there is one
  4686. return (x[idx - 1] + x[idx]) / 2;
  4687. } else {
  4688. // Finally, in the simple case of an integer value
  4689. // with an odd-length list, return the x value at the index.
  4690. return x[idx];
  4691. }
  4692. }
  4693. function calculateTicks(cfg) {
  4694. var tickCount = cfg.tickCount,
  4695. values = cfg.values;
  4696. if (!values || !values.length) {
  4697. return [];
  4698. }
  4699. var sorted = values.slice().sort(function (a, b) {
  4700. return a - b;
  4701. });
  4702. var ticks = [];
  4703. for (var i = 0; i < tickCount; i++) {
  4704. var p = i / (tickCount - 1);
  4705. ticks.push(quantileSorted(sorted, p));
  4706. }
  4707. return ticks;
  4708. }
  4709. /**
  4710. * 计算线性的 ticks,使用 R's pretty 方法
  4711. * @param cfg 度量的配置项
  4712. * @returns 计算后的 ticks
  4713. */
  4714. function linearPretty(cfg) {
  4715. var min = cfg.min,
  4716. max = cfg.max,
  4717. tickCount = cfg.tickCount,
  4718. tickInterval = cfg.tickInterval,
  4719. minLimit = cfg.minLimit,
  4720. maxLimit = cfg.maxLimit;
  4721. var ticks = pretty(min, max, tickCount).ticks;
  4722. if (!isNil(minLimit) || !isNil(maxLimit)) {
  4723. return strictLimit(cfg, head(ticks), last(ticks));
  4724. }
  4725. if (tickInterval) {
  4726. return intervalTicks(min, max, tickInterval).ticks;
  4727. }
  4728. return ticks;
  4729. }
  4730. function calculateTimeTicks(cfg) {
  4731. var min = cfg.min,
  4732. max = cfg.max,
  4733. minTickInterval = cfg.minTickInterval;
  4734. var tickInterval = cfg.tickInterval;
  4735. var tickCount = cfg.tickCount; // 指定 tickInterval 后 tickCount 不生效,需要重新计算
  4736. if (tickInterval) {
  4737. tickCount = Math.ceil((max - min) / tickInterval);
  4738. } else {
  4739. tickInterval = getTickInterval(min, max, tickCount)[1];
  4740. var count = (max - min) / tickInterval;
  4741. var ratio = count / tickCount;
  4742. if (ratio > 1) {
  4743. tickInterval = tickInterval * Math.ceil(ratio);
  4744. } // 如果设置了最小间距,则使用最小间距
  4745. if (minTickInterval && tickInterval < minTickInterval) {
  4746. tickInterval = minTickInterval;
  4747. }
  4748. }
  4749. var ticks = [];
  4750. for (var i = min; i < max + tickInterval; i += tickInterval) {
  4751. ticks.push(i);
  4752. }
  4753. return ticks;
  4754. }
  4755. /**
  4756. * 计算时间分类的 ticks, 保头,保尾
  4757. * @param cfg 度量的配置项
  4758. * @returns 计算后的 ticks
  4759. */
  4760. function calculateTimeCatTicks(cfg) {
  4761. var ticks = calculateCatTicks(cfg);
  4762. var lastValue = last(cfg.values);
  4763. if (lastValue !== last(ticks)) {
  4764. ticks.push(lastValue);
  4765. }
  4766. return ticks;
  4767. }
  4768. function getYear(date) {
  4769. return new Date(date).getFullYear();
  4770. }
  4771. function createYear(year) {
  4772. return new Date(year, 0, 1).getTime();
  4773. }
  4774. function getMonth(date) {
  4775. return new Date(date).getMonth();
  4776. }
  4777. function diffMonth(min, max) {
  4778. var minYear = getYear(min);
  4779. var maxYear = getYear(max);
  4780. var minMonth = getMonth(min);
  4781. var maxMonth = getMonth(max);
  4782. return (maxYear - minYear) * 12 + (maxMonth - minMonth) % 12;
  4783. }
  4784. function creatMonth(year, month) {
  4785. return new Date(year, month, 1).getTime();
  4786. }
  4787. function diffDay(min, max) {
  4788. return Math.ceil((max - min) / DAY);
  4789. }
  4790. function diffHour(min, max) {
  4791. return Math.ceil((max - min) / HOUR);
  4792. }
  4793. function diffMinus(min, max) {
  4794. return Math.ceil((max - min) / (60 * 1000));
  4795. }
  4796. /**
  4797. * 计算 time 的 ticks,对 month, year 进行 pretty 处理
  4798. * @param cfg 度量的配置项
  4799. * @returns 计算后的 ticks
  4800. */
  4801. function timePretty(cfg) {
  4802. var min = cfg.min,
  4803. max = cfg.max,
  4804. minTickInterval = cfg.minTickInterval,
  4805. tickCount = cfg.tickCount;
  4806. var tickInterval = cfg.tickInterval;
  4807. var ticks = []; // 指定 tickInterval 后 tickCount 不生效,需要重新计算
  4808. if (!tickInterval) {
  4809. tickInterval = (max - min) / tickCount; // 如果设置了最小间距,则使用最小间距
  4810. if (minTickInterval && tickInterval < minTickInterval) {
  4811. tickInterval = minTickInterval;
  4812. }
  4813. }
  4814. var minYear = getYear(min); // 如果间距大于 1 年,则将开始日期从整年开始
  4815. if (tickInterval > YEAR) {
  4816. var maxYear = getYear(max);
  4817. var yearInterval = Math.ceil(tickInterval / YEAR);
  4818. for (var i = minYear; i <= maxYear + yearInterval; i = i + yearInterval) {
  4819. ticks.push(createYear(i));
  4820. }
  4821. } else if (tickInterval > MONTH) {
  4822. // 大于月时
  4823. var monthInterval = Math.ceil(tickInterval / MONTH);
  4824. var mmMoth = getMonth(min);
  4825. var dMonths = diffMonth(min, max);
  4826. for (var i = 0; i <= dMonths + monthInterval; i = i + monthInterval) {
  4827. ticks.push(creatMonth(minYear, i + mmMoth));
  4828. }
  4829. } else if (tickInterval > DAY) {
  4830. // 大于天
  4831. var date = new Date(min);
  4832. var year = date.getFullYear();
  4833. var month = date.getMonth();
  4834. var mday = date.getDate();
  4835. var day = Math.ceil(tickInterval / DAY);
  4836. var ddays = diffDay(min, max);
  4837. for (var i = 0; i < ddays + day; i = i + day) {
  4838. ticks.push(new Date(year, month, mday + i).getTime());
  4839. }
  4840. } else if (tickInterval > HOUR) {
  4841. // 大于小时
  4842. var date = new Date(min);
  4843. var year = date.getFullYear();
  4844. var month = date.getMonth();
  4845. var day = date.getDate();
  4846. var hour = date.getHours();
  4847. var hours = Math.ceil(tickInterval / HOUR);
  4848. var dHours = diffHour(min, max);
  4849. for (var i = 0; i <= dHours + hours; i = i + hours) {
  4850. ticks.push(new Date(year, month, day, hour + i).getTime());
  4851. }
  4852. } else if (tickInterval > MINUTE) {
  4853. // 大于分钟
  4854. var dMinus = diffMinus(min, max);
  4855. var minutes = Math.ceil(tickInterval / MINUTE);
  4856. for (var i = 0; i <= dMinus + minutes; i = i + minutes) {
  4857. ticks.push(min + i * MINUTE);
  4858. }
  4859. } else {
  4860. // 小于分钟
  4861. var interval = tickInterval;
  4862. if (interval < SECOND) {
  4863. interval = SECOND;
  4864. }
  4865. var minSecond = Math.floor(min / SECOND) * SECOND;
  4866. var dSeconds = Math.ceil((max - min) / SECOND);
  4867. var seconds = Math.ceil(interval / SECOND);
  4868. for (var i = 0; i < dSeconds + seconds; i = i + seconds) {
  4869. ticks.push(minSecond + i * SECOND);
  4870. }
  4871. } // 最好是能从算法能解决这个问题,但是如果指定了 tickInterval,计算 ticks,也只能这么算,所以
  4872. // 打印警告提示
  4873. if (ticks.length >= 512) {
  4874. console.warn("Notice: current ticks length(" + ticks.length + ") >= 512, may cause performance issues, even out of memory. Because of the configure \"tickInterval\"(in milliseconds, current is " + tickInterval + ") is too small, increase the value to solve the problem!");
  4875. }
  4876. return ticks;
  4877. }
  4878. registerTickMethod('cat', calculateCatTicks);
  4879. registerTickMethod('time-cat', calculateTimeCatTicks);
  4880. registerTickMethod('wilkinson-extended', linear);
  4881. registerTickMethod('r-pretty', linearPretty);
  4882. registerTickMethod('time', calculateTimeTicks);
  4883. registerTickMethod('time-pretty', timePretty);
  4884. registerTickMethod('log', calculateLogTicks);
  4885. registerTickMethod('pow', calculatePowTicks);
  4886. registerTickMethod('quantile', calculateTicks);
  4887. registerTickMethod('d3-linear', d3LinearTickMethod);
  4888. registerClass('cat', Category);
  4889. registerClass('category', Category);
  4890. registerClass('identity', Identity);
  4891. registerClass('linear', Linear);
  4892. registerClass('log', Log);
  4893. registerClass('pow', Pow);
  4894. registerClass('time', Time);
  4895. registerClass('timeCat', TimeCat);
  4896. registerClass('quantize', Quantize);
  4897. registerClass('quantile', Quantile);
  4898. // cat平均算法,保头保尾
  4899. var CatTick = (function (cfg) {
  4900. var values = cfg.values,
  4901. tickCount = cfg.tickCount;
  4902. if (!tickCount) {
  4903. return values;
  4904. }
  4905. if (values.length <= 1) {
  4906. return values;
  4907. } // 获取间隔步长, 最小是1
  4908. var step = parseInt(values.length / (tickCount - 1)) || 1;
  4909. var ticks = []; // 按间隔数取对应节点
  4910. for (var index = 0; index < values.length; index = index + step) {
  4911. ticks.push(values[index]);
  4912. }
  4913. var last = values[values.length - 1]; // 如果最后一个tick不等于原数据的最后一个
  4914. if (ticks[ticks.length - 1] !== last) {
  4915. if (ticks.length >= tickCount) {
  4916. // 如果当前的tick个数满足要求
  4917. ticks[ticks.length - 1] = last;
  4918. } else {
  4919. // 不满足tickCount则直接加入最后一个
  4920. ticks.push(last);
  4921. }
  4922. }
  4923. return ticks;
  4924. });
  4925. // 认为是nice的刻度
  4926. var SNAP_COUNT_ARRAY = [1, 1.2, 1.5, 2, 2.2, 2.4, 2.5, 3, 4, 5, 6, 7.5, 8, 10];
  4927. var DEFAULT_COUNT$1 = 5; // 默认刻度值
  4928. var LinearTick = (function (cfg) {
  4929. var _ref = cfg || {},
  4930. tickCount = _ref.tickCount,
  4931. tickInterval = _ref.tickInterval;
  4932. var _ref2 = cfg || {},
  4933. min = _ref2.min,
  4934. max = _ref2.max;
  4935. min = isNaN(min) ? 0 : min;
  4936. max = isNaN(max) ? 0 : max;
  4937. var count = tickCount && tickCount >= 2 ? tickCount : DEFAULT_COUNT$1; // 计算interval, 优先取tickInterval
  4938. var interval = tickInterval || getBestInterval({
  4939. tickCount: count,
  4940. max: max,
  4941. min: min
  4942. }); // 通过interval计算最小tick
  4943. var minTick = Math.floor(min / interval) * interval; // 如果指定了tickInterval, count 需要根据指定的tickInterval来算计
  4944. if (tickInterval) {
  4945. var intervalCount = Math.abs(Math.ceil((max - minTick) / tickInterval)) + 1; // tickCount 作为最小 count 处理
  4946. count = Math.max(count, intervalCount);
  4947. }
  4948. var ticks = [];
  4949. var tickLength = 0;
  4950. var fixedLength = getFixedLength(interval);
  4951. while (tickLength < count) {
  4952. ticks.push(toFixed(minTick + tickLength * interval, fixedLength));
  4953. tickLength++;
  4954. }
  4955. return ticks;
  4956. });
  4957. var DECIMAL_LENGTH = 12;
  4958. function getFactor(number) {
  4959. // 取正数
  4960. number = Math.abs(number);
  4961. var factor = 1;
  4962. if (number === 0) {
  4963. return factor;
  4964. } // 小于1,逐渐放大
  4965. if (number < 1) {
  4966. var count = 0;
  4967. while (number < 1) {
  4968. factor = factor / 10;
  4969. number = number * 10;
  4970. count++;
  4971. } // 浮点数计算出现问题
  4972. if (factor.toString().length > DECIMAL_LENGTH) {
  4973. factor = parseFloat(factor.toFixed(count));
  4974. }
  4975. return factor;
  4976. } // 大于10逐渐缩小
  4977. while (number > 10) {
  4978. factor = factor * 10;
  4979. number = number / 10;
  4980. }
  4981. return factor;
  4982. } // 获取最佳匹配刻度
  4983. function getBestInterval(_ref3) {
  4984. var tickCount = _ref3.tickCount,
  4985. min = _ref3.min,
  4986. max = _ref3.max;
  4987. // 如果最大最小相等,则直接按1处理
  4988. if (min === max) {
  4989. return 1 * getFactor(max);
  4990. } // 1.计算平均刻度间隔
  4991. var avgInterval = (max - min) / (tickCount - 1); // 2.数据标准归一化 映射到[1-10]区间
  4992. var factor = getFactor(avgInterval);
  4993. var calInterval = avgInterval / factor;
  4994. var calMax = max / factor;
  4995. var calMin = min / factor; // 根据平均值推算最逼近刻度值
  4996. var similarityIndex = 0;
  4997. for (var index = 0; index < SNAP_COUNT_ARRAY.length; index++) {
  4998. var item = SNAP_COUNT_ARRAY[index];
  4999. if (calInterval <= item) {
  5000. similarityIndex = index;
  5001. break;
  5002. }
  5003. }
  5004. var similarityInterval = getInterval(similarityIndex, tickCount, calMin, calMax); // 小数点位数还原到数据的位数, 因为similarityIndex有可能是小数,所以需要保留similarityIndex自己的小数位数
  5005. var fixedLength = getFixedLength(similarityInterval) + getFixedLength(factor);
  5006. return toFixed(similarityInterval * factor, fixedLength);
  5007. }
  5008. function getInterval(startIndex, tickCount, min, max) {
  5009. var verify = false;
  5010. var interval = SNAP_COUNT_ARRAY[startIndex]; // 刻度值校验,如果不满足,循环下去
  5011. for (var i = startIndex; i < SNAP_COUNT_ARRAY.length; i++) {
  5012. if (intervalIsVerify({
  5013. interval: SNAP_COUNT_ARRAY[i],
  5014. tickCount: tickCount,
  5015. max: max,
  5016. min: min
  5017. })) {
  5018. // 有符合条件的interval
  5019. interval = SNAP_COUNT_ARRAY[i];
  5020. verify = true;
  5021. break;
  5022. }
  5023. } // 如果不满足, 依次缩小10倍,再计算
  5024. if (!verify) {
  5025. return 10 * getInterval(0, tickCount, min / 10, max / 10);
  5026. }
  5027. return interval;
  5028. } // 刻度是否满足展示需求
  5029. function intervalIsVerify(_ref4) {
  5030. var interval = _ref4.interval,
  5031. tickCount = _ref4.tickCount,
  5032. max = _ref4.max,
  5033. min = _ref4.min;
  5034. var minTick = Math.floor(min / interval) * interval;
  5035. if (minTick + (tickCount - 1) * interval >= max) {
  5036. return true;
  5037. }
  5038. return false;
  5039. } // 计算小数点应该保留的位数
  5040. function getFixedLength(num) {
  5041. var str = num.toString();
  5042. var index = str.indexOf('.');
  5043. var indexOfExp = str.indexOf('e-');
  5044. var length = indexOfExp >= 0 ? parseInt(str.substr(indexOfExp + 2), 10) : str.substr(index + 1).length;
  5045. if (length > 20) {
  5046. // 最多保留20位小数
  5047. length = 20;
  5048. }
  5049. return length;
  5050. } // @antv/util fixedbase不支持科学计数法的判断,需要提mr
  5051. function toFixed(v, length) {
  5052. return parseFloat(v.toFixed(length));
  5053. }
  5054. var Linear$1 = getClass('linear');
  5055. var Identity$1 = getClass('identity');
  5056. var Category$1 = getClass('category');
  5057. var TimeCat$1 = getClass('timeCat'); // 覆盖0.3.x的 cat 方法
  5058. registerTickMethod('cat', CatTick);
  5059. registerTickMethod('time-cat', CatTick); // 覆盖linear 度量的tick算法
  5060. registerTickMethod('wilkinson-extended', LinearTick);
  5061. Scale.Linear = Linear$1;
  5062. Scale.Identity = Identity$1;
  5063. Scale.Category = Category$1;
  5064. Scale.Cat = Category$1;
  5065. Scale.TimeCat = TimeCat$1;
  5066. function isFullCircle(coord) {
  5067. if (!coord.isPolar) {
  5068. return false;
  5069. }
  5070. var startAngle = coord.startAngle;
  5071. var endAngle = coord.endAngle;
  5072. if (!isNil(startAngle) && !isNil(endAngle) && endAngle - startAngle < Math.PI * 2) {
  5073. return false;
  5074. }
  5075. return true;
  5076. }
  5077. function clearObj(obj) {
  5078. Object.keys(obj).forEach(function (key) {
  5079. delete obj[key];
  5080. });
  5081. }
  5082. var ScaleController = /*#__PURE__*/function () {
  5083. function ScaleController(cfg) {
  5084. // defs 列定义
  5085. this.defs = {}; // 已经实例化的scale
  5086. this.scales = {};
  5087. mix(this, cfg);
  5088. }
  5089. var _proto = ScaleController.prototype;
  5090. _proto.setFieldDef = function setFieldDef(field, cfg) {
  5091. var defs = this.defs;
  5092. if (isObject(field)) {
  5093. mix(defs, field);
  5094. } else {
  5095. defs[field] = cfg;
  5096. } // 因为可能同时变更多个scale,所以要把所有已实例化的scale都更新下
  5097. this.updateScales();
  5098. };
  5099. _proto._getDef = function _getDef(field) {
  5100. var defs = this.defs;
  5101. var def = null;
  5102. if (Global.scales[field] || defs[field]) {
  5103. def = mix({}, Global.scales[field]);
  5104. each(defs[field], function (v, k) {
  5105. if (isNil(v)) {
  5106. delete def[k];
  5107. } else {
  5108. def[k] = v;
  5109. }
  5110. });
  5111. }
  5112. return def;
  5113. };
  5114. _proto._getDefaultType = function _getDefaultType(field, data, def) {
  5115. if (def && def.type) {
  5116. return def.type;
  5117. }
  5118. var type = 'linear';
  5119. var value = firstValue(data, field);
  5120. if (isArray(value)) {
  5121. value = value[0];
  5122. }
  5123. if (isString(value)) {
  5124. type = 'cat';
  5125. }
  5126. return type;
  5127. };
  5128. _proto._getScaleDef = function _getScaleDef(type, field, data, def) {
  5129. var values$1;
  5130. if (def && def.values) {
  5131. values$1 = def.values;
  5132. } else {
  5133. values$1 = values(data, field);
  5134. }
  5135. var cfg = {
  5136. field: field,
  5137. values: values$1
  5138. };
  5139. if (type !== 'cat' && type !== 'timeCat') {
  5140. if (!def || !(def.min && def.max)) {
  5141. var _Array$getRange = getRange$1(values$1),
  5142. min = _Array$getRange.min,
  5143. max = _Array$getRange.max;
  5144. cfg.min = min;
  5145. cfg.max = max;
  5146. cfg.nice = true;
  5147. }
  5148. } else {
  5149. cfg.isRounding = false; // used for tickCount calculation
  5150. }
  5151. return cfg;
  5152. } // 调整range,为了让图形居中
  5153. ;
  5154. _proto._adjustRange = function _adjustRange(type, cfg) {
  5155. var range = cfg.range,
  5156. values = cfg.values; // 如果是线性, 或者有自定义range都不处理
  5157. if (type === 'linear' || range || !values) {
  5158. return cfg;
  5159. }
  5160. var count = values.length; // 单只有一条数据时,在中间显示
  5161. if (count === 1) {
  5162. cfg.range = [0.5, 1];
  5163. } else {
  5164. var chart = this.chart;
  5165. var coord = chart.get('coord');
  5166. var widthRatio = Global.widthRatio.multiplePie;
  5167. var offset = 0;
  5168. if (isFullCircle(coord)) {
  5169. if (!coord.transposed) {
  5170. cfg.range = [0, 1 - 1 / count];
  5171. } else {
  5172. offset = 1 / count * widthRatio;
  5173. cfg.range = [offset / 2, 1 - offset / 2];
  5174. }
  5175. } else {
  5176. // 为了让图形居中,所以才设置range
  5177. offset = 1 / count * 0.5; // 这里可能用0.25会更合理
  5178. cfg.range = [offset, 1 - offset];
  5179. }
  5180. }
  5181. return cfg;
  5182. };
  5183. _proto._getScaleCfg = function _getScaleCfg(field, data) {
  5184. var self = this;
  5185. var def = self._getDef(field);
  5186. if (!data || !data.length) {
  5187. if (def && def.type) {
  5188. def.field = field;
  5189. return {
  5190. type: def.type,
  5191. cfg: def
  5192. };
  5193. }
  5194. return {
  5195. type: 'identity',
  5196. cfg: {
  5197. value: field,
  5198. field: field.toString(),
  5199. values: [field]
  5200. }
  5201. };
  5202. }
  5203. var firstObj = data[0];
  5204. var firstValue$1 = firstObj[field];
  5205. if (firstValue$1 === null) {
  5206. firstValue$1 = firstValue(data, field);
  5207. }
  5208. if (isNumber(field) || isNil(firstValue$1) && !def) {
  5209. return {
  5210. type: 'identity',
  5211. cfg: {
  5212. value: field,
  5213. field: field.toString(),
  5214. values: [field]
  5215. }
  5216. };
  5217. }
  5218. var type = self._getDefaultType(field, data, def);
  5219. var cfg = self._getScaleDef(type, field, data, def);
  5220. def && mix(cfg, def);
  5221. cfg = this._adjustRange(type, cfg);
  5222. return {
  5223. type: type,
  5224. cfg: cfg
  5225. };
  5226. };
  5227. _proto.createScale = function createScale(field, data) {
  5228. var scales = this.scales;
  5229. var _this$_getScaleCfg = this._getScaleCfg(field, data),
  5230. type = _this$_getScaleCfg.type,
  5231. cfg = _this$_getScaleCfg.cfg;
  5232. var scale = scales[field]; // 如果已经存在,且类型相等时直接返回
  5233. if (scale && scale.type === type) {
  5234. scale.change(cfg);
  5235. return scale;
  5236. }
  5237. var Scale = getClass(type);
  5238. var newScale = new Scale(cfg);
  5239. scales[field] = newScale;
  5240. return newScale;
  5241. };
  5242. _proto._updateScale = function _updateScale(scale) {
  5243. var field = scale.field; // 因为每个field的数据都会不同
  5244. var data = this.chart._getScaleData(field);
  5245. var _this$_getScaleCfg2 = this._getScaleCfg(field, data),
  5246. cfg = _this$_getScaleCfg2.cfg;
  5247. scale.change(cfg);
  5248. };
  5249. _proto.updateScales = function updateScales() {
  5250. var _this = this;
  5251. var scales = this.scales; // 修改完列定义后,需要更新已经实例化的scale
  5252. // 如果是还没有实例化的,在geom初始化的时候会被实例化,所以这里可以不用更新
  5253. each(scales, function (scale) {
  5254. _this._updateScale(scale);
  5255. });
  5256. } // 调整scale从0开始
  5257. ;
  5258. _proto.adjustStartZero = function adjustStartZero(scale) {
  5259. var defs = this.defs;
  5260. var field = scale.field,
  5261. min = scale.min,
  5262. max = scale.max; // 如果有定义,则不处理
  5263. if (defs[field] && defs[field].min) {
  5264. return;
  5265. }
  5266. if (min > 0) {
  5267. scale.change({
  5268. min: 0
  5269. });
  5270. } else if (max < 0) {
  5271. scale.change({
  5272. max: 0
  5273. });
  5274. }
  5275. };
  5276. _proto.clear = function clear() {
  5277. // this.defs = {};
  5278. // this.scales = {};
  5279. clearObj(this.defs);
  5280. clearObj(this.scales);
  5281. this.data = null;
  5282. };
  5283. return ScaleController;
  5284. }();
  5285. var Abastract = /*#__PURE__*/function () {
  5286. var _proto = Abastract.prototype;
  5287. _proto._initDefaultCfg = function _initDefaultCfg() {
  5288. /**
  5289. * ticks
  5290. * @type {Array}
  5291. */
  5292. this.ticks = [];
  5293. /**
  5294. * the configuration for tickLine
  5295. * @type {Object}
  5296. */
  5297. this.tickLine = {};
  5298. /**
  5299. * the direction of ticks, 1 means clockwise
  5300. * @type {Number}
  5301. */
  5302. this.offsetFactor = 1;
  5303. /**
  5304. * the top container
  5305. * @type {container}
  5306. */
  5307. this.frontContainer = null;
  5308. /**
  5309. * the back container
  5310. * @type {[type]}
  5311. */
  5312. this.backContainer = null;
  5313. /**
  5314. * points for draw grid line
  5315. * @type {Array}
  5316. */
  5317. this.gridPoints = [];
  5318. };
  5319. function Abastract(cfg) {
  5320. this._initDefaultCfg();
  5321. mix(this, cfg);
  5322. this.draw();
  5323. }
  5324. _proto.draw = function draw() {
  5325. var line = this.line,
  5326. tickLine = this.tickLine,
  5327. label = this.label,
  5328. grid = this.grid;
  5329. grid && this.drawGrid(grid); // draw the grid lines
  5330. tickLine && this.drawTicks(tickLine); // draw the tickLine
  5331. line && this.drawLine(line); // draw axis line
  5332. label && this.drawLabels(); // draw ticks
  5333. };
  5334. _proto.drawTicks = function drawTicks(tickCfg) {
  5335. var self = this;
  5336. var ticks = self.ticks;
  5337. var length = tickCfg.length;
  5338. var container = self.getContainer(tickCfg.top);
  5339. each(ticks, function (tick) {
  5340. var start = self.getOffsetPoint(tick.value);
  5341. var end = self.getSidePoint(start, length);
  5342. var shape = container.addShape('line', {
  5343. className: 'axis-tick',
  5344. attrs: mix({
  5345. x1: start.x,
  5346. y1: start.y,
  5347. x2: end.x,
  5348. y2: end.y
  5349. }, tickCfg)
  5350. });
  5351. shape._id = self._id + '-ticks';
  5352. });
  5353. };
  5354. _proto.drawLabels = function drawLabels() {
  5355. var self = this;
  5356. var labelOffset = self.labelOffset;
  5357. var labels = self.labels;
  5358. each(labels, function (labelShape) {
  5359. var container = self.getContainer(labelShape.get('top'));
  5360. var start = self.getOffsetPoint(labelShape.get('value'));
  5361. var _self$getSidePoint = self.getSidePoint(start, labelOffset),
  5362. x = _self$getSidePoint.x,
  5363. y = _self$getSidePoint.y;
  5364. labelShape.attr(mix({
  5365. x: x,
  5366. y: y
  5367. }, self.getTextAlignInfo(start, labelOffset), labelShape.get('textStyle')));
  5368. labelShape._id = self._id + '-' + labelShape.attr('text');
  5369. container.add(labelShape);
  5370. });
  5371. };
  5372. _proto.drawLine = function drawLine() {};
  5373. _proto.drawGrid = function drawGrid(grid) {
  5374. var self = this;
  5375. var gridPoints = self.gridPoints,
  5376. ticks = self.ticks;
  5377. var gridCfg = grid;
  5378. var count = gridPoints.length;
  5379. each(gridPoints, function (subPoints, index) {
  5380. if (isFunction(grid)) {
  5381. var tick = ticks[index] || {};
  5382. var executedGrid = grid(tick.text, index, count);
  5383. gridCfg = executedGrid ? mix({}, Global._defaultAxis.grid, executedGrid) : null;
  5384. }
  5385. if (gridCfg) {
  5386. var type = gridCfg.type; // has two types: 'line' and 'arc'
  5387. var points = subPoints.points;
  5388. var container = self.getContainer(gridCfg.top);
  5389. var shape;
  5390. if (type === 'arc') {
  5391. var center = self.center,
  5392. startAngle = self.startAngle,
  5393. endAngle = self.endAngle;
  5394. var radius = Vector2.length([points[0].x - center.x, points[0].y - center.y]);
  5395. shape = container.addShape('Arc', {
  5396. className: 'axis-grid',
  5397. attrs: mix({
  5398. x: center.x,
  5399. y: center.y,
  5400. startAngle: startAngle,
  5401. endAngle: endAngle,
  5402. r: radius
  5403. }, gridCfg)
  5404. });
  5405. } else {
  5406. shape = container.addShape('Polyline', {
  5407. className: 'axis-grid',
  5408. attrs: mix({
  5409. points: points
  5410. }, gridCfg)
  5411. });
  5412. }
  5413. shape._id = subPoints._id;
  5414. }
  5415. });
  5416. };
  5417. _proto.getOffsetPoint = function getOffsetPoint() {};
  5418. _proto.getAxisVector = function getAxisVector() {};
  5419. _proto.getOffsetVector = function getOffsetVector(point, offset) {
  5420. var self = this;
  5421. var axisVector = self.getAxisVector(point);
  5422. var normal = Vector2.normalize([], axisVector);
  5423. var factor = self.offsetFactor;
  5424. var verticalVector = [normal[1] * -1 * factor, normal[0] * factor];
  5425. return Vector2.scale([], verticalVector, offset);
  5426. };
  5427. _proto.getSidePoint = function getSidePoint(point, offset) {
  5428. var self = this;
  5429. var offsetVector = self.getOffsetVector(point, offset);
  5430. return {
  5431. x: point.x + offsetVector[0],
  5432. y: point.y + offsetVector[1]
  5433. };
  5434. };
  5435. _proto.getTextAlignInfo = function getTextAlignInfo(point, offset) {
  5436. var self = this;
  5437. var offsetVector = self.getOffsetVector(point, offset);
  5438. var align;
  5439. var baseLine;
  5440. if (offsetVector[0] > 0) {
  5441. align = 'left';
  5442. } else if (offsetVector[0] < 0) {
  5443. align = 'right';
  5444. } else {
  5445. align = 'center';
  5446. }
  5447. if (offsetVector[1] > 0) {
  5448. baseLine = 'top';
  5449. } else if (offsetVector[1] < 0) {
  5450. baseLine = 'bottom';
  5451. } else {
  5452. baseLine = 'middle';
  5453. }
  5454. return {
  5455. textAlign: align,
  5456. textBaseline: baseLine
  5457. };
  5458. };
  5459. _proto.getContainer = function getContainer(isTop) {
  5460. var frontContainer = this.frontContainer,
  5461. backContainer = this.backContainer;
  5462. return isTop ? frontContainer : backContainer;
  5463. };
  5464. return Abastract;
  5465. }();
  5466. var Line = /*#__PURE__*/function (_Abstract) {
  5467. _inheritsLoose(Line, _Abstract);
  5468. function Line() {
  5469. return _Abstract.apply(this, arguments) || this;
  5470. }
  5471. var _proto = Line.prototype;
  5472. _proto._initDefaultCfg = function _initDefaultCfg() {
  5473. _Abstract.prototype._initDefaultCfg.call(this);
  5474. this.start = null;
  5475. this.end = null;
  5476. };
  5477. _proto.getOffsetPoint = function getOffsetPoint(value) {
  5478. var start = this.start,
  5479. end = this.end;
  5480. return {
  5481. x: start.x + (end.x - start.x) * value,
  5482. y: start.y + (end.y - start.y) * value
  5483. };
  5484. };
  5485. _proto.getAxisVector = function getAxisVector() {
  5486. var start = this.start,
  5487. end = this.end;
  5488. return [end.x - start.x, end.y - start.y];
  5489. };
  5490. _proto.drawLine = function drawLine(lineCfg) {
  5491. var container = this.getContainer(lineCfg.top);
  5492. var start = this.start,
  5493. end = this.end;
  5494. container.addShape('line', {
  5495. className: 'axis-line',
  5496. attrs: mix({
  5497. x1: start.x,
  5498. y1: start.y,
  5499. x2: end.x,
  5500. y2: end.y
  5501. }, lineCfg)
  5502. });
  5503. };
  5504. return Line;
  5505. }(Abastract);
  5506. Abastract.Line = Line;
  5507. function formatTicks(ticks) {
  5508. var tmp = ticks.slice(0);
  5509. if (tmp.length > 0) {
  5510. var first = tmp[0];
  5511. var last = tmp[tmp.length - 1];
  5512. if (first.value !== 0) {
  5513. tmp.unshift({
  5514. value: 0
  5515. });
  5516. }
  5517. if (last.value !== 1) {
  5518. tmp.push({
  5519. value: 1
  5520. });
  5521. }
  5522. }
  5523. return tmp;
  5524. }
  5525. var AxisController = /*#__PURE__*/function () {
  5526. function AxisController(cfg) {
  5527. this.axisCfg = {};
  5528. this.frontPlot = null;
  5529. this.backPlot = null;
  5530. this.axes = {}; // store the axes's options
  5531. mix(this, cfg);
  5532. }
  5533. var _proto = AxisController.prototype;
  5534. _proto._isHide = function _isHide(field) {
  5535. var axisCfg = this.axisCfg;
  5536. return !axisCfg || axisCfg[field] === false;
  5537. };
  5538. _proto._getLinePosition = function _getLinePosition(scale, dimType, index, transposed) {
  5539. var position = '';
  5540. var field = scale.field;
  5541. var axisCfg = this.axisCfg;
  5542. if (axisCfg[field] && axisCfg[field].position) {
  5543. position = axisCfg[field].position;
  5544. } else if (dimType === 'x') {
  5545. position = transposed ? 'left' : 'bottom';
  5546. } else if (dimType === 'y') {
  5547. position = index ? 'right' : 'left';
  5548. if (transposed) {
  5549. position = 'bottom';
  5550. }
  5551. }
  5552. return position;
  5553. };
  5554. _proto._getLineCfg = function _getLineCfg(coord, dimType, position) {
  5555. var start;
  5556. var end;
  5557. var factor = 1; // Mark clockwise or counterclockwise
  5558. if (dimType === 'x') {
  5559. start = {
  5560. x: 0,
  5561. y: 0
  5562. };
  5563. end = {
  5564. x: 1,
  5565. y: 0
  5566. };
  5567. } else {
  5568. if (position === 'right') {
  5569. // there will be several y axes
  5570. start = {
  5571. x: 1,
  5572. y: 0
  5573. };
  5574. end = {
  5575. x: 1,
  5576. y: 1
  5577. };
  5578. } else {
  5579. start = {
  5580. x: 0,
  5581. y: 0
  5582. };
  5583. end = {
  5584. x: 0,
  5585. y: 1
  5586. };
  5587. factor = -1;
  5588. }
  5589. }
  5590. if (coord.transposed) {
  5591. factor *= -1;
  5592. }
  5593. return {
  5594. offsetFactor: factor,
  5595. start: coord.convertPoint(start),
  5596. end: coord.convertPoint(end)
  5597. };
  5598. };
  5599. _proto._getCircleCfg = function _getCircleCfg(coord) {
  5600. return {
  5601. startAngle: coord.startAngle,
  5602. endAngle: coord.endAngle,
  5603. center: coord.center,
  5604. radius: coord.circleRadius
  5605. };
  5606. };
  5607. _proto._getRadiusCfg = function _getRadiusCfg(coord) {
  5608. var transposed = coord.transposed;
  5609. var start;
  5610. var end;
  5611. if (transposed) {
  5612. start = {
  5613. x: 0,
  5614. y: 0
  5615. };
  5616. end = {
  5617. x: 1,
  5618. y: 0
  5619. };
  5620. } else {
  5621. start = {
  5622. x: 0,
  5623. y: 0
  5624. };
  5625. end = {
  5626. x: 0,
  5627. y: 1
  5628. };
  5629. }
  5630. return {
  5631. offsetFactor: -1,
  5632. start: coord.convertPoint(start),
  5633. end: coord.convertPoint(end)
  5634. };
  5635. };
  5636. _proto._getAxisCfg = function _getAxisCfg(coord, scale, verticalScale, dimType, defaultCfg) {
  5637. var _this = this;
  5638. var self = this;
  5639. var axisCfg = this.axisCfg;
  5640. var ticks = scale.getTicks();
  5641. var cfg = deepMix({
  5642. ticks: ticks,
  5643. frontContainer: this.frontPlot,
  5644. backContainer: this.backPlot
  5645. }, defaultCfg, axisCfg[scale.field]);
  5646. var labels = [];
  5647. var label = cfg.label;
  5648. var count = ticks.length;
  5649. var maxWidth = 0;
  5650. var maxHeight = 0;
  5651. var labelCfg = label;
  5652. each(ticks, function (tick, index) {
  5653. if (isFunction(label)) {
  5654. var executedLabel = label(tick.text, index, count);
  5655. labelCfg = executedLabel ? mix({}, Global._defaultAxis.label, executedLabel) : null;
  5656. }
  5657. if (labelCfg) {
  5658. var textStyle = {};
  5659. if (labelCfg.textAlign) {
  5660. textStyle.textAlign = labelCfg.textAlign;
  5661. }
  5662. if (labelCfg.textBaseline) {
  5663. textStyle.textBaseline = labelCfg.textBaseline;
  5664. }
  5665. var container = labelCfg.top ? _this.frontPlot : _this.backPlot;
  5666. var axisLabel = container.addShape('text', {
  5667. className: 'axis-label',
  5668. aria: false,
  5669. attrs: mix({
  5670. x: 0,
  5671. y: 0,
  5672. text: tick.text,
  5673. fontFamily: self.chart.get('canvas').get('fontFamily')
  5674. }, labelCfg),
  5675. value: tick.value,
  5676. textStyle: textStyle,
  5677. top: labelCfg.top,
  5678. context: self.chart.get('canvas').get('context')
  5679. });
  5680. labels.push(axisLabel);
  5681. var _axisLabel$getBBox = axisLabel.getBBox(),
  5682. width = _axisLabel$getBBox.width,
  5683. height = _axisLabel$getBBox.height;
  5684. maxWidth = Math.max(maxWidth, width);
  5685. maxHeight = Math.max(maxHeight, height);
  5686. }
  5687. });
  5688. cfg.labels = labels;
  5689. cfg.maxWidth = maxWidth;
  5690. cfg.maxHeight = maxHeight;
  5691. return cfg;
  5692. };
  5693. _proto._createAxis = function _createAxis(coord, scale, verticalScale, dimType, index) {
  5694. if (index === void 0) {
  5695. index = '';
  5696. }
  5697. var self = this;
  5698. var coordType = coord.type;
  5699. var transposed = coord.transposed;
  5700. var type;
  5701. var key;
  5702. var defaultCfg;
  5703. if (coordType === 'cartesian' || coordType === 'rect') {
  5704. var position = self._getLinePosition(scale, dimType, index, transposed);
  5705. defaultCfg = Global.axis[position];
  5706. defaultCfg.position = position;
  5707. type = 'Line';
  5708. key = position;
  5709. } else {
  5710. if (dimType === 'x' && !transposed || dimType === 'y' && transposed) {
  5711. defaultCfg = Global.axis.circle;
  5712. type = 'Circle';
  5713. key = 'circle';
  5714. } else {
  5715. defaultCfg = Global.axis.radius;
  5716. type = 'Line';
  5717. key = 'radius';
  5718. }
  5719. }
  5720. var cfg = self._getAxisCfg(coord, scale, verticalScale, dimType, defaultCfg);
  5721. cfg.type = type;
  5722. cfg.dimType = dimType;
  5723. cfg.verticalScale = verticalScale;
  5724. cfg.index = index;
  5725. this.axes[key] = cfg;
  5726. };
  5727. _proto.createAxis = function createAxis(coord, xScale, yScales) {
  5728. var self = this;
  5729. if (xScale && !self._isHide(xScale.field)) {
  5730. self._createAxis(coord, xScale, yScales[0], 'x');
  5731. }
  5732. each(yScales, function (yScale, index) {
  5733. if (!self._isHide(yScale.field)) {
  5734. self._createAxis(coord, yScale, xScale, 'y', index);
  5735. }
  5736. });
  5737. var axes = this.axes;
  5738. var chart = self.chart;
  5739. if (chart._isAutoPadding()) {
  5740. var userPadding = parsePadding(chart.get('padding'));
  5741. var appendPadding = parsePadding(chart.get('appendPadding'));
  5742. var legendRange = chart.get('legendRange') || {
  5743. top: 0,
  5744. right: 0,
  5745. bottom: 0,
  5746. left: 0
  5747. };
  5748. var padding = [userPadding[0] === 'auto' ? legendRange.top + appendPadding[0] * 2 : userPadding[0], userPadding[1] === 'auto' ? legendRange.right + appendPadding[1] : userPadding[1], userPadding[2] === 'auto' ? legendRange.bottom + appendPadding[2] : userPadding[2], userPadding[3] === 'auto' ? legendRange.left + appendPadding[3] : userPadding[3]];
  5749. if (coord.isPolar) {
  5750. var circleAxis = axes.circle;
  5751. if (circleAxis) {
  5752. var maxHeight = circleAxis.maxHeight,
  5753. maxWidth = circleAxis.maxWidth,
  5754. labelOffset = circleAxis.labelOffset;
  5755. padding[0] += maxHeight + labelOffset;
  5756. padding[1] += maxWidth + labelOffset;
  5757. padding[2] += maxHeight + labelOffset;
  5758. padding[3] += maxWidth + labelOffset;
  5759. }
  5760. } else {
  5761. if (axes.right && userPadding[1] === 'auto') {
  5762. var _axes$right = axes.right,
  5763. _maxWidth = _axes$right.maxWidth,
  5764. _labelOffset = _axes$right.labelOffset;
  5765. padding[1] += _maxWidth + _labelOffset;
  5766. }
  5767. if (axes.left && userPadding[3] === 'auto') {
  5768. var _axes$left = axes.left,
  5769. _maxWidth2 = _axes$left.maxWidth,
  5770. _labelOffset2 = _axes$left.labelOffset;
  5771. padding[3] += _maxWidth2 + _labelOffset2;
  5772. }
  5773. if (axes.bottom && userPadding[2] === 'auto') {
  5774. var _axes$bottom = axes.bottom,
  5775. _maxHeight = _axes$bottom.maxHeight,
  5776. _labelOffset3 = _axes$bottom.labelOffset;
  5777. padding[2] += _maxHeight + _labelOffset3;
  5778. }
  5779. }
  5780. chart.set('_padding', padding);
  5781. chart._updateLayout(padding);
  5782. }
  5783. each(axes, function (axis) {
  5784. var type = axis.type,
  5785. grid = axis.grid,
  5786. verticalScale = axis.verticalScale,
  5787. ticks = axis.ticks,
  5788. dimType = axis.dimType,
  5789. position = axis.position,
  5790. index = axis.index;
  5791. var appendCfg;
  5792. if (coord.isPolar) {
  5793. if (type === 'Line') {
  5794. appendCfg = self._getRadiusCfg(coord);
  5795. } else if (type === 'Circle') {
  5796. appendCfg = self._getCircleCfg(coord);
  5797. }
  5798. } else {
  5799. appendCfg = self._getLineCfg(coord, dimType, position);
  5800. }
  5801. if (grid && verticalScale) {
  5802. var gridPoints = [];
  5803. var verticalTicks = formatTicks(verticalScale.getTicks());
  5804. each(ticks, function (tick) {
  5805. var subPoints = [];
  5806. each(verticalTicks, function (verticalTick) {
  5807. var x = dimType === 'x' ? tick.value : verticalTick.value;
  5808. var y = dimType === 'x' ? verticalTick.value : tick.value;
  5809. if (x >= 0 && x <= 1 && y >= 0 && y <= 1) {
  5810. var point = coord.convertPoint({
  5811. x: x,
  5812. y: y
  5813. });
  5814. subPoints.push(point);
  5815. }
  5816. });
  5817. gridPoints.push({
  5818. points: subPoints,
  5819. _id: 'axis-' + dimType + index + '-grid-' + tick.tickValue
  5820. });
  5821. });
  5822. axis.gridPoints = gridPoints;
  5823. if (coord.isPolar) {
  5824. axis.center = coord.center;
  5825. axis.startAngle = coord.startAngle;
  5826. axis.endAngle = coord.endAngle;
  5827. }
  5828. }
  5829. appendCfg._id = 'axis-' + dimType;
  5830. if (!isNil(index)) {
  5831. appendCfg._id = 'axis-' + dimType + index;
  5832. }
  5833. new Abastract[type](mix(axis, appendCfg));
  5834. });
  5835. };
  5836. _proto.clear = function clear() {
  5837. this.axes = {};
  5838. this.frontPlot.clear();
  5839. this.backPlot.clear();
  5840. };
  5841. return AxisController;
  5842. }();
  5843. var calcDirection = function calcDirection(start, end) {
  5844. var xDistance = end.x - start.x;
  5845. var yDistance = end.y - start.y; // x 的距离大于y 说明是横向,否则就是纵向
  5846. if (Math.abs(xDistance) > Math.abs(yDistance)) {
  5847. return xDistance > 0 ? 'right' : 'left';
  5848. }
  5849. return yDistance > 0 ? 'down' : 'up';
  5850. }; // 计算2点之间的距离
  5851. var calcDistance = function calcDistance(point1, point2) {
  5852. var xDistance = Math.abs(point2.x - point1.x);
  5853. var yDistance = Math.abs(point2.y - point1.y);
  5854. return Math.sqrt(xDistance * xDistance + yDistance * yDistance);
  5855. };
  5856. var getCenter = function getCenter(point1, point2) {
  5857. var x = point1.x + (point2.x - point1.x) / 2;
  5858. var y = point1.y + (point2.y - point1.y) / 2;
  5859. return {
  5860. x: x,
  5861. y: y
  5862. };
  5863. };
  5864. var PRESS_DELAY = 250;
  5865. var EventController = /*#__PURE__*/function () {
  5866. function EventController(_ref) {
  5867. var _this = this;
  5868. var canvas = _ref.canvas,
  5869. el = _ref.el;
  5870. _defineProperty(this, "_click", function (ev) {
  5871. var points = convertPoints(ev, _this.canvas);
  5872. ev.points = points;
  5873. _this.emitEvent('click', ev);
  5874. });
  5875. _defineProperty(this, "_start", function (ev) {
  5876. var points = convertPoints(ev, _this.canvas);
  5877. if (!points) {
  5878. return;
  5879. }
  5880. ev.points = points;
  5881. _this.emitEvent('touchstart', ev); // 防止上次的内容没有清理掉,重新reset下
  5882. _this.reset(); // 记录touch start 的时间
  5883. _this.startTime = Date.now(); // 记录touch start 的点
  5884. _this.startPoints = points;
  5885. if (points.length > 1) {
  5886. _this.startDistance = calcDistance(points[0], points[1]);
  5887. _this.center = getCenter(points[0], points[1]);
  5888. } else {
  5889. // 如果touchstart后停顿250ms, 则也触发press事件
  5890. _this.pressTimeout = setTimeout(function () {
  5891. // 这里固定触发press事件
  5892. var eventType = 'press';
  5893. var direction = 'none';
  5894. ev.direction = direction;
  5895. _this.emitStart(eventType, ev);
  5896. _this.emitEvent(eventType, ev);
  5897. _this.eventType = eventType;
  5898. _this.direction = direction;
  5899. }, PRESS_DELAY);
  5900. }
  5901. });
  5902. _defineProperty(this, "_move", function (ev) {
  5903. var points = convertPoints(ev, _this.canvas);
  5904. if (!points) return;
  5905. _this.clearPressTimeout();
  5906. ev.points = points;
  5907. _this.emitEvent('touchmove', ev);
  5908. var startPoints = _this.startPoints;
  5909. if (!startPoints) return; // 多指触控
  5910. if (points.length > 1) {
  5911. // touchstart的距离
  5912. var startDistance = _this.startDistance;
  5913. var currentDistance = calcDistance(points[0], points[1]);
  5914. ev.zoom = currentDistance / startDistance;
  5915. ev.center = _this.center; // 触发缩放事件
  5916. _this.emitStart('pinch', ev);
  5917. _this.emitEvent('pinch', ev);
  5918. } else {
  5919. var deltaX = points[0].x - startPoints[0].x;
  5920. var deltaY = points[0].y - startPoints[0].y;
  5921. var direction = _this.direction || calcDirection(startPoints[0], points[0]);
  5922. _this.direction = direction; // 获取press或者pan的事件类型
  5923. // press 按住滑动, pan表示平移
  5924. // 如果start后立刻move,则触发pan, 如果有停顿,则触发press
  5925. var eventType = _this.getEventType(points);
  5926. ev.direction = direction;
  5927. ev.deltaX = deltaX;
  5928. ev.deltaY = deltaY;
  5929. _this.emitStart(eventType, ev);
  5930. _this.emitEvent(eventType, ev); // 记录最后2次move的时间和坐标,为了给swipe事件用
  5931. var prevMoveTime = _this.lastMoveTime;
  5932. var now = Date.now(); // 最后2次的时间间隔一定要大于0,否则swipe没发计算
  5933. if (now - prevMoveTime > 0) {
  5934. _this.prevMoveTime = prevMoveTime;
  5935. _this.prevMovePoints = _this.lastMovePoints;
  5936. _this.lastMoveTime = now;
  5937. _this.lastMovePoints = points;
  5938. }
  5939. }
  5940. });
  5941. _defineProperty(this, "_end", function (ev) {
  5942. var points = convertPoints(ev, _this.canvas);
  5943. ev.points = points;
  5944. _this.emitEnd(ev);
  5945. _this.emitEvent('touchend', ev); // swipe事件处理, 在touchend之后触发
  5946. var lastMoveTime = _this.lastMoveTime;
  5947. var now = Date.now(); // 做这个判断是为了最后一次touchmove后到end前,还有一个停顿的过程
  5948. // 100 是拍的一个值,理论这个值会很短,一般不卡顿的话在10ms以内
  5949. if (now - lastMoveTime < 100) {
  5950. var prevMoveTime = _this.prevMoveTime || _this.startTime;
  5951. var intervalTime = lastMoveTime - prevMoveTime; // 时间间隔一定要大于0, 否则计算没意义
  5952. if (intervalTime > 0) {
  5953. var prevMovePoints = _this.prevMovePoints || _this.startPoints;
  5954. var lastMovePoints = _this.lastMovePoints; // move速率
  5955. var velocity = calcDistance(prevMovePoints[0], lastMovePoints[0]) / intervalTime; // 0.3 是参考hammerjs的设置
  5956. if (velocity > 0.3) {
  5957. ev.velocity = velocity;
  5958. ev.direction = calcDirection(prevMovePoints[0], lastMovePoints[0]);
  5959. _this.emitEvent('swipe', ev);
  5960. }
  5961. }
  5962. }
  5963. _this.reset();
  5964. var touches = ev.touches; // 当多指只释放了1指时也会触发end, 这时重新触发一次start
  5965. if (touches && touches.length > 0) {
  5966. _this._start(ev);
  5967. }
  5968. });
  5969. _defineProperty(this, "_cancel", function (ev) {
  5970. _this.emitEvent('touchcancel', ev);
  5971. _this.reset();
  5972. });
  5973. // canvasEl
  5974. this.canvas = canvas;
  5975. this.delegateEvent(el); // 用来记录当前触发的事件
  5976. this.processEvent = {};
  5977. }
  5978. var _proto = EventController.prototype;
  5979. _proto.delegateEvent = function delegateEvent(canvasEl) {
  5980. // 代理这几个事件
  5981. canvasEl.addEventListener('click', this._click);
  5982. canvasEl.addEventListener('touchstart', this._start);
  5983. canvasEl.addEventListener('touchmove', this._move);
  5984. canvasEl.addEventListener('touchend', this._end);
  5985. canvasEl.addEventListener('touchcancel', this._cancel);
  5986. };
  5987. _proto.emitEvent = function emitEvent(type, ev) {
  5988. var canvas = this.canvas;
  5989. canvas.emit(type, ev);
  5990. };
  5991. _proto.getEventType = function getEventType(points) {
  5992. var eventType = this.eventType,
  5993. canvas = this.canvas,
  5994. startTime = this.startTime,
  5995. startPoints = this.startPoints;
  5996. if (eventType) {
  5997. return eventType;
  5998. }
  5999. var type;
  6000. var panEventListeners = canvas.__events.pan; // 如果没有pan事件的监听,默认都是press
  6001. if (!panEventListeners || !panEventListeners.length) {
  6002. type = 'press';
  6003. } else {
  6004. // 如果有pan事件的处理,press则需要停顿250ms, 且移动距离小于10
  6005. var now = Date.now();
  6006. if (now - startTime > PRESS_DELAY && calcDistance(startPoints[0], points[0]) < 10) {
  6007. type = 'press';
  6008. } else {
  6009. type = 'pan';
  6010. }
  6011. }
  6012. this.eventType = type;
  6013. return type;
  6014. };
  6015. _proto.enable = function enable(eventType) {
  6016. this.processEvent[eventType] = true;
  6017. } // 是否进行中的事件
  6018. ;
  6019. _proto.isProcess = function isProcess(eventType) {
  6020. return this.processEvent[eventType];
  6021. } // 触发start事件
  6022. ;
  6023. _proto.emitStart = function emitStart(type, ev) {
  6024. if (this.isProcess(type)) {
  6025. return;
  6026. }
  6027. this.enable(type);
  6028. this.emitEvent(type + "start", ev);
  6029. } // 触发end事件
  6030. ;
  6031. _proto.emitEnd = function emitEnd(ev) {
  6032. var _this2 = this;
  6033. var processEvent = this.processEvent;
  6034. Object.keys(processEvent).forEach(function (type) {
  6035. _this2.emitEvent(type + "end", ev);
  6036. delete processEvent[type];
  6037. });
  6038. };
  6039. _proto.clearPressTimeout = function clearPressTimeout() {
  6040. if (this.pressTimeout) {
  6041. clearTimeout(this.pressTimeout);
  6042. this.pressTimeout = 0;
  6043. }
  6044. };
  6045. _proto.reset = function reset() {
  6046. this.clearPressTimeout();
  6047. this.startTime = 0;
  6048. this.startPoints = null;
  6049. this.startDistance = 0;
  6050. this.direction = null;
  6051. this.eventType = null;
  6052. this.pinch = false;
  6053. this.prevMoveTime = 0;
  6054. this.prevMovePoints = null;
  6055. this.lastMoveTime = 0;
  6056. this.lastMovePoints = null;
  6057. };
  6058. return EventController;
  6059. }();
  6060. var CanvasElement = /*#__PURE__*/function (_EventEmit) {
  6061. _inheritsLoose(CanvasElement, _EventEmit);
  6062. function CanvasElement(ctx) {
  6063. var _this;
  6064. _this = _EventEmit.call(this) || this;
  6065. _this.context = ctx; // canvas实际的宽高 (width/height) * pixelRatio
  6066. _this.width = 0;
  6067. _this.height = 0;
  6068. _this.style = {};
  6069. _this.currentStyle = {};
  6070. _this.attrs = {}; // 用来标识是CanvasElement实例
  6071. _this.isCanvasElement = true;
  6072. return _this;
  6073. }
  6074. var _proto = CanvasElement.prototype;
  6075. _proto.getContext = function getContext()
  6076. /* type */
  6077. {
  6078. return this.context;
  6079. };
  6080. _proto.getBoundingClientRect = function getBoundingClientRect() {
  6081. var width = this.width;
  6082. var height = this.height; // 默认都处理成可视窗口的顶部位置
  6083. return {
  6084. top: 0,
  6085. right: width,
  6086. bottom: height,
  6087. left: 0
  6088. };
  6089. };
  6090. _proto.setAttribute = function setAttribute(key, value) {
  6091. this.attrs[key] = value;
  6092. };
  6093. _proto.addEventListener = function addEventListener(type, listener) {
  6094. this.on(type, listener);
  6095. };
  6096. _proto.removeEventListener = function removeEventListener(type, listener) {
  6097. this.off(type, listener);
  6098. };
  6099. _proto.dispatchEvent = function dispatchEvent(type, e) {
  6100. this.emit(type, e);
  6101. };
  6102. return CanvasElement;
  6103. }(EventEmit);
  6104. function supportEventListener(canvas) {
  6105. if (!canvas) {
  6106. return false;
  6107. } // 非 HTMLCanvasElement
  6108. if (canvas.nodeType !== 1 || !canvas.nodeName || canvas.nodeName.toLowerCase() !== 'canvas') {
  6109. return false;
  6110. } // 微信小程序canvas.getContext('2d')时也是CanvasRenderingContext2D
  6111. // 也会有ctx.canvas, 而且nodeType也是1,所以还要在看下是否支持addEventListener
  6112. var support = false;
  6113. try {
  6114. canvas.addEventListener('eventTest', function () {
  6115. support = true;
  6116. });
  6117. canvas.dispatchEvent(new Event('eventTest'));
  6118. } catch (error) {
  6119. support = false;
  6120. }
  6121. return support;
  6122. }
  6123. var CanvasElement$1 = {
  6124. create: function create(ctx) {
  6125. if (!ctx) {
  6126. return null;
  6127. }
  6128. if (supportEventListener(ctx.canvas)) {
  6129. return ctx.canvas;
  6130. }
  6131. return new CanvasElement(ctx);
  6132. }
  6133. };
  6134. function _mod(n, m) {
  6135. return (n % m + m) % m;
  6136. }
  6137. function _addStop(steps, gradient) {
  6138. each(steps, function (item) {
  6139. item = item.split(':');
  6140. gradient.addColorStop(Number(item[0]), item[1]);
  6141. });
  6142. } // the string format: 'l(0) 0:#ffffff 0.5:#7ec2f3 1:#1890ff'
  6143. function _parseLineGradient(color, shape, context) {
  6144. var arr = color.split(' ');
  6145. var angle = arr[0].slice(2, arr[0].length - 1);
  6146. angle = _mod(parseFloat(angle) * Math.PI / 180, Math.PI * 2);
  6147. var steps = arr.slice(1);
  6148. var _shape$getBBox = shape.getBBox(),
  6149. minX = _shape$getBBox.minX,
  6150. minY = _shape$getBBox.minY,
  6151. maxX = _shape$getBBox.maxX,
  6152. maxY = _shape$getBBox.maxY;
  6153. var start;
  6154. var end;
  6155. if (angle >= 0 && angle < 0.5 * Math.PI) {
  6156. start = {
  6157. x: minX,
  6158. y: minY
  6159. };
  6160. end = {
  6161. x: maxX,
  6162. y: maxY
  6163. };
  6164. } else if (0.5 * Math.PI <= angle && angle < Math.PI) {
  6165. start = {
  6166. x: maxX,
  6167. y: minY
  6168. };
  6169. end = {
  6170. x: minX,
  6171. y: maxY
  6172. };
  6173. } else if (Math.PI <= angle && angle < 1.5 * Math.PI) {
  6174. start = {
  6175. x: maxX,
  6176. y: maxY
  6177. };
  6178. end = {
  6179. x: minX,
  6180. y: minY
  6181. };
  6182. } else {
  6183. start = {
  6184. x: minX,
  6185. y: maxY
  6186. };
  6187. end = {
  6188. x: maxX,
  6189. y: minY
  6190. };
  6191. }
  6192. var tanTheta = Math.tan(angle);
  6193. var tanTheta2 = tanTheta * tanTheta;
  6194. var x = (end.x - start.x + tanTheta * (end.y - start.y)) / (tanTheta2 + 1) + start.x;
  6195. var y = tanTheta * (end.x - start.x + tanTheta * (end.y - start.y)) / (tanTheta2 + 1) + start.y;
  6196. var gradient = context.createLinearGradient(start.x, start.y, x, y);
  6197. _addStop(steps, gradient);
  6198. return gradient;
  6199. } // the string format: 'r(0.5, 0.5, 0.1) 0:#ffffff 1:#1890ff'
  6200. function _parseRadialGradient(color, shape, context) {
  6201. var arr = color.split(' ');
  6202. var circleCfg = arr[0].slice(2, arr[0].length - 1);
  6203. circleCfg = circleCfg.split(',');
  6204. var fx = parseFloat(circleCfg[0]);
  6205. var fy = parseFloat(circleCfg[1]);
  6206. var fr = parseFloat(circleCfg[2]);
  6207. var steps = arr.slice(1); // if radius is 0, no gradient, stroke with the last color
  6208. if (fr === 0) {
  6209. var _color = steps[steps.length - 1];
  6210. return _color.split(':')[1];
  6211. }
  6212. var _shape$getBBox2 = shape.getBBox(),
  6213. width = _shape$getBBox2.width,
  6214. height = _shape$getBBox2.height,
  6215. minX = _shape$getBBox2.minX,
  6216. minY = _shape$getBBox2.minY;
  6217. var r = Math.sqrt(width * width + height * height) / 2;
  6218. var gradient = context.createRadialGradient(minX + width * fx, minY + height * fy, fr * r, minX + width / 2, minY + height / 2, r);
  6219. _addStop(steps, gradient);
  6220. return gradient;
  6221. }
  6222. function parseStyle(color, shape, context) {
  6223. if (color[1] === '(') {
  6224. try {
  6225. var firstCode = color[0];
  6226. if (firstCode === 'l') {
  6227. return _parseLineGradient(color, shape, context);
  6228. } else if (firstCode === 'r') {
  6229. return _parseRadialGradient(color, shape, context);
  6230. }
  6231. } catch (ev) {
  6232. console.error('error in parsing gradient string, please check if there are any extra whitespaces.');
  6233. console.error(ev);
  6234. }
  6235. }
  6236. return color;
  6237. }
  6238. var ALIAS_ATTRS_MAP = {
  6239. stroke: 'strokeStyle',
  6240. fill: 'fillStyle',
  6241. opacity: 'globalAlpha'
  6242. };
  6243. var SHAPE_ATTRS = ['fillStyle', 'font', 'globalAlpha', 'lineCap', 'lineWidth', 'lineJoin', 'miterLimit', 'shadowBlur', 'shadowColor', 'shadowOffsetX', 'shadowOffsetY', 'strokeStyle', 'textAlign', 'textBaseline', 'lineDash', 'shadow' // 兼容支付宝小程序
  6244. ];
  6245. var CLIP_SHAPES = ['circle', 'sector', 'polygon', 'rect', 'polyline'];
  6246. var Element = /*#__PURE__*/function () {
  6247. var _proto = Element.prototype;
  6248. _proto._initProperties = function _initProperties() {
  6249. this._attrs = {
  6250. zIndex: 0,
  6251. visible: true,
  6252. destroyed: false
  6253. };
  6254. };
  6255. function Element(cfg) {
  6256. this._initProperties();
  6257. mix(this._attrs, cfg);
  6258. var attrs = this._attrs.attrs;
  6259. if (attrs) {
  6260. this.initAttrs(attrs);
  6261. }
  6262. this.initTransform();
  6263. }
  6264. _proto.get = function get(name) {
  6265. return this._attrs[name];
  6266. };
  6267. _proto.set = function set(name, value) {
  6268. this._attrs[name] = value;
  6269. };
  6270. _proto.isGroup = function isGroup() {
  6271. return this.get('isGroup');
  6272. };
  6273. _proto.isShape = function isShape() {
  6274. return this.get('isShape');
  6275. };
  6276. _proto.initAttrs = function initAttrs(attrs) {
  6277. this.attr(mix(this.getDefaultAttrs(), attrs));
  6278. };
  6279. _proto.getDefaultAttrs = function getDefaultAttrs() {
  6280. return {};
  6281. };
  6282. _proto._setAttr = function _setAttr(name, value) {
  6283. var attrs = this._attrs.attrs;
  6284. if (name === 'clip') {
  6285. value = this._setAttrClip(value);
  6286. } else {
  6287. var alias = ALIAS_ATTRS_MAP[name];
  6288. if (alias) {
  6289. attrs[alias] = value;
  6290. }
  6291. }
  6292. attrs[name] = value;
  6293. };
  6294. _proto._getAttr = function _getAttr(name) {
  6295. return this._attrs.attrs[name];
  6296. } // _afterAttrsSet() {}
  6297. ;
  6298. _proto._setAttrClip = function _setAttrClip(clip) {
  6299. if (clip && CLIP_SHAPES.indexOf(clip._attrs.type) > -1) {
  6300. if (clip.get('canvas') === null) {
  6301. clip = Object.assign({}, clip);
  6302. }
  6303. clip.set('parent', this.get('parent'));
  6304. clip.set('context', this.get('context'));
  6305. return clip;
  6306. }
  6307. return null;
  6308. };
  6309. _proto.attr = function attr(name, value) {
  6310. var self = this;
  6311. if (self.get('destroyed')) return null;
  6312. var argumentsLen = arguments.length;
  6313. if (argumentsLen === 0) {
  6314. return self._attrs.attrs;
  6315. }
  6316. if (isObject(name)) {
  6317. this._attrs.bbox = null;
  6318. for (var k in name) {
  6319. self._setAttr(k, name[k]);
  6320. }
  6321. if (self._afterAttrsSet) {
  6322. self._afterAttrsSet();
  6323. }
  6324. return self;
  6325. }
  6326. if (argumentsLen === 2) {
  6327. this._attrs.bbox = null;
  6328. self._setAttr(name, value);
  6329. if (self._afterAttrsSet) {
  6330. self._afterAttrsSet();
  6331. }
  6332. return self;
  6333. }
  6334. return self._getAttr(name);
  6335. };
  6336. _proto.getParent = function getParent() {
  6337. return this.get('parent');
  6338. };
  6339. _proto.draw = function draw(context) {
  6340. if (this.get('destroyed')) {
  6341. return;
  6342. }
  6343. if (this.get('visible')) {
  6344. this.setContext(context);
  6345. this.drawInner(context);
  6346. this.restoreContext(context);
  6347. }
  6348. };
  6349. _proto.setContext = function setContext(context) {
  6350. var clip = this._attrs.attrs.clip;
  6351. context.save();
  6352. if (clip) {
  6353. clip.resetTransform(context);
  6354. clip.createPath(context);
  6355. context.clip();
  6356. }
  6357. this.resetContext(context);
  6358. this.resetTransform(context);
  6359. };
  6360. _proto.restoreContext = function restoreContext(context) {
  6361. context.restore();
  6362. };
  6363. _proto.resetContext = function resetContext(context) {
  6364. var elAttrs = this._attrs.attrs;
  6365. for (var k in elAttrs) {
  6366. if (SHAPE_ATTRS.indexOf(k) > -1) {
  6367. var v = elAttrs[k];
  6368. if ((k === 'fillStyle' || k === 'strokeStyle') && v) {
  6369. v = parseStyle(v, this, context);
  6370. }
  6371. if (k === 'lineDash' && context.setLineDash && isArray(v)) {
  6372. context.setLineDash(v);
  6373. } else {
  6374. context[k] = v;
  6375. }
  6376. }
  6377. }
  6378. };
  6379. _proto.hasFill = function hasFill() {
  6380. return this.get('canFill') && this._attrs.attrs.fillStyle;
  6381. };
  6382. _proto.hasStroke = function hasStroke() {
  6383. return this.get('canStroke') && this._attrs.attrs.strokeStyle;
  6384. };
  6385. _proto.drawInner = function drawInner()
  6386. /* context */
  6387. {};
  6388. _proto.show = function show() {
  6389. this.set('visible', true);
  6390. return this;
  6391. };
  6392. _proto.hide = function hide() {
  6393. this.set('visible', false);
  6394. return this;
  6395. };
  6396. _proto.isVisible = function isVisible() {
  6397. return this.get('visible');
  6398. };
  6399. _proto.getAriaLabel = function getAriaLabel() {
  6400. var _this$_attrs = this._attrs,
  6401. destroyed = _this$_attrs.destroyed,
  6402. visible = _this$_attrs.visible,
  6403. isShape = _this$_attrs.isShape,
  6404. aria = _this$_attrs.aria;
  6405. if (destroyed || !visible || isShape && !aria) {
  6406. return;
  6407. }
  6408. return this._getAriaLabel();
  6409. };
  6410. _proto._getAriaLabel = function _getAriaLabel() {
  6411. return this._attrs.ariaLabel;
  6412. };
  6413. _proto._removeFromParent = function _removeFromParent() {
  6414. var parent = this.get('parent');
  6415. if (parent) {
  6416. var children = parent.get('children');
  6417. remove(children, this);
  6418. }
  6419. return this;
  6420. };
  6421. _proto.remove = function remove(destroy) {
  6422. if (destroy) {
  6423. this.destroy();
  6424. } else {
  6425. this._removeFromParent();
  6426. }
  6427. };
  6428. _proto.destroy = function destroy() {
  6429. var destroyed = this.get('destroyed');
  6430. if (destroyed) {
  6431. return null;
  6432. }
  6433. this._removeFromParent();
  6434. this._attrs = {};
  6435. this.set('destroyed', true);
  6436. };
  6437. _proto.getBBox = function getBBox() {
  6438. return {
  6439. minX: 0,
  6440. maxX: 0,
  6441. minY: 0,
  6442. maxY: 0,
  6443. width: 0,
  6444. height: 0
  6445. };
  6446. };
  6447. _proto.initTransform = function initTransform() {
  6448. var attrs = this._attrs.attrs || {};
  6449. if (!attrs.matrix) {
  6450. attrs.matrix = [1, 0, 0, 1, 0, 0];
  6451. }
  6452. this._attrs.attrs = attrs;
  6453. };
  6454. _proto.getMatrix = function getMatrix() {
  6455. return this._attrs.attrs.matrix;
  6456. };
  6457. _proto.setMatrix = function setMatrix(m) {
  6458. this._attrs.attrs.matrix = [m[0], m[1], m[2], m[3], m[4], m[5]];
  6459. };
  6460. _proto.transform = function transform(actions) {
  6461. var matrix = this._attrs.attrs.matrix;
  6462. this._attrs.attrs.matrix = Matrix.transform(matrix, actions);
  6463. return this;
  6464. };
  6465. _proto.setTransform = function setTransform(actions) {
  6466. this._attrs.attrs.matrix = [1, 0, 0, 1, 0, 0];
  6467. return this.transform(actions);
  6468. };
  6469. _proto.translate = function translate(x, y) {
  6470. var matrix = this._attrs.attrs.matrix;
  6471. Matrix.translate(matrix, matrix, [x, y]);
  6472. };
  6473. _proto.rotate = function rotate(rad) {
  6474. var matrix = this._attrs.attrs.matrix;
  6475. Matrix.rotate(matrix, matrix, rad);
  6476. };
  6477. _proto.scale = function scale(sx, sy) {
  6478. var matrix = this._attrs.attrs.matrix;
  6479. Matrix.scale(matrix, matrix, [sx, sy]);
  6480. };
  6481. _proto.moveTo = function moveTo(x, y) {
  6482. var cx = this._attrs.x || 0;
  6483. var cy = this._attrs.y || 0;
  6484. this.translate(x - cx, y - cy);
  6485. this.set('x', x);
  6486. this.set('y', y);
  6487. };
  6488. _proto.apply = function apply(v) {
  6489. var m = this._attrs.attrs.matrix;
  6490. Vector2.transformMat2d(v, v, m);
  6491. return this;
  6492. };
  6493. _proto.resetTransform = function resetTransform(context) {
  6494. var mo = this._attrs.attrs.matrix;
  6495. if (Matrix.isChanged(mo)) {
  6496. context.transform(mo[0], mo[1], mo[2], mo[3], mo[4], mo[5]);
  6497. }
  6498. };
  6499. _proto.isDestroyed = function isDestroyed() {
  6500. return this.get('destroyed');
  6501. };
  6502. return Element;
  6503. }();
  6504. var Shape$2 = /*#__PURE__*/function (_Element) {
  6505. _inheritsLoose(Shape, _Element);
  6506. function Shape() {
  6507. return _Element.apply(this, arguments) || this;
  6508. }
  6509. var _proto = Shape.prototype;
  6510. _proto._initProperties = function _initProperties() {
  6511. this._attrs = {
  6512. zIndex: 0,
  6513. visible: true,
  6514. destroyed: false,
  6515. isShape: true,
  6516. attrs: {}
  6517. };
  6518. };
  6519. _proto.getType = function getType() {
  6520. return this._attrs.type;
  6521. };
  6522. _proto.drawInner = function drawInner(context) {
  6523. var self = this;
  6524. var attrs = self.get('attrs');
  6525. self.createPath(context);
  6526. var originOpacity = context.globalAlpha;
  6527. if (self.hasFill()) {
  6528. var fillOpacity = attrs.fillOpacity;
  6529. if (!isNil(fillOpacity) && fillOpacity !== 1) {
  6530. context.globalAlpha = fillOpacity;
  6531. context.fill();
  6532. context.globalAlpha = originOpacity;
  6533. } else {
  6534. context.fill();
  6535. }
  6536. }
  6537. if (self.hasStroke()) {
  6538. var lineWidth = attrs.lineWidth;
  6539. if (lineWidth > 0) {
  6540. var strokeOpacity = attrs.strokeOpacity;
  6541. if (!isNil(strokeOpacity) && strokeOpacity !== 1) {
  6542. context.globalAlpha = strokeOpacity;
  6543. }
  6544. context.stroke();
  6545. }
  6546. }
  6547. };
  6548. _proto.getBBox = function getBBox() {
  6549. var bbox = this._attrs.bbox;
  6550. if (!bbox) {
  6551. bbox = this.calculateBox();
  6552. if (bbox) {
  6553. bbox.x = bbox.minX;
  6554. bbox.y = bbox.minY;
  6555. bbox.width = bbox.maxX - bbox.minX;
  6556. bbox.height = bbox.maxY - bbox.minY;
  6557. }
  6558. this._attrs.bbox = bbox;
  6559. }
  6560. return bbox;
  6561. };
  6562. _proto.calculateBox = function calculateBox() {
  6563. return null;
  6564. };
  6565. _proto.createPath = function createPath() {};
  6566. return Shape;
  6567. }(Element);
  6568. function parseRadius(radius, width, height) {
  6569. radius = parsePadding(radius); // 都为0
  6570. if (!radius[0] && !radius[1] && !radius[2] && !radius[3]) {
  6571. return radius;
  6572. }
  6573. var minWidth = Math.max(radius[0] + radius[1], radius[2] + radius[3]);
  6574. var minHeight = Math.max(radius[0] + radius[3], radius[1] + radius[2]);
  6575. var scale = Math.min(width / minWidth, height / minHeight);
  6576. if (scale < 1) {
  6577. return radius.map(function (r) {
  6578. return r * scale;
  6579. });
  6580. }
  6581. return radius;
  6582. }
  6583. var Rect = /*#__PURE__*/function (_Shape) {
  6584. _inheritsLoose(Rect, _Shape);
  6585. function Rect() {
  6586. return _Shape.apply(this, arguments) || this;
  6587. }
  6588. var _proto = Rect.prototype;
  6589. _proto._initProperties = function _initProperties() {
  6590. _Shape.prototype._initProperties.call(this);
  6591. this._attrs.canFill = true;
  6592. this._attrs.canStroke = true;
  6593. this._attrs.type = 'rect';
  6594. };
  6595. _proto.getDefaultAttrs = function getDefaultAttrs() {
  6596. return {
  6597. x: 0,
  6598. y: 0,
  6599. width: 0,
  6600. height: 0,
  6601. radius: 0,
  6602. lineWidth: 0
  6603. };
  6604. };
  6605. _proto.createRadiusPath = function createRadiusPath(context, x, y, width, height, radius) {
  6606. radius = parseRadius(radius, width, height);
  6607. context.moveTo(x + radius[0], y);
  6608. context.lineTo(x + width - radius[1], y);
  6609. context.arc(x + width - radius[1], y + radius[1], radius[1], -Math.PI / 2, 0, false);
  6610. context.lineTo(x + width, y + height - radius[2]);
  6611. context.arc(x + width - radius[2], y + height - radius[2], radius[2], 0, Math.PI / 2, false);
  6612. context.lineTo(x + radius[3], y + height);
  6613. context.arc(x + radius[3], y + height - radius[3], radius[3], Math.PI / 2, Math.PI, false);
  6614. context.lineTo(x, y + radius[0]);
  6615. context.arc(x + radius[0], y + radius[0], radius[0], Math.PI, Math.PI * 3 / 2, false);
  6616. context.closePath();
  6617. };
  6618. _proto.createPath = function createPath(context) {
  6619. var self = this;
  6620. var attrs = self.get('attrs');
  6621. var x = attrs.x,
  6622. y = attrs.y,
  6623. width = attrs.width,
  6624. height = attrs.height,
  6625. radius = attrs.radius;
  6626. context.beginPath();
  6627. if (!radius || !(width * height)) {
  6628. context.rect(x, y, width, height);
  6629. } else {
  6630. this.createRadiusPath(context, x, y, width, height, radius);
  6631. }
  6632. };
  6633. _proto.calculateBox = function calculateBox() {
  6634. var attrs = this.get('attrs');
  6635. var x = attrs.x,
  6636. y = attrs.y,
  6637. width = attrs.width,
  6638. height = attrs.height;
  6639. return {
  6640. minX: x,
  6641. minY: y,
  6642. maxX: x + width,
  6643. maxY: y + height
  6644. };
  6645. };
  6646. return Rect;
  6647. }(Shape$2);
  6648. var imageCaches = {};
  6649. var ImageShape = /*#__PURE__*/function (_Rect) {
  6650. _inheritsLoose(ImageShape, _Rect);
  6651. function ImageShape() {
  6652. return _Rect.apply(this, arguments) || this;
  6653. }
  6654. var _proto = ImageShape.prototype;
  6655. _proto._initProperties = function _initProperties() {
  6656. _Rect.prototype._initProperties.call(this);
  6657. this._attrs.canFill = false;
  6658. this._attrs.canStroke = false;
  6659. this._attrs.loading = false;
  6660. this._attrs.image = null;
  6661. this._attrs.type = 'image';
  6662. };
  6663. _proto.draw = function draw(context) {
  6664. var _this = this;
  6665. // 如果图片还在loading中直接返回,等下次绘制
  6666. if (this.get('loading')) {
  6667. return;
  6668. } // 如果已经有image对象,直接绘制,会调用createPath绘制
  6669. var image = this.get('image');
  6670. if (image) {
  6671. _Rect.prototype.draw.call(this, context);
  6672. return;
  6673. }
  6674. var attrs = this.get('attrs');
  6675. var src = attrs.src;
  6676. if (src && window.Image) {
  6677. var cacheImage = this.get('cacheImage'); // 如果有缓存,则直接从缓存中拿
  6678. if (cacheImage && imageCaches[src]) {
  6679. this.set('image', imageCaches[src]);
  6680. this.draw(context);
  6681. return;
  6682. }
  6683. this.set('loading', true);
  6684. var _image = new Image(); // 设置跨域, 等同于 image.crossOrigin = 'anonymous'
  6685. _image.crossOrigin = '';
  6686. _image.onload = function () {
  6687. _this.set('loading', false);
  6688. _this.set('image', _image);
  6689. _this.draw(context);
  6690. }; // src 一定要在 crossOrigin 之后,否则 toDataURL 就会报 SecurityError
  6691. _image.src = src; // 设置全局缓存
  6692. if (cacheImage) {
  6693. imageCaches[src] = _image;
  6694. }
  6695. }
  6696. };
  6697. _proto.createPath = function createPath(context) {
  6698. var image = this.get('image');
  6699. this.drawImage(context, image);
  6700. };
  6701. _proto.drawImage = function drawImage(context, image) {
  6702. var _this$_attrs = this._attrs,
  6703. attrs = _this$_attrs.attrs,
  6704. destroyed = _this$_attrs.destroyed;
  6705. if (destroyed) {
  6706. return;
  6707. }
  6708. var x = attrs.x,
  6709. y = attrs.y,
  6710. width = attrs.width,
  6711. height = attrs.height,
  6712. sx = attrs.sx,
  6713. sy = attrs.sy,
  6714. swidth = attrs.swidth,
  6715. sheight = attrs.sheight,
  6716. radius = attrs.radius,
  6717. fillOpacity = attrs.fillOpacity;
  6718. if (radius) {
  6719. context.save();
  6720. this.createRadiusPath(context, x, y, width, height, radius);
  6721. context.clip();
  6722. } // 设置透明度
  6723. var originOpacity = context.globalAlpha;
  6724. if (!isNil(fillOpacity)) {
  6725. context.globalAlpha = fillOpacity;
  6726. }
  6727. if (!isNil(sx) && !isNil(sy) && !isNil(swidth) && !isNil(sheight)) {
  6728. context.drawImage(image, sx, sy, swidth, sheight, x, y, width, height);
  6729. } else {
  6730. context.drawImage(image, x, y, width, height);
  6731. }
  6732. context.globalAlpha = originOpacity;
  6733. if (radius) {
  6734. // 因为 save 和 restore 会一定程度上影响绘图性能,所以只在必要是调用
  6735. context.restore();
  6736. }
  6737. };
  6738. return ImageShape;
  6739. }(Rect);
  6740. var Circle = /*#__PURE__*/function (_Shape) {
  6741. _inheritsLoose(Circle, _Shape);
  6742. function Circle() {
  6743. return _Shape.apply(this, arguments) || this;
  6744. }
  6745. var _proto = Circle.prototype;
  6746. _proto._initProperties = function _initProperties() {
  6747. _Shape.prototype._initProperties.call(this);
  6748. this._attrs.canFill = true;
  6749. this._attrs.canStroke = true;
  6750. this._attrs.type = 'circle';
  6751. };
  6752. _proto.getDefaultAttrs = function getDefaultAttrs() {
  6753. return {
  6754. x: 0,
  6755. y: 0,
  6756. r: 0,
  6757. lineWidth: 0
  6758. };
  6759. };
  6760. _proto.createPath = function createPath(context) {
  6761. var attrs = this.get('attrs');
  6762. var x = attrs.x,
  6763. y = attrs.y,
  6764. r = attrs.r;
  6765. context.beginPath();
  6766. context.arc(x, y, r, 0, Math.PI * 2, false);
  6767. context.closePath();
  6768. };
  6769. _proto.calculateBox = function calculateBox() {
  6770. var attrs = this.get('attrs');
  6771. var x = attrs.x,
  6772. y = attrs.y,
  6773. r = attrs.r;
  6774. return {
  6775. minX: x - r,
  6776. maxX: x + r,
  6777. minY: y - r,
  6778. maxY: y + r
  6779. };
  6780. };
  6781. return Circle;
  6782. }(Shape$2);
  6783. var start = Vector2.create();
  6784. var end = Vector2.create();
  6785. var extremity = Vector2.create();
  6786. function getCubicBezierXYatT(startPt, controlPt1, controlPt2, endPt, T) {
  6787. var x = CubicN(T, startPt.x, controlPt1.x, controlPt2.x, endPt.x);
  6788. var y = CubicN(T, startPt.y, controlPt1.y, controlPt2.y, endPt.y);
  6789. return {
  6790. x: x,
  6791. y: y
  6792. };
  6793. } // cubic helper formula at T distance
  6794. function CubicN(T, a, b, c, d) {
  6795. var t2 = T * T;
  6796. var t3 = t2 * T;
  6797. return a + (-a * 3 + T * (3 * a - a * T)) * T + (3 * b + T * (-6 * b + b * 3 * T)) * T + (c * 3 - c * 3 * T) * t2 + d * t3;
  6798. }
  6799. function cubicBezierBounds(c) {
  6800. var minX = Infinity;
  6801. var maxX = -Infinity;
  6802. var minY = Infinity;
  6803. var maxY = -Infinity;
  6804. var s = {
  6805. x: c[0],
  6806. y: c[1]
  6807. };
  6808. var c1 = {
  6809. x: c[2],
  6810. y: c[3]
  6811. };
  6812. var c2 = {
  6813. x: c[4],
  6814. y: c[5]
  6815. };
  6816. var e = {
  6817. x: c[6],
  6818. y: c[7]
  6819. };
  6820. for (var t = 0; t < 100; t++) {
  6821. var pt = getCubicBezierXYatT(s, c1, c2, e, t / 100);
  6822. if (pt.x < minX) {
  6823. minX = pt.x;
  6824. }
  6825. if (pt.x > maxX) {
  6826. maxX = pt.x;
  6827. }
  6828. if (pt.y < minY) {
  6829. minY = pt.y;
  6830. }
  6831. if (pt.y > maxY) {
  6832. maxY = pt.y;
  6833. }
  6834. }
  6835. return {
  6836. minX: minX,
  6837. minY: minY,
  6838. maxX: maxX,
  6839. maxY: maxY
  6840. };
  6841. }
  6842. function getBBoxFromPoints(points, lineWidth) {
  6843. if (points.length === 0) {
  6844. return;
  6845. }
  6846. var p = points[0];
  6847. var left = p.x;
  6848. var right = p.x;
  6849. var top = p.y;
  6850. var bottom = p.y;
  6851. var len = points.length;
  6852. for (var i = 1; i < len; i++) {
  6853. p = points[i];
  6854. left = Math.min(left, p.x);
  6855. right = Math.max(right, p.x);
  6856. top = Math.min(top, p.y);
  6857. bottom = Math.max(bottom, p.y);
  6858. }
  6859. lineWidth = lineWidth / 2 || 0;
  6860. return {
  6861. minX: left - lineWidth,
  6862. minY: top - lineWidth,
  6863. maxX: right + lineWidth,
  6864. maxY: bottom + lineWidth
  6865. };
  6866. }
  6867. function getBBoxFromLine(x0, y0, x1, y1, lineWidth) {
  6868. lineWidth = lineWidth / 2 || 0;
  6869. return {
  6870. minX: Math.min(x0, x1) - lineWidth,
  6871. minY: Math.min(y0, y1) - lineWidth,
  6872. maxX: Math.max(x0, x1) + lineWidth,
  6873. maxY: Math.max(y0, y1) + lineWidth
  6874. };
  6875. }
  6876. function getBBoxFromArc(x, y, r, startAngle, endAngle, anticlockwise) {
  6877. var diff = Math.abs(startAngle - endAngle);
  6878. if (diff % (Math.PI * 2) < 1e-4 && diff > 1e-4) {
  6879. // Is a circle
  6880. return {
  6881. minX: x - r,
  6882. minY: y - r,
  6883. maxX: x + r,
  6884. maxY: y + r
  6885. };
  6886. }
  6887. start[0] = Math.cos(startAngle) * r + x;
  6888. start[1] = Math.sin(startAngle) * r + y;
  6889. end[0] = Math.cos(endAngle) * r + x;
  6890. end[1] = Math.sin(endAngle) * r + y;
  6891. var min = [0, 0];
  6892. var max = [0, 0];
  6893. Vector2.min(min, start, end);
  6894. Vector2.max(max, start, end); // Thresh to [0, Math.PI * 2]
  6895. startAngle = startAngle % (Math.PI * 2);
  6896. if (startAngle < 0) {
  6897. startAngle = startAngle + Math.PI * 2;
  6898. }
  6899. endAngle = endAngle % (Math.PI * 2);
  6900. if (endAngle < 0) {
  6901. endAngle = endAngle + Math.PI * 2;
  6902. }
  6903. if (startAngle > endAngle && !anticlockwise) {
  6904. endAngle += Math.PI * 2;
  6905. } else if (startAngle < endAngle && anticlockwise) {
  6906. startAngle += Math.PI * 2;
  6907. }
  6908. if (anticlockwise) {
  6909. var tmp = endAngle;
  6910. endAngle = startAngle;
  6911. startAngle = tmp;
  6912. }
  6913. for (var angle = 0; angle < endAngle; angle += Math.PI / 2) {
  6914. if (angle > startAngle) {
  6915. extremity[0] = Math.cos(angle) * r + x;
  6916. extremity[1] = Math.sin(angle) * r + y;
  6917. Vector2.min(min, extremity, min);
  6918. Vector2.max(max, extremity, max);
  6919. }
  6920. }
  6921. return {
  6922. minX: min[0],
  6923. minY: min[1],
  6924. maxX: max[0],
  6925. maxY: max[1]
  6926. };
  6927. }
  6928. function getBBoxFromBezierGroup(points, lineWidth) {
  6929. var minX = Infinity;
  6930. var maxX = -Infinity;
  6931. var minY = Infinity;
  6932. var maxY = -Infinity;
  6933. for (var i = 0, len = points.length; i < len; i++) {
  6934. var bbox = cubicBezierBounds(points[i]);
  6935. if (bbox.minX < minX) {
  6936. minX = bbox.minX;
  6937. }
  6938. if (bbox.maxX > maxX) {
  6939. maxX = bbox.maxX;
  6940. }
  6941. if (bbox.minY < minY) {
  6942. minY = bbox.minY;
  6943. }
  6944. if (bbox.maxY > maxY) {
  6945. maxY = bbox.maxY;
  6946. }
  6947. }
  6948. lineWidth = lineWidth / 2 || 0;
  6949. return {
  6950. minX: minX - lineWidth,
  6951. minY: minY - lineWidth,
  6952. maxX: maxX + lineWidth,
  6953. maxY: maxY + lineWidth
  6954. };
  6955. }
  6956. var Line$1 = /*#__PURE__*/function (_Shape) {
  6957. _inheritsLoose(Line, _Shape);
  6958. function Line() {
  6959. return _Shape.apply(this, arguments) || this;
  6960. }
  6961. var _proto = Line.prototype;
  6962. _proto._initProperties = function _initProperties() {
  6963. _Shape.prototype._initProperties.call(this);
  6964. this._attrs.canStroke = true;
  6965. this._attrs.type = 'line';
  6966. };
  6967. _proto.getDefaultAttrs = function getDefaultAttrs() {
  6968. return {
  6969. x1: 0,
  6970. y1: 0,
  6971. x2: 0,
  6972. y2: 0,
  6973. lineWidth: 1
  6974. };
  6975. };
  6976. _proto.createPath = function createPath(context) {
  6977. var attrs = this.get('attrs');
  6978. var x1 = attrs.x1,
  6979. y1 = attrs.y1,
  6980. x2 = attrs.x2,
  6981. y2 = attrs.y2;
  6982. context.beginPath();
  6983. context.moveTo(x1, y1);
  6984. context.lineTo(x2, y2);
  6985. };
  6986. _proto.calculateBox = function calculateBox() {
  6987. var attrs = this.get('attrs');
  6988. var x1 = attrs.x1,
  6989. y1 = attrs.y1,
  6990. x2 = attrs.x2,
  6991. y2 = attrs.y2,
  6992. lineWidth = attrs.lineWidth;
  6993. return getBBoxFromLine(x1, y1, x2, y2, lineWidth);
  6994. };
  6995. return Line;
  6996. }(Shape$2);
  6997. var Polygon = /*#__PURE__*/function (_Shape) {
  6998. _inheritsLoose(Polygon, _Shape);
  6999. function Polygon() {
  7000. return _Shape.apply(this, arguments) || this;
  7001. }
  7002. var _proto = Polygon.prototype;
  7003. _proto._initProperties = function _initProperties() {
  7004. _Shape.prototype._initProperties.call(this);
  7005. this._attrs.canFill = true;
  7006. this._attrs.canStroke = true;
  7007. this._attrs.type = 'polygon';
  7008. };
  7009. _proto.getDefaultAttrs = function getDefaultAttrs() {
  7010. return {
  7011. points: null,
  7012. lineWidth: 0
  7013. };
  7014. };
  7015. _proto.createPath = function createPath(context) {
  7016. var self = this;
  7017. var attrs = self.get('attrs');
  7018. var points = attrs.points;
  7019. context.beginPath();
  7020. for (var i = 0, len = points.length; i < len; i++) {
  7021. var point = points[i];
  7022. if (i === 0) {
  7023. context.moveTo(point.x, point.y);
  7024. } else {
  7025. context.lineTo(point.x, point.y);
  7026. }
  7027. }
  7028. context.closePath();
  7029. };
  7030. _proto.calculateBox = function calculateBox() {
  7031. var attrs = this.get('attrs');
  7032. var points = attrs.points;
  7033. return getBBoxFromPoints(points);
  7034. };
  7035. return Polygon;
  7036. }(Shape$2);
  7037. /**
  7038. * @fileOverview convert the line to curve
  7039. * @author dxq613@gmail.com
  7040. */
  7041. function getPoint(v) {
  7042. return [v.x, v.y];
  7043. }
  7044. function smoothBezier(points, smooth, isLoop, constraint) {
  7045. var cps = [];
  7046. var prevPoint;
  7047. var nextPoint;
  7048. var hasConstraint = !!constraint;
  7049. var min;
  7050. var max;
  7051. var point;
  7052. var len;
  7053. var l;
  7054. var i;
  7055. if (hasConstraint) {
  7056. min = [Infinity, Infinity];
  7057. max = [-Infinity, -Infinity];
  7058. for (i = 0, l = points.length; i < l; i++) {
  7059. point = getPoint(points[i]);
  7060. Vector2.min(min, min, point);
  7061. Vector2.max(max, max, point);
  7062. }
  7063. Vector2.min(min, min, constraint[0]);
  7064. Vector2.max(max, max, constraint[1]);
  7065. }
  7066. for (i = 0, len = points.length; i < len; i++) {
  7067. point = getPoint(points[i]);
  7068. if (isLoop) {
  7069. prevPoint = getPoint(points[i ? i - 1 : len - 1]);
  7070. nextPoint = getPoint(points[(i + 1) % len]);
  7071. } else {
  7072. if (i === 0 || i === len - 1) {
  7073. cps.push([point[0], point[1]]);
  7074. continue;
  7075. } else {
  7076. prevPoint = getPoint(points[i - 1]);
  7077. nextPoint = getPoint(points[i + 1]);
  7078. }
  7079. }
  7080. var v = Vector2.sub([], nextPoint, prevPoint);
  7081. Vector2.scale(v, v, smooth);
  7082. var d0 = Vector2.distance(point, prevPoint);
  7083. var d1 = Vector2.distance(point, nextPoint);
  7084. var sum = d0 + d1;
  7085. if (sum !== 0) {
  7086. d0 /= sum;
  7087. d1 /= sum;
  7088. }
  7089. var v1 = Vector2.scale([], v, -d0);
  7090. var v2 = Vector2.scale([], v, d1);
  7091. var cp0 = Vector2.add([], point, v1);
  7092. var cp1 = Vector2.add([], point, v2);
  7093. if (hasConstraint) {
  7094. Vector2.max(cp0, cp0, min);
  7095. Vector2.min(cp0, cp0, max);
  7096. Vector2.max(cp1, cp1, min);
  7097. Vector2.min(cp1, cp1, max);
  7098. }
  7099. cps.push([cp0[0], cp0[1]]);
  7100. cps.push([cp1[0], cp1[1]]);
  7101. }
  7102. if (isLoop) {
  7103. cps.push(cps.shift());
  7104. }
  7105. return cps;
  7106. }
  7107. function catmullRom2bezier(pointList, z, constraint) {
  7108. var isLoop = !!z;
  7109. var controlPointList = smoothBezier(pointList, 0.4, isLoop, constraint);
  7110. var len = pointList.length;
  7111. var d1 = [];
  7112. var cp1;
  7113. var cp2;
  7114. var p;
  7115. for (var i = 0; i < len - 1; i++) {
  7116. cp1 = controlPointList[i * 2];
  7117. cp2 = controlPointList[i * 2 + 1];
  7118. p = pointList[i + 1];
  7119. d1.push(['C', cp1[0], cp1[1], cp2[0], cp2[1], p.x, p.y]);
  7120. }
  7121. if (isLoop) {
  7122. cp1 = controlPointList[len];
  7123. cp2 = controlPointList[len + 1];
  7124. p = pointList[0];
  7125. d1.push(['C', cp1[0], cp1[1], cp2[0], cp2[1], p.x, p.y]);
  7126. }
  7127. return d1;
  7128. }
  7129. function _filterPoints(points) {
  7130. var filteredPoints = [];
  7131. for (var i = 0, len = points.length; i < len; i++) {
  7132. var point = points[i];
  7133. if (!isNaN(point.x) && !isNaN(point.y)) {
  7134. filteredPoints.push(point);
  7135. }
  7136. }
  7137. return filteredPoints;
  7138. }
  7139. var Polyline = /*#__PURE__*/function (_Shape) {
  7140. _inheritsLoose(Polyline, _Shape);
  7141. function Polyline() {
  7142. return _Shape.apply(this, arguments) || this;
  7143. }
  7144. var _proto = Polyline.prototype;
  7145. _proto._initProperties = function _initProperties() {
  7146. _Shape.prototype._initProperties.call(this);
  7147. this._attrs.canFill = true;
  7148. this._attrs.canStroke = true;
  7149. this._attrs.type = 'polyline';
  7150. };
  7151. _proto.getDefaultAttrs = function getDefaultAttrs() {
  7152. return {
  7153. points: null,
  7154. lineWidth: 1,
  7155. smooth: false
  7156. };
  7157. };
  7158. _proto.createPath = function createPath(context) {
  7159. var self = this;
  7160. var attrs = self.get('attrs');
  7161. var points = attrs.points,
  7162. smooth = attrs.smooth;
  7163. var filteredPoints = _filterPoints(points);
  7164. context.beginPath();
  7165. if (filteredPoints.length) {
  7166. context.moveTo(filteredPoints[0].x, filteredPoints[0].y);
  7167. if (smooth) {
  7168. var constaint = [[0, 0], [1, 1]];
  7169. var sps = catmullRom2bezier(filteredPoints, false, constaint);
  7170. for (var i = 0, n = sps.length; i < n; i++) {
  7171. var sp = sps[i];
  7172. context.bezierCurveTo(sp[1], sp[2], sp[3], sp[4], sp[5], sp[6]);
  7173. }
  7174. } else {
  7175. var _i;
  7176. var l;
  7177. for (_i = 1, l = filteredPoints.length - 1; _i < l; _i++) {
  7178. context.lineTo(filteredPoints[_i].x, filteredPoints[_i].y);
  7179. }
  7180. context.lineTo(filteredPoints[l].x, filteredPoints[l].y);
  7181. }
  7182. }
  7183. };
  7184. _proto.calculateBox = function calculateBox() {
  7185. var attrs = this.get('attrs');
  7186. var points = attrs.points,
  7187. smooth = attrs.smooth,
  7188. lineWidth = attrs.lineWidth;
  7189. var filteredPoints = _filterPoints(points);
  7190. if (smooth) {
  7191. var newPoints = [];
  7192. var constaint = [[0, 0], [1, 1]];
  7193. var sps = catmullRom2bezier(filteredPoints, false, constaint);
  7194. for (var i = 0, n = sps.length; i < n; i++) {
  7195. var sp = sps[i];
  7196. if (i === 0) {
  7197. newPoints.push([filteredPoints[0].x, filteredPoints[0].y, sp[1], sp[2], sp[3], sp[4], sp[5], sp[6]]);
  7198. } else {
  7199. var lastPoint = sps[i - 1];
  7200. newPoints.push([lastPoint[5], lastPoint[6], sp[1], sp[2], sp[3], sp[4], sp[5], sp[6]]);
  7201. }
  7202. }
  7203. return getBBoxFromBezierGroup(newPoints, lineWidth);
  7204. }
  7205. return getBBoxFromPoints(filteredPoints, lineWidth);
  7206. };
  7207. return Polyline;
  7208. }(Shape$2);
  7209. var Arc = /*#__PURE__*/function (_Shape) {
  7210. _inheritsLoose(Arc, _Shape);
  7211. function Arc() {
  7212. return _Shape.apply(this, arguments) || this;
  7213. }
  7214. var _proto = Arc.prototype;
  7215. _proto._initProperties = function _initProperties() {
  7216. _Shape.prototype._initProperties.call(this);
  7217. this._attrs.canStroke = true;
  7218. this._attrs.canFill = true;
  7219. this._attrs.type = 'arc';
  7220. };
  7221. _proto.getDefaultAttrs = function getDefaultAttrs() {
  7222. return {
  7223. x: 0,
  7224. y: 0,
  7225. r: 0,
  7226. startAngle: 0,
  7227. endAngle: Math.PI * 2,
  7228. anticlockwise: false,
  7229. lineWidth: 1
  7230. };
  7231. };
  7232. _proto.createPath = function createPath(context) {
  7233. var attrs = this.get('attrs');
  7234. var x = attrs.x,
  7235. y = attrs.y,
  7236. r = attrs.r,
  7237. startAngle = attrs.startAngle,
  7238. endAngle = attrs.endAngle,
  7239. anticlockwise = attrs.anticlockwise;
  7240. context.beginPath();
  7241. if (startAngle !== endAngle) {
  7242. context.arc(x, y, r, startAngle, endAngle, anticlockwise);
  7243. }
  7244. };
  7245. _proto.calculateBox = function calculateBox() {
  7246. var attrs = this.get('attrs');
  7247. var x = attrs.x,
  7248. y = attrs.y,
  7249. r = attrs.r,
  7250. startAngle = attrs.startAngle,
  7251. endAngle = attrs.endAngle,
  7252. anticlockwise = attrs.anticlockwise;
  7253. return getBBoxFromArc(x, y, r, startAngle, endAngle, anticlockwise);
  7254. };
  7255. return Arc;
  7256. }(Shape$2);
  7257. var Sector = /*#__PURE__*/function (_Shape) {
  7258. _inheritsLoose(Sector, _Shape);
  7259. function Sector() {
  7260. return _Shape.apply(this, arguments) || this;
  7261. }
  7262. var _proto = Sector.prototype;
  7263. _proto._initProperties = function _initProperties() {
  7264. _Shape.prototype._initProperties.call(this);
  7265. this._attrs.canFill = true;
  7266. this._attrs.canStroke = true;
  7267. this._attrs.type = 'sector';
  7268. };
  7269. _proto.getDefaultAttrs = function getDefaultAttrs() {
  7270. return {
  7271. x: 0,
  7272. y: 0,
  7273. lineWidth: 0,
  7274. r: 0,
  7275. r0: 0,
  7276. startAngle: 0,
  7277. endAngle: Math.PI * 2,
  7278. anticlockwise: false
  7279. };
  7280. };
  7281. _proto.createPath = function createPath(context) {
  7282. var attrs = this.get('attrs');
  7283. var x = attrs.x,
  7284. y = attrs.y,
  7285. startAngle = attrs.startAngle,
  7286. endAngle = attrs.endAngle,
  7287. r = attrs.r,
  7288. r0 = attrs.r0,
  7289. anticlockwise = attrs.anticlockwise;
  7290. context.beginPath();
  7291. var unitX = Math.cos(startAngle);
  7292. var unitY = Math.sin(startAngle);
  7293. context.moveTo(unitX * r0 + x, unitY * r0 + y);
  7294. context.lineTo(unitX * r + x, unitY * r + y); // 当扇形的角度非常小的时候,就不进行弧线的绘制;或者整个只有1个扇形时,会出现end<0的情况不绘制
  7295. if (Math.abs(endAngle - startAngle) > 0.0001 || startAngle === 0 && endAngle < 0) {
  7296. context.arc(x, y, r, startAngle, endAngle, anticlockwise);
  7297. context.lineTo(Math.cos(endAngle) * r0 + x, Math.sin(endAngle) * r0 + y);
  7298. if (r0 !== 0) {
  7299. context.arc(x, y, r0, endAngle, startAngle, !anticlockwise);
  7300. }
  7301. }
  7302. context.closePath();
  7303. };
  7304. _proto.calculateBox = function calculateBox() {
  7305. var attrs = this.get('attrs');
  7306. var x = attrs.x,
  7307. y = attrs.y,
  7308. r = attrs.r,
  7309. r0 = attrs.r0,
  7310. startAngle = attrs.startAngle,
  7311. endAngle = attrs.endAngle,
  7312. anticlockwise = attrs.anticlockwise;
  7313. var outerBBox = getBBoxFromArc(x, y, r, startAngle, endAngle, anticlockwise);
  7314. var innerBBox = getBBoxFromArc(x, y, r0, startAngle, endAngle, anticlockwise);
  7315. return {
  7316. minX: Math.min(outerBBox.minX, innerBBox.minX),
  7317. minY: Math.min(outerBBox.minY, innerBBox.minY),
  7318. maxX: Math.max(outerBBox.maxX, innerBBox.maxX),
  7319. maxY: Math.max(outerBBox.maxY, innerBBox.maxY)
  7320. };
  7321. };
  7322. return Sector;
  7323. }(Shape$2);
  7324. var Rect$1 = {
  7325. calcRotatedBox: function calcRotatedBox(_ref) {
  7326. var width = _ref.width,
  7327. height = _ref.height,
  7328. rotate = _ref.rotate;
  7329. var absRotate = Math.abs(rotate);
  7330. return {
  7331. width: Math.abs(width * Math.cos(absRotate) + height * Math.sin(absRotate)),
  7332. height: Math.abs(height * Math.cos(absRotate) + width * Math.sin(absRotate))
  7333. };
  7334. }
  7335. };
  7336. var textWidthCacheCounter = 0;
  7337. var textWidthCache = {};
  7338. var TEXT_CACHE_MAX = 5000;
  7339. var Text = /*#__PURE__*/function (_Shape) {
  7340. _inheritsLoose(Text, _Shape);
  7341. function Text() {
  7342. return _Shape.apply(this, arguments) || this;
  7343. }
  7344. var _proto = Text.prototype;
  7345. _proto._initProperties = function _initProperties() {
  7346. _Shape.prototype._initProperties.call(this);
  7347. this._attrs.canFill = true;
  7348. this._attrs.canStroke = true;
  7349. this._attrs.type = 'text';
  7350. };
  7351. _proto.getDefaultAttrs = function getDefaultAttrs() {
  7352. return {
  7353. lineWidth: 0,
  7354. lineCount: 1,
  7355. fontSize: 12,
  7356. fontFamily: 'sans-serif',
  7357. fontStyle: 'normal',
  7358. fontWeight: 'normal',
  7359. fontVariant: 'normal',
  7360. textAlign: 'start',
  7361. textBaseline: 'bottom',
  7362. lineHeight: null,
  7363. textArr: null
  7364. };
  7365. };
  7366. _proto._getFontStyle = function _getFontStyle() {
  7367. var attrs = this._attrs.attrs;
  7368. var fontSize = attrs.fontSize,
  7369. fontFamily = attrs.fontFamily,
  7370. fontWeight = attrs.fontWeight,
  7371. fontStyle = attrs.fontStyle,
  7372. fontVariant = attrs.fontVariant;
  7373. return fontStyle + " " + fontVariant + " " + fontWeight + " " + fontSize + "px " + fontFamily;
  7374. };
  7375. _proto._afterAttrsSet = function _afterAttrsSet() {
  7376. var attrs = this._attrs.attrs;
  7377. attrs.font = this._getFontStyle();
  7378. if (attrs.text) {
  7379. var text = attrs.text;
  7380. var textArr = null;
  7381. var lineCount = 1;
  7382. if (isString(text) && text.indexOf('\n') !== -1) {
  7383. textArr = text.split('\n');
  7384. lineCount = textArr.length;
  7385. }
  7386. attrs.lineCount = lineCount;
  7387. attrs.textArr = textArr;
  7388. }
  7389. this.set('attrs', attrs);
  7390. };
  7391. _proto._getTextHeight = function _getTextHeight() {
  7392. var attrs = this._attrs.attrs;
  7393. if (attrs.height) {
  7394. return attrs.height;
  7395. }
  7396. var lineCount = attrs.lineCount;
  7397. var fontSize = attrs.fontSize * 1;
  7398. if (lineCount > 1) {
  7399. var spaceingY = this._getSpaceingY();
  7400. return fontSize * lineCount + spaceingY * (lineCount - 1);
  7401. }
  7402. return fontSize;
  7403. };
  7404. _proto._getSpaceingY = function _getSpaceingY() {
  7405. var attrs = this._attrs.attrs;
  7406. var lineHeight = attrs.lineHeight;
  7407. var fontSize = attrs.fontSize * 1;
  7408. return lineHeight ? lineHeight - fontSize : fontSize * 0.14;
  7409. };
  7410. _proto.drawInner = function drawInner(context) {
  7411. var self = this;
  7412. var attrs = self._attrs.attrs;
  7413. var text = attrs.text;
  7414. var x = attrs.x;
  7415. var y = attrs.y;
  7416. if (isNil(text) || isNaN(x) || isNaN(y)) {
  7417. // text will be 0
  7418. return;
  7419. }
  7420. var textArr = attrs.textArr;
  7421. var fontSize = attrs.fontSize * 1;
  7422. var spaceingY = self._getSpaceingY();
  7423. if (attrs.rotate) {
  7424. // do rotation
  7425. context.translate(x, y);
  7426. context.rotate(attrs.rotate);
  7427. x = 0;
  7428. y = 0;
  7429. }
  7430. var textBaseline = attrs.textBaseline;
  7431. var height;
  7432. if (textArr) {
  7433. height = self._getTextHeight();
  7434. }
  7435. var subY; // context.beginPath();
  7436. if (self.hasFill()) {
  7437. var fillOpacity = attrs.fillOpacity;
  7438. if (!isNil(fillOpacity) && fillOpacity !== 1) {
  7439. context.globalAlpha = fillOpacity;
  7440. }
  7441. if (textArr) {
  7442. for (var i = 0, len = textArr.length; i < len; i++) {
  7443. var subText = textArr[i];
  7444. subY = y + i * (spaceingY + fontSize) - height + fontSize; // bottom;
  7445. if (textBaseline === 'middle') {
  7446. subY += height - fontSize - (height - fontSize) / 2;
  7447. }
  7448. if (textBaseline === 'top') {
  7449. subY += height - fontSize;
  7450. }
  7451. context.fillText(subText, x, subY);
  7452. }
  7453. } else {
  7454. context.fillText(text, x, y);
  7455. }
  7456. }
  7457. if (self.hasStroke()) {
  7458. if (textArr) {
  7459. for (var _i = 0, _len = textArr.length; _i < _len; _i++) {
  7460. var _subText = textArr[_i];
  7461. subY = y + _i * (spaceingY + fontSize) - height + fontSize; // bottom;
  7462. if (textBaseline === 'middle') {
  7463. subY += height - fontSize - (height - fontSize) / 2;
  7464. }
  7465. if (textBaseline === 'top') {
  7466. subY += height - fontSize;
  7467. }
  7468. context.strokeText(_subText, x, subY);
  7469. }
  7470. } else {
  7471. context.strokeText(text, x, y);
  7472. }
  7473. }
  7474. };
  7475. _proto._getAriaLabel = function _getAriaLabel() {
  7476. return this._attrs.attrs.text;
  7477. };
  7478. _proto.calculateBox = function calculateBox() {
  7479. var self = this;
  7480. var attrs = self._attrs.attrs;
  7481. var x = attrs.x,
  7482. y = attrs.y,
  7483. textAlign = attrs.textAlign,
  7484. textBaseline = attrs.textBaseline;
  7485. var width = self._getTextWidth(); // attrs.width
  7486. if (!width) {
  7487. return {
  7488. minX: x,
  7489. minY: y,
  7490. maxX: x,
  7491. maxY: y
  7492. };
  7493. }
  7494. var height = self._getTextHeight(); // attrs.height
  7495. if (attrs.rotate) {
  7496. var rotatedBox = Rect$1.calcRotatedBox({
  7497. width: width,
  7498. height: height,
  7499. rotate: attrs.rotate
  7500. });
  7501. width = rotatedBox.width;
  7502. height = rotatedBox.height;
  7503. }
  7504. var point = {
  7505. x: x,
  7506. y: y - height
  7507. }; // default textAlign: start, textBaseline: bottom
  7508. if (textAlign) {
  7509. if (textAlign === 'end' || textAlign === 'right') {
  7510. point.x -= width;
  7511. } else if (textAlign === 'center') {
  7512. point.x -= width / 2;
  7513. }
  7514. }
  7515. if (textBaseline) {
  7516. if (textBaseline === 'top') {
  7517. point.y += height;
  7518. } else if (textBaseline === 'middle') {
  7519. point.y += height / 2;
  7520. }
  7521. }
  7522. return {
  7523. minX: point.x,
  7524. minY: point.y,
  7525. maxX: point.x + width,
  7526. maxY: point.y + height
  7527. };
  7528. };
  7529. _proto._getTextWidth = function _getTextWidth() {
  7530. var attrs = this._attrs.attrs;
  7531. if (attrs.width) {
  7532. return attrs.width;
  7533. }
  7534. var text = attrs.text;
  7535. var context = this.get('context');
  7536. if (isNil(text)) return undefined;
  7537. var font = attrs.font;
  7538. var textArr = attrs.textArr;
  7539. var key = text + '' + font;
  7540. if (textWidthCache[key]) {
  7541. return textWidthCache[key];
  7542. }
  7543. var width = 0;
  7544. if (textArr) {
  7545. for (var i = 0, length = textArr.length; i < length; i++) {
  7546. var subText = textArr[i];
  7547. width = Math.max(width, measureText(subText, font, context).width);
  7548. }
  7549. } else {
  7550. width = measureText(text, font, context).width;
  7551. }
  7552. if (textWidthCacheCounter > TEXT_CACHE_MAX) {
  7553. textWidthCacheCounter = 0;
  7554. textWidthCache = {};
  7555. }
  7556. textWidthCacheCounter++;
  7557. textWidthCache[key] = width;
  7558. return width;
  7559. };
  7560. return Text;
  7561. }(Shape$2);
  7562. var Custom = /*#__PURE__*/function (_Shape) {
  7563. _inheritsLoose(Custom, _Shape);
  7564. function Custom() {
  7565. return _Shape.apply(this, arguments) || this;
  7566. }
  7567. var _proto = Custom.prototype;
  7568. _proto._initProperties = function _initProperties() {
  7569. _Shape.prototype._initProperties.call(this);
  7570. this._attrs.canFill = true;
  7571. this._attrs.canStroke = true;
  7572. this._attrs.createPath = null;
  7573. this._attrs.type = 'custom';
  7574. };
  7575. _proto.createPath = function createPath(context) {
  7576. var createPath = this.get('createPath');
  7577. createPath && createPath.call(this, context);
  7578. };
  7579. _proto.calculateBox = function calculateBox() {
  7580. var calculateBox = this.get('calculateBox');
  7581. return calculateBox && calculateBox.call(this);
  7582. };
  7583. return Custom;
  7584. }(Shape$2);
  7585. var SYMBOLS = {
  7586. circle: function circle(x, y, r, ctx) {
  7587. ctx.arc(x, y, r, 0, Math.PI * 2, false);
  7588. },
  7589. square: function square(x, y, r, ctx) {
  7590. ctx.moveTo(x - r, y - r);
  7591. ctx.lineTo(x + r, y - r);
  7592. ctx.lineTo(x + r, y + r);
  7593. ctx.lineTo(x - r, y + r);
  7594. ctx.closePath();
  7595. }
  7596. };
  7597. var Marker = /*#__PURE__*/function (_Shape) {
  7598. _inheritsLoose(Marker, _Shape);
  7599. function Marker() {
  7600. return _Shape.apply(this, arguments) || this;
  7601. }
  7602. var _proto = Marker.prototype;
  7603. _proto._initProperties = function _initProperties() {
  7604. _Shape.prototype._initProperties.call(this);
  7605. this._attrs.canFill = true;
  7606. this._attrs.canStroke = true;
  7607. this._attrs.type = 'marker';
  7608. };
  7609. _proto.getDefaultAttrs = function getDefaultAttrs() {
  7610. return {
  7611. x: 0,
  7612. y: 0,
  7613. lineWidth: 0
  7614. };
  7615. };
  7616. _proto.createPath = function createPath(context) {
  7617. var attrs = this.get('attrs');
  7618. var x = attrs.x,
  7619. y = attrs.y,
  7620. radius = attrs.radius;
  7621. var symbol = attrs.symbol || 'circle';
  7622. var method;
  7623. if (isFunction(symbol)) {
  7624. method = symbol;
  7625. } else {
  7626. method = SYMBOLS[symbol];
  7627. }
  7628. context.beginPath();
  7629. method(x, y, radius, context, this);
  7630. };
  7631. _proto.calculateBox = function calculateBox() {
  7632. var attrs = this.get('attrs');
  7633. var x = attrs.x,
  7634. y = attrs.y,
  7635. radius = attrs.radius;
  7636. return {
  7637. minX: x - radius,
  7638. minY: y - radius,
  7639. maxX: x + radius,
  7640. maxY: y + radius
  7641. };
  7642. };
  7643. return Marker;
  7644. }(Shape$2);
  7645. Shape$2.Rect = Rect;
  7646. Shape$2.Image = ImageShape;
  7647. Shape$2.Circle = Circle;
  7648. Shape$2.Line = Line$1;
  7649. Shape$2.Polygon = Polygon;
  7650. Shape$2.Polyline = Polyline;
  7651. Shape$2.Arc = Arc;
  7652. Shape$2.Sector = Sector;
  7653. Shape$2.Text = Text;
  7654. Shape$2.Custom = Custom;
  7655. Shape$2.Marker = Marker;
  7656. var SHAPE_MAP = {};
  7657. var INDEX = '_INDEX';
  7658. function getComparer(compare) {
  7659. return function (left, right) {
  7660. var result = compare(left, right);
  7661. return result === 0 ? left[INDEX] - right[INDEX] : result;
  7662. };
  7663. }
  7664. var Container = {
  7665. getGroupClass: function getGroupClass() {},
  7666. getChildren: function getChildren() {
  7667. return this.get('children');
  7668. },
  7669. addShape: function addShape(type, cfg) {
  7670. if (cfg === void 0) {
  7671. cfg = {};
  7672. }
  7673. var shapeType = SHAPE_MAP[type];
  7674. if (!shapeType) {
  7675. shapeType = upperFirst(type);
  7676. SHAPE_MAP[type] = shapeType;
  7677. }
  7678. var shape = new Shape$2[shapeType](cfg);
  7679. this.add(shape);
  7680. return shape;
  7681. },
  7682. addGroup: function addGroup(cfg) {
  7683. var groupClass = this.getGroupClass();
  7684. var rst = new groupClass(cfg);
  7685. this.add(rst);
  7686. return rst;
  7687. },
  7688. contain: function contain(item) {
  7689. var children = this.get('children');
  7690. return children.indexOf(item) > -1;
  7691. },
  7692. sort: function sort() {
  7693. var children = this.get('children');
  7694. for (var i = 0, len = children.length; i < len; i++) {
  7695. var child = children[i];
  7696. child[INDEX] = i;
  7697. }
  7698. children.sort(getComparer(function (obj1, obj2) {
  7699. return obj1.get('zIndex') - obj2.get('zIndex');
  7700. }));
  7701. return this;
  7702. },
  7703. drawChildren: function drawChildren(context) {
  7704. var children = this.get('children');
  7705. for (var i = 0, len = children.length; i < len; i++) {
  7706. var child = children[i];
  7707. child.draw(context);
  7708. }
  7709. return this;
  7710. },
  7711. clear: function clear() {
  7712. var children = this.get('children');
  7713. while (children.length !== 0) {
  7714. children[children.length - 1].remove(true);
  7715. }
  7716. return this;
  7717. },
  7718. add: function add(items) {
  7719. var self = this;
  7720. var children = self.get('children');
  7721. if (!isArray(items)) {
  7722. items = [items];
  7723. }
  7724. for (var i = 0, len = items.length; i < len; i++) {
  7725. var item = items[i];
  7726. var parent = item.get('parent');
  7727. if (parent) {
  7728. var descendants = parent.get('children');
  7729. remove(descendants, item);
  7730. }
  7731. self._setEvn(item);
  7732. children.push(item);
  7733. }
  7734. return self;
  7735. },
  7736. _setEvn: function _setEvn(item) {
  7737. var self = this;
  7738. var _self$_attrs = self._attrs,
  7739. context = _self$_attrs.context,
  7740. canvas = _self$_attrs.canvas,
  7741. aria = _self$_attrs.aria;
  7742. var _item$_attrs = item._attrs,
  7743. isGroup = _item$_attrs.isGroup,
  7744. type = _item$_attrs.type;
  7745. item._attrs.parent = self;
  7746. item._attrs.context = context;
  7747. item._attrs.canvas = canvas; // 是否需要无障碍处理
  7748. if (aria && item._attrs.aria !== false) {
  7749. item._attrs.aria = aria;
  7750. }
  7751. if (type === 'text' && canvas && canvas.get('fontFamily')) {
  7752. item._attrs.attrs.fontFamily = item._attrs.attrs.fontFamily || canvas.get('fontFamily');
  7753. }
  7754. var clip = item._attrs.attrs.clip;
  7755. if (clip) {
  7756. clip._attrs.parent = self;
  7757. clip._attrs.context = context;
  7758. clip._attrs.canvas = canvas;
  7759. }
  7760. if (isGroup) {
  7761. var children = item._attrs.children;
  7762. for (var i = 0, len = children.length; i < len; i++) {
  7763. item._setEvn(children[i]);
  7764. }
  7765. }
  7766. },
  7767. _getAriaLabel: function _getAriaLabel() {
  7768. var _this$_attrs = this._attrs,
  7769. aria = _this$_attrs.aria,
  7770. ariaLabel = _this$_attrs.ariaLabel,
  7771. children = _this$_attrs.children; // 主动关闭
  7772. if (!aria) return;
  7773. var childAriaLabels = [];
  7774. if (children && children.length) {
  7775. for (var i = 0, len = children.length; i < len; i++) {
  7776. var _childAriaLabel = children[i].getAriaLabel();
  7777. if (_childAriaLabel) {
  7778. childAriaLabels.push(_childAriaLabel);
  7779. }
  7780. }
  7781. }
  7782. var childAriaLabel = childAriaLabels.join(' '); // 2个都有时拼接成完整句子
  7783. if (ariaLabel && childAriaLabel) {
  7784. return ariaLabel + " " + childAriaLabel + " ";
  7785. } // 只有1个,或者都没有
  7786. return ariaLabel || childAriaLabel;
  7787. }
  7788. };
  7789. var Group = /*#__PURE__*/function (_Rect) {
  7790. _inheritsLoose(Group, _Rect);
  7791. function Group() {
  7792. return _Rect.apply(this, arguments) || this;
  7793. }
  7794. var _proto = Group.prototype;
  7795. _proto._initProperties = function _initProperties() {
  7796. this._attrs = {
  7797. type: 'group',
  7798. zIndex: 0,
  7799. visible: true,
  7800. destroyed: false,
  7801. isGroup: true,
  7802. canFill: true,
  7803. canStroke: true,
  7804. attrs: {},
  7805. children: []
  7806. };
  7807. };
  7808. _proto.getBBox = function getBBox() {
  7809. var self = this;
  7810. var minX = Infinity;
  7811. var maxX = -Infinity;
  7812. var minY = Infinity;
  7813. var maxY = -Infinity;
  7814. var children = self.get('children');
  7815. for (var i = 0, length = children.length; i < length; i++) {
  7816. var child = children[i];
  7817. if (child.get('visible')) {
  7818. var box = child.getBBox();
  7819. if (!box) {
  7820. continue;
  7821. }
  7822. var leftTop = [box.minX, box.minY];
  7823. var leftBottom = [box.minX, box.maxY];
  7824. var rightTop = [box.maxX, box.minY];
  7825. var rightBottom = [box.maxX, box.maxY];
  7826. var matrix = child.attr('matrix');
  7827. Vector2.transformMat2d(leftTop, leftTop, matrix);
  7828. Vector2.transformMat2d(leftBottom, leftBottom, matrix);
  7829. Vector2.transformMat2d(rightTop, rightTop, matrix);
  7830. Vector2.transformMat2d(rightBottom, rightBottom, matrix);
  7831. minX = Math.min(leftTop[0], leftBottom[0], rightTop[0], rightBottom[0], minX);
  7832. maxX = Math.max(leftTop[0], leftBottom[0], rightTop[0], rightBottom[0], maxX);
  7833. minY = Math.min(leftTop[1], leftBottom[1], rightTop[1], rightBottom[1], minY);
  7834. maxY = Math.max(leftTop[1], leftBottom[1], rightTop[1], rightBottom[1], maxY);
  7835. }
  7836. }
  7837. return {
  7838. minX: minX,
  7839. minY: minY,
  7840. maxX: maxX,
  7841. maxY: maxY,
  7842. x: minX,
  7843. y: minY,
  7844. width: maxX - minX,
  7845. height: maxY - minY
  7846. };
  7847. };
  7848. _proto.createPath = function createPath(context) {
  7849. var attrs = this.get('attrs'); // 只有在有fillStyle或strokeStyle 时才需要绘制
  7850. if (!attrs.fillStyle && !attrs.strokeStyle) {
  7851. return;
  7852. }
  7853. _Rect.prototype.createPath.call(this, context);
  7854. };
  7855. _proto.drawInner = function drawInner(context) {
  7856. _Rect.prototype.drawInner.call(this, context);
  7857. this.drawChildren(context);
  7858. };
  7859. _proto.destroy = function destroy() {
  7860. if (this.get('destroyed')) {
  7861. return;
  7862. }
  7863. this.clear();
  7864. _Rect.prototype.destroy.call(this);
  7865. };
  7866. return Group;
  7867. }(Rect);
  7868. mix(Group.prototype, Container, {
  7869. getGroupClass: function getGroupClass() {
  7870. return Group;
  7871. }
  7872. });
  7873. var requestAnimationFrame = typeof window === 'object' && window.requestAnimationFrame ? window.requestAnimationFrame : function (fn) {
  7874. return setTimeout(fn, 16);
  7875. };
  7876. var Canvas = /*#__PURE__*/function (_EventEmit) {
  7877. _inheritsLoose(Canvas, _EventEmit);
  7878. var _proto = Canvas.prototype;
  7879. _proto.get = function get(name) {
  7880. return this._attrs[name];
  7881. };
  7882. _proto.set = function set(name, value) {
  7883. this._attrs[name] = value;
  7884. };
  7885. function Canvas(cfg) {
  7886. var _this;
  7887. _this = _EventEmit.call(this) || this;
  7888. var title = cfg.title;
  7889. var ariaLabel = title ? substitute(lang.general.withTitle, {
  7890. title: title
  7891. }) : lang.general.title;
  7892. _this._attrs = mix({
  7893. type: 'canvas',
  7894. children: [],
  7895. ariaLabel: ariaLabel
  7896. }, cfg);
  7897. _this._initPixelRatio();
  7898. _this._initCanvas();
  7899. return _this;
  7900. }
  7901. _proto._initPixelRatio = function _initPixelRatio() {
  7902. var pixelRatio = this.get('pixelRatio');
  7903. if (!pixelRatio) {
  7904. this.set('pixelRatio', getPixelRatio());
  7905. }
  7906. };
  7907. _proto.beforeDraw = function beforeDraw() {
  7908. var context = this._attrs.context;
  7909. var el = this._attrs.el;
  7910. context && context.clearRect && context.clearRect(0, 0, el.width, el.height);
  7911. };
  7912. _proto._initCanvas = function _initCanvas() {
  7913. var self = this;
  7914. var el = self.get('el');
  7915. var context = self.get('context');
  7916. if (!el && !context) {
  7917. throw new Error('Please specify the id, el or context of the chart!');
  7918. }
  7919. var canvas;
  7920. if (el) {
  7921. // DOMElement or String
  7922. canvas = isString(el) ? getDomById(el) : el;
  7923. } else {
  7924. // 说明没有指定el
  7925. canvas = CanvasElement$1.create(context);
  7926. }
  7927. if (context && canvas && !canvas.getContext) {
  7928. canvas.getContext = function () {
  7929. return context;
  7930. };
  7931. }
  7932. var width = self.get('width');
  7933. if (!width) {
  7934. width = getWidth(canvas);
  7935. }
  7936. var height = self.get('height');
  7937. if (!height) {
  7938. height = getHeight(canvas);
  7939. }
  7940. self.set('canvas', this);
  7941. self.set('el', canvas);
  7942. self.set('context', context || canvas.getContext('2d'));
  7943. self.changeSize(width, height); // 初始化事件控制器
  7944. var eventController = new EventController({
  7945. canvas: this,
  7946. el: canvas
  7947. });
  7948. self.set('eventController', eventController);
  7949. };
  7950. _proto.changeSize = function changeSize(width, height) {
  7951. var pixelRatio = this.get('pixelRatio');
  7952. var canvasDOM = this.get('el'); // HTMLCanvasElement or canvasElement
  7953. // 浏览器环境设置style样式
  7954. if (canvasDOM.style) {
  7955. canvasDOM.style.width = width + 'px';
  7956. canvasDOM.style.height = height + 'px';
  7957. }
  7958. if (isCanvasElement(canvasDOM)) {
  7959. canvasDOM.width = width * pixelRatio;
  7960. canvasDOM.height = height * pixelRatio;
  7961. if (pixelRatio !== 1) {
  7962. var ctx = this.get('context');
  7963. ctx.scale(pixelRatio, pixelRatio);
  7964. }
  7965. }
  7966. this.set('width', width);
  7967. this.set('height', height);
  7968. };
  7969. _proto.getWidth = function getWidth() {
  7970. var pixelRatio = this.get('pixelRatio');
  7971. var width = this.get('width');
  7972. return width * pixelRatio;
  7973. };
  7974. _proto.getHeight = function getHeight() {
  7975. var pixelRatio = this.get('pixelRatio');
  7976. var height = this.get('height');
  7977. return height * pixelRatio;
  7978. };
  7979. _proto.getPointByClient = function getPointByClient(clientX, clientY) {
  7980. var el = this.get('el');
  7981. var bbox = el.getBoundingClientRect();
  7982. var width = bbox.right - bbox.left;
  7983. var height = bbox.bottom - bbox.top;
  7984. return {
  7985. x: (clientX - bbox.left) * (el.width / width),
  7986. y: (clientY - bbox.top) * (el.height / height)
  7987. };
  7988. };
  7989. _proto._beginDraw = function _beginDraw() {
  7990. this._attrs.toDraw = true;
  7991. };
  7992. _proto._endDraw = function _endDraw() {
  7993. this._attrs.toDraw = false;
  7994. };
  7995. _proto.draw = function draw() {
  7996. var self = this;
  7997. function drawInner() {
  7998. self.set('animateHandler', requestAnimationFrame(function () {
  7999. self.set('animateHandler', undefined);
  8000. if (self.get('toDraw')) {
  8001. drawInner();
  8002. }
  8003. }));
  8004. self.beforeDraw();
  8005. try {
  8006. var context = self._attrs.context;
  8007. self.drawChildren(context); // 支付宝,微信小程序,需要调context.draw才能完成绘制, 所以这里直接判断是否有.draw方法
  8008. if (context.draw) {
  8009. context.draw();
  8010. } // 设置无障碍文本
  8011. self.setAriaLabel();
  8012. } catch (ev) {
  8013. console.warn('error in draw canvas, detail as:');
  8014. console.warn(ev);
  8015. self._endDraw();
  8016. }
  8017. self._endDraw();
  8018. }
  8019. if (self.get('destroyed')) {
  8020. return;
  8021. }
  8022. if (self.get('animateHandler')) {
  8023. this._beginDraw();
  8024. } else {
  8025. drawInner();
  8026. }
  8027. } // 设置无障碍文本
  8028. ;
  8029. _proto.setAriaLabel = function setAriaLabel() {
  8030. var el = this._attrs.el;
  8031. var ariaLabel = this._getAriaLabel();
  8032. if (ariaLabel && el.setAttribute) {
  8033. el.setAttribute('aria-label', ariaLabel);
  8034. }
  8035. };
  8036. _proto.destroy = function destroy() {
  8037. if (this.get('destroyed')) {
  8038. return;
  8039. } // 需要清理 canvas 画布内容,否则会导致 spa 应用 ios 下 canvas 白屏
  8040. // https://stackoverflow.com/questions/52532614/total-canvas-memory-use-exceeds-the-maximum-limit-safari-12
  8041. // https://github.com/antvis/F2/issues/630
  8042. var el = this.get('el');
  8043. el.width = 0;
  8044. el.height = 0;
  8045. this.clear();
  8046. this._attrs = {};
  8047. this.set('destroyed', true);
  8048. };
  8049. _proto.isDestroyed = function isDestroyed() {
  8050. return this.get('destroyed');
  8051. };
  8052. return Canvas;
  8053. }(EventEmit);
  8054. mix(Canvas.prototype, Container, {
  8055. getGroupClass: function getGroupClass() {
  8056. return Group;
  8057. }
  8058. });
  8059. var engines = {};
  8060. function registerEngine(name, engine) {
  8061. engines[name] = engine;
  8062. }
  8063. function getEngine(name) {
  8064. var G = engines[name];
  8065. if (G) {
  8066. return G;
  8067. }
  8068. return {
  8069. Canvas: Canvas,
  8070. Group: Group,
  8071. Shape: Shape$2
  8072. };
  8073. }
  8074. function createCanvas(cfg) {
  8075. var renderer = cfg.renderer;
  8076. var G = getEngine(renderer);
  8077. return new G.Canvas(cfg);
  8078. }
  8079. var G = /*#__PURE__*/Object.freeze({
  8080. __proto__: null,
  8081. registerEngine: registerEngine,
  8082. getEngine: getEngine,
  8083. createCanvas: createCanvas,
  8084. Canvas: Canvas,
  8085. Group: Group,
  8086. Shape: Shape$2,
  8087. Matrix: Matrix,
  8088. Vector2: Vector2
  8089. });
  8090. function getClip(coord) {
  8091. var start = coord.start;
  8092. var end = coord.end;
  8093. var width = end.x - start.x;
  8094. var height = Math.abs(end.y - start.y);
  8095. var margin = 10;
  8096. var clip;
  8097. if (coord.isPolar) {
  8098. var circleRadius = coord.circleRadius,
  8099. center = coord.center,
  8100. startAngle = coord.startAngle,
  8101. endAngle = coord.endAngle;
  8102. clip = new Shape$2.Sector({
  8103. attrs: {
  8104. x: center.x,
  8105. y: center.y,
  8106. r: circleRadius,
  8107. r0: 0,
  8108. startAngle: startAngle,
  8109. endAngle: endAngle
  8110. }
  8111. });
  8112. } else {
  8113. clip = new Shape$2.Rect({
  8114. attrs: {
  8115. x: start.x,
  8116. y: end.y - margin,
  8117. width: width,
  8118. height: height + 2 * margin
  8119. }
  8120. });
  8121. }
  8122. clip.isClip = true;
  8123. return clip;
  8124. }
  8125. function isPointInPlot(point, plot) {
  8126. var x = point.x,
  8127. y = point.y;
  8128. var tl = plot.tl,
  8129. tr = plot.tr,
  8130. br = plot.br;
  8131. return x >= tl.x && x <= tr.x && y >= tl.y && y <= br.y;
  8132. }
  8133. var Helper = /*#__PURE__*/Object.freeze({
  8134. __proto__: null,
  8135. getClip: getClip,
  8136. isPointInPlot: isPointInPlot
  8137. });
  8138. function compare(a, b) {
  8139. return a - b;
  8140. }
  8141. function _isScaleExist(scales, compareScale) {
  8142. var flag = false;
  8143. each(scales, function (scale) {
  8144. var scaleValues = [].concat(scale.values);
  8145. var compareScaleValues = [].concat(compareScale.values);
  8146. if (scale.type === compareScale.type && scale.field === compareScale.field && scaleValues.sort(compare).toString() === compareScaleValues.sort(compare).toString()) {
  8147. flag = true;
  8148. return;
  8149. }
  8150. });
  8151. return flag;
  8152. }
  8153. var Chart = /*#__PURE__*/function (_Base) {
  8154. _inheritsLoose(Chart, _Base);
  8155. Chart.initPlugins = function initPlugins() {
  8156. return {
  8157. _plugins: [],
  8158. _cacheId: 0,
  8159. register: function register(plugins) {
  8160. var p = this._plugins;
  8161. [].concat(plugins).forEach(function (plugin) {
  8162. if (p.indexOf(plugin) === -1) {
  8163. p.push(plugin);
  8164. }
  8165. });
  8166. this._cacheId++;
  8167. },
  8168. unregister: function unregister(plugins) {
  8169. var p = this._plugins;
  8170. [].concat(plugins).forEach(function (plugin) {
  8171. var idx = p.indexOf(plugin);
  8172. if (idx !== -1) {
  8173. p.splice(idx, 1);
  8174. }
  8175. });
  8176. this._cacheId++;
  8177. },
  8178. clear: function clear() {
  8179. this._plugins = [];
  8180. this._cacheId++;
  8181. },
  8182. count: function count() {
  8183. return this._plugins.length;
  8184. },
  8185. getAll: function getAll() {
  8186. return this._plugins;
  8187. },
  8188. notify: function notify(chart, hook, args) {
  8189. var descriptors = this.descriptors(chart);
  8190. var ilen = descriptors.length;
  8191. var i;
  8192. var descriptor;
  8193. var plugin;
  8194. var params;
  8195. var method;
  8196. for (i = 0; i < ilen; ++i) {
  8197. descriptor = descriptors[i];
  8198. plugin = descriptor.plugin;
  8199. method = plugin[hook];
  8200. if (typeof method === 'function') {
  8201. params = [chart].concat(args || []);
  8202. if (method.apply(plugin, params) === false) {
  8203. return false;
  8204. }
  8205. }
  8206. }
  8207. return true;
  8208. },
  8209. descriptors: function descriptors(chart) {
  8210. var cache = chart._plugins || (chart._plugins = {});
  8211. if (cache.id === this._cacheId) {
  8212. return cache.descriptors;
  8213. }
  8214. var plugins = [];
  8215. var descriptors = [];
  8216. this._plugins.concat(chart && chart.get('plugins') || []).forEach(function (plugin) {
  8217. var idx = plugins.indexOf(plugin);
  8218. if (idx !== -1) {
  8219. return;
  8220. }
  8221. plugins.push(plugin);
  8222. descriptors.push({
  8223. plugin: plugin
  8224. });
  8225. });
  8226. cache.descriptors = descriptors;
  8227. cache.id = this._cacheId;
  8228. return descriptors;
  8229. }
  8230. };
  8231. };
  8232. var _proto = Chart.prototype;
  8233. _proto.getDefaultCfg = function getDefaultCfg() {
  8234. return {
  8235. /**
  8236. * the id of canvas
  8237. * @type {String}
  8238. */
  8239. id: null,
  8240. /** 图表渲染引擎 */
  8241. renderer: 'canvas',
  8242. rendered: false,
  8243. /**
  8244. * padding
  8245. * @type {Array|Number}
  8246. */
  8247. padding: Global.padding,
  8248. /**
  8249. * data
  8250. * @type {Array}
  8251. */
  8252. data: null,
  8253. /**
  8254. * scales of chart
  8255. * @type {Object}
  8256. */
  8257. scales: {},
  8258. /**
  8259. * @private
  8260. * geometry instances
  8261. * @type {Array}
  8262. */
  8263. geoms: [],
  8264. /**
  8265. * scale configuration
  8266. * @type {Object}
  8267. */
  8268. colDefs: null,
  8269. pixelRatio: Global.pixelRatio,
  8270. /**
  8271. * filter options
  8272. * @type {Object}
  8273. */
  8274. filters: null,
  8275. appendPadding: Global.appendPadding
  8276. };
  8277. };
  8278. _proto._syncYScales = function _syncYScales() {
  8279. var syncY = this.get('syncY');
  8280. if (!syncY) {
  8281. return;
  8282. }
  8283. var geoms = this.get('geoms');
  8284. var syncScales = [];
  8285. var min = [];
  8286. var max = [];
  8287. each(geoms, function (geom) {
  8288. var yScale = geom.getYScale();
  8289. if (yScale.isLinear) {
  8290. syncScales.push(yScale);
  8291. min.push(yScale.min);
  8292. max.push(yScale.max);
  8293. }
  8294. });
  8295. min = Math.min.apply(null, min);
  8296. max = Math.max.apply(null, max);
  8297. each(syncScales, function (scale) {
  8298. scale.change({
  8299. min: min
  8300. });
  8301. scale.change({
  8302. max: max
  8303. });
  8304. });
  8305. };
  8306. _proto._getFieldsForLegend = function _getFieldsForLegend() {
  8307. var fields = [];
  8308. var geoms = this.get('geoms');
  8309. each(geoms, function (geom) {
  8310. var attrOptions = geom.get('attrOptions');
  8311. var attrCfg = attrOptions.color;
  8312. if (attrCfg && attrCfg.field && isString(attrCfg.field)) {
  8313. var arr = attrCfg.field.split('*');
  8314. each(arr, function (item) {
  8315. if (fields.indexOf(item) === -1) {
  8316. fields.push(item);
  8317. }
  8318. });
  8319. }
  8320. });
  8321. return fields;
  8322. };
  8323. _proto._getScaleData = function _getScaleData(field) {
  8324. var data = this.get('data');
  8325. var filteredData = this.get('filteredData');
  8326. if (filteredData.length) {
  8327. var legendFields = this._getFieldsForLegend();
  8328. if (legendFields.indexOf(field) === -1) {
  8329. data = filteredData;
  8330. }
  8331. }
  8332. return data;
  8333. } // _updateScales() {
  8334. // const scaleController = this.get('scaleController');
  8335. // scaleController.updateScales();
  8336. // this._adjustScale();
  8337. // }
  8338. ;
  8339. _proto._adjustScale = function _adjustScale() {
  8340. var self = this;
  8341. var scaleController = self.get('scaleController'); // 看起来是为了让柱状图最小或最大都默认从0开始
  8342. var geoms = this.get('geoms');
  8343. for (var i = 0; i < geoms.length; i++) {
  8344. var geom = geoms[i];
  8345. if (geom.get('type') === 'interval') {
  8346. var yScale = geom.getYScale();
  8347. scaleController.adjustStartZero(yScale);
  8348. }
  8349. }
  8350. };
  8351. _proto._removeGeoms = function _removeGeoms() {
  8352. var geoms = this.get('geoms');
  8353. while (geoms.length > 0) {
  8354. var geom = geoms.shift();
  8355. geom.destroy();
  8356. }
  8357. };
  8358. _proto._clearGeoms = function _clearGeoms() {
  8359. var geoms = this.get('geoms');
  8360. for (var i = 0, length = geoms.length; i < length; i++) {
  8361. var geom = geoms[i];
  8362. geom.clear();
  8363. }
  8364. };
  8365. _proto._clearInner = function _clearInner() {
  8366. this._clearGeoms();
  8367. Chart.plugins.notify(this, 'clearInner');
  8368. this.emit(EVENT_CLEAR_INNER);
  8369. this.get('axisController') && this.get('axisController').clear();
  8370. };
  8371. _proto._initFilteredData = function _initFilteredData() {
  8372. var filters = this.get('filters');
  8373. var data = this.get('data') || [];
  8374. if (filters) {
  8375. data = data.filter(function (obj) {
  8376. var rst = true;
  8377. each(filters, function (fn, k) {
  8378. if (fn) {
  8379. rst = fn(obj[k], obj);
  8380. if (!rst) {
  8381. return false;
  8382. }
  8383. }
  8384. });
  8385. return rst;
  8386. });
  8387. }
  8388. this.set('filteredData', data);
  8389. };
  8390. _proto._changeGeomsData = function _changeGeomsData() {
  8391. var geoms = this.get('geoms');
  8392. var data = this.get('filteredData');
  8393. for (var i = 0, length = geoms.length; i < length; i++) {
  8394. var geom = geoms[i];
  8395. geom.changeData(data);
  8396. }
  8397. };
  8398. _proto._initGeom = function _initGeom(geom) {
  8399. if (geom.get('isInit')) {
  8400. return;
  8401. }
  8402. var coord = this.get('coord');
  8403. var data = this.get('filteredData');
  8404. var colDefs = this.get('colDefs');
  8405. var middlePlot = this.get('middlePlot');
  8406. geom.set('chart', this);
  8407. geom.set('container', middlePlot.addGroup());
  8408. geom.set('data', data);
  8409. geom.set('coord', coord);
  8410. geom.set('colDefs', colDefs);
  8411. geom.init();
  8412. this.emit(EVENT_AFTER_GEOM_INIT, geom);
  8413. };
  8414. _proto._initGeoms = function _initGeoms() {
  8415. var geoms = this.get('geoms');
  8416. for (var i = 0, length = geoms.length; i < length; i++) {
  8417. this._initGeom(geoms[i]);
  8418. }
  8419. };
  8420. _proto._initCoord = function _initCoord() {
  8421. var plot = this.get('plotRange');
  8422. var coordCfg = mix({
  8423. type: 'cartesian'
  8424. }, this.get('coordCfg'), {
  8425. plot: plot
  8426. });
  8427. var type = coordCfg.type;
  8428. var C = Base$1[upperFirst(type)];
  8429. var coord = new C(coordCfg);
  8430. this.set('coord', coord);
  8431. };
  8432. _proto._initLayout = function _initLayout() {
  8433. var padding = this.get('_padding');
  8434. if (!padding) {
  8435. padding = this.get('margin') || this.get('padding');
  8436. padding = parsePadding(padding);
  8437. }
  8438. var top = padding[0] === 'auto' ? 0 : padding[0];
  8439. var right = padding[1] === 'auto' ? 0 : padding[1];
  8440. var bottom = padding[2] === 'auto' ? 0 : padding[2];
  8441. var left = padding[3] === 'auto' ? 0 : padding[3];
  8442. var width = this.get('width');
  8443. var height = this.get('height');
  8444. var start = {
  8445. x: left,
  8446. y: top
  8447. };
  8448. var end = {
  8449. x: width - right,
  8450. y: height - bottom
  8451. };
  8452. var plot = this.get('plot');
  8453. if (plot) {
  8454. plot.reset(start, end);
  8455. return;
  8456. }
  8457. var newPlot = new Plot({
  8458. start: start,
  8459. end: end
  8460. });
  8461. this.set('plotRange', newPlot);
  8462. this.set('plot', newPlot);
  8463. };
  8464. _proto._initCanvas = function _initCanvas() {
  8465. var self = this;
  8466. try {
  8467. var canvas = createCanvas({
  8468. renderer: self.get('renderer'),
  8469. el: self.get('el') || self.get('id'),
  8470. context: self.get('context'),
  8471. pixelRatio: self.get('pixelRatio'),
  8472. width: self.get('width'),
  8473. height: self.get('height'),
  8474. fontFamily: Global.fontFamily,
  8475. aria: self.get('aria'),
  8476. title: self.get('title'),
  8477. landscape: self.get('landscape')
  8478. });
  8479. self.set('canvas', canvas);
  8480. self.set('el', canvas.get('el'));
  8481. self.set('width', canvas.get('width'));
  8482. self.set('height', canvas.get('height'));
  8483. } catch (error) {
  8484. throw error;
  8485. }
  8486. Chart.plugins.notify(self, 'afterCanvasInit');
  8487. };
  8488. _proto._initLayers = function _initLayers() {
  8489. var canvas = this.get('canvas');
  8490. this.set('backPlot', canvas.addGroup());
  8491. this.set('middlePlot', canvas.addGroup({
  8492. zIndex: 10
  8493. }));
  8494. this.set('frontPlot', canvas.addGroup({
  8495. zIndex: 20
  8496. }));
  8497. };
  8498. _proto._initEvents = function _initEvents() {
  8499. var _this2 = this;
  8500. // 数据更新后的一些更新
  8501. this.on(EVENT_AFTER_DATA_CHANGE, function () {
  8502. // 数据更新后,重新设置filterdata
  8503. _this2._initFilteredData(); // 更新geoms里的数据
  8504. _this2._changeGeomsData();
  8505. }); // 大小变化后的一些更新
  8506. this.on(EVENT_AFTER_SIZE_CHANGE, function () {
  8507. _this2._initLayout(); // layout变化后,坐标轴也需要做相应的变化
  8508. var coord = _this2.get('coord');
  8509. if (coord) {
  8510. coord.reset(_this2.get('plot'));
  8511. }
  8512. });
  8513. };
  8514. _proto._initScaleController = function _initScaleController() {
  8515. var scaleController = new ScaleController({
  8516. chart: this
  8517. }); // 让colDefs 和 scaleController.defs 用同一个对象,这样就不用考虑同步的问题
  8518. this.set('colDefs', scaleController.defs); // 已经实例化的scales 也保持统一个对象
  8519. this.set('scales', scaleController.scales);
  8520. this.set('scaleController', scaleController);
  8521. };
  8522. _proto._clearScaleController = function _clearScaleController() {
  8523. var scaleController = this.get('scaleController');
  8524. scaleController.clear();
  8525. };
  8526. _proto._init = function _init() {
  8527. var self = this;
  8528. self._initCanvas();
  8529. self._initLayout();
  8530. self._initLayers();
  8531. self._initEvents();
  8532. self._initScaleController();
  8533. self.set('axisController', new AxisController({
  8534. frontPlot: self.get('frontPlot').addGroup({
  8535. className: 'axisContainer'
  8536. }),
  8537. backPlot: self.get('backPlot').addGroup({
  8538. className: 'axisContainer'
  8539. }),
  8540. chart: self
  8541. }));
  8542. Chart.plugins.notify(self, 'init');
  8543. };
  8544. function Chart(cfg) {
  8545. var _this;
  8546. _this = _Base.call(this, cfg) || this;
  8547. var self = _assertThisInitialized(_this);
  8548. each(Geom, function (geomConstructor, className) {
  8549. var methodName = lowerFirst(className);
  8550. self[methodName] = function (cfg) {
  8551. var geom = new geomConstructor(cfg);
  8552. self.addGeom(geom);
  8553. return geom;
  8554. };
  8555. });
  8556. self._init();
  8557. return _this;
  8558. }
  8559. _proto.init = function init() {
  8560. // 初始filterData
  8561. this._initFilteredData(); // initialization coordinate instance
  8562. this._initCoord();
  8563. Chart.plugins.notify(this, 'beforeGeomInit'); // init all geometry instances
  8564. this._initGeoms(); // 多 Y 轴的情况时,统一 Y 轴的数值范围。
  8565. this._syncYScales(); // do some adjust for data
  8566. this._adjustScale();
  8567. this.emit(EVENT_AFTER_INIT);
  8568. }
  8569. /**
  8570. * set data and some scale configuration
  8571. * @chainable
  8572. * @param {Array} data the dataset to visualize
  8573. * @param {Object} colDefs the configuration for scales
  8574. * @return {Chart} return the chart instance
  8575. */
  8576. ;
  8577. _proto.source = function source(data, colDefs) {
  8578. this.set('data', data);
  8579. if (colDefs) {
  8580. this.scale(colDefs);
  8581. }
  8582. return this;
  8583. };
  8584. _proto.scale = function scale(field, cfg) {
  8585. var scaleController = this.get('scaleController');
  8586. scaleController.setFieldDef(field, cfg);
  8587. return this;
  8588. }
  8589. /**
  8590. * configure the axis
  8591. * @chainable
  8592. * @param {String|Boolean} field the field name of data
  8593. * @param {Object} cfg configuration for axis
  8594. * @return {Chart} return the chart instance
  8595. */
  8596. ;
  8597. _proto.axis = function axis(field, cfg) {
  8598. var axisController = this.get('axisController');
  8599. if (!field) {
  8600. axisController.axisCfg = null;
  8601. } else {
  8602. axisController.axisCfg = axisController.axisCfg || {};
  8603. axisController.axisCfg[field] = cfg;
  8604. }
  8605. return this;
  8606. }
  8607. /**
  8608. * configure the coordinate
  8609. * @chainable
  8610. * @param {String} type set the type of coodinate
  8611. * @param {Object} cfg configuration for coordinate
  8612. * @return {Chart} return the chart instance
  8613. */
  8614. ;
  8615. _proto.coord = function coord(type, cfg) {
  8616. var coordCfg;
  8617. if (isObject(type)) {
  8618. coordCfg = type;
  8619. } else {
  8620. coordCfg = cfg || {};
  8621. coordCfg.type = type || 'cartesian';
  8622. }
  8623. this.set('coordCfg', coordCfg);
  8624. return this;
  8625. };
  8626. _proto.filter = function filter(field, condition) {
  8627. var filters = this.get('filters') || {};
  8628. filters[field] = condition;
  8629. this.set('filters', filters); // 如果已经render过,则再重新触发一次change
  8630. if (this.get('rendered')) {
  8631. this.emit(EVENT_AFTER_DATA_CHANGE, this.get('data'));
  8632. }
  8633. }
  8634. /**
  8635. * render the chart
  8636. * @chainable
  8637. * @return {Chart} return the chart instance
  8638. */
  8639. ;
  8640. _proto.render = function render() {
  8641. var rendered = this.get('rendered');
  8642. var canvas = this.get('canvas');
  8643. var geoms = this.get('geoms'); // 已经渲染过
  8644. if (rendered) {
  8645. this._initGeoms();
  8646. this._adjustScale();
  8647. } else {
  8648. this.init();
  8649. this.set('rendered', true);
  8650. }
  8651. this.emit(EVENT_BEFORE_RENDER);
  8652. Chart.plugins.notify(this, 'beforeGeomDraw');
  8653. this._renderAxis();
  8654. var middlePlot = this.get('middlePlot');
  8655. if (this.get('limitInPlot') && !middlePlot.attr('clip')) {
  8656. var coord = this.get('coord');
  8657. var clip = getClip(coord);
  8658. clip.set('canvas', middlePlot.get('canvas'));
  8659. middlePlot.attr('clip', clip);
  8660. }
  8661. this.emit(EVENT_BEFORE_GEOM_DRAW);
  8662. for (var i = 0, length = geoms.length; i < length; i++) {
  8663. var geom = geoms[i];
  8664. geom.paint();
  8665. }
  8666. this.emit(EVENT_AFTER_GEOM_DRAW);
  8667. Chart.plugins.notify(this, 'afterGeomDraw');
  8668. canvas.sort();
  8669. this.get('frontPlot').sort();
  8670. Chart.plugins.notify(this, 'beforeCanvasDraw');
  8671. canvas.draw();
  8672. this.emit(EVENT_AFTER_RENDER);
  8673. return this;
  8674. }
  8675. /**
  8676. * clear the chart, include geometris and all the shapes
  8677. * @chainable
  8678. * @return {Chart} return the chart
  8679. */
  8680. ;
  8681. _proto.clear = function clear() {
  8682. Chart.plugins.notify(this, 'clear');
  8683. this.emit(EVENT_CLEAR);
  8684. this._clearInner();
  8685. this._removeGeoms();
  8686. this._clearScaleController();
  8687. this.set('legendItems', null);
  8688. this.set('filters', null);
  8689. this.set('isUpdate', false);
  8690. this.set('_padding', null);
  8691. this.set('rendered', false);
  8692. var canvas = this.get('canvas');
  8693. canvas.draw();
  8694. return this;
  8695. };
  8696. _proto.repaint = function repaint() {
  8697. // 如果在没有render之前就repaint的,就直接return退出
  8698. var rendered = this.get('rendered');
  8699. if (!rendered) {
  8700. return;
  8701. }
  8702. this.set('isUpdate', true);
  8703. this.set('legendItems', null);
  8704. Chart.plugins.notify(this, 'repaint');
  8705. this._clearInner();
  8706. this.emit(EVENT_REPAINT);
  8707. this.render();
  8708. };
  8709. _proto.changeData = function changeData(data) {
  8710. this.emit(EVENT_BEFORE_DATA_CHANGE, data);
  8711. this.set('data', data);
  8712. Chart.plugins.notify(this, 'changeData');
  8713. this.emit(EVENT_AFTER_DATA_CHANGE, data);
  8714. this.set('_padding', null);
  8715. this.repaint();
  8716. };
  8717. _proto.changeSize = function changeSize(width, height) {
  8718. if (width) {
  8719. this.set('width', width);
  8720. } else {
  8721. width = this.get('width');
  8722. }
  8723. if (height) {
  8724. this.set('height', height);
  8725. } else {
  8726. height = this.get('height');
  8727. }
  8728. var canvas = this.get('canvas');
  8729. canvas.changeSize(width, height);
  8730. this.emit(EVENT_AFTER_SIZE_CHANGE, {
  8731. width: width,
  8732. height: height
  8733. });
  8734. this.repaint();
  8735. return this;
  8736. };
  8737. _proto.destroy = function destroy() {
  8738. this.clear();
  8739. var canvas = this.get('canvas');
  8740. canvas.destroy();
  8741. Chart.plugins.notify(this, 'afterCanvasDestroyed');
  8742. if (this._interactions) {
  8743. each(this._interactions, function (interaction) {
  8744. interaction.destroy();
  8745. });
  8746. }
  8747. _Base.prototype.destroy.call(this);
  8748. }
  8749. /**
  8750. * calculate dataset's position on canvas
  8751. * @param {Object} record the dataset
  8752. * @return {Object} return the position
  8753. */
  8754. ;
  8755. _proto.getPosition = function getPosition(record) {
  8756. var self = this;
  8757. var coord = self.get('coord');
  8758. var xScale = self.getXScale();
  8759. var xField = xScale.field;
  8760. var yScales = self.getYScales(); // default first
  8761. var yScale = yScales[0];
  8762. var yField = yScale.field;
  8763. for (var i = 0, len = yScales.length; i < len; i++) {
  8764. var scale = yScales[i];
  8765. var field = scale.field;
  8766. if (record[field]) {
  8767. yScale = scale;
  8768. yField = field;
  8769. break;
  8770. }
  8771. }
  8772. var x = xScale.scale(record[xField]);
  8773. var y = yScale.scale(record[yField]);
  8774. return coord.convertPoint({
  8775. x: x,
  8776. y: y
  8777. });
  8778. }
  8779. /**
  8780. * get the data item of the point
  8781. * @param {Object} point canvas position
  8782. * @return {Object} return the data item
  8783. */
  8784. ;
  8785. _proto.getRecord = function getRecord(point) {
  8786. var self = this;
  8787. var coord = self.get('coord');
  8788. var xScale = self.getXScale();
  8789. var yScale = self.getYScales()[0];
  8790. var invertPoint = coord.invertPoint(point);
  8791. var record = {};
  8792. record[xScale.field] = xScale.invert(invertPoint.x);
  8793. record[yScale.field] = yScale.invert(invertPoint.y);
  8794. return record;
  8795. }
  8796. /**
  8797. * get the dataset of the point
  8798. * @param {Object} point canvas position
  8799. * @return {Array} return the dataset
  8800. **/
  8801. ;
  8802. _proto.getSnapRecords = function getSnapRecords(point) {
  8803. var geom = this.get('geoms')[0];
  8804. var data = [];
  8805. if (geom) {
  8806. // need to judge
  8807. data = geom.getSnapRecords(point);
  8808. }
  8809. return data;
  8810. }
  8811. /**
  8812. * creat scale instances
  8813. * @param {String} field field name of data
  8814. * @return {Scale} return the scale
  8815. */
  8816. ;
  8817. _proto.createScale = function createScale(field) {
  8818. var data = this._getScaleData(field);
  8819. var scaleController = this.get('scaleController');
  8820. return scaleController.createScale(field, data);
  8821. }
  8822. /**
  8823. * @protected
  8824. * add geometry instance to geoms
  8825. * @param {Geom} geom geometry instance
  8826. */
  8827. ;
  8828. _proto.addGeom = function addGeom(geom) {
  8829. var geoms = this.get('geoms');
  8830. geoms.push(geom);
  8831. }
  8832. /**
  8833. * get the scale of x axis
  8834. * @return {Scale} return the scale
  8835. */
  8836. ;
  8837. _proto.getXScale = function getXScale() {
  8838. var self = this;
  8839. var geoms = self.get('geoms');
  8840. var xScale = geoms[0].getXScale();
  8841. return xScale;
  8842. }
  8843. /**
  8844. * get the scale of y axis
  8845. * @return {Array} return the scale
  8846. */
  8847. ;
  8848. _proto.getYScales = function getYScales() {
  8849. var geoms = this.get('geoms');
  8850. var rst = [];
  8851. each(geoms, function (geom) {
  8852. var yScale = geom.getYScale();
  8853. if (rst.indexOf(yScale) === -1) {
  8854. rst.push(yScale);
  8855. }
  8856. });
  8857. return rst;
  8858. };
  8859. _proto.getLegendItems = function getLegendItems() {
  8860. if (this.get('legendItems')) {
  8861. return this.get('legendItems');
  8862. }
  8863. var legendItems = {};
  8864. var scales = [];
  8865. var geoms = this.get('geoms');
  8866. each(geoms, function (geom) {
  8867. var colorAttr = geom.getAttr('color');
  8868. if (colorAttr) {
  8869. var scale = colorAttr.getScale('color'); // 只支持分类图例
  8870. if (scale.isCategory && !_isScaleExist(scales, scale)) {
  8871. scales.push(scale);
  8872. var field = scale.field;
  8873. var ticks = scale.getTicks();
  8874. var items = [];
  8875. each(ticks, function (tick) {
  8876. var text = tick.text;
  8877. var name = text;
  8878. var scaleValue = tick.value;
  8879. var value = scale.invert(scaleValue);
  8880. var color = colorAttr.mapping(value).join('') || Global.defaultColor;
  8881. var marker = {
  8882. fill: color,
  8883. radius: 3,
  8884. symbol: 'circle',
  8885. stroke: '#fff'
  8886. };
  8887. items.push({
  8888. name: name,
  8889. // for display
  8890. dataValue: value,
  8891. // the origin value
  8892. checked: true,
  8893. marker: marker
  8894. });
  8895. });
  8896. legendItems[field] = items;
  8897. }
  8898. }
  8899. });
  8900. this.set('legendItems', legendItems);
  8901. return legendItems;
  8902. } // register the plugins
  8903. ;
  8904. _proto.registerPlugins = function registerPlugins(plugins) {
  8905. var self = this;
  8906. var chartPlugins = self.get('plugins') || [];
  8907. if (!isArray(chartPlugins)) {
  8908. chartPlugins = [chartPlugins];
  8909. }
  8910. [].concat(plugins).forEach(function (plugin) {
  8911. if (chartPlugins.indexOf(plugin) === -1) {
  8912. plugin.init && plugin.init(self); // init
  8913. chartPlugins.push(plugin);
  8914. }
  8915. });
  8916. Chart.plugins._cacheId++;
  8917. self.set('plugins', chartPlugins);
  8918. };
  8919. _proto._renderAxis = function _renderAxis() {
  8920. var axisController = this.get('axisController');
  8921. var xScale = this.getXScale();
  8922. var yScales = this.getYScales();
  8923. var coord = this.get('coord');
  8924. Chart.plugins.notify(this, 'beforeRenderAxis');
  8925. axisController.createAxis(coord, xScale, yScales);
  8926. };
  8927. _proto._isAutoPadding = function _isAutoPadding() {
  8928. if (this.get('_padding')) {
  8929. return false;
  8930. }
  8931. var padding = this.get('padding');
  8932. if (isArray(padding)) {
  8933. return padding.indexOf('auto') !== -1;
  8934. }
  8935. return padding === 'auto';
  8936. };
  8937. _proto._updateLayout = function _updateLayout(padding) {
  8938. var width = this.get('width');
  8939. var height = this.get('height');
  8940. var start = {
  8941. x: padding[3],
  8942. y: padding[0]
  8943. };
  8944. var end = {
  8945. x: width - padding[1],
  8946. y: height - padding[2]
  8947. };
  8948. var plot = this.get('plot');
  8949. var coord = this.get('coord');
  8950. plot.reset(start, end);
  8951. coord.reset(plot);
  8952. }
  8953. /**
  8954. * 是否为横屏展示
  8955. *
  8956. * @param {Boolean} landscape 是否为横屏
  8957. */
  8958. ;
  8959. _proto.landscape = function landscape(_landscape) {
  8960. var canvas = this.get('canvas');
  8961. canvas.set('landscape', _landscape);
  8962. };
  8963. return Chart;
  8964. }(Base);
  8965. Chart.plugins = Chart.initPlugins();
  8966. var track = function track() {
  8967. return null;
  8968. };
  8969. /**
  8970. * @fileOverview shape util
  8971. * @author dxq613@gmail.com
  8972. */
  8973. function splitPoints(obj) {
  8974. var points = [];
  8975. var x = obj.x;
  8976. var y = obj.y;
  8977. y = isArray(y) ? y : [y];
  8978. y.forEach(function (yItem, index) {
  8979. var point = {
  8980. x: isArray(x) ? x[index] : x,
  8981. y: yItem
  8982. };
  8983. points.push(point);
  8984. });
  8985. return points;
  8986. }
  8987. function splitArray(data, yField, connectNulls) {
  8988. if (!data.length) return [];
  8989. var arr = [];
  8990. var tmp = [];
  8991. var yValue;
  8992. each(data, function (obj) {
  8993. yValue = obj._origin ? obj._origin[yField] : obj[yField];
  8994. if (connectNulls) {
  8995. if (!isNil(yValue)) {
  8996. tmp.push(obj);
  8997. }
  8998. } else {
  8999. if (isArray(yValue) && isNil(yValue[0]) || isNil(yValue)) {
  9000. if (tmp.length) {
  9001. arr.push(tmp);
  9002. tmp = [];
  9003. }
  9004. } else {
  9005. tmp.push(obj);
  9006. }
  9007. }
  9008. });
  9009. if (tmp.length) {
  9010. arr.push(tmp);
  9011. }
  9012. return arr;
  9013. }
  9014. var SHAPES = ['circle', 'hollowCircle', 'rect'];
  9015. var Point = Shape$1.registerFactory('point', {
  9016. defaultShapeType: 'circle',
  9017. getDefaultPoints: function getDefaultPoints(pointInfo) {
  9018. return splitPoints(pointInfo);
  9019. }
  9020. });
  9021. function getPointsCfg(cfg) {
  9022. var style = {
  9023. lineWidth: 0,
  9024. stroke: cfg.color,
  9025. fill: cfg.color
  9026. };
  9027. if (cfg.size) {
  9028. style.size = cfg.size;
  9029. }
  9030. mix(style, cfg.style);
  9031. return mix({}, Global.shape.point, style);
  9032. }
  9033. function drawShape(cfg, container, shape) {
  9034. if (cfg.size === 0) return;
  9035. var pointCfg = getPointsCfg(cfg);
  9036. var size = pointCfg.r || pointCfg.size;
  9037. var x = cfg.x;
  9038. var y = !isArray(cfg.y) ? [cfg.y] : cfg.y;
  9039. if (shape === 'hollowCircle') {
  9040. pointCfg.lineWidth = 1;
  9041. pointCfg.fill = null;
  9042. }
  9043. for (var i = 0, len = y.length; i < len; i++) {
  9044. if (shape === 'rect') {
  9045. return container.addShape('Rect', {
  9046. className: 'point',
  9047. attrs: mix({
  9048. x: x - size,
  9049. y: y[i] - size,
  9050. width: size * 2,
  9051. height: size * 2
  9052. }, pointCfg)
  9053. });
  9054. }
  9055. return container.addShape('Circle', {
  9056. className: 'point',
  9057. attrs: mix({
  9058. x: x,
  9059. y: y[i],
  9060. r: size
  9061. }, pointCfg)
  9062. });
  9063. }
  9064. }
  9065. each(SHAPES, function (shapeType) {
  9066. Shape$1.registerShape('point', shapeType, {
  9067. draw: function draw(cfg, container) {
  9068. return drawShape(cfg, container, shapeType);
  9069. }
  9070. });
  9071. });
  9072. var Point$1 = /*#__PURE__*/function (_Geom) {
  9073. _inheritsLoose(Point, _Geom);
  9074. function Point() {
  9075. return _Geom.apply(this, arguments) || this;
  9076. }
  9077. var _proto = Point.prototype;
  9078. _proto.getDefaultCfg = function getDefaultCfg() {
  9079. var cfg = _Geom.prototype.getDefaultCfg.call(this);
  9080. cfg.type = 'point';
  9081. cfg.shapeType = 'point';
  9082. cfg.generatePoints = false;
  9083. return cfg;
  9084. };
  9085. _proto.draw = function draw(data, shapeFactory) {
  9086. var self = this;
  9087. var container = self.get('container');
  9088. each(data, function (obj) {
  9089. var shape = obj.shape;
  9090. var cfg = self.getDrawCfg(obj);
  9091. if (isArray(obj.y)) {
  9092. var hasStack = self.hasAdjust('stack');
  9093. each(obj.y, function (y, idx) {
  9094. cfg.y = y;
  9095. if (!hasStack || idx !== 0) {
  9096. self.drawShape(shape, obj, cfg, container, shapeFactory);
  9097. }
  9098. });
  9099. } else if (!isNil(obj.y)) {
  9100. self.drawShape(shape, obj, cfg, container, shapeFactory);
  9101. }
  9102. });
  9103. };
  9104. return Point;
  9105. }(Geom);
  9106. Geom.Point = Point$1;
  9107. var Line$2 = Shape$1.registerFactory('line', {
  9108. defaultShapeType: 'line'
  9109. });
  9110. function getStyle$1(cfg) {
  9111. var style = {
  9112. strokeStyle: cfg.color
  9113. };
  9114. if (cfg.size >= 0) {
  9115. style.lineWidth = cfg.size;
  9116. }
  9117. mix(style, cfg.style);
  9118. return mix({}, Global.shape.line, style);
  9119. }
  9120. function drawLines(cfg, container, style, smooth) {
  9121. var points = cfg.points;
  9122. if (points.length && isArray(points[0].y)) {
  9123. var topPoints = [];
  9124. var bottomPoints = [];
  9125. for (var i = 0, len = points.length; i < len; i++) {
  9126. var point = points[i];
  9127. var tmp = splitPoints(point);
  9128. bottomPoints.push(tmp[0]);
  9129. topPoints.push(tmp[1]);
  9130. }
  9131. if (cfg.isInCircle) {
  9132. topPoints.push(topPoints[0]);
  9133. bottomPoints.push(bottomPoints[0]);
  9134. }
  9135. if (cfg.isStack) {
  9136. return container.addShape('Polyline', {
  9137. className: 'line',
  9138. attrs: mix({
  9139. points: topPoints,
  9140. smooth: smooth
  9141. }, style)
  9142. });
  9143. }
  9144. var topShape = container.addShape('Polyline', {
  9145. className: 'line',
  9146. attrs: mix({
  9147. points: topPoints,
  9148. smooth: smooth
  9149. }, style)
  9150. });
  9151. var bottomShape = container.addShape('Polyline', {
  9152. className: 'line',
  9153. attrs: mix({
  9154. points: bottomPoints,
  9155. smooth: smooth
  9156. }, style)
  9157. });
  9158. return [topShape, bottomShape];
  9159. }
  9160. if (cfg.isInCircle) {
  9161. points.push(points[0]);
  9162. }
  9163. return container.addShape('Polyline', {
  9164. className: 'line',
  9165. attrs: mix({
  9166. points: points,
  9167. smooth: smooth
  9168. }, style)
  9169. });
  9170. }
  9171. var SHAPES$1 = ['line', 'smooth', 'dash'];
  9172. each(SHAPES$1, function (shapeType) {
  9173. Shape$1.registerShape('line', shapeType, {
  9174. draw: function draw(cfg, container) {
  9175. var smooth = shapeType === 'smooth';
  9176. var style = getStyle$1(cfg);
  9177. if (shapeType === 'dash') {
  9178. style.lineDash = Global.lineDash;
  9179. }
  9180. return drawLines(cfg, container, style, smooth);
  9181. }
  9182. });
  9183. });
  9184. var Path = /*#__PURE__*/function (_Geom) {
  9185. _inheritsLoose(Path, _Geom);
  9186. function Path() {
  9187. return _Geom.apply(this, arguments) || this;
  9188. }
  9189. var _proto = Path.prototype;
  9190. _proto.getDefaultCfg = function getDefaultCfg() {
  9191. var cfg = _Geom.prototype.getDefaultCfg.call(this);
  9192. cfg.type = 'path';
  9193. cfg.shapeType = 'line';
  9194. return cfg;
  9195. };
  9196. _proto.getDrawCfg = function getDrawCfg(obj) {
  9197. var cfg = _Geom.prototype.getDrawCfg.call(this, obj);
  9198. cfg.isStack = this.hasAdjust('stack');
  9199. return cfg;
  9200. };
  9201. _proto.draw = function draw(data, shapeFactory) {
  9202. var self = this;
  9203. var container = self.get('container');
  9204. var yScale = self.getYScale();
  9205. var connectNulls = self.get('connectNulls');
  9206. var splitArrayObj = splitArray(data, yScale.field, connectNulls);
  9207. var cfg = this.getDrawCfg(data[0]);
  9208. cfg.origin = data;
  9209. each(splitArrayObj, function (subData, splitedIndex) {
  9210. cfg.splitedIndex = splitedIndex;
  9211. cfg.points = subData;
  9212. self.drawShape(cfg.shape, data[0], cfg, container, shapeFactory);
  9213. });
  9214. };
  9215. return Path;
  9216. }(Geom);
  9217. Geom.Path = Path;
  9218. var Line$3 = /*#__PURE__*/function (_Path) {
  9219. _inheritsLoose(Line, _Path);
  9220. function Line() {
  9221. return _Path.apply(this, arguments) || this;
  9222. }
  9223. var _proto = Line.prototype;
  9224. _proto.getDefaultCfg = function getDefaultCfg() {
  9225. var cfg = _Path.prototype.getDefaultCfg.call(this);
  9226. cfg.type = 'line';
  9227. cfg.sortable = true;
  9228. return cfg;
  9229. };
  9230. return Line;
  9231. }(Path);
  9232. Geom.Line = Line$3;
  9233. function equals(v1, v2) {
  9234. return Math.abs(v1 - v2) < 0.00001;
  9235. }
  9236. function notEmpty(value) {
  9237. return !isNaN(value) && !isNil(value);
  9238. }
  9239. function filterPoints(points) {
  9240. var filteredPoints = []; // filter the point which x or y is NaN
  9241. for (var i = 0, len = points.length; i < len; i++) {
  9242. var point = points[i];
  9243. if (notEmpty(point.x) && notEmpty(point.y)) {
  9244. filteredPoints.push(point);
  9245. }
  9246. }
  9247. return filteredPoints;
  9248. }
  9249. function equalsCenter(points, center) {
  9250. var eqls = true;
  9251. each(points, function (point) {
  9252. if (!equals(point.x, center.x) || !equals(point.y, center.y)) {
  9253. eqls = false;
  9254. return false;
  9255. }
  9256. });
  9257. return eqls;
  9258. }
  9259. function drawRectShape(topPoints, bottomPoints, container, style, isSmooth) {
  9260. var shape;
  9261. var points = topPoints.concat(bottomPoints);
  9262. if (isSmooth) {
  9263. shape = container.addShape('Custom', {
  9264. className: 'area',
  9265. attrs: mix({
  9266. points: points
  9267. }, style),
  9268. createPath: function createPath(context) {
  9269. var constaint = [[0, 0], [1, 1]];
  9270. var points = filterPoints(this._attrs.attrs.points);
  9271. var pointsLen = points.length;
  9272. var topPoints = points.slice(0, pointsLen / 2);
  9273. var bottomPoints = points.slice(pointsLen / 2, pointsLen);
  9274. var topSps = catmullRom2bezier(topPoints, false, constaint);
  9275. context.beginPath();
  9276. context.moveTo(topPoints[0].x, topPoints[0].y);
  9277. for (var i = 0, n = topSps.length; i < n; i++) {
  9278. var sp = topSps[i];
  9279. context.bezierCurveTo(sp[1], sp[2], sp[3], sp[4], sp[5], sp[6]);
  9280. }
  9281. if (bottomPoints.length) {
  9282. var bottomSps = catmullRom2bezier(bottomPoints, false, constaint);
  9283. context.lineTo(bottomPoints[0].x, bottomPoints[0].y);
  9284. for (var _i = 0, _n = bottomSps.length; _i < _n; _i++) {
  9285. var _sp = bottomSps[_i];
  9286. context.bezierCurveTo(_sp[1], _sp[2], _sp[3], _sp[4], _sp[5], _sp[6]);
  9287. }
  9288. }
  9289. context.closePath();
  9290. },
  9291. calculateBox: function calculateBox() {
  9292. var points = filterPoints(this._attrs.attrs.points);
  9293. return getBBoxFromPoints(points);
  9294. }
  9295. });
  9296. } else {
  9297. shape = container.addShape('Polyline', {
  9298. className: 'area',
  9299. attrs: mix({
  9300. points: points
  9301. }, style)
  9302. });
  9303. }
  9304. return shape;
  9305. }
  9306. function drawShape$1(cfg, container, isSmooth) {
  9307. var self = this;
  9308. var points = cfg.points;
  9309. var topPoints = [];
  9310. var bottomPoints = [];
  9311. each(points, function (point) {
  9312. bottomPoints.push(point[0]);
  9313. topPoints.push(point[1]);
  9314. });
  9315. var style = mix({
  9316. fillStyle: cfg.color
  9317. }, Global.shape.area, cfg.style);
  9318. bottomPoints.reverse();
  9319. topPoints = self.parsePoints(topPoints);
  9320. bottomPoints = self.parsePoints(bottomPoints);
  9321. if (cfg.isInCircle) {
  9322. topPoints.push(topPoints[0]);
  9323. bottomPoints.unshift(bottomPoints[bottomPoints.length - 1]);
  9324. if (equalsCenter(bottomPoints, cfg.center)) {
  9325. bottomPoints = [];
  9326. }
  9327. }
  9328. return drawRectShape(topPoints, bottomPoints, container, style, isSmooth);
  9329. }
  9330. var Area = Shape$1.registerFactory('area', {
  9331. defaultShapeType: 'area',
  9332. getDefaultPoints: function getDefaultPoints(obj) {
  9333. var x = obj.x;
  9334. var y = obj.y;
  9335. var y0 = obj.y0;
  9336. y = isArray(y) ? y : [y0, y];
  9337. var points = [];
  9338. points.push({
  9339. x: x,
  9340. y: y[0]
  9341. }, {
  9342. x: x,
  9343. y: y[1]
  9344. });
  9345. return points;
  9346. }
  9347. });
  9348. var SHAPES$2 = ['area', 'smooth'];
  9349. each(SHAPES$2, function (shapeType) {
  9350. Shape$1.registerShape('area', shapeType, {
  9351. draw: function draw(cfg, container) {
  9352. var smooth = shapeType === 'smooth';
  9353. return drawShape$1.call(this, cfg, container, smooth);
  9354. }
  9355. });
  9356. });
  9357. var Area$1 = /*#__PURE__*/function (_Geom) {
  9358. _inheritsLoose(Area, _Geom);
  9359. function Area() {
  9360. return _Geom.apply(this, arguments) || this;
  9361. }
  9362. var _proto = Area.prototype;
  9363. /**
  9364. * get the default configuration
  9365. * @protected
  9366. * @return {Object} return the result
  9367. */
  9368. _proto.getDefaultCfg = function getDefaultCfg() {
  9369. var cfg = _Geom.prototype.getDefaultCfg.call(this);
  9370. cfg.type = 'area';
  9371. cfg.shapeType = 'area';
  9372. cfg.generatePoints = true;
  9373. cfg.sortable = true;
  9374. return cfg;
  9375. };
  9376. _proto.draw = function draw(data, shapeFactory) {
  9377. var self = this;
  9378. var container = self.get('container');
  9379. var cfg = this.getDrawCfg(data[0]);
  9380. var yScale = self.getYScale();
  9381. var connectNulls = self.get('connectNulls');
  9382. var splitArrayfn = splitArray(data, yScale.field, connectNulls);
  9383. cfg.origin = data;
  9384. each(splitArrayfn, function (subData, splitedIndex) {
  9385. cfg.splitedIndex = splitedIndex;
  9386. var points = subData.map(function (obj) {
  9387. return obj.points;
  9388. });
  9389. cfg.points = points;
  9390. self.drawShape(cfg.shape, data[0], cfg, container, shapeFactory);
  9391. });
  9392. };
  9393. return Area;
  9394. }(Geom);
  9395. Geom.Area = Area$1;
  9396. /**
  9397. * @fileOverview Utility for calculate the with ratui in x axis
  9398. * @author sima.zhang1990@gmail.com
  9399. * @author dxq613@gmail.com
  9400. */
  9401. var SizeMixin = {
  9402. initEvent: function initEvent() {
  9403. var _this = this;
  9404. var chart = this.get('chart');
  9405. if (!chart) {
  9406. return;
  9407. }
  9408. chart.on(EVENT_AFTER_SIZE_CHANGE, function () {
  9409. _this.set('_width', null);
  9410. });
  9411. },
  9412. getDefaultSize: function getDefaultSize() {
  9413. var defaultSize = this.get('defaultSize');
  9414. if (!defaultSize) {
  9415. var coord = this.get('coord');
  9416. var xScale = this.getXScale();
  9417. var dataArray = this.get('dataArray');
  9418. var values = uniq(xScale.values);
  9419. var count = values.length;
  9420. var range = xScale.range;
  9421. var normalizeSize = 1 / count;
  9422. var widthRatio = 1;
  9423. if (coord && coord.isPolar) {
  9424. if (coord.transposed && count > 1) {
  9425. widthRatio = Global.widthRatio.multiplePie;
  9426. } else {
  9427. widthRatio = Global.widthRatio.rose;
  9428. }
  9429. } else {
  9430. if (xScale.isLinear) {
  9431. normalizeSize *= range[1] - range[0];
  9432. }
  9433. widthRatio = Global.widthRatio.column;
  9434. }
  9435. normalizeSize *= widthRatio;
  9436. if (this.hasAdjust('dodge')) {
  9437. normalizeSize = normalizeSize / dataArray.length;
  9438. }
  9439. defaultSize = normalizeSize;
  9440. this.set('defaultSize', defaultSize);
  9441. }
  9442. return defaultSize;
  9443. },
  9444. getDimWidth: function getDimWidth(dimName) {
  9445. var coord = this.get('coord');
  9446. var start = coord.convertPoint({
  9447. x: 0,
  9448. y: 0
  9449. });
  9450. var end = coord.convertPoint({
  9451. x: dimName === 'x' ? 1 : 0,
  9452. y: dimName === 'x' ? 0 : 1
  9453. });
  9454. var width = 0;
  9455. if (start && end) {
  9456. width = Math.sqrt(Math.pow(end.x - start.x, 2) + Math.pow(end.y - start.y, 2));
  9457. }
  9458. return width;
  9459. },
  9460. _getWidth: function _getWidth() {
  9461. var width = this.get('_width');
  9462. if (!width) {
  9463. var coord = this.get('coord');
  9464. if (coord && coord.isPolar && !coord.transposed) {
  9465. width = (coord.endAngle - coord.startAngle) * coord.circleRadius;
  9466. } else {
  9467. width = this.getDimWidth('x');
  9468. }
  9469. this.set('_width', width);
  9470. }
  9471. return width;
  9472. },
  9473. _toNormalizedSize: function _toNormalizedSize(size) {
  9474. var width = this._getWidth();
  9475. return size / width;
  9476. },
  9477. _toCoordSize: function _toCoordSize(normalizeSize) {
  9478. var width = this._getWidth();
  9479. return width * normalizeSize;
  9480. },
  9481. getNormalizedSize: function getNormalizedSize(obj) {
  9482. var size = this.getAttrValue('size', obj);
  9483. if (isNil(size)) {
  9484. size = this.getDefaultSize();
  9485. } else {
  9486. size = this._toNormalizedSize(size);
  9487. }
  9488. return size;
  9489. },
  9490. getSize: function getSize(obj) {
  9491. var size = this.getAttrValue('size', obj);
  9492. if (isNil(size)) {
  9493. var normalizeSize = this.getDefaultSize();
  9494. size = this._toCoordSize(normalizeSize);
  9495. }
  9496. return size;
  9497. }
  9498. };
  9499. function getRectPoints(cfg) {
  9500. var x = cfg.x,
  9501. y = cfg.y,
  9502. y0 = cfg.y0,
  9503. size = cfg.size;
  9504. var ymin = y0;
  9505. var ymax = y;
  9506. if (isArray(y)) {
  9507. ymax = y[1];
  9508. ymin = y[0];
  9509. }
  9510. var xmin;
  9511. var xmax;
  9512. if (isArray(x)) {
  9513. xmin = x[0];
  9514. xmax = x[1];
  9515. } else {
  9516. xmin = x - size / 2;
  9517. xmax = x + size / 2;
  9518. }
  9519. return [{
  9520. x: xmin,
  9521. y: ymin
  9522. }, {
  9523. x: xmin,
  9524. y: ymax
  9525. }, {
  9526. x: xmax,
  9527. y: ymax
  9528. }, {
  9529. x: xmax,
  9530. y: ymin
  9531. }];
  9532. }
  9533. function getRectRange(points) {
  9534. var xValues = [];
  9535. var yValues = [];
  9536. for (var i = 0, len = points.length; i < len; i++) {
  9537. var point = points[i];
  9538. xValues.push(point.x);
  9539. yValues.push(point.y);
  9540. }
  9541. var xMin = Math.min.apply(null, xValues);
  9542. var yMin = Math.min.apply(null, yValues);
  9543. var xMax = Math.max.apply(null, xValues);
  9544. var yMax = Math.max.apply(null, yValues);
  9545. return {
  9546. x: xMin,
  9547. y: yMin,
  9548. width: xMax - xMin,
  9549. height: yMax - yMin
  9550. };
  9551. }
  9552. function getMiddlePoint(a, b) {
  9553. var x = (a.x - b.x) / 2 + b.x;
  9554. var y = (a.y - b.y) / 2 + b.y;
  9555. return {
  9556. x: x,
  9557. y: y
  9558. };
  9559. }
  9560. var Interval = Shape$1.registerFactory('interval', {
  9561. defaultShapeType: 'rect',
  9562. getDefaultPoints: function getDefaultPoints(cfg) {
  9563. return getRectPoints(cfg);
  9564. }
  9565. });
  9566. Shape$1.registerShape('interval', 'rect', {
  9567. draw: function draw(cfg, container) {
  9568. var points = this.parsePoints(cfg.points);
  9569. var style = mix({
  9570. fill: cfg.color
  9571. }, Global.shape.interval, cfg.style);
  9572. if (cfg.isInCircle) {
  9573. var newPoints = points.slice(0);
  9574. if (this._coord.transposed) {
  9575. newPoints = [points[0], points[3], points[2], points[1]];
  9576. }
  9577. var _cfg$center = cfg.center,
  9578. x = _cfg$center.x,
  9579. y = _cfg$center.y;
  9580. var v = [1, 0];
  9581. var v0 = [newPoints[0].x - x, newPoints[0].y - y];
  9582. var v1 = [newPoints[1].x - x, newPoints[1].y - y];
  9583. var v2 = [newPoints[2].x - x, newPoints[2].y - y];
  9584. var startAngle = Vector2.angleTo(v, v1);
  9585. var endAngle = Vector2.angleTo(v, v2);
  9586. var r0 = Vector2.length(v0);
  9587. var r = Vector2.length(v1);
  9588. if (startAngle >= 1.5 * Math.PI) {
  9589. startAngle = startAngle - 2 * Math.PI;
  9590. }
  9591. if (endAngle >= 1.5 * Math.PI) {
  9592. endAngle = endAngle - 2 * Math.PI;
  9593. }
  9594. return container.addShape('Sector', {
  9595. className: 'interval',
  9596. attrs: mix({
  9597. x: x,
  9598. y: y,
  9599. r: r,
  9600. r0: r0,
  9601. startAngle: startAngle,
  9602. endAngle: endAngle
  9603. }, style)
  9604. });
  9605. }
  9606. var rectCfg = getRectRange(points);
  9607. return container.addShape('rect', {
  9608. className: 'interval',
  9609. attrs: mix(rectCfg, style)
  9610. });
  9611. }
  9612. }); // 金字塔 和 漏斗图
  9613. ['pyramid', 'funnel'].forEach(function (shapeType) {
  9614. Shape$1.registerShape('interval', shapeType, {
  9615. getPoints: function getPoints(cfg) {
  9616. cfg.size = cfg.size * 2; // 漏斗图的 size 是柱状图的两倍
  9617. return getRectPoints(cfg);
  9618. },
  9619. draw: function draw(cfg, container) {
  9620. var points = this.parsePoints(cfg.points);
  9621. var nextPoints = this.parsePoints(cfg.nextPoints);
  9622. var polygonPoints = null;
  9623. if (nextPoints) {
  9624. polygonPoints = [points[0], points[1], nextPoints[1], nextPoints[0]];
  9625. } else {
  9626. polygonPoints = [points[0], points[1]]; // pyramid 顶部是三角形,所以取中心点就好了,funnel顶部是长方形
  9627. if (shapeType === 'pyramid') {
  9628. polygonPoints.push(getMiddlePoint(points[2], points[3]));
  9629. } else {
  9630. polygonPoints.push(points[2], points[3]);
  9631. }
  9632. }
  9633. var attrs = mix({
  9634. fill: cfg.color,
  9635. points: polygonPoints
  9636. }, Global.shape.interval, cfg.style);
  9637. return container.addShape('polygon', {
  9638. className: 'interval',
  9639. attrs: attrs
  9640. });
  9641. }
  9642. });
  9643. });
  9644. var Interval$1 = /*#__PURE__*/function (_Geom) {
  9645. _inheritsLoose(Interval, _Geom);
  9646. var _proto = Interval.prototype;
  9647. _proto.getDefaultCfg = function getDefaultCfg() {
  9648. var cfg = _Geom.prototype.getDefaultCfg.call(this);
  9649. cfg.type = 'interval';
  9650. cfg.shapeType = 'interval';
  9651. cfg.generatePoints = true;
  9652. return cfg;
  9653. };
  9654. function Interval(cfg) {
  9655. var _this;
  9656. _this = _Geom.call(this, cfg) || this;
  9657. mix(_assertThisInitialized(_this), SizeMixin);
  9658. return _this;
  9659. }
  9660. _proto.init = function init() {
  9661. _Geom.prototype.init.call(this); // 绑定事件
  9662. this.initEvent();
  9663. };
  9664. _proto.createShapePointsCfg = function createShapePointsCfg(obj) {
  9665. var cfg = _Geom.prototype.createShapePointsCfg.call(this, obj);
  9666. cfg.size = this.getNormalizedSize(obj);
  9667. return cfg;
  9668. };
  9669. _proto.clearInner = function clearInner() {
  9670. _Geom.prototype.clearInner.call(this);
  9671. this.set('defaultSize', null);
  9672. };
  9673. return Interval;
  9674. }(Geom);
  9675. Geom.Interval = Interval$1;
  9676. var Polygon$1 = Shape$1.registerFactory('polygon', {
  9677. defaultShapeType: 'polygon',
  9678. getDefaultPoints: function getDefaultPoints(pointInfo) {
  9679. var points = [];
  9680. var x = pointInfo.x,
  9681. y = pointInfo.y;
  9682. for (var i = 0, len = x.length; i < len; i++) {
  9683. points.push({
  9684. x: x[i],
  9685. y: y[i]
  9686. });
  9687. }
  9688. return points;
  9689. }
  9690. });
  9691. Shape$1.registerShape('polygon', 'polygon', {
  9692. draw: function draw(cfg, container) {
  9693. var points = this.parsePoints(cfg.points);
  9694. var style = mix({
  9695. fill: cfg.color,
  9696. points: points
  9697. }, cfg.style);
  9698. return container.addShape('Polygon', {
  9699. className: 'polygon',
  9700. attrs: style
  9701. });
  9702. }
  9703. });
  9704. var Polygon$2 = /*#__PURE__*/function (_Geom) {
  9705. _inheritsLoose(Polygon, _Geom);
  9706. function Polygon() {
  9707. return _Geom.apply(this, arguments) || this;
  9708. }
  9709. var _proto = Polygon.prototype;
  9710. _proto.getDefaultCfg = function getDefaultCfg() {
  9711. var cfg = _Geom.prototype.getDefaultCfg.call(this);
  9712. cfg.type = 'polygon';
  9713. cfg.shapeType = 'polygon';
  9714. cfg.generatePoints = true;
  9715. return cfg;
  9716. };
  9717. _proto.createShapePointsCfg = function createShapePointsCfg(obj) {
  9718. var cfg = _Geom.prototype.createShapePointsCfg.call(this, obj);
  9719. var self = this;
  9720. var x = cfg.x;
  9721. var y = cfg.y;
  9722. var temp;
  9723. if (!(isArray(x) && isArray(y))) {
  9724. var xScale = self.getXScale();
  9725. var yScale = self.getYScale();
  9726. var xCount = xScale.values ? xScale.values.length : xScale.ticks.length;
  9727. var yCount = yScale.values ? yScale.values.length : yScale.ticks.length;
  9728. var xOffset = 0.5 * 1 / xCount;
  9729. var yOffset = 0.5 * 1 / yCount;
  9730. if (xScale.isCategory && yScale.isCategory) {
  9731. x = [x - xOffset, x - xOffset, x + xOffset, x + xOffset];
  9732. y = [y - yOffset, y + yOffset, y + yOffset, y - yOffset];
  9733. } else if (isArray(x)) {
  9734. temp = x;
  9735. x = [temp[0], temp[0], temp[1], temp[1]];
  9736. y = [y - yOffset / 2, y + yOffset / 2, y + yOffset / 2, y - yOffset / 2];
  9737. } else if (isArray(y)) {
  9738. temp = y;
  9739. y = [temp[0], temp[1], temp[1], temp[0]];
  9740. x = [x - xOffset / 2, x - xOffset / 2, x + xOffset / 2, x + xOffset / 2];
  9741. }
  9742. cfg.x = x;
  9743. cfg.y = y;
  9744. }
  9745. return cfg;
  9746. };
  9747. return Polygon;
  9748. }(Geom);
  9749. Geom.Polygon = Polygon$2;
  9750. function _sortValue(value) {
  9751. var sorted = value.sort(function (a, b) {
  9752. return a < b ? 1 : -1;
  9753. });
  9754. var length = sorted.length;
  9755. if (length < 4) {
  9756. var min = sorted[length - 1];
  9757. for (var i = 0; i < 4 - length; i++) {
  9758. sorted.push(min);
  9759. }
  9760. }
  9761. return sorted;
  9762. } // from left bottom corner, and clockwise
  9763. function getCandlePoints(x, y, width) {
  9764. var yValues = _sortValue(y);
  9765. var points = [{
  9766. x: x,
  9767. y: yValues[0]
  9768. }, {
  9769. x: x,
  9770. y: yValues[1]
  9771. }, {
  9772. x: x - width / 2,
  9773. y: yValues[2]
  9774. }, {
  9775. x: x - width / 2,
  9776. y: yValues[1]
  9777. }, {
  9778. x: x + width / 2,
  9779. y: yValues[1]
  9780. }, {
  9781. x: x + width / 2,
  9782. y: yValues[2]
  9783. }, {
  9784. x: x,
  9785. y: yValues[2]
  9786. }, {
  9787. x: x,
  9788. y: yValues[3]
  9789. }];
  9790. return points;
  9791. }
  9792. var Schema = Shape$1.registerFactory('schema', {});
  9793. Shape$1.registerShape('schema', 'candle', {
  9794. getPoints: function getPoints(cfg) {
  9795. return getCandlePoints(cfg.x, cfg.y, cfg.size);
  9796. },
  9797. draw: function draw(cfg, container) {
  9798. var points = this.parsePoints(cfg.points);
  9799. var style = mix({
  9800. stroke: cfg.color,
  9801. fill: cfg.color,
  9802. lineWidth: 1
  9803. }, cfg.style);
  9804. return container.addShape('Custom', {
  9805. className: 'schema',
  9806. attrs: style,
  9807. createPath: function createPath(ctx) {
  9808. ctx.beginPath();
  9809. ctx.moveTo(points[0].x, points[0].y);
  9810. ctx.lineTo(points[1].x, points[1].y);
  9811. ctx.moveTo(points[2].x, points[2].y);
  9812. for (var i = 3; i < 6; i++) {
  9813. ctx.lineTo(points[i].x, points[i].y);
  9814. }
  9815. ctx.closePath();
  9816. ctx.moveTo(points[6].x, points[6].y);
  9817. ctx.lineTo(points[7].x, points[7].y);
  9818. }
  9819. });
  9820. }
  9821. });
  9822. var Schema$1 = /*#__PURE__*/function (_Geom) {
  9823. _inheritsLoose(Schema, _Geom);
  9824. var _proto = Schema.prototype;
  9825. _proto.getDefaultCfg = function getDefaultCfg() {
  9826. var cfg = _Geom.prototype.getDefaultCfg.call(this);
  9827. cfg.type = 'schema';
  9828. cfg.shapeType = 'schema';
  9829. cfg.generatePoints = true;
  9830. return cfg;
  9831. };
  9832. function Schema(cfg) {
  9833. var _this;
  9834. _this = _Geom.call(this, cfg) || this;
  9835. mix(_assertThisInitialized(_this), SizeMixin);
  9836. return _this;
  9837. }
  9838. _proto.init = function init() {
  9839. _Geom.prototype.init.call(this); // 绑定事件
  9840. this.initEvent();
  9841. };
  9842. _proto.createShapePointsCfg = function createShapePointsCfg(obj) {
  9843. var cfg = _Geom.prototype.createShapePointsCfg.call(this, obj);
  9844. cfg.size = this.getNormalizedSize(obj);
  9845. return cfg;
  9846. };
  9847. _proto.clearInner = function clearInner() {
  9848. _Geom.prototype.clearInner.call(this);
  9849. this.set('defaultSize', null);
  9850. };
  9851. return Schema;
  9852. }(Geom);
  9853. Geom.Schema = Schema$1;
  9854. var toString$3 = {}.toString;
  9855. var isType$1 = function isType(value, type) {
  9856. return toString$3.call(value) === '[object ' + type + ']';
  9857. };
  9858. var isType_1 = isType$1;
  9859. var isArray$1 = Array.isArray ? Array.isArray : function (value) {
  9860. return isType_1(value, 'Array');
  9861. };
  9862. var isArray_1 = isArray$1;
  9863. // isFinite,
  9864. var isNil$1 = function isNil(value) {
  9865. /**
  9866. * isNil(null) => true
  9867. * isNil() => true
  9868. */
  9869. return value === null || value === undefined;
  9870. };
  9871. var isNil_1 = isNil$1;
  9872. function _inheritsLoose$1(subClass, superClass) {
  9873. subClass.prototype = Object.create(superClass.prototype);
  9874. subClass.prototype.constructor = subClass;
  9875. subClass.__proto__ = superClass;
  9876. }
  9877. var Stack = /*#__PURE__*/function (_Adjust) {
  9878. _inheritsLoose$1(Stack, _Adjust);
  9879. function Stack() {
  9880. return _Adjust.apply(this, arguments) || this;
  9881. }
  9882. var _proto = Stack.prototype;
  9883. _proto._initDefaultCfg = function _initDefaultCfg() {
  9884. this.xField = null; // 调整对应的 x 方向对应的字段名称
  9885. this.yField = null; // 调整对应的 y 方向对应的字段名称
  9886. };
  9887. _proto.processAdjust = function processAdjust(dataArray) {
  9888. this.processStack(dataArray);
  9889. };
  9890. _proto.processStack = function processStack(dataArray) {
  9891. var self = this;
  9892. var xField = self.xField;
  9893. var yField = self.yField;
  9894. var count = dataArray.length;
  9895. var stackCache = {
  9896. positive: {},
  9897. negative: {}
  9898. }; // 层叠顺序翻转
  9899. if (self.reverseOrder) {
  9900. dataArray = dataArray.slice(0).reverse();
  9901. }
  9902. for (var i = 0; i < count; i++) {
  9903. var data = dataArray[i];
  9904. for (var j = 0, len = data.length; j < len; j++) {
  9905. var item = data[j];
  9906. var x = item[xField] || 0;
  9907. var y = item[yField];
  9908. var xkey = x.toString();
  9909. y = isArray_1(y) ? y[1] : y;
  9910. if (!isNil_1(y)) {
  9911. var direction = y >= 0 ? 'positive' : 'negative';
  9912. if (!stackCache[direction][xkey]) {
  9913. stackCache[direction][xkey] = 0;
  9914. }
  9915. item[yField] = [stackCache[direction][xkey], y + stackCache[direction][xkey]];
  9916. stackCache[direction][xkey] += y;
  9917. }
  9918. }
  9919. }
  9920. };
  9921. return Stack;
  9922. }(base);
  9923. base.Stack = Stack;
  9924. var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) {
  9925. return typeof obj;
  9926. } : function (obj) {
  9927. return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
  9928. };
  9929. var isObject$1 = function isObject(value) {
  9930. /**
  9931. * isObject({}) => true
  9932. * isObject([1, 2, 3]) => true
  9933. * isObject(Function) => true
  9934. * isObject(null) => false
  9935. */
  9936. var type = typeof value === 'undefined' ? 'undefined' : _typeof(value);
  9937. return value !== null && type === 'object' || type === 'function';
  9938. };
  9939. var isObject_1 = isObject$1;
  9940. var each$1 = function each(elements, func) {
  9941. if (!elements) {
  9942. return;
  9943. }
  9944. var rst = void 0;
  9945. if (isArray_1(elements)) {
  9946. for (var i = 0, len = elements.length; i < len; i++) {
  9947. rst = func(elements[i], i);
  9948. if (rst === false) {
  9949. break;
  9950. }
  9951. }
  9952. } else if (isObject_1(elements)) {
  9953. for (var k in elements) {
  9954. if (elements.hasOwnProperty(k)) {
  9955. rst = func(elements[k], k);
  9956. if (rst === false) {
  9957. break;
  9958. }
  9959. }
  9960. }
  9961. }
  9962. };
  9963. var each_1 = each$1;
  9964. function _inheritsLoose$2(subClass, superClass) {
  9965. subClass.prototype = Object.create(superClass.prototype);
  9966. subClass.prototype.constructor = subClass;
  9967. subClass.__proto__ = superClass;
  9968. }
  9969. var MARGIN_RATIO = 1 / 2;
  9970. var DODGE_RATIO = 1 / 2;
  9971. var Dodge = /*#__PURE__*/function (_Adjust) {
  9972. _inheritsLoose$2(Dodge, _Adjust);
  9973. function Dodge() {
  9974. return _Adjust.apply(this, arguments) || this;
  9975. }
  9976. var _proto = Dodge.prototype;
  9977. _proto._initDefaultCfg = function _initDefaultCfg() {
  9978. /**
  9979. * 调整过程中,2个数据的间距
  9980. * @type {Number}
  9981. */
  9982. this.marginRatio = MARGIN_RATIO;
  9983. /**
  9984. * 调整占单位宽度的比例,例如:占2个分类间距的 1/2
  9985. * @type {Number}
  9986. */
  9987. this.dodgeRatio = DODGE_RATIO;
  9988. this.adjustNames = ['x', 'y']; // 调整的维度,默认,x,y都做调整
  9989. };
  9990. _proto.getDodgeOffset = function getDodgeOffset(range, index, count) {
  9991. var self = this;
  9992. var pre = range.pre;
  9993. var next = range.next;
  9994. var tickLength = next - pre;
  9995. var width = tickLength * self.dodgeRatio / count;
  9996. var margin = self.marginRatio * width;
  9997. var offset = 1 / 2 * (tickLength - count * width - (count - 1) * margin) + ((index + 1) * width + index * margin) - 1 / 2 * width - 1 / 2 * tickLength;
  9998. return (pre + next) / 2 + offset;
  9999. };
  10000. _proto.processAdjust = function processAdjust(dataArray) {
  10001. var self = this;
  10002. var count = dataArray.length;
  10003. var xField = self.xField;
  10004. each_1(dataArray, function (data, index) {
  10005. for (var i = 0, len = data.length; i < len; i++) {
  10006. var obj = data[i];
  10007. var value = obj[xField];
  10008. var range = {
  10009. pre: len === 1 ? value - 1 : value - 0.5,
  10010. next: len === 1 ? value + 1 : value + 0.5
  10011. };
  10012. var dodgeValue = self.getDodgeOffset(range, index, count);
  10013. obj[xField] = dodgeValue;
  10014. }
  10015. });
  10016. };
  10017. return Dodge;
  10018. }(base);
  10019. base.Dodge = Dodge;
  10020. /**
  10021. * 是否为函数
  10022. * @param {*} fn 对象
  10023. * @return {Boolean} 是否函数
  10024. */
  10025. var isFunction$1 = function isFunction(value) {
  10026. return isType_1(value, 'Function');
  10027. };
  10028. var isFunction_1 = isFunction$1;
  10029. /**
  10030. * @param {Array} arr The array to iterate over.
  10031. * @param {Function} [fn] The iteratee invoked per element.
  10032. * @return {*} Returns the maximum value.
  10033. * @example
  10034. *
  10035. * var objects = [{ 'n': 1 }, { 'n': 2 }];
  10036. *
  10037. * maxBy(objects, function(o) { return o.n; });
  10038. * // => { 'n': 2 }
  10039. *
  10040. * maxBy(objects, 'n');
  10041. * // => { 'n': 2 }
  10042. */
  10043. var maxBy = function maxBy(arr, fn) {
  10044. if (!isArray_1(arr)) {
  10045. return undefined;
  10046. }
  10047. var max = arr[0];
  10048. var maxData = void 0;
  10049. if (isFunction_1(fn)) {
  10050. maxData = fn(arr[0]);
  10051. } else {
  10052. maxData = arr[0][fn];
  10053. }
  10054. var data = void 0;
  10055. each_1(arr, function (val) {
  10056. if (isFunction_1(fn)) {
  10057. data = fn(val);
  10058. } else {
  10059. data = val[fn];
  10060. }
  10061. if (data > maxData) {
  10062. max = val;
  10063. maxData = data;
  10064. }
  10065. });
  10066. return max;
  10067. };
  10068. var maxBy_1 = maxBy;
  10069. var merge$1 = function merge(dataArray) {
  10070. var rst = [];
  10071. for (var i = 0; i < dataArray.length; i++) {
  10072. rst = rst.concat(dataArray[i]);
  10073. }
  10074. return rst;
  10075. };
  10076. var merge_1 = merge$1;
  10077. function _inheritsLoose$3(subClass, superClass) {
  10078. subClass.prototype = Object.create(superClass.prototype);
  10079. subClass.prototype.constructor = subClass;
  10080. subClass.__proto__ = superClass;
  10081. }
  10082. var ArrayUtil = {
  10083. merge: merge_1
  10084. };
  10085. var Symmetric = /*#__PURE__*/function (_Adjust) {
  10086. _inheritsLoose$3(Symmetric, _Adjust);
  10087. function Symmetric() {
  10088. return _Adjust.apply(this, arguments) || this;
  10089. }
  10090. var _proto = Symmetric.prototype;
  10091. _proto._initDefaultCfg = function _initDefaultCfg() {
  10092. this.xField = null; // 调整对应的 x 方向对应的字段名称
  10093. this.yField = null; // 调整对应的 y 方向对应的字段名称
  10094. this.cacheMax = null; // 缓存的最大值
  10095. this.adjustNames = ['y']; // Only support stack y
  10096. this.groupFields = null; // 参与分组的数据维度
  10097. }; // 获取最大的y值
  10098. _proto._getMax = function _getMax(dim) {
  10099. var self = this;
  10100. var mergeData = self.mergeData;
  10101. var maxRecord = maxBy_1(mergeData, function (obj) {
  10102. var value = obj[dim];
  10103. if (isArray_1(value)) {
  10104. return Math.max.apply(null, value);
  10105. }
  10106. return value;
  10107. });
  10108. var maxValue = maxRecord[dim];
  10109. var max = isArray_1(maxValue) ? Math.max.apply(null, maxValue) : maxValue;
  10110. return max;
  10111. }; // 获取每个字段最大的值
  10112. _proto._getXValuesMax = function _getXValuesMax() {
  10113. var self = this;
  10114. var yField = self.yField;
  10115. var xField = self.xField;
  10116. var cache = {};
  10117. var mergeData = self.mergeData;
  10118. each_1(mergeData, function (obj) {
  10119. var xValue = obj[xField];
  10120. var yValue = obj[yField];
  10121. var max = isArray_1(yValue) ? Math.max.apply(null, yValue) : yValue;
  10122. cache[xValue] = cache[xValue] || 0;
  10123. if (cache[xValue] < max) {
  10124. cache[xValue] = max;
  10125. }
  10126. });
  10127. return cache;
  10128. }; // 入口函数
  10129. _proto.processAdjust = function processAdjust(dataArray) {
  10130. var self = this;
  10131. var mergeData = ArrayUtil.merge(dataArray);
  10132. self.mergeData = mergeData;
  10133. self._processSymmetric(dataArray);
  10134. self.mergeData = null;
  10135. }; // 处理对称
  10136. _proto._processSymmetric = function _processSymmetric(dataArray) {
  10137. var self = this;
  10138. var xField = self.xField;
  10139. var yField = self.yField;
  10140. var max = self._getMax(yField);
  10141. var first = dataArray[0][0];
  10142. var cache;
  10143. if (first && isArray_1(first[yField])) {
  10144. cache = self._getXValuesMax();
  10145. }
  10146. each_1(dataArray, function (data) {
  10147. each_1(data, function (obj) {
  10148. var value = obj[yField];
  10149. var offset;
  10150. if (isArray_1(value)) {
  10151. var xValue = obj[xField];
  10152. var valueMax = cache[xValue];
  10153. offset = (max - valueMax) / 2;
  10154. var tmp = [];
  10155. /* eslint-disable no-loop-func */
  10156. each_1(value, function (subVal) {
  10157. // 多个字段
  10158. tmp.push(offset + subVal);
  10159. });
  10160. /* eslint-enable no-loop-func */
  10161. obj[yField] = tmp;
  10162. } else {
  10163. offset = (max - value) / 2;
  10164. obj[yField] = [offset, value + offset];
  10165. }
  10166. });
  10167. });
  10168. };
  10169. return Symmetric;
  10170. }(base);
  10171. base.Symmetric = Symmetric;
  10172. var Polar = /*#__PURE__*/function (_Base) {
  10173. _inheritsLoose(Polar, _Base);
  10174. function Polar() {
  10175. return _Base.apply(this, arguments) || this;
  10176. }
  10177. var _proto = Polar.prototype;
  10178. _proto._initDefaultCfg = function _initDefaultCfg() {
  10179. this.type = 'polar';
  10180. this.startAngle = -Math.PI / 2;
  10181. this.endAngle = Math.PI * 3 / 2;
  10182. this.inner = 0;
  10183. this.innerRadius = 0; // alias
  10184. this.isPolar = true;
  10185. this.transposed = false;
  10186. this.center = null;
  10187. this.radius = null; // relative, 0 ~ 1
  10188. };
  10189. _proto.init = function init(start, end) {
  10190. _Base.prototype.init.call(this, start, end);
  10191. var self = this;
  10192. var inner = self.inner || self.innerRadius;
  10193. var width = Math.abs(end.x - start.x);
  10194. var height = Math.abs(end.y - start.y);
  10195. var maxRadius;
  10196. var center;
  10197. if (self.startAngle === -Math.PI && self.endAngle === 0) {
  10198. maxRadius = Math.min(width / 2, height);
  10199. center = {
  10200. x: (start.x + end.x) / 2,
  10201. y: start.y
  10202. };
  10203. } else {
  10204. maxRadius = Math.min(width, height) / 2;
  10205. center = {
  10206. x: (start.x + end.x) / 2,
  10207. y: (start.y + end.y) / 2
  10208. };
  10209. }
  10210. var radius = self.radius;
  10211. if (radius > 0 && radius <= 1) {
  10212. maxRadius = maxRadius * radius;
  10213. }
  10214. this.x = {
  10215. start: self.startAngle,
  10216. end: self.endAngle
  10217. };
  10218. this.y = {
  10219. start: maxRadius * inner,
  10220. end: maxRadius
  10221. };
  10222. this.center = center;
  10223. this.circleRadius = maxRadius; // the radius value in px
  10224. };
  10225. _proto._convertPoint = function _convertPoint(point) {
  10226. var self = this;
  10227. var center = self.center;
  10228. var transposed = self.transposed;
  10229. var xDim = transposed ? 'y' : 'x';
  10230. var yDim = transposed ? 'x' : 'y';
  10231. var x = self.x;
  10232. var y = self.y;
  10233. var angle = x.start + (x.end - x.start) * point[xDim];
  10234. var radius = y.start + (y.end - y.start) * point[yDim];
  10235. return {
  10236. x: center.x + Math.cos(angle) * radius,
  10237. y: center.y + Math.sin(angle) * radius
  10238. };
  10239. };
  10240. _proto._invertPoint = function _invertPoint(point) {
  10241. var self = this;
  10242. var center = self.center,
  10243. transposed = self.transposed,
  10244. x = self.x,
  10245. y = self.y;
  10246. var xDim = transposed ? 'y' : 'x';
  10247. var yDim = transposed ? 'x' : 'y';
  10248. var m = [1, 0, 0, 1, 0, 0];
  10249. Matrix.rotate(m, m, x.start);
  10250. var startV = [1, 0];
  10251. Vector2.transformMat2d(startV, startV, m);
  10252. startV = [startV[0], startV[1]];
  10253. var pointV = [point.x - center.x, point.y - center.y];
  10254. if (Vector2.zero(pointV)) {
  10255. return {
  10256. x: 0,
  10257. y: 0
  10258. };
  10259. }
  10260. var theta = Vector2.angleTo(startV, pointV, x.end < x.start);
  10261. if (Math.abs(theta - Math.PI * 2) < 0.001) {
  10262. theta = 0;
  10263. }
  10264. var l = Vector2.length(pointV);
  10265. var percentX = theta / (x.end - x.start);
  10266. percentX = x.end - x.start > 0 ? percentX : -percentX;
  10267. var percentY = (l - y.start) / (y.end - y.start);
  10268. var rst = {};
  10269. rst[xDim] = percentX;
  10270. rst[yDim] = percentY;
  10271. return rst;
  10272. };
  10273. return Polar;
  10274. }(Base$1);
  10275. Base$1.Polar = Polar;
  10276. var Circle$1 = /*#__PURE__*/function (_Abstract) {
  10277. _inheritsLoose(Circle, _Abstract);
  10278. function Circle() {
  10279. return _Abstract.apply(this, arguments) || this;
  10280. }
  10281. var _proto = Circle.prototype;
  10282. _proto._initDefaultCfg = function _initDefaultCfg() {
  10283. _Abstract.prototype._initDefaultCfg.call(this);
  10284. this.startAngle = -Math.PI / 2; // start angle,in radian
  10285. this.endAngle = Math.PI * 3 / 2; // end angle, in radian
  10286. this.radius = null; // radius
  10287. this.center = null; // center
  10288. };
  10289. _proto.getOffsetPoint = function getOffsetPoint(value) {
  10290. var startAngle = this.startAngle,
  10291. endAngle = this.endAngle;
  10292. var angle = startAngle + (endAngle - startAngle) * value;
  10293. return this._getCirclePoint(angle);
  10294. };
  10295. _proto._getCirclePoint = function _getCirclePoint(angle, radius) {
  10296. var self = this;
  10297. var center = self.center;
  10298. radius = radius || self.radius;
  10299. return {
  10300. x: center.x + Math.cos(angle) * radius,
  10301. y: center.y + Math.sin(angle) * radius
  10302. };
  10303. };
  10304. _proto.getTextAlignInfo = function getTextAlignInfo(point, offset) {
  10305. var self = this;
  10306. var offsetVector = self.getOffsetVector(point, offset);
  10307. var align;
  10308. var baseLine = 'middle';
  10309. if (offsetVector[0] > 0) {
  10310. align = 'left';
  10311. } else if (offsetVector[0] < 0) {
  10312. align = 'right';
  10313. } else {
  10314. align = 'center';
  10315. if (offsetVector[1] > 0) {
  10316. baseLine = 'top';
  10317. } else if (offsetVector[1] < 0) {
  10318. baseLine = 'bottom';
  10319. }
  10320. }
  10321. return {
  10322. textAlign: align,
  10323. textBaseline: baseLine
  10324. };
  10325. };
  10326. _proto.getAxisVector = function getAxisVector(point) {
  10327. var center = this.center;
  10328. var factor = this.offsetFactor;
  10329. return [(point.y - center.y) * factor, (point.x - center.x) * -1 * factor];
  10330. };
  10331. _proto.drawLine = function drawLine(lineCfg) {
  10332. var center = this.center,
  10333. radius = this.radius,
  10334. startAngle = this.startAngle,
  10335. endAngle = this.endAngle;
  10336. var container = this.getContainer(lineCfg.top);
  10337. container.addShape('arc', {
  10338. className: 'axis-line',
  10339. attrs: mix({
  10340. x: center.x,
  10341. y: center.y,
  10342. r: radius,
  10343. startAngle: startAngle,
  10344. endAngle: endAngle
  10345. }, lineCfg)
  10346. });
  10347. };
  10348. return Circle;
  10349. }(Abastract);
  10350. Abastract.Circle = Circle$1;
  10351. var KEYWORDS_PERCENT = {
  10352. min: 0,
  10353. median: 0.5,
  10354. max: 1
  10355. };
  10356. var GuideBase = /*#__PURE__*/function () {
  10357. var _proto = GuideBase.prototype;
  10358. _proto._initDefaultCfg = function _initDefaultCfg() {};
  10359. function GuideBase(cfg) {
  10360. this._initDefaultCfg();
  10361. deepMix(this, cfg);
  10362. }
  10363. _proto._getNormalizedValue = function _getNormalizedValue(val, scale) {
  10364. var rst;
  10365. if (isNil(KEYWORDS_PERCENT[val])) {
  10366. rst = scale.scale(val);
  10367. } else {
  10368. rst = KEYWORDS_PERCENT[val];
  10369. }
  10370. return rst;
  10371. };
  10372. _proto.parsePercentPoint = function parsePercentPoint(coord, position) {
  10373. var xPercent = parseFloat(position[0]) / 100;
  10374. var yPercent = parseFloat(position[1]) / 100;
  10375. var start = coord.start;
  10376. var end = coord.end;
  10377. var width = Math.abs(start.x - end.x);
  10378. var height = Math.abs(start.y - end.y);
  10379. var x = width * xPercent + Math.min(start.x, end.x);
  10380. var y = height * yPercent + Math.min(start.y, end.y);
  10381. return {
  10382. x: x,
  10383. y: y
  10384. };
  10385. };
  10386. _proto.parsePoint = function parsePoint(coord, position) {
  10387. var self = this;
  10388. var xScale = self.xScale;
  10389. var yScales = self.yScales;
  10390. if (isFunction(position)) {
  10391. position = position(xScale, yScales); // position 必须是对象
  10392. } // 如果数据格式是 ['50%', '50%'] 的格式
  10393. // fix: 原始数据中可能会包含 'xxx5%xxx' 这样的数据,需要判断下 https://github.com/antvis/f2/issues/590
  10394. if (isString(position[0]) && position[0].indexOf('%') !== -1 && !isNaN(position[0].slice(0, -1))) {
  10395. return this.parsePercentPoint(coord, position);
  10396. }
  10397. var x = self._getNormalizedValue(position[0], xScale);
  10398. var y = self._getNormalizedValue(position[1], yScales[0]);
  10399. var point = coord.convertPoint({
  10400. x: x,
  10401. y: y
  10402. });
  10403. if (self.limitInPlot) {
  10404. // limit in chart plotRange
  10405. if (x >= 0 && x <= 1 && y >= 0 && y <= 1) {
  10406. return point;
  10407. }
  10408. return null;
  10409. }
  10410. return point;
  10411. }
  10412. /**
  10413. * render the guide component
  10414. * @param {Coord} coord coordinate instance
  10415. * @param {Canvas.Group} group the container
  10416. */
  10417. ;
  10418. _proto.render = function render()
  10419. /* coord,group */
  10420. {};
  10421. _proto.repaint = function repaint() {
  10422. this.remove();
  10423. var coord = this.coord,
  10424. container = this.container,
  10425. canvas = this.canvas;
  10426. if (container && !container.isDestroyed()) {
  10427. this.render(coord, container);
  10428. canvas.draw();
  10429. }
  10430. };
  10431. _proto.remove = function remove() {
  10432. var element = this.element;
  10433. element && element.remove(true);
  10434. };
  10435. _proto.changeVisible = function changeVisible(visible) {
  10436. var self = this;
  10437. self.visible = visible;
  10438. var element = self.element;
  10439. if (!element) return;
  10440. if (element.set) {
  10441. element.set('visible', visible);
  10442. } else {
  10443. element.style.display = visible ? '' : 'none';
  10444. }
  10445. };
  10446. return GuideBase;
  10447. }();
  10448. var Text$1 = /*#__PURE__*/function (_GuideBase) {
  10449. _inheritsLoose(Text, _GuideBase);
  10450. function Text() {
  10451. return _GuideBase.apply(this, arguments) || this;
  10452. }
  10453. var _proto = Text.prototype;
  10454. _proto._initDefaultCfg = function _initDefaultCfg() {
  10455. this.type = 'text';
  10456. /**
  10457. * the position of text
  10458. * @type {Function | Array}
  10459. */
  10460. this.position = null;
  10461. /**
  10462. * the display content
  10463. * @type {String}
  10464. */
  10465. this.content = null;
  10466. /**
  10467. * style configuration for text
  10468. * @type {Object}
  10469. */
  10470. this.style = {
  10471. fill: '#000'
  10472. };
  10473. /**
  10474. * offset of horizontal direction
  10475. * @type {Number}
  10476. */
  10477. this.offsetX = 0;
  10478. /**
  10479. * offset of vertical direction
  10480. * @type {Number}
  10481. */
  10482. this.offsetY = 0;
  10483. };
  10484. _proto.render = function render(coord, container) {
  10485. var position = this.position;
  10486. var point = this.parsePoint(coord, position);
  10487. if (!point) {
  10488. return;
  10489. }
  10490. var content = this.content,
  10491. style = this.style,
  10492. offsetX = this.offsetX,
  10493. offsetY = this.offsetY;
  10494. if (offsetX) {
  10495. point.x += offsetX;
  10496. }
  10497. if (offsetY) {
  10498. point.y += offsetY;
  10499. }
  10500. var shape = container.addShape('text', {
  10501. className: 'guide-text',
  10502. attrs: mix({
  10503. x: point.x,
  10504. y: point.y,
  10505. text: content
  10506. }, style)
  10507. });
  10508. this.element = shape;
  10509. return shape;
  10510. };
  10511. return Text;
  10512. }(GuideBase);
  10513. GuideBase.Text = Text$1;
  10514. var Line$4 = /*#__PURE__*/function (_GuideBase) {
  10515. _inheritsLoose(Line, _GuideBase);
  10516. function Line() {
  10517. return _GuideBase.apply(this, arguments) || this;
  10518. }
  10519. var _proto = Line.prototype;
  10520. _proto._initDefaultCfg = function _initDefaultCfg() {
  10521. this.type = 'line';
  10522. this.start = [];
  10523. this.end = [];
  10524. this.style = {
  10525. stroke: '#000',
  10526. lineWidth: 1
  10527. };
  10528. };
  10529. _proto.render = function render(coord, container) {
  10530. var points = [];
  10531. points[0] = this.parsePoint(coord, this.start);
  10532. points[1] = this.parsePoint(coord, this.end);
  10533. if (!points[0] || !points[1]) {
  10534. return;
  10535. }
  10536. var shape = container.addShape('Line', {
  10537. className: 'guide-line',
  10538. attrs: mix({
  10539. x1: points[0].x,
  10540. y1: points[0].y,
  10541. x2: points[1].x,
  10542. y2: points[1].y
  10543. }, this.style)
  10544. });
  10545. this.element = shape;
  10546. return shape;
  10547. };
  10548. return Line;
  10549. }(GuideBase);
  10550. GuideBase.Line = Line$4;
  10551. var Arc$1 = /*#__PURE__*/function (_GuideBase) {
  10552. _inheritsLoose(Arc, _GuideBase);
  10553. function Arc() {
  10554. return _GuideBase.apply(this, arguments) || this;
  10555. }
  10556. var _proto = Arc.prototype;
  10557. _proto._initDefaultCfg = function _initDefaultCfg() {
  10558. this.type = 'arc';
  10559. /**
  10560. * start point
  10561. * @type {Array | Function}
  10562. */
  10563. this.start = [];
  10564. /**
  10565. * end point
  10566. * @type {Array | Function}
  10567. */
  10568. this.end = [];
  10569. /**
  10570. * style configuration
  10571. * @type {Object}
  10572. */
  10573. this.style = {
  10574. stroke: '#999',
  10575. lineWidth: 1
  10576. };
  10577. };
  10578. _proto.render = function render(coord, container) {
  10579. var self = this;
  10580. var start = self.parsePoint(coord, self.start);
  10581. var end = self.parsePoint(coord, self.end);
  10582. if (!start || !end) {
  10583. return;
  10584. }
  10585. var coordCenter = coord.center;
  10586. var radius = Math.sqrt((start.x - coordCenter.x) * (start.x - coordCenter.x) + (start.y - coordCenter.y) * (start.y - coordCenter.y));
  10587. var startAngle = Math.atan2(start.y - coordCenter.y, start.x - coordCenter.x);
  10588. var endAngle = Math.atan2(end.y - coordCenter.y, end.x - coordCenter.x);
  10589. var shape = container.addShape('arc', {
  10590. className: 'guide-arc',
  10591. attrs: mix({
  10592. x: coordCenter.x,
  10593. y: coordCenter.y,
  10594. r: radius,
  10595. startAngle: startAngle,
  10596. endAngle: endAngle
  10597. }, self.style)
  10598. });
  10599. self.element = shape;
  10600. return shape;
  10601. };
  10602. return Arc;
  10603. }(GuideBase);
  10604. GuideBase.Arc = Arc$1;
  10605. var Rect$2 = /*#__PURE__*/function (_GuideBase) {
  10606. _inheritsLoose(Rect, _GuideBase);
  10607. function Rect() {
  10608. return _GuideBase.apply(this, arguments) || this;
  10609. }
  10610. var _proto = Rect.prototype;
  10611. _proto._initDefaultCfg = function _initDefaultCfg() {
  10612. this.type = 'rect';
  10613. this.start = [];
  10614. this.end = [];
  10615. this.style = {
  10616. fill: '#CCD7EB',
  10617. opacity: 0.4
  10618. };
  10619. };
  10620. _proto.render = function render(coord, container) {
  10621. var start = this.parsePoint(coord, this.start);
  10622. var end = this.parsePoint(coord, this.end);
  10623. if (!start || !end) {
  10624. return;
  10625. }
  10626. var shape = container.addShape('rect', {
  10627. className: 'guide-rect',
  10628. attrs: mix({
  10629. x: Math.min(start.x, end.x),
  10630. y: Math.min(start.y, end.y),
  10631. width: Math.abs(end.x - start.x),
  10632. height: Math.abs(start.y - end.y)
  10633. }, this.style)
  10634. });
  10635. this.element = shape;
  10636. return shape;
  10637. };
  10638. return Rect;
  10639. }(GuideBase);
  10640. GuideBase.Rect = Rect$2;
  10641. function getOffsetFromAlign(alignX, alignY, width, height) {
  10642. var result = [];
  10643. if (alignX === 'left' && alignY === 'top') {
  10644. result[0] = 0;
  10645. result[1] = 0;
  10646. } else if (alignX === 'right' && alignY === 'top') {
  10647. result[0] = -width;
  10648. result[1] = 0;
  10649. } else if (alignX === 'left' && alignY === 'bottom') {
  10650. result[0] = 0;
  10651. result[1] = Math.floor(-height);
  10652. } else if (alignX === 'right' && alignY === 'bottom') {
  10653. result[0] = Math.floor(-width);
  10654. result[1] = Math.floor(-height);
  10655. } else if (alignX === 'right' && alignY === 'middle') {
  10656. result[0] = Math.floor(-width);
  10657. result[1] = Math.floor(-height / 2);
  10658. } else if (alignX === 'left' && alignY === 'middle') {
  10659. result[0] = 0;
  10660. result[1] = Math.floor(-height / 2);
  10661. } else if (alignX === 'center' && alignY === 'bottom') {
  10662. result[0] = Math.floor(-width / 2);
  10663. result[1] = Math.floor(-height);
  10664. } else if (alignX === 'center' && alignY === 'top') {
  10665. result[0] = Math.floor(-width / 2);
  10666. result[1] = 0;
  10667. } else {
  10668. result[0] = Math.floor(-width / 2);
  10669. result[1] = Math.floor(-height / 2);
  10670. }
  10671. return result;
  10672. }
  10673. function modifyCSS(DOM, CSS) {
  10674. for (var key in CSS) {
  10675. if (CSS.hasOwnProperty(key)) {
  10676. DOM.style[key] = CSS[key];
  10677. }
  10678. }
  10679. return DOM;
  10680. }
  10681. function createDom(str) {
  10682. var container = document.createElement('div');
  10683. str = str.replace(/(^\s*)|(\s*$)/g, '');
  10684. container.innerHTML = '' + str;
  10685. return container.childNodes[0];
  10686. }
  10687. var Html = /*#__PURE__*/function (_GuideBase) {
  10688. _inheritsLoose(Html, _GuideBase);
  10689. function Html() {
  10690. return _GuideBase.apply(this, arguments) || this;
  10691. }
  10692. var _proto = Html.prototype;
  10693. _proto._initDefaultCfg = function _initDefaultCfg() {
  10694. this.type = 'html';
  10695. /**
  10696. * dom position
  10697. * @type {Object | Array}
  10698. */
  10699. this.position = null;
  10700. /**
  10701. * alignment for horizontal direction,can be 'left','center','right'
  10702. * @type {String}
  10703. */
  10704. this.alignX = 'center';
  10705. /**
  10706. * alignment for vertical direction,can be 'top', 'middle', 'bottom'
  10707. * @type {String}
  10708. */
  10709. this.alignY = 'middle';
  10710. /**
  10711. * offset for horizontal direction
  10712. * @type {Number}
  10713. */
  10714. this.offsetX = null;
  10715. /**
  10716. * offset for vertical direction
  10717. * @type {Number}
  10718. */
  10719. this.offsetY = null;
  10720. /**
  10721. * the html string
  10722. *@type {String | Function}
  10723. */
  10724. this.html = null;
  10725. } // override paint
  10726. ;
  10727. _proto.render = function render(coord, container) {
  10728. var self = this;
  10729. var position = self.parsePoint(coord, self.position);
  10730. if (!position) {
  10731. return;
  10732. }
  10733. var myNode = createDom(self.html);
  10734. myNode = modifyCSS(myNode, {
  10735. position: 'absolute',
  10736. top: Math.floor(position.y) + 'px',
  10737. left: Math.floor(position.x) + 'px',
  10738. visibility: 'hidden'
  10739. });
  10740. var canvasDom = container.get('canvas').get('el');
  10741. var parentNode = canvasDom.parentNode;
  10742. parentNode = modifyCSS(parentNode, {
  10743. position: 'relative'
  10744. });
  10745. var wrapperNode = createDom('<div class="guideWapper" style="position: absolute;top: 0; left: 0;"></div>');
  10746. parentNode.appendChild(wrapperNode);
  10747. wrapperNode.appendChild(myNode);
  10748. var canvasOffsetTop = canvasDom.offsetTop;
  10749. var canvasOffsetLeft = canvasDom.offsetLeft;
  10750. var alignX = self.alignX,
  10751. alignY = self.alignY,
  10752. offsetX = self.offsetX,
  10753. offsetY = self.offsetY;
  10754. var width = getWidth(myNode);
  10755. var height = getHeight(myNode);
  10756. var newOffset = getOffsetFromAlign(alignX, alignY, width, height);
  10757. position.x = position.x + newOffset[0] + canvasOffsetLeft;
  10758. position.y = position.y + newOffset[1] + canvasOffsetTop;
  10759. if (offsetX) {
  10760. position.x += offsetX;
  10761. }
  10762. if (offsetY) {
  10763. position.y += offsetY;
  10764. }
  10765. modifyCSS(myNode, {
  10766. top: Math.floor(position.y) + 'px',
  10767. left: Math.floor(position.x) + 'px',
  10768. visibility: 'visible'
  10769. });
  10770. self.element = wrapperNode;
  10771. };
  10772. _proto.remove = function remove() {
  10773. var element = this.element;
  10774. element && element.parentNode && element.parentNode.removeChild(element);
  10775. };
  10776. return Html;
  10777. }(GuideBase);
  10778. GuideBase.Html = Html;
  10779. var Tag = /*#__PURE__*/function (_GuideBase) {
  10780. _inheritsLoose(Tag, _GuideBase);
  10781. function Tag() {
  10782. return _GuideBase.apply(this, arguments) || this;
  10783. }
  10784. var _proto = Tag.prototype;
  10785. _proto._initDefaultCfg = function _initDefaultCfg() {
  10786. this.type = 'tag';
  10787. this.position = null;
  10788. this.content = null;
  10789. this.direct = 'tl';
  10790. this.autoAdjust = true;
  10791. this.offsetX = 0;
  10792. this.offsetY = 0;
  10793. this.side = 4;
  10794. this.background = {
  10795. padding: 5,
  10796. radius: 2,
  10797. fill: '#1890FF'
  10798. };
  10799. this.textStyle = {
  10800. fontSize: 12,
  10801. fill: '#fff',
  10802. textAlign: 'center',
  10803. textBaseline: 'middle'
  10804. };
  10805. this.withPoint = true;
  10806. this.pointStyle = {
  10807. fill: '#1890FF',
  10808. r: 3,
  10809. lineWidth: 1,
  10810. stroke: '#fff'
  10811. };
  10812. };
  10813. _proto._getDirect = function _getDirect(container, point, tagWidth, tagHeight) {
  10814. var direct = this.direct;
  10815. var side = this.side;
  10816. var canvas = container.get('canvas');
  10817. var clientWidth = canvas.get('width');
  10818. var clientHeight = canvas.get('height');
  10819. var x = point.x,
  10820. y = point.y;
  10821. var vertical = direct[0];
  10822. var horizontal = direct[1]; // adjust for vertical direction
  10823. if (vertical === 't' && y - side - tagHeight < 0) {
  10824. vertical = 'b';
  10825. } else if (vertical === 'b' && y + side + tagHeight > clientHeight) {
  10826. vertical = 't';
  10827. } // adjust for horizontal direction
  10828. var diff = vertical === 'c' ? side : 0;
  10829. if (horizontal === 'l' && x - diff - tagWidth < 0) {
  10830. horizontal = 'r';
  10831. } else if (horizontal === 'r' && x + diff + tagWidth > clientWidth) {
  10832. horizontal = 'l';
  10833. } else if (horizontal === 'c') {
  10834. if (tagWidth / 2 + x + diff > clientWidth) {
  10835. horizontal = 'l';
  10836. } else if (x - tagWidth / 2 - diff < 0) {
  10837. horizontal = 'r';
  10838. }
  10839. }
  10840. direct = vertical + horizontal;
  10841. return direct;
  10842. };
  10843. _proto.render = function render(coord, container) {
  10844. var position = this.parsePoint(coord, this.position);
  10845. if (!position) {
  10846. return;
  10847. } // 数据不在显示范围内时,x/y 会为NaN
  10848. if (isNaN(position.x) || isNaN(position.y)) {
  10849. return;
  10850. }
  10851. var content = this.content,
  10852. background = this.background,
  10853. textStyle = this.textStyle;
  10854. var shapes = [];
  10855. var wrapperContainer = container.addGroup({
  10856. className: 'guide-tag'
  10857. });
  10858. if (this.withPoint) {
  10859. var pointShape = wrapperContainer.addShape('Circle', {
  10860. className: 'guide-tag-point',
  10861. attrs: mix({
  10862. x: position.x,
  10863. y: position.y
  10864. }, this.pointStyle)
  10865. });
  10866. shapes.push(pointShape);
  10867. }
  10868. var tagContainer = wrapperContainer.addGroup(); // create a text shape
  10869. var tagText = tagContainer.addShape('text', {
  10870. className: 'guide-tag-text',
  10871. zIndex: 1,
  10872. attrs: mix({
  10873. x: 0,
  10874. y: 0,
  10875. text: content
  10876. }, textStyle)
  10877. });
  10878. shapes.push(tagText); // create background box
  10879. var textBBox = tagText.getBBox();
  10880. var padding = parsePadding(background.padding);
  10881. var tagWidth = textBBox.width + padding[1] + padding[3];
  10882. var tagHeight = textBBox.height + padding[0] + padding[2];
  10883. var yMin = textBBox.minY - padding[0];
  10884. var xMin = textBBox.minX - padding[3];
  10885. var tagBg = tagContainer.addShape('rect', {
  10886. className: 'guide-tag-bg',
  10887. zIndex: -1,
  10888. attrs: mix({
  10889. x: xMin,
  10890. y: yMin,
  10891. width: tagWidth,
  10892. height: tagHeight
  10893. }, background)
  10894. });
  10895. shapes.push(tagBg);
  10896. var direct = this.autoAdjust ? this._getDirect(container, position, tagWidth, tagHeight) : this.direct;
  10897. var side = this.side;
  10898. var x = position.x + this.offsetX;
  10899. var y = position.y + this.offsetY;
  10900. var arrowPoints;
  10901. var radius = parsePadding(background.radius);
  10902. if (direct === 'tl') {
  10903. arrowPoints = [{
  10904. x: tagWidth + xMin - side - 1,
  10905. y: tagHeight + yMin - 1
  10906. }, // 这个 1 是为了防止出现白边
  10907. {
  10908. x: tagWidth + xMin,
  10909. y: tagHeight + yMin - 1
  10910. }, {
  10911. x: tagWidth + xMin,
  10912. y: tagHeight + side + yMin
  10913. }];
  10914. radius[2] = 0;
  10915. x = x - tagWidth;
  10916. y = y - side - tagHeight;
  10917. } else if (direct === 'cl') {
  10918. arrowPoints = [{
  10919. x: tagWidth + xMin - 1,
  10920. y: (tagHeight - side) / 2 + yMin - 1
  10921. }, {
  10922. x: tagWidth + xMin - 1,
  10923. y: (tagHeight + side) / 2 + yMin + 1
  10924. }, {
  10925. x: tagWidth + side + xMin,
  10926. y: tagHeight / 2 + yMin
  10927. }];
  10928. x = x - tagWidth - side;
  10929. y = y - tagHeight / 2;
  10930. } else if (direct === 'bl') {
  10931. arrowPoints = [{
  10932. x: tagWidth + xMin,
  10933. y: -side + yMin
  10934. }, {
  10935. x: tagWidth + xMin - side - 1,
  10936. y: yMin + 1
  10937. }, {
  10938. x: tagWidth + xMin,
  10939. y: yMin + 1
  10940. }];
  10941. radius[1] = 0;
  10942. x = x - tagWidth;
  10943. y = y + side;
  10944. } else if (direct === 'bc') {
  10945. arrowPoints = [{
  10946. x: tagWidth / 2 + xMin,
  10947. y: -side + yMin
  10948. }, {
  10949. x: (tagWidth - side) / 2 + xMin - 1,
  10950. y: yMin + 1
  10951. }, {
  10952. x: (tagWidth + side) / 2 + xMin + 1,
  10953. y: yMin + 1
  10954. }];
  10955. x = x - tagWidth / 2;
  10956. y = y + side;
  10957. } else if (direct === 'br') {
  10958. arrowPoints = [{
  10959. x: xMin,
  10960. y: yMin - side
  10961. }, {
  10962. x: xMin,
  10963. y: yMin + 1
  10964. }, {
  10965. x: xMin + side + 1,
  10966. y: yMin + 1
  10967. }];
  10968. radius[0] = 0;
  10969. y = y + side;
  10970. } else if (direct === 'cr') {
  10971. arrowPoints = [{
  10972. x: xMin - side,
  10973. y: tagHeight / 2 + yMin
  10974. }, {
  10975. x: xMin + 1,
  10976. y: (tagHeight - side) / 2 + yMin - 1
  10977. }, {
  10978. x: xMin + 1,
  10979. y: (tagHeight + side) / 2 + yMin + 1
  10980. }];
  10981. x = x + side;
  10982. y = y - tagHeight / 2;
  10983. } else if (direct === 'tr') {
  10984. arrowPoints = [{
  10985. x: xMin,
  10986. y: tagHeight + side + yMin
  10987. }, {
  10988. x: xMin,
  10989. y: tagHeight + yMin - 1
  10990. }, {
  10991. x: side + xMin + 1,
  10992. y: tagHeight + yMin - 1
  10993. }];
  10994. radius[3] = 0;
  10995. y = y - tagHeight - side;
  10996. } else if (direct === 'tc') {
  10997. arrowPoints = [{
  10998. x: (tagWidth - side) / 2 + xMin - 1,
  10999. y: tagHeight + yMin - 1
  11000. }, {
  11001. x: (tagWidth + side) / 2 + xMin + 1,
  11002. y: tagHeight + yMin - 1
  11003. }, {
  11004. x: tagWidth / 2 + xMin,
  11005. y: tagHeight + side + yMin
  11006. }];
  11007. x = x - tagWidth / 2;
  11008. y = y - tagHeight - side;
  11009. }
  11010. var sideShape = tagContainer.addShape('Polygon', {
  11011. className: 'guide-tag-side',
  11012. zIndex: 0,
  11013. attrs: {
  11014. points: arrowPoints,
  11015. fill: background.fill
  11016. }
  11017. });
  11018. shapes.push(sideShape);
  11019. tagBg.attr('radius', radius);
  11020. tagContainer.moveTo(x - xMin, y - yMin);
  11021. tagContainer.sort();
  11022. this.element = wrapperContainer;
  11023. return shapes;
  11024. };
  11025. return Tag;
  11026. }(GuideBase);
  11027. GuideBase.Tag = Tag;
  11028. var Point$2 = /*#__PURE__*/function (_GuideBase) {
  11029. _inheritsLoose(Point, _GuideBase);
  11030. function Point() {
  11031. return _GuideBase.apply(this, arguments) || this;
  11032. }
  11033. var _proto = Point.prototype;
  11034. _proto._initDefaultCfg = function _initDefaultCfg() {
  11035. this.type = 'point';
  11036. this.position = null;
  11037. this.offsetX = 0;
  11038. this.offsetY = 0;
  11039. this.style = {
  11040. fill: '#1890FF',
  11041. r: 3,
  11042. lineWidth: 1,
  11043. stroke: '#fff'
  11044. };
  11045. };
  11046. _proto.render = function render(coord, container) {
  11047. var position = this.parsePoint(coord, this.position);
  11048. if (!position) return null;
  11049. var shape = container.addShape('Circle', {
  11050. className: 'guide-point',
  11051. attrs: mix({
  11052. x: position.x + this.offsetX,
  11053. y: position.y + this.offsetY
  11054. }, this.style)
  11055. });
  11056. this.element = shape;
  11057. return shape;
  11058. };
  11059. return Point;
  11060. }(GuideBase);
  11061. GuideBase.Point = Point$2;
  11062. var RegionFilter = /*#__PURE__*/function (_GuideBase) {
  11063. _inheritsLoose(RegionFilter, _GuideBase);
  11064. function RegionFilter() {
  11065. return _GuideBase.apply(this, arguments) || this;
  11066. }
  11067. var _proto = RegionFilter.prototype;
  11068. _proto._initDefaultCfg = function _initDefaultCfg() {
  11069. this.type = 'regionFilter';
  11070. this.start = [];
  11071. this.end = [];
  11072. this.color = null;
  11073. this.style = null;
  11074. };
  11075. _proto.render = function render(coord) {
  11076. var start = this.parsePoint(coord, this.start);
  11077. var end = this.parsePoint(coord, this.end);
  11078. if (!start || !end) {
  11079. return;
  11080. }
  11081. var clip = new Rect({
  11082. attrs: {
  11083. x: Math.min(start.x, end.x),
  11084. y: Math.min(start.y, end.y),
  11085. width: Math.abs(end.x - start.x),
  11086. height: Math.abs(end.y - start.y)
  11087. }
  11088. }); // 新建剪切区域
  11089. this.clip = clip;
  11090. var chart = this.chart;
  11091. var color = this.color;
  11092. var style = this.style || {};
  11093. var regionElements = [];
  11094. var geoms = chart.get('geoms');
  11095. geoms.map(function (geom) {
  11096. var geomContainer = geom.get('container');
  11097. var children = geomContainer.get('children');
  11098. var group = geomContainer.addGroup({
  11099. zIndex: 10,
  11100. className: 'guide-region-filter'
  11101. });
  11102. children.map(function (c) {
  11103. if (c.get('isShape')) {
  11104. var type = c.get('type');
  11105. var attrs = mix({}, c.get('attrs'), style);
  11106. if (color && (attrs.fill || attrs.fillStyle)) {
  11107. attrs.fill = attrs.fillStyle = color;
  11108. }
  11109. if (color && (attrs.stroke || attrs.strokeStyle)) {
  11110. attrs.stroke = attrs.strokeStyle = color;
  11111. }
  11112. var cfg = {
  11113. attrs: attrs
  11114. };
  11115. if (type === 'custom' || type === 'Custom') {
  11116. // custom 类型的 shape 会自定义绘制 path 的逻辑
  11117. cfg.createPath = c.get('createPath');
  11118. cfg.calculateBox = c.get('calculateBox');
  11119. }
  11120. group.addShape(type, cfg);
  11121. }
  11122. return c;
  11123. });
  11124. group.attr('clip', clip);
  11125. geomContainer.sort();
  11126. regionElements.push(group);
  11127. return geom;
  11128. });
  11129. this.element = regionElements;
  11130. };
  11131. _proto.remove = function remove() {
  11132. var element = this.element;
  11133. each(element, function (group) {
  11134. group && group.remove(true);
  11135. });
  11136. this.clip && this.clip.remove(true);
  11137. };
  11138. return RegionFilter;
  11139. }(GuideBase);
  11140. GuideBase.RegionFilter = RegionFilter;
  11141. var MARKER_RADIUS = 3;
  11142. var List = /*#__PURE__*/function () {
  11143. var _proto = List.prototype;
  11144. _proto.getDefaultCfg = function getDefaultCfg() {
  11145. return {
  11146. showTitle: false,
  11147. /**
  11148. * title string
  11149. * @type {?String}
  11150. */
  11151. title: null,
  11152. /**
  11153. * items array
  11154. * @type {?Array}
  11155. */
  11156. items: null,
  11157. /**
  11158. * offset between title and items
  11159. * @type {Number}
  11160. */
  11161. titleGap: 12,
  11162. /**
  11163. * offset between each item
  11164. * @type {Number}
  11165. */
  11166. itemGap: 10,
  11167. /**
  11168. * the offset between each item in vertical direaction
  11169. * @type {Number}
  11170. */
  11171. itemMarginBottom: 12,
  11172. /**
  11173. * the formatter for item text
  11174. * @type {[type]}
  11175. */
  11176. itemFormatter: null,
  11177. itemWidth: null,
  11178. /**
  11179. * offset between marker and text
  11180. * @type {Number}
  11181. */
  11182. wordSpace: 6,
  11183. x: 0,
  11184. y: 0,
  11185. layout: 'horizontal',
  11186. /**
  11187. * the join string of `name` and `value`
  11188. * @type {String}
  11189. */
  11190. joinString: ': '
  11191. };
  11192. };
  11193. function List(cfg) {
  11194. deepMix(this, this.getDefaultCfg(), cfg);
  11195. this._init();
  11196. this._renderTitle();
  11197. this._renderItems();
  11198. }
  11199. _proto._init = function _init() {
  11200. var parent = this.parent;
  11201. if (!parent) return;
  11202. var container = parent.addGroup({
  11203. zIndex: this.zIndex || 0
  11204. });
  11205. this.container = container;
  11206. var wrapper = container.addGroup();
  11207. this.wrapper = wrapper;
  11208. var itemsGroup = wrapper.addGroup({
  11209. className: 'itemsGroup'
  11210. });
  11211. this.itemsGroup = itemsGroup;
  11212. };
  11213. _proto._renderTitle = function _renderTitle(title) {
  11214. title = title || this.title;
  11215. var titleShape = this.titleShape;
  11216. var titleHeight = 0;
  11217. if (this.showTitle && title) {
  11218. if (titleShape && !titleShape.get('destroyed')) {
  11219. titleShape.attr('text', title);
  11220. } else {
  11221. var wrapper = this.wrapper,
  11222. titleStyle = this.titleStyle;
  11223. titleShape = wrapper.addShape('text', {
  11224. className: 'title',
  11225. attrs: mix({
  11226. x: 0,
  11227. y: 0,
  11228. text: title
  11229. }, titleStyle)
  11230. });
  11231. this.titleShape = titleShape;
  11232. }
  11233. titleHeight = titleShape.getBBox().height + this.titleGap;
  11234. }
  11235. this._titleHeight = titleHeight;
  11236. };
  11237. _proto._renderItems = function _renderItems(items) {
  11238. var self = this;
  11239. items = items || self.items;
  11240. if (!items) {
  11241. return;
  11242. }
  11243. if (self.reversed) {
  11244. items.reverse();
  11245. }
  11246. each(items, function (item, index) {
  11247. self._addItem(item, index);
  11248. });
  11249. if (items.length > 1) {
  11250. this._adjustItems();
  11251. }
  11252. this._renderBackground();
  11253. };
  11254. _proto._renderBackground = function _renderBackground() {
  11255. var background = this.background;
  11256. if (background) {
  11257. var container = this.container;
  11258. var wrapper = this.wrapper;
  11259. var _wrapper$getBBox = wrapper.getBBox(),
  11260. minX = _wrapper$getBBox.minX,
  11261. minY = _wrapper$getBBox.minY,
  11262. width = _wrapper$getBBox.width,
  11263. height = _wrapper$getBBox.height;
  11264. var padding = background.padding || [0, 0, 0, 0];
  11265. padding = parsePadding(padding);
  11266. var attrs = mix({
  11267. x: minX - padding[3],
  11268. y: minY - padding[0],
  11269. width: width + padding[1] + padding[3],
  11270. height: height + padding[0] + padding[2]
  11271. }, background);
  11272. var backShape = this.backShape;
  11273. if (backShape) {
  11274. backShape.attr(attrs);
  11275. } else {
  11276. backShape = container.addShape('Rect', {
  11277. zIndex: -1,
  11278. attrs: attrs
  11279. });
  11280. }
  11281. this.backShape = backShape;
  11282. container.sort();
  11283. }
  11284. };
  11285. _proto._addItem = function _addItem(item) {
  11286. var itemsGroup = this.itemsGroup;
  11287. var itemGroup = itemsGroup.addGroup({
  11288. name: item.name,
  11289. value: item.value,
  11290. dataValue: item.dataValue,
  11291. checked: item.checked
  11292. });
  11293. var unCheckStyle = this.unCheckStyle,
  11294. unCheckColor = this.unCheckColor,
  11295. nameStyle = this.nameStyle,
  11296. valueStyle = this.valueStyle,
  11297. wordSpace = this.wordSpace;
  11298. var marker = item.marker,
  11299. value = item.value;
  11300. var startX = 0;
  11301. if (unCheckColor) {
  11302. unCheckStyle.fill = unCheckColor;
  11303. }
  11304. if (marker) {
  11305. var radius = marker.radius || MARKER_RADIUS;
  11306. var markerAttrs = mix({
  11307. x: radius,
  11308. y: this._titleHeight
  11309. }, marker);
  11310. if (item.checked === false) {
  11311. mix(markerAttrs, unCheckStyle);
  11312. }
  11313. var markerShape = itemGroup.addShape('marker', {
  11314. className: 'item-marker',
  11315. attrs: markerAttrs
  11316. });
  11317. startX += markerShape.getBBox().width + wordSpace;
  11318. }
  11319. var nameText;
  11320. var name = item.name;
  11321. if (name) {
  11322. var joinString = this.joinString || '';
  11323. name = value ? name + joinString : name;
  11324. nameText = itemGroup.addShape('text', {
  11325. className: 'name',
  11326. attrs: mix({
  11327. x: startX,
  11328. y: this._titleHeight,
  11329. text: this._formatItemValue(name)
  11330. }, nameStyle, item.checked === false ? unCheckStyle : null)
  11331. });
  11332. }
  11333. if (value) {
  11334. var valueX = startX;
  11335. if (nameText) {
  11336. valueX += nameText.getBBox().width;
  11337. }
  11338. itemGroup.addShape('text', {
  11339. className: 'value',
  11340. attrs: mix({
  11341. x: valueX,
  11342. y: this._titleHeight,
  11343. text: value
  11344. }, valueStyle, item.checked === false ? unCheckStyle : null)
  11345. });
  11346. }
  11347. return itemGroup;
  11348. };
  11349. _proto._formatItemValue = function _formatItemValue(value) {
  11350. var formatter = this.itemFormatter;
  11351. if (formatter) {
  11352. value = formatter.call(this, value);
  11353. }
  11354. return value;
  11355. };
  11356. _proto._getMaxItemWidth = function _getMaxItemWidth() {
  11357. var width;
  11358. var itemWidth = this.itemWidth;
  11359. if (isNumber(itemWidth) || isNil(itemWidth)) {
  11360. return itemWidth;
  11361. }
  11362. if (itemWidth === 'auto') {
  11363. var itemsGroup = this.itemsGroup;
  11364. var children = itemsGroup.get('children');
  11365. var count = children.length;
  11366. var maxItemWidth = 0;
  11367. for (var i = 0; i < count; i++) {
  11368. var _children$i$getBBox = children[i].getBBox(),
  11369. _width = _children$i$getBBox.width;
  11370. maxItemWidth = Math.max(maxItemWidth, _width);
  11371. }
  11372. var maxLength = this.maxLength;
  11373. var itemGap = this.itemGap;
  11374. var twoAvgWidth = (maxLength - itemGap) / 2;
  11375. var threeAvgWidth = (maxLength - itemGap * 2) / 3;
  11376. if (count === 2) {
  11377. width = Math.max(maxItemWidth, twoAvgWidth);
  11378. } else {
  11379. // 1. max <= 3Avg, 3Avg
  11380. // 2. 3Avg < max && max < 2avg, 2avg
  11381. // 3. max > 2avg, max, one column
  11382. if (maxItemWidth <= threeAvgWidth) {
  11383. width = threeAvgWidth;
  11384. } else if (maxItemWidth <= twoAvgWidth) {
  11385. width = twoAvgWidth;
  11386. } else {
  11387. width = maxItemWidth;
  11388. }
  11389. }
  11390. return width;
  11391. }
  11392. };
  11393. _proto._adjustHorizontal = function _adjustHorizontal() {
  11394. var maxLength = this.maxLength,
  11395. itemsGroup = this.itemsGroup;
  11396. var children = itemsGroup.get('children');
  11397. var itemGap = this.itemGap,
  11398. itemMarginBottom = this.itemMarginBottom;
  11399. var titleHeight = this._titleHeight;
  11400. var row = 0;
  11401. var rowWidth = 0;
  11402. var width;
  11403. var height;
  11404. var itemWidth = this._getMaxItemWidth();
  11405. var legendHitBoxes = [];
  11406. for (var i = 0, len = children.length; i < len; i++) {
  11407. var child = children[i];
  11408. var box = child.getBBox();
  11409. var childHeight = box.height;
  11410. var childWidth = box.width;
  11411. width = itemWidth || childWidth;
  11412. height = childHeight + itemMarginBottom;
  11413. if (width - (maxLength - rowWidth) > 0.0001) {
  11414. row++;
  11415. rowWidth = 0;
  11416. }
  11417. child.moveTo(rowWidth, row * height);
  11418. legendHitBoxes.push({
  11419. x: rowWidth,
  11420. y: row * height + titleHeight - childHeight / 2,
  11421. width: childWidth * 1.375,
  11422. height: childHeight * 1.375
  11423. });
  11424. rowWidth += width + itemGap;
  11425. }
  11426. this.legendHitBoxes = legendHitBoxes;
  11427. return;
  11428. };
  11429. _proto._adjustVertical = function _adjustVertical() {
  11430. var maxLength = this.maxLength,
  11431. itemsGroup = this.itemsGroup;
  11432. var itemGap = this.itemGap,
  11433. itemMarginBottom = this.itemMarginBottom,
  11434. itemWidth = this.itemWidth;
  11435. var titleHeight = this._titleHeight;
  11436. var children = itemsGroup.get('children');
  11437. var colHeight = 0;
  11438. var width;
  11439. var height;
  11440. var maxItemWidth = 0;
  11441. var totalWidth = 0;
  11442. var legendHitBoxes = [];
  11443. for (var i = 0, length = children.length; i < length; i++) {
  11444. var child = children[i];
  11445. var bbox = child.getBBox();
  11446. width = bbox.width;
  11447. height = bbox.height;
  11448. if (isNumber(itemWidth)) {
  11449. maxItemWidth = itemWidth + itemGap;
  11450. } else if (width > maxItemWidth) {
  11451. maxItemWidth = width + itemGap;
  11452. }
  11453. if (maxLength - colHeight < height) {
  11454. colHeight = 0;
  11455. totalWidth += maxItemWidth;
  11456. child.moveTo(totalWidth, 0);
  11457. legendHitBoxes.push({
  11458. x: totalWidth,
  11459. y: titleHeight - height / 2,
  11460. width: width * 1.375,
  11461. height: height * 1.375
  11462. });
  11463. } else {
  11464. child.moveTo(totalWidth, colHeight);
  11465. legendHitBoxes.push({
  11466. x: totalWidth,
  11467. y: colHeight - height / 2 + titleHeight,
  11468. width: width * 1.375,
  11469. height: height * 1.375
  11470. });
  11471. }
  11472. colHeight += height + itemMarginBottom;
  11473. }
  11474. this.legendHitBoxes = legendHitBoxes;
  11475. return;
  11476. };
  11477. _proto._adjustItems = function _adjustItems() {
  11478. var layout = this.layout;
  11479. if (layout === 'horizontal') {
  11480. this._adjustHorizontal();
  11481. } else {
  11482. this._adjustVertical();
  11483. }
  11484. };
  11485. _proto.moveTo = function moveTo(x, y) {
  11486. this.x = x;
  11487. this.y = y;
  11488. var container = this.container;
  11489. container && container.moveTo(x, y);
  11490. return this;
  11491. };
  11492. _proto.setItems = function setItems(items) {
  11493. this.clearItems();
  11494. this._renderItems(items);
  11495. };
  11496. _proto.setTitle = function setTitle(title) {
  11497. this._renderTitle(title);
  11498. };
  11499. _proto.clearItems = function clearItems() {
  11500. var itemsGroup = this.itemsGroup;
  11501. itemsGroup.clear();
  11502. };
  11503. _proto.getWidth = function getWidth() {
  11504. var container = this.container;
  11505. var bbox = container.getBBox();
  11506. return bbox.width;
  11507. };
  11508. _proto.getHeight = function getHeight() {
  11509. var container = this.container;
  11510. var bbox = container.getBBox();
  11511. return bbox.height;
  11512. };
  11513. _proto.show = function show() {
  11514. var container = this.container;
  11515. container.show();
  11516. };
  11517. _proto.hide = function hide() {
  11518. var container = this.container;
  11519. container.hide();
  11520. };
  11521. _proto.clear = function clear() {
  11522. var container = this.container;
  11523. container.clear();
  11524. container.remove(true);
  11525. };
  11526. return List;
  11527. }();
  11528. var TextBox = /*#__PURE__*/function () {
  11529. var _proto = TextBox.prototype;
  11530. _proto.getDefaultCfg = function getDefaultCfg() {
  11531. return {
  11532. x: 0,
  11533. y: 0,
  11534. content: '',
  11535. textStyle: {
  11536. fontSize: 12,
  11537. fill: '#fff',
  11538. textAlign: 'center',
  11539. textBaseline: 'middle',
  11540. fontFamily: 'Arial'
  11541. },
  11542. background: {
  11543. radius: 1,
  11544. fill: 'rgba(0, 0, 0, 0.65)',
  11545. padding: [3, 5]
  11546. },
  11547. width: 0,
  11548. height: 0,
  11549. className: ''
  11550. };
  11551. };
  11552. function TextBox(cfg) {
  11553. deepMix(this, this.getDefaultCfg(), cfg);
  11554. this._init();
  11555. var content = this.content,
  11556. x = this.x,
  11557. y = this.y;
  11558. if (!isNil(content)) {
  11559. this.updateContent(content);
  11560. }
  11561. this.updatePosition(x, y);
  11562. }
  11563. _proto._init = function _init() {
  11564. var content = this.content,
  11565. textStyle = this.textStyle,
  11566. background = this.background,
  11567. className = this.className,
  11568. visible = this.visible,
  11569. context = this.context;
  11570. var container = new Group({
  11571. context: context,
  11572. className: className,
  11573. zIndex: 0,
  11574. visible: visible
  11575. });
  11576. var text = container.addShape('Text', {
  11577. className: className + '-text',
  11578. zIndex: 1,
  11579. attrs: mix({
  11580. text: content,
  11581. x: 0,
  11582. y: 0
  11583. }, textStyle)
  11584. });
  11585. var backgroundShape = container.addShape('Rect', {
  11586. className: className + '-bg',
  11587. zIndex: -1,
  11588. attrs: mix({
  11589. x: 0,
  11590. y: 0,
  11591. width: 0,
  11592. height: 0
  11593. }, background)
  11594. });
  11595. container.sort();
  11596. this.container = container;
  11597. this.textShape = text;
  11598. this.backgroundShape = backgroundShape;
  11599. };
  11600. _proto._getBBox = function _getBBox() {
  11601. var textShape = this.textShape;
  11602. var background = this.background;
  11603. var textBBox = textShape.getBBox();
  11604. var padding = parsePadding(background.padding);
  11605. var width = textBBox.width + padding[1] + padding[3];
  11606. var height = textBBox.height + padding[0] + padding[2];
  11607. var x = textBBox.minX - padding[3];
  11608. var y = textBBox.minY - padding[0];
  11609. return {
  11610. x: x,
  11611. y: y,
  11612. width: width,
  11613. height: height
  11614. };
  11615. };
  11616. _proto.updateContent = function updateContent(text) {
  11617. var textShape = this.textShape,
  11618. backgroundShape = this.backgroundShape;
  11619. if (!isNil(text)) {
  11620. if (!isObject(text)) {
  11621. text = {
  11622. text: text
  11623. };
  11624. }
  11625. textShape.attr(text); // update box shape
  11626. var _this$_getBBox = this._getBBox(),
  11627. x = _this$_getBBox.x,
  11628. y = _this$_getBBox.y,
  11629. tipWidth = _this$_getBBox.width,
  11630. tipHeight = _this$_getBBox.height;
  11631. var width = this.width || tipWidth;
  11632. var height = this.height || tipHeight;
  11633. backgroundShape.attr({
  11634. x: x,
  11635. y: y,
  11636. width: width,
  11637. height: height
  11638. });
  11639. this._width = width;
  11640. this._height = height;
  11641. this.content = text.text;
  11642. }
  11643. };
  11644. _proto.updatePosition = function updatePosition(x, y) {
  11645. var container = this.container;
  11646. var _this$_getBBox2 = this._getBBox(),
  11647. xMin = _this$_getBBox2.x,
  11648. yMin = _this$_getBBox2.y;
  11649. container.moveTo(x - xMin, y - yMin);
  11650. this.x = x - xMin;
  11651. this.y = y - yMin;
  11652. };
  11653. _proto.getWidth = function getWidth() {
  11654. return this._width;
  11655. };
  11656. _proto.getHeight = function getHeight() {
  11657. return this._height;
  11658. };
  11659. _proto.show = function show() {
  11660. this.container.show();
  11661. };
  11662. _proto.hide = function hide() {
  11663. this.container.hide();
  11664. };
  11665. _proto.clear = function clear() {
  11666. var container = this.container;
  11667. container.clear();
  11668. container.remove(true);
  11669. this.container = null;
  11670. this.textShape = null;
  11671. this.backgroundShape = null;
  11672. };
  11673. return TextBox;
  11674. }();
  11675. var GAP = 4;
  11676. /**
  11677. * TODOList:
  11678. * 1. 移除 fixed 参数
  11679. */
  11680. var Tooltip = /*#__PURE__*/function () {
  11681. var _proto = Tooltip.prototype;
  11682. _proto.getDefaultCfg = function getDefaultCfg() {
  11683. return {
  11684. /**
  11685. * wether show the crosshairs
  11686. * @type {Object}
  11687. */
  11688. showCrosshairs: false,
  11689. /**
  11690. * the style for crosshairs
  11691. * @type {Object}
  11692. */
  11693. crosshairsStyle: {
  11694. stroke: 'rgba(0, 0, 0, 0.25)',
  11695. lineWidth: 1
  11696. },
  11697. /**
  11698. * the type of crosshairs, optional value is 'x', 'y' or 'xy', default is 'y'
  11699. */
  11700. crosshairsType: 'y',
  11701. /**
  11702. * show or hide the x axis tip
  11703. */
  11704. showXTip: false,
  11705. /**
  11706. * show or hide the y axis tip
  11707. */
  11708. showYTip: false,
  11709. xTip: null,
  11710. xTipBackground: {
  11711. radius: 1,
  11712. fill: 'rgba(0, 0, 0, 0.65)',
  11713. padding: [3, 5]
  11714. },
  11715. xTipTextStyle: {
  11716. fontSize: 12,
  11717. fill: '#fff',
  11718. textAlign: 'center',
  11719. textBaseline: 'middle'
  11720. },
  11721. yTip: null,
  11722. yTipBackground: {
  11723. radius: 1,
  11724. fill: 'rgba(0, 0, 0, 0.65)',
  11725. padding: [3, 5]
  11726. },
  11727. yTipTextStyle: {
  11728. fontSize: 12,
  11729. fill: '#fff',
  11730. textAlign: 'center',
  11731. textBaseline: 'middle'
  11732. },
  11733. /**
  11734. * the style for tooltip container's background
  11735. * @type {Object}
  11736. */
  11737. background: null,
  11738. /**
  11739. * layout, can be horizontal or vertical
  11740. * @type {String}
  11741. */
  11742. layout: 'horizontal',
  11743. offsetX: 0,
  11744. offsetY: 0
  11745. };
  11746. };
  11747. function Tooltip(cfg) {
  11748. deepMix(this, this.getDefaultCfg(), cfg);
  11749. var frontPlot = this.frontPlot,
  11750. custom = this.custom;
  11751. if (!custom) {
  11752. // custom means user do customize
  11753. var container = new List(mix({
  11754. parent: frontPlot,
  11755. zIndex: 3
  11756. }, cfg));
  11757. this.container = container;
  11758. var fixed = this.fixed,
  11759. background = this.background;
  11760. if (!fixed) {
  11761. this.tooltipArrow = frontPlot.addShape('Polygon', {
  11762. className: 'tooltip-arrow',
  11763. visible: false,
  11764. zIndex: 2,
  11765. attrs: mix({
  11766. points: []
  11767. }, background)
  11768. });
  11769. }
  11770. }
  11771. if (this.showXTip) {
  11772. var xTipBackground = this.xTipBackground,
  11773. xTipTextStyle = this.xTipTextStyle;
  11774. var xTipBox = new TextBox({
  11775. context: frontPlot.get('context'),
  11776. className: 'xTip',
  11777. background: xTipBackground,
  11778. textStyle: xTipTextStyle,
  11779. visible: false
  11780. });
  11781. frontPlot.add(xTipBox.container);
  11782. this.xTipBox = xTipBox;
  11783. }
  11784. if (this.showYTip) {
  11785. var yTipBackground = this.yTipBackground,
  11786. yTipTextStyle = this.yTipTextStyle;
  11787. var yTipBox = new TextBox({
  11788. context: frontPlot.get('context'),
  11789. className: 'yTip',
  11790. background: yTipBackground,
  11791. textStyle: yTipTextStyle,
  11792. visible: false
  11793. });
  11794. frontPlot.add(yTipBox.container);
  11795. this.yTipBox = yTipBox;
  11796. }
  11797. if (this.showCrosshairs) {
  11798. this._renderCrosshairs();
  11799. }
  11800. frontPlot.sort();
  11801. }
  11802. _proto.setContent = function setContent(title, items) {
  11803. this.title = title;
  11804. this.items = items;
  11805. if (!this.custom) {
  11806. var container = this.container;
  11807. container.setTitle(title);
  11808. container.setItems(items);
  11809. }
  11810. };
  11811. _proto.setYTipContent = function setYTipContent(val) {
  11812. var yTip = this.yTip;
  11813. if (isFunction(yTip)) {
  11814. val = yTip(val);
  11815. } else {
  11816. val = mix({
  11817. text: val
  11818. }, yTip);
  11819. }
  11820. this.yTipBox && this.yTipBox.updateContent(val);
  11821. };
  11822. _proto.setYTipPosition = function setYTipPosition(pos) {
  11823. var plotRange = this.plotRange;
  11824. var crosshairsShapeX = this.crosshairsShapeX;
  11825. if (this.showYTip) {
  11826. var yTipBox = this.yTipBox;
  11827. var yTipHeight = yTipBox.getHeight();
  11828. var yTipWidth = yTipBox.getWidth();
  11829. var posX = plotRange.tl.x - yTipWidth;
  11830. var posY = pos - yTipHeight / 2;
  11831. if (posY <= plotRange.tl.y) {
  11832. posY = plotRange.tl.y;
  11833. }
  11834. if (posY + yTipHeight >= plotRange.br.y) {
  11835. posY = plotRange.br.y - yTipHeight;
  11836. }
  11837. if (posX < 0) {
  11838. posX = plotRange.tl.x;
  11839. crosshairsShapeX && crosshairsShapeX.attr('x1', plotRange.tl.x + yTipWidth);
  11840. }
  11841. yTipBox.updatePosition(posX, posY);
  11842. }
  11843. };
  11844. _proto.setXTipContent = function setXTipContent(val) {
  11845. var xTip = this.xTip;
  11846. if (isFunction(xTip)) {
  11847. val = xTip(val);
  11848. } else {
  11849. val = mix({
  11850. text: val
  11851. }, xTip);
  11852. }
  11853. this.xTipBox && this.xTipBox.updateContent(val);
  11854. };
  11855. _proto.setXTipPosition = function setXTipPosition(pos) {
  11856. var showXTip = this.showXTip,
  11857. canvas = this.canvas,
  11858. plotRange = this.plotRange,
  11859. xTipBox = this.xTipBox,
  11860. crosshairsShapeY = this.crosshairsShapeY;
  11861. if (showXTip) {
  11862. // const el = canvas.get('el');
  11863. // const canvasHeight = Util.getHeight(el);
  11864. var canvasHeight = canvas.get('height');
  11865. var xTipWidth = xTipBox.getWidth();
  11866. var xTipHeight = xTipBox.getHeight();
  11867. var posX = pos - xTipWidth / 2;
  11868. var posY = plotRange.br.y;
  11869. if (posX <= plotRange.tl.x) {
  11870. posX = plotRange.tl.x;
  11871. }
  11872. if (posX + xTipWidth >= plotRange.tr.x) {
  11873. posX = plotRange.tr.x - xTipWidth;
  11874. }
  11875. if (canvasHeight - posY < xTipHeight) {
  11876. posY -= xTipHeight;
  11877. }
  11878. xTipBox.updatePosition(posX, posY);
  11879. crosshairsShapeY && crosshairsShapeY.attr('y1', posY);
  11880. }
  11881. };
  11882. _proto.setXCrosshairPosition = function setXCrosshairPosition(pos) {
  11883. this.crosshairsShapeX && this.crosshairsShapeX.moveTo(0, pos);
  11884. };
  11885. _proto.setYCrosshairPosition = function setYCrosshairPosition(pos) {
  11886. this.crosshairsShapeY && this.crosshairsShapeY.moveTo(pos, 0);
  11887. };
  11888. _proto.setPosition = function setPosition(items) {
  11889. var container = this.container,
  11890. plotRange = this.plotRange,
  11891. offsetX = this.offsetX,
  11892. offsetY = this.offsetY,
  11893. fixed = this.fixed,
  11894. tooltipArrow = this.tooltipArrow;
  11895. if (!container) {
  11896. return;
  11897. }
  11898. var containerBBox = container.container.getBBox();
  11899. var minX = containerBBox.minX,
  11900. minY = containerBBox.minY,
  11901. width = containerBBox.width,
  11902. height = containerBBox.height;
  11903. var tl = plotRange.tl,
  11904. tr = plotRange.tr;
  11905. var posX = 0;
  11906. var posY = tl.y - height - GAP + offsetY;
  11907. if (posY < 0) {
  11908. posY = 0;
  11909. }
  11910. if (fixed) {
  11911. var x = (tl.x + tr.x) / 2;
  11912. posX = x - width / 2 + offsetX;
  11913. } else {
  11914. var _x;
  11915. if (items.length > 1) {
  11916. _x = (items[0].x + items[items.length - 1].x) / 2;
  11917. } else {
  11918. _x = items[0].x;
  11919. }
  11920. posX = _x - width / 2 + offsetX;
  11921. if (posX < tl.x) {
  11922. posX = tl.x;
  11923. }
  11924. if (posX + width > tr.x) {
  11925. posX = tr.x - width;
  11926. }
  11927. if (tooltipArrow) {
  11928. var arrowY = posY + height;
  11929. tooltipArrow.attr('points', [{
  11930. x: _x - 3,
  11931. y: arrowY
  11932. }, {
  11933. x: _x + 3,
  11934. y: arrowY
  11935. }, {
  11936. x: _x,
  11937. y: arrowY + GAP
  11938. }]);
  11939. var backShape = container.backShape;
  11940. var radius = parsePadding(backShape.attr('radius'));
  11941. if (_x === tl.x) {
  11942. radius[3] = 0;
  11943. tooltipArrow.attr('points', [{
  11944. x: tl.x,
  11945. y: arrowY
  11946. }, {
  11947. x: tl.x + GAP,
  11948. y: arrowY
  11949. }, {
  11950. x: tl.x,
  11951. y: arrowY + GAP
  11952. }]);
  11953. } else if (_x === tr.x) {
  11954. radius[2] = 0;
  11955. tooltipArrow.attr('points', [{
  11956. x: tr.x - GAP,
  11957. y: arrowY
  11958. }, {
  11959. x: tr.x,
  11960. y: arrowY
  11961. }, {
  11962. x: tr.x,
  11963. y: arrowY + GAP
  11964. }]);
  11965. }
  11966. backShape.attr('radius', radius);
  11967. }
  11968. }
  11969. container.moveTo(posX - minX, posY - minY);
  11970. };
  11971. _proto.setMarkers = function setMarkers(cfg) {
  11972. if (cfg === void 0) {
  11973. cfg = {};
  11974. }
  11975. var self = this;
  11976. var _cfg = cfg,
  11977. items = _cfg.items,
  11978. style = _cfg.style,
  11979. type = _cfg.type;
  11980. var markerGroup = self._getMarkerGroup(type);
  11981. if (type === 'circle') {
  11982. for (var i = 0, length = items.length; i < length; i++) {
  11983. var item = items[i];
  11984. markerGroup.addShape('marker', {
  11985. className: 'tooltip-circle-marker',
  11986. attrs: mix({
  11987. x: item.x,
  11988. y: item.y,
  11989. stroke: item.color
  11990. }, style)
  11991. });
  11992. }
  11993. } else {
  11994. markerGroup.addShape('rect', {
  11995. className: 'tooltip-rect-marker',
  11996. attrs: style
  11997. });
  11998. }
  11999. };
  12000. _proto.clearMarkers = function clearMarkers() {
  12001. var markerGroup = this.markerGroup;
  12002. markerGroup && markerGroup.clear();
  12003. };
  12004. _proto.show = function show() {
  12005. var crosshairsShapeX = this.crosshairsShapeX;
  12006. var crosshairsShapeY = this.crosshairsShapeY;
  12007. var markerGroup = this.markerGroup;
  12008. var container = this.container;
  12009. var tooltipArrow = this.tooltipArrow;
  12010. var xTipBox = this.xTipBox;
  12011. var yTipBox = this.yTipBox;
  12012. var canvas = this.canvas;
  12013. crosshairsShapeX && crosshairsShapeX.show();
  12014. crosshairsShapeY && crosshairsShapeY.show();
  12015. markerGroup && markerGroup.show();
  12016. container && container.show();
  12017. tooltipArrow && tooltipArrow.show();
  12018. xTipBox && xTipBox.show();
  12019. yTipBox && yTipBox.show();
  12020. canvas.draw();
  12021. };
  12022. _proto.hide = function hide() {
  12023. var crosshairsShapeX = this.crosshairsShapeX;
  12024. var crosshairsShapeY = this.crosshairsShapeY;
  12025. var markerGroup = this.markerGroup;
  12026. var container = this.container;
  12027. var tooltipArrow = this.tooltipArrow;
  12028. var xTipBox = this.xTipBox;
  12029. var yTipBox = this.yTipBox;
  12030. crosshairsShapeX && crosshairsShapeX.hide();
  12031. crosshairsShapeY && crosshairsShapeY.hide();
  12032. markerGroup && markerGroup.hide();
  12033. container && container.hide();
  12034. tooltipArrow && tooltipArrow.hide();
  12035. xTipBox && xTipBox.hide();
  12036. yTipBox && yTipBox.hide();
  12037. };
  12038. _proto.destroy = function destroy() {
  12039. var crosshairsShapeX = this.crosshairsShapeX;
  12040. var crosshairsShapeY = this.crosshairsShapeY;
  12041. var markerGroup = this.markerGroup;
  12042. var container = this.container;
  12043. var tooltipArrow = this.tooltipArrow;
  12044. var xTipBox = this.xTipBox;
  12045. var yTipBox = this.yTipBox;
  12046. crosshairsShapeX && crosshairsShapeX.remove(true);
  12047. crosshairsShapeY && crosshairsShapeY.remove(true);
  12048. markerGroup && markerGroup.remove(true);
  12049. tooltipArrow && tooltipArrow.remove(true);
  12050. container && container.clear();
  12051. xTipBox && xTipBox.clear();
  12052. yTipBox && yTipBox.clear();
  12053. this.destroyed = true;
  12054. };
  12055. _proto._getMarkerGroup = function _getMarkerGroup(type) {
  12056. var markerGroup = this.markerGroup;
  12057. if (!markerGroup) {
  12058. if (type === 'circle') {
  12059. markerGroup = this.frontPlot.addGroup({
  12060. zIndex: 1
  12061. });
  12062. this.frontPlot.sort();
  12063. } else {
  12064. markerGroup = this.backPlot.addGroup();
  12065. }
  12066. this.markerGroup = markerGroup;
  12067. } else {
  12068. markerGroup.clear();
  12069. }
  12070. return markerGroup;
  12071. };
  12072. _proto._renderCrosshairs = function _renderCrosshairs() {
  12073. var crosshairsType = this.crosshairsType,
  12074. crosshairsStyle = this.crosshairsStyle,
  12075. frontPlot = this.frontPlot,
  12076. plotRange = this.plotRange;
  12077. var tl = plotRange.tl,
  12078. br = plotRange.br;
  12079. if (directionEnabled(crosshairsType, 'x')) {
  12080. this.crosshairsShapeX = frontPlot.addShape('Line', {
  12081. className: 'tooltip-crosshairs-x',
  12082. zIndex: 0,
  12083. visible: false,
  12084. attrs: mix({
  12085. x1: tl.x,
  12086. y1: 0,
  12087. x2: br.x,
  12088. y2: 0
  12089. }, crosshairsStyle)
  12090. });
  12091. }
  12092. if (directionEnabled(crosshairsType, 'y')) {
  12093. this.crosshairsShapeY = frontPlot.addShape('Line', {
  12094. className: 'tooltip-crosshairs-y',
  12095. zIndex: 0,
  12096. visible: false,
  12097. attrs: mix({
  12098. x1: 0,
  12099. y1: br.y,
  12100. x2: 0,
  12101. y2: tl.y
  12102. }, crosshairsStyle)
  12103. });
  12104. }
  12105. };
  12106. return Tooltip;
  12107. }();
  12108. Global.tooltip = deepMix({
  12109. triggerOn: 'press',
  12110. triggerOff: 'pressend',
  12111. alwaysShow: false,
  12112. showTitle: false,
  12113. showCrosshairs: false,
  12114. crosshairsStyle: {
  12115. stroke: 'rgba(0, 0, 0, 0.25)',
  12116. lineWidth: 1
  12117. },
  12118. showTooltipMarker: true,
  12119. background: {
  12120. radius: 1,
  12121. fill: 'rgba(0, 0, 0, 0.65)',
  12122. padding: [3, 5]
  12123. },
  12124. titleStyle: {
  12125. fontSize: 12,
  12126. fill: '#fff',
  12127. textAlign: 'start',
  12128. textBaseline: 'top'
  12129. },
  12130. nameStyle: {
  12131. fontSize: 12,
  12132. fill: 'rgba(255, 255, 255, 0.65)',
  12133. textAlign: 'start',
  12134. textBaseline: 'middle'
  12135. },
  12136. valueStyle: {
  12137. fontSize: 12,
  12138. fill: '#fff',
  12139. textAlign: 'start',
  12140. textBaseline: 'middle'
  12141. },
  12142. showItemMarker: true,
  12143. itemMarkerStyle: {
  12144. radius: 3,
  12145. symbol: 'circle',
  12146. lineWidth: 1,
  12147. stroke: '#fff'
  12148. },
  12149. layout: 'horizontal',
  12150. snap: false
  12151. }, Global.tooltip || {});
  12152. function _getTooltipValueScale(geom) {
  12153. var colorAttr = geom.getAttr('color');
  12154. if (colorAttr) {
  12155. var colorScale = colorAttr.getScale(colorAttr.type);
  12156. if (colorScale.isLinear) {
  12157. return colorScale;
  12158. }
  12159. }
  12160. var xScale = geom.getXScale();
  12161. var yScale = geom.getYScale();
  12162. if (yScale) {
  12163. return yScale;
  12164. }
  12165. return xScale;
  12166. }
  12167. function getTooltipName(geom, origin) {
  12168. var name;
  12169. var nameScale;
  12170. var groupScales = geom._getGroupScales();
  12171. if (groupScales.length) {
  12172. each(groupScales, function (scale) {
  12173. nameScale = scale;
  12174. return false;
  12175. });
  12176. }
  12177. if (nameScale) {
  12178. var field = nameScale.field;
  12179. name = nameScale.getText(origin[field]);
  12180. } else {
  12181. var valueScale = _getTooltipValueScale(geom);
  12182. name = valueScale.alias || valueScale.field;
  12183. }
  12184. return name;
  12185. }
  12186. function getTooltipValue(geom, origin) {
  12187. var scale = _getTooltipValueScale(geom);
  12188. return scale.getText(origin[scale.field]);
  12189. }
  12190. function getTooltipTitle(geom, origin) {
  12191. var position = geom.getAttr('position');
  12192. var field = position.getFields()[0];
  12193. var scale = geom.get('scales')[field];
  12194. return scale.getText(origin[scale.field]);
  12195. }
  12196. function _indexOfArray(items, item) {
  12197. var rst = -1;
  12198. each(items, function (sub, index) {
  12199. if (sub.title === item.title && sub.name === item.name && sub.value === item.value && sub.color === item.color) {
  12200. rst = index;
  12201. return false;
  12202. }
  12203. });
  12204. return rst;
  12205. }
  12206. function _uniqItems(items) {
  12207. var tmp = [];
  12208. each(items, function (item) {
  12209. var index = _indexOfArray(tmp, item);
  12210. if (index === -1) {
  12211. tmp.push(item);
  12212. } else {
  12213. tmp[index] = item;
  12214. }
  12215. });
  12216. return tmp;
  12217. }
  12218. function isEqual$1(arr1, arr2) {
  12219. return JSON.stringify(arr1) === JSON.stringify(arr2);
  12220. }
  12221. var TooltipController = /*#__PURE__*/function () {
  12222. function TooltipController(cfg) {
  12223. var _this = this;
  12224. _defineProperty(this, "handleShowEvent", function (ev) {
  12225. var chart = _this.chart;
  12226. if (!_this.enable) return;
  12227. var plot = chart.get('plotRange');
  12228. var point = createEvent(ev, chart);
  12229. if (!isPointInPlot(point, plot) && !_this._tooltipCfg.alwaysShow) {
  12230. // not in chart plot
  12231. _this.hideTooltip();
  12232. return;
  12233. }
  12234. var lastTimeStamp = _this.timeStamp;
  12235. var timeStamp = +new Date();
  12236. if (timeStamp - lastTimeStamp > 16) {
  12237. _this.showTooltip(point);
  12238. _this.timeStamp = timeStamp;
  12239. }
  12240. });
  12241. _defineProperty(this, "handleHideEvent", function () {
  12242. if (!_this.enable) return;
  12243. _this.hideTooltip();
  12244. });
  12245. this.enable = true;
  12246. this.cfg = {};
  12247. this.tooltip = null;
  12248. this.chart = null;
  12249. this.timeStamp = 0;
  12250. mix(this, cfg);
  12251. var _chart = this.chart;
  12252. var canvas = _chart.get('canvas');
  12253. this.canvas = canvas;
  12254. this.canvasDom = canvas.get('el');
  12255. }
  12256. var _proto = TooltipController.prototype;
  12257. _proto._setCrosshairsCfg = function _setCrosshairsCfg() {
  12258. var self = this;
  12259. var chart = self.chart;
  12260. var defaultCfg = mix({}, Global.tooltip);
  12261. var geoms = chart.get('geoms');
  12262. var shapes = [];
  12263. each(geoms, function (geom) {
  12264. var type = geom.get('type');
  12265. if (shapes.indexOf(type) === -1) {
  12266. shapes.push(type);
  12267. }
  12268. });
  12269. var coordType = chart.get('coord').type;
  12270. if (geoms.length && (coordType === 'cartesian' || coordType === 'rect')) {
  12271. if (shapes.length === 1 && ['line', 'area', 'path', 'point'].indexOf(shapes[0]) !== -1) {
  12272. mix(defaultCfg, {
  12273. showCrosshairs: true
  12274. });
  12275. }
  12276. }
  12277. return defaultCfg;
  12278. };
  12279. _proto._getMaxLength = function _getMaxLength(cfg) {
  12280. if (cfg === void 0) {
  12281. cfg = {};
  12282. }
  12283. var _cfg = cfg,
  12284. layout = _cfg.layout,
  12285. plotRange = _cfg.plotRange;
  12286. return layout === 'horizontal' ? plotRange.br.x - plotRange.bl.x : plotRange.bl.y - plotRange.tr.y;
  12287. };
  12288. _proto.render = function render() {
  12289. var self = this;
  12290. if (self.tooltip) {
  12291. return;
  12292. }
  12293. var chart = self.chart;
  12294. var canvas = chart.get('canvas');
  12295. var frontPlot = chart.get('frontPlot').addGroup({
  12296. className: 'tooltipContainer',
  12297. zIndex: 10
  12298. });
  12299. var backPlot = chart.get('backPlot').addGroup({
  12300. className: 'tooltipContainer'
  12301. });
  12302. var plotRange = chart.get('plotRange');
  12303. var coord = chart.get('coord');
  12304. var defaultCfg = self._setCrosshairsCfg();
  12305. var cfg = self.cfg; // 通过 chart.tooltip() 接口传入的 tooltip 配置项
  12306. var tooltipCfg = deepMix({
  12307. plotRange: plotRange,
  12308. frontPlot: frontPlot,
  12309. backPlot: backPlot,
  12310. canvas: canvas,
  12311. fixed: coord.transposed || coord.isPolar
  12312. }, defaultCfg, cfg); // 创建 tooltip 实例需要的配置,不应该修改 this.cfg,即用户传入的配置
  12313. tooltipCfg.maxLength = self._getMaxLength(tooltipCfg);
  12314. this._tooltipCfg = tooltipCfg;
  12315. var tooltip = new Tooltip(tooltipCfg);
  12316. self.tooltip = tooltip; // 需要保持tooltip一直显示
  12317. if (tooltipCfg.alwaysShow && self.prePoint) {
  12318. this.showTooltip(self.prePoint);
  12319. }
  12320. self.bindEvents();
  12321. };
  12322. _proto.clear = function clear() {
  12323. var tooltip = this.tooltip;
  12324. if (tooltip) {
  12325. tooltip.destroy();
  12326. this.unBindEvents();
  12327. }
  12328. this.tooltip = null;
  12329. this._lastActive = null;
  12330. };
  12331. _proto._getTooltipMarkerStyle = function _getTooltipMarkerStyle(cfg) {
  12332. if (cfg === void 0) {
  12333. cfg = {};
  12334. }
  12335. var _cfg2 = cfg,
  12336. type = _cfg2.type,
  12337. items = _cfg2.items;
  12338. var tooltipCfg = this._tooltipCfg;
  12339. if (type === 'rect') {
  12340. var x;
  12341. var y;
  12342. var width;
  12343. var height;
  12344. var chart = this.chart;
  12345. var _chart$get = chart.get('plotRange'),
  12346. tl = _chart$get.tl,
  12347. br = _chart$get.br;
  12348. var coord = chart.get('coord');
  12349. var firstItem = items[0];
  12350. var lastItem = items[items.length - 1];
  12351. var intervalWidth = firstItem.width;
  12352. if (coord.transposed) {
  12353. x = tl.x;
  12354. y = lastItem.y - intervalWidth * 0.75;
  12355. width = br.x - tl.x;
  12356. height = firstItem.y - lastItem.y + 1.5 * intervalWidth;
  12357. } else {
  12358. x = firstItem.x - intervalWidth * 0.75;
  12359. y = tl.y;
  12360. width = lastItem.x - firstItem.x + 1.5 * intervalWidth;
  12361. height = br.y - tl.y;
  12362. }
  12363. cfg.style = mix({
  12364. x: x,
  12365. y: y,
  12366. width: width,
  12367. height: height,
  12368. fill: '#CCD6EC',
  12369. opacity: 0.3
  12370. }, tooltipCfg.tooltipMarkerStyle);
  12371. } else {
  12372. cfg.style = mix({
  12373. radius: 4,
  12374. fill: '#fff',
  12375. lineWidth: 2
  12376. }, tooltipCfg.tooltipMarkerStyle);
  12377. }
  12378. return cfg;
  12379. };
  12380. _proto._setTooltip = function _setTooltip(point, items, tooltipMarkerCfg) {
  12381. if (tooltipMarkerCfg === void 0) {
  12382. tooltipMarkerCfg = {};
  12383. }
  12384. this.prePoint = point;
  12385. var lastActive = this._lastActive;
  12386. var tooltip = this.tooltip;
  12387. var cfg = this._tooltipCfg;
  12388. items = _uniqItems(items);
  12389. var chart = this.chart;
  12390. var coord = chart.get('coord');
  12391. var yScale = chart.getYScales()[0];
  12392. var snap = cfg.snap;
  12393. if (snap === false && yScale.isLinear) {
  12394. var invertPoint = coord.invertPoint(point);
  12395. var plot = chart.get('plotRange');
  12396. var tip;
  12397. var pos;
  12398. if (isPointInPlot(point, plot)) {
  12399. if (coord.transposed) {
  12400. tip = yScale.invert(invertPoint.x);
  12401. pos = point.x;
  12402. tooltip.setXTipContent(tip);
  12403. tooltip.setXTipPosition(pos);
  12404. tooltip.setYCrosshairPosition(pos);
  12405. } else {
  12406. tip = yScale.invert(invertPoint.y);
  12407. pos = point.y;
  12408. tooltip.setYTipContent(tip);
  12409. tooltip.setYTipPosition(pos);
  12410. tooltip.setXCrosshairPosition(pos);
  12411. }
  12412. }
  12413. }
  12414. if (cfg.onShow) {
  12415. cfg.onShow({
  12416. x: point.x,
  12417. y: point.y,
  12418. tooltip: tooltip,
  12419. items: items,
  12420. tooltipMarkerCfg: tooltipMarkerCfg
  12421. });
  12422. }
  12423. if (isEqual$1(lastActive, items)) {
  12424. if (snap === false && (directionEnabled(cfg.crosshairsType, 'y') || cfg.showYTip)) {
  12425. var canvas = this.chart.get('canvas');
  12426. canvas.draw();
  12427. }
  12428. return;
  12429. }
  12430. this._lastActive = items;
  12431. var onChange = cfg.onChange;
  12432. if (onChange) {
  12433. onChange({
  12434. x: point.x,
  12435. y: point.y,
  12436. tooltip: tooltip,
  12437. items: items,
  12438. tooltipMarkerCfg: tooltipMarkerCfg
  12439. });
  12440. }
  12441. var first = items[0];
  12442. var title = first.title || first.name;
  12443. var xTipPosX = first.x;
  12444. if (items.length > 1) {
  12445. xTipPosX = (items[0].x + items[items.length - 1].x) / 2;
  12446. }
  12447. tooltip.setContent(title, items, coord.transposed);
  12448. tooltip.setPosition(items, point);
  12449. if (coord.transposed) {
  12450. var yTipPosY = first.y;
  12451. if (items.length > 1) {
  12452. yTipPosY = (items[0].y + items[items.length - 1].y) / 2;
  12453. }
  12454. tooltip.setYTipContent(title);
  12455. tooltip.setYTipPosition(yTipPosY);
  12456. tooltip.setXCrosshairPosition(yTipPosY);
  12457. if (snap) {
  12458. tooltip.setXTipContent(first.value);
  12459. tooltip.setXTipPosition(xTipPosX);
  12460. tooltip.setYCrosshairPosition(xTipPosX);
  12461. }
  12462. } else {
  12463. tooltip.setXTipContent(title);
  12464. tooltip.setXTipPosition(xTipPosX);
  12465. tooltip.setYCrosshairPosition(xTipPosX);
  12466. if (snap) {
  12467. tooltip.setYTipContent(first.value);
  12468. tooltip.setYTipPosition(first.y);
  12469. tooltip.setXCrosshairPosition(first.y);
  12470. }
  12471. }
  12472. var markerItems = tooltipMarkerCfg.items;
  12473. if (cfg.showTooltipMarker && markerItems.length) {
  12474. tooltipMarkerCfg = this._getTooltipMarkerStyle(tooltipMarkerCfg);
  12475. tooltip.setMarkers(tooltipMarkerCfg);
  12476. } else {
  12477. tooltip.clearMarkers();
  12478. }
  12479. tooltip.show();
  12480. };
  12481. _proto.showTooltip = function showTooltip(point) {
  12482. var self = this;
  12483. var chart = self.chart;
  12484. var tooltipMarkerType;
  12485. var tooltipMarkerItems = [];
  12486. var items = [];
  12487. var cfg = self._tooltipCfg;
  12488. var showItemMarker = cfg.showItemMarker,
  12489. itemMarkerStyle = cfg.itemMarkerStyle,
  12490. alwaysShow = cfg.alwaysShow;
  12491. var marker;
  12492. if (showItemMarker) {
  12493. marker = itemMarkerStyle;
  12494. }
  12495. var geoms = chart.get('geoms');
  12496. var coord = chart.get('coord');
  12497. each(geoms, function (geom) {
  12498. if (geom.get('visible')) {
  12499. var type = geom.get('type');
  12500. var records = geom.getSnapRecords(point);
  12501. var adjust = geom.get('adjust'); // 漏斗图和金子塔图tooltip位置有问题,暂时不开放显示
  12502. if (type === 'interval' && adjust && adjust.type === 'symmetric') {
  12503. return;
  12504. }
  12505. each(records, function (record) {
  12506. var x = record.x,
  12507. y = record.y,
  12508. _origin = record._origin,
  12509. color = record.color;
  12510. if ((x || !isNaN(x)) && (y || !isNaN(y))) {
  12511. var tooltipItem = {
  12512. x: x,
  12513. y: isArray(y) ? y[1] : y,
  12514. color: color || Global.defaultColor,
  12515. origin: _origin,
  12516. name: getTooltipName(geom, _origin),
  12517. value: getTooltipValue(geom, _origin),
  12518. title: getTooltipTitle(geom, _origin)
  12519. };
  12520. if (marker) {
  12521. tooltipItem.marker = mix({
  12522. fill: color || Global.defaultColor
  12523. }, marker);
  12524. }
  12525. items.push(tooltipItem);
  12526. if (['line', 'area', 'path'].indexOf(type) !== -1) {
  12527. tooltipMarkerType = 'circle';
  12528. tooltipMarkerItems.push(tooltipItem);
  12529. } else if (type === 'interval' && (coord.type === 'cartesian' || coord.type === 'rect')) {
  12530. tooltipMarkerType = 'rect';
  12531. tooltipItem.width = geom.getSize(record._origin);
  12532. tooltipMarkerItems.push(tooltipItem);
  12533. }
  12534. }
  12535. });
  12536. }
  12537. });
  12538. if (items.length) {
  12539. var tooltipMarkerCfg = {
  12540. items: tooltipMarkerItems,
  12541. type: tooltipMarkerType
  12542. };
  12543. self._setTooltip(point, items, tooltipMarkerCfg);
  12544. return;
  12545. }
  12546. if (!alwaysShow) {
  12547. self.hideTooltip();
  12548. }
  12549. };
  12550. _proto.hideTooltip = function hideTooltip() {
  12551. var cfg = this._tooltipCfg;
  12552. this._lastActive = null;
  12553. var tooltip = this.tooltip;
  12554. if (tooltip) {
  12555. tooltip.hide();
  12556. if (cfg.onHide) {
  12557. cfg.onHide({
  12558. tooltip: tooltip
  12559. });
  12560. }
  12561. var canvas = this.chart.get('canvas');
  12562. canvas.draw();
  12563. }
  12564. };
  12565. _proto._handleEvent = function _handleEvent(methodName, method, action) {
  12566. var canvas = this.canvas;
  12567. each([].concat(methodName), function (aMethod) {
  12568. if (action === 'bind') {
  12569. canvas.on(aMethod, method);
  12570. } else {
  12571. canvas.off(aMethod, method);
  12572. }
  12573. });
  12574. };
  12575. _proto.bindEvents = function bindEvents() {
  12576. var cfg = this._tooltipCfg;
  12577. var triggerOn = cfg.triggerOn,
  12578. triggerOff = cfg.triggerOff,
  12579. alwaysShow = cfg.alwaysShow;
  12580. triggerOn && this._handleEvent(triggerOn, this.handleShowEvent, 'bind'); // 如果 !alwaysShow, 则在手势离开后就隐藏
  12581. if (!alwaysShow) {
  12582. this._handleEvent(triggerOff, this.handleHideEvent, 'bind');
  12583. }
  12584. };
  12585. _proto.unBindEvents = function unBindEvents() {
  12586. var cfg = this._tooltipCfg;
  12587. var triggerOn = cfg.triggerOn,
  12588. triggerOff = cfg.triggerOff,
  12589. alwaysShow = cfg.alwaysShow;
  12590. triggerOn && this._handleEvent(triggerOn, this.handleShowEvent, 'unBind');
  12591. if (!alwaysShow) {
  12592. this._handleEvent(triggerOff, this.handleHideEvent, 'unBind');
  12593. }
  12594. };
  12595. return TooltipController;
  12596. }();
  12597. function init(chart) {
  12598. var tooltipController = new TooltipController({
  12599. chart: chart
  12600. });
  12601. chart.set('tooltipController', tooltipController);
  12602. chart.tooltip = function (enable, cfg) {
  12603. if (isObject(enable)) {
  12604. cfg = enable;
  12605. enable = true;
  12606. }
  12607. tooltipController.enable = enable;
  12608. if (cfg) {
  12609. tooltipController.cfg = cfg;
  12610. }
  12611. return this;
  12612. };
  12613. }
  12614. function afterGeomDraw(chart) {
  12615. var tooltipController = chart.get('tooltipController');
  12616. tooltipController.render();
  12617. chart.showTooltip = function (point) {
  12618. tooltipController.showTooltip(point);
  12619. return this;
  12620. };
  12621. chart.hideTooltip = function () {
  12622. tooltipController.hideTooltip();
  12623. return this;
  12624. };
  12625. }
  12626. function clearInner(chart) {
  12627. var tooltipController = chart.get('tooltipController');
  12628. tooltipController.clear();
  12629. }
  12630. var tooltip = {
  12631. init: init,
  12632. afterGeomDraw: afterGeomDraw,
  12633. clearInner: clearInner
  12634. };
  12635. var Tooltip$1 = /*#__PURE__*/Object.freeze({
  12636. __proto__: null,
  12637. init: init,
  12638. afterGeomDraw: afterGeomDraw,
  12639. clearInner: clearInner,
  12640. 'default': tooltip
  12641. });
  12642. Global.guide = deepMix({
  12643. line: {
  12644. style: {
  12645. stroke: '#a3a3a3',
  12646. lineWidth: 1
  12647. },
  12648. top: true
  12649. },
  12650. text: {
  12651. style: {
  12652. fill: '#787878',
  12653. textAlign: 'center',
  12654. textBaseline: 'middle'
  12655. },
  12656. offsetX: 0,
  12657. offsetY: 0,
  12658. top: true
  12659. },
  12660. rect: {
  12661. style: {
  12662. fill: '#fafafa'
  12663. },
  12664. top: false
  12665. },
  12666. arc: {
  12667. style: {
  12668. stroke: '#a3a3a3'
  12669. },
  12670. top: true
  12671. },
  12672. html: {
  12673. offsetX: 0,
  12674. offsetY: 0,
  12675. alignX: 'center',
  12676. alignY: 'middle'
  12677. },
  12678. tag: {
  12679. top: true,
  12680. offsetX: 0,
  12681. offsetY: 0,
  12682. side: 4,
  12683. background: {
  12684. padding: 5,
  12685. radius: 2,
  12686. fill: '#1890FF'
  12687. },
  12688. textStyle: {
  12689. fontSize: 12,
  12690. fill: '#fff',
  12691. textAlign: 'center',
  12692. textBaseline: 'middle'
  12693. }
  12694. },
  12695. point: {
  12696. top: true,
  12697. offsetX: 0,
  12698. offsetY: 0,
  12699. style: {
  12700. fill: '#fff',
  12701. r: 3,
  12702. lineWidth: 2,
  12703. stroke: '#1890ff'
  12704. }
  12705. }
  12706. }, Global.guide || {});
  12707. var GuideController = /*#__PURE__*/function () {
  12708. function GuideController(cfg) {
  12709. this.guides = [];
  12710. this.xScale = null;
  12711. this.yScales = null;
  12712. this.guideShapes = [];
  12713. mix(this, cfg);
  12714. }
  12715. var _proto = GuideController.prototype;
  12716. _proto._toString = function _toString(position) {
  12717. if (isFunction(position)) {
  12718. position = position(this.xScale, this.yScales);
  12719. }
  12720. position = position.toString();
  12721. return position;
  12722. };
  12723. _proto._getId = function _getId(shape, guide) {
  12724. var id = guide.id;
  12725. if (!id) {
  12726. var type = guide.type;
  12727. if (type === 'arc' || type === 'line' || type === 'rect') {
  12728. id = this._toString(guide.start) + '-' + this._toString(guide.end);
  12729. } else {
  12730. id = this._toString(guide.position);
  12731. }
  12732. }
  12733. return id;
  12734. };
  12735. _proto.paint = function paint(coord) {
  12736. var self = this;
  12737. var chart = self.chart,
  12738. guides = self.guides,
  12739. xScale = self.xScale,
  12740. yScales = self.yScales;
  12741. var guideShapes = [];
  12742. each(guides, function (guide, idx) {
  12743. guide.xScale = xScale;
  12744. guide.yScales = yScales;
  12745. var container;
  12746. if (guide.type === 'regionFilter') {
  12747. // TODO: RegionFilter support animation
  12748. guide.chart = chart;
  12749. } else {
  12750. container = guide.top ? self.frontPlot : self.backPlot;
  12751. }
  12752. guide.coord = coord;
  12753. guide.container = container;
  12754. guide.canvas = chart.get('canvas');
  12755. var shape = guide.render(coord, container);
  12756. if (shape) {
  12757. var id = self._getId(shape, guide);
  12758. [].concat(shape).forEach(function (s) {
  12759. s._id = s.get('className') + '-' + id;
  12760. s.set('index', idx);
  12761. guideShapes.push(s);
  12762. });
  12763. }
  12764. });
  12765. self.guideShapes = guideShapes;
  12766. };
  12767. _proto.clear = function clear() {
  12768. this.reset();
  12769. this.guides = [];
  12770. return this;
  12771. };
  12772. _proto.reset = function reset() {
  12773. var guides = this.guides;
  12774. each(guides, function (guide) {
  12775. guide.remove();
  12776. });
  12777. };
  12778. _proto._createGuide = function _createGuide(type, cfg) {
  12779. var ClassName = upperFirst(type);
  12780. var guide = new GuideBase[ClassName](deepMix({}, Global.guide[type], cfg));
  12781. this.guides.push(guide);
  12782. return guide;
  12783. };
  12784. _proto.line = function line(cfg) {
  12785. if (cfg === void 0) {
  12786. cfg = {};
  12787. }
  12788. return this._createGuide('line', cfg);
  12789. };
  12790. _proto.text = function text(cfg) {
  12791. if (cfg === void 0) {
  12792. cfg = {};
  12793. }
  12794. return this._createGuide('text', cfg);
  12795. };
  12796. _proto.arc = function arc(cfg) {
  12797. if (cfg === void 0) {
  12798. cfg = {};
  12799. }
  12800. return this._createGuide('arc', cfg);
  12801. };
  12802. _proto.html = function html(cfg) {
  12803. if (cfg === void 0) {
  12804. cfg = {};
  12805. }
  12806. return this._createGuide('html', cfg);
  12807. };
  12808. _proto.rect = function rect(cfg) {
  12809. if (cfg === void 0) {
  12810. cfg = {};
  12811. }
  12812. return this._createGuide('rect', cfg);
  12813. };
  12814. _proto.tag = function tag(cfg) {
  12815. if (cfg === void 0) {
  12816. cfg = {};
  12817. }
  12818. return this._createGuide('tag', cfg);
  12819. };
  12820. _proto.point = function point(cfg) {
  12821. if (cfg === void 0) {
  12822. cfg = {};
  12823. }
  12824. return this._createGuide('point', cfg);
  12825. };
  12826. _proto.regionFilter = function regionFilter(cfg) {
  12827. if (cfg === void 0) {
  12828. cfg = {};
  12829. }
  12830. return this._createGuide('regionFilter', cfg);
  12831. };
  12832. return GuideController;
  12833. }();
  12834. function init$1(chart) {
  12835. var guideController = new GuideController({
  12836. frontPlot: chart.get('frontPlot').addGroup({
  12837. zIndex: 20,
  12838. className: 'guideContainer'
  12839. }),
  12840. backPlot: chart.get('backPlot').addGroup({
  12841. className: 'guideContainer'
  12842. })
  12843. });
  12844. chart.set('guideController', guideController);
  12845. /**
  12846. * 为图表添加 guide
  12847. * @return {GuideController} 返回 guide 控制器
  12848. */
  12849. chart.guide = function () {
  12850. return guideController;
  12851. };
  12852. }
  12853. function afterGeomDraw$1(chart) {
  12854. var guideController = chart.get('guideController');
  12855. if (!guideController.guides.length) {
  12856. return;
  12857. }
  12858. var xScale = chart.getXScale();
  12859. var yScales = chart.getYScales();
  12860. var coord = chart.get('coord');
  12861. guideController.xScale = xScale;
  12862. guideController.yScales = yScales;
  12863. guideController.chart = chart; // for regionFilter
  12864. guideController.paint(coord);
  12865. }
  12866. function clear(chart) {
  12867. chart.get('guideController').clear();
  12868. }
  12869. function repaint(chart) {
  12870. chart.get('guideController').reset();
  12871. }
  12872. var guide = {
  12873. init: init$1,
  12874. afterGeomDraw: afterGeomDraw$1,
  12875. clear: clear,
  12876. repaint: repaint
  12877. };
  12878. var Guide = /*#__PURE__*/Object.freeze({
  12879. __proto__: null,
  12880. init: init$1,
  12881. afterGeomDraw: afterGeomDraw$1,
  12882. clear: clear,
  12883. repaint: repaint,
  12884. 'default': guide
  12885. });
  12886. var LEGEND_GAP = 12;
  12887. var MARKER_SIZE = 3;
  12888. var DEFAULT_CFG = {
  12889. itemMarginBottom: 12,
  12890. itemGap: 10,
  12891. showTitle: false,
  12892. titleStyle: {
  12893. fontSize: 12,
  12894. fill: '#808080',
  12895. textAlign: 'start',
  12896. textBaseline: 'top'
  12897. },
  12898. nameStyle: {
  12899. fill: '#808080',
  12900. fontSize: 12,
  12901. textAlign: 'start',
  12902. textBaseline: 'middle'
  12903. },
  12904. valueStyle: {
  12905. fill: '#000000',
  12906. fontSize: 12,
  12907. textAlign: 'start',
  12908. textBaseline: 'middle'
  12909. },
  12910. unCheckStyle: {
  12911. fill: '#bfbfbf'
  12912. },
  12913. itemWidth: 'auto',
  12914. wordSpace: 6,
  12915. selectedMode: 'multiple' // 'multiple' or 'single'
  12916. }; // Register the default configuration for Legend
  12917. Global.legend = deepMix({
  12918. common: DEFAULT_CFG,
  12919. // common legend configuration
  12920. right: mix({
  12921. position: 'right',
  12922. layout: 'vertical'
  12923. }, DEFAULT_CFG),
  12924. left: mix({
  12925. position: 'left',
  12926. layout: 'vertical'
  12927. }, DEFAULT_CFG),
  12928. top: mix({
  12929. position: 'top',
  12930. layout: 'horizontal'
  12931. }, DEFAULT_CFG),
  12932. bottom: mix({
  12933. position: 'bottom',
  12934. layout: 'horizontal'
  12935. }, DEFAULT_CFG)
  12936. }, Global.legend || {});
  12937. function getPaddingByPos(pos, appendPadding) {
  12938. var padding = 0;
  12939. appendPadding = parsePadding(appendPadding);
  12940. switch (pos) {
  12941. case 'top':
  12942. padding = appendPadding[0];
  12943. break;
  12944. case 'right':
  12945. padding = appendPadding[1];
  12946. break;
  12947. case 'bottom':
  12948. padding = appendPadding[2];
  12949. break;
  12950. case 'left':
  12951. padding = appendPadding[3];
  12952. break;
  12953. }
  12954. return padding;
  12955. }
  12956. var LegendController = /*#__PURE__*/function () {
  12957. function LegendController(cfg) {
  12958. var _this = this;
  12959. _defineProperty(this, "handleEvent", function (ev) {
  12960. var self = _this;
  12961. function findItem(x, y) {
  12962. var result = null;
  12963. var legends = self.legends;
  12964. each(legends, function (legendItems) {
  12965. each(legendItems, function (legend) {
  12966. var itemsGroup = legend.itemsGroup,
  12967. legendHitBoxes = legend.legendHitBoxes;
  12968. var children = itemsGroup.get('children');
  12969. if (children.length) {
  12970. var legendPosX = legend.x;
  12971. var legendPosY = legend.y;
  12972. each(legendHitBoxes, function (box, index) {
  12973. if (x >= box.x + legendPosX && x <= box.x + box.width + legendPosX && y >= box.y + legendPosY && y <= box.height + box.y + legendPosY) {
  12974. // inbox
  12975. result = {
  12976. clickedItem: children[index],
  12977. clickedLegend: legend
  12978. };
  12979. return false;
  12980. }
  12981. });
  12982. }
  12983. });
  12984. });
  12985. return result;
  12986. }
  12987. var chart = self.chart;
  12988. var _createEvent = createEvent(ev, chart),
  12989. x = _createEvent.x,
  12990. y = _createEvent.y;
  12991. var clicked = findItem(x, y);
  12992. if (clicked && clicked.clickedLegend.clickable !== false) {
  12993. var clickedItem = clicked.clickedItem,
  12994. clickedLegend = clicked.clickedLegend;
  12995. if (clickedLegend.onClick) {
  12996. ev.clickedItem = clickedItem;
  12997. clickedLegend.onClick(ev);
  12998. } else if (!clickedLegend.custom) {
  12999. var checked = clickedItem.get('checked');
  13000. var value = clickedItem.get('dataValue');
  13001. var filteredVals = clickedLegend.filteredVals,
  13002. field = clickedLegend.field,
  13003. selectedMode = clickedLegend.selectedMode;
  13004. var isSingeSelected = selectedMode === 'single';
  13005. if (isSingeSelected) {
  13006. chart.filter(field, function (val) {
  13007. return val === value;
  13008. });
  13009. } else {
  13010. if (checked) {
  13011. filteredVals.push(value);
  13012. } else {
  13013. remove(filteredVals, value);
  13014. }
  13015. chart.filter(field, function (val) {
  13016. return filteredVals.indexOf(val) === -1;
  13017. });
  13018. }
  13019. chart.repaint();
  13020. }
  13021. }
  13022. });
  13023. this.legendCfg = {};
  13024. this.enable = true;
  13025. this.position = 'top';
  13026. mix(this, cfg);
  13027. var _chart = this.chart;
  13028. this.canvasDom = _chart.get('canvas').get('el');
  13029. this.clear();
  13030. }
  13031. var _proto = LegendController.prototype;
  13032. _proto.addLegend = function addLegend(scale, items, filteredVals) {
  13033. var self = this;
  13034. var legendCfg = self.legendCfg;
  13035. var field = scale.field;
  13036. var fieldCfg = legendCfg[field];
  13037. if (fieldCfg === false) {
  13038. return null;
  13039. }
  13040. if (fieldCfg && fieldCfg.custom) {
  13041. self.addCustomLegend(field);
  13042. } else {
  13043. var position = legendCfg.position || self.position;
  13044. if (fieldCfg && fieldCfg.position) {
  13045. position = fieldCfg.position;
  13046. }
  13047. if (scale.isCategory) {
  13048. self._addCategoryLegend(scale, items, position, filteredVals);
  13049. }
  13050. }
  13051. };
  13052. _proto.addCustomLegend = function addCustomLegend(field) {
  13053. var self = this;
  13054. var legendCfg = self.legendCfg;
  13055. if (field && legendCfg[field]) {
  13056. legendCfg = legendCfg[field];
  13057. }
  13058. var position = legendCfg.position || self.position;
  13059. var legends = self.legends;
  13060. legends[position] = legends[position] || [];
  13061. var items = legendCfg.items;
  13062. if (!items) {
  13063. return null;
  13064. }
  13065. var container = self.container;
  13066. each(items, function (item) {
  13067. if (!isPlainObject(item.marker)) {
  13068. item.marker = {
  13069. symbol: item.marker || 'circle',
  13070. fill: item.fill,
  13071. radius: MARKER_SIZE
  13072. };
  13073. } else {
  13074. item.marker.radius = item.marker.radius || MARKER_SIZE;
  13075. }
  13076. item.checked = isNil(item.checked) ? true : item.checked;
  13077. item.name = item.name || item.value;
  13078. });
  13079. var legend = new List(deepMix({}, Global.legend[position], legendCfg, {
  13080. maxLength: self._getMaxLength(position),
  13081. items: items,
  13082. parent: container
  13083. }));
  13084. legends[position].push(legend);
  13085. };
  13086. _proto.clear = function clear() {
  13087. var legends = this.legends;
  13088. each(legends, function (legendItems) {
  13089. each(legendItems, function (legend) {
  13090. legend.clear();
  13091. });
  13092. });
  13093. this.legends = {};
  13094. this.unBindEvents();
  13095. };
  13096. _proto._isFiltered = function _isFiltered(scale, values, value) {
  13097. var rst = false;
  13098. each(values, function (val) {
  13099. rst = rst || scale.getText(val) === scale.getText(value);
  13100. if (rst) {
  13101. return false;
  13102. }
  13103. });
  13104. return rst;
  13105. };
  13106. _proto._getMaxLength = function _getMaxLength(position) {
  13107. var chart = this.chart;
  13108. var appendPadding = parsePadding(chart.get('appendPadding'));
  13109. return position === 'right' || position === 'left' ? chart.get('height') - (appendPadding[0] + appendPadding[2]) : chart.get('width') - (appendPadding[1] + appendPadding[3]);
  13110. };
  13111. _proto._addCategoryLegend = function _addCategoryLegend(scale, items, position, filteredVals) {
  13112. var self = this;
  13113. var legendCfg = self.legendCfg,
  13114. legends = self.legends,
  13115. container = self.container,
  13116. chart = self.chart;
  13117. var field = scale.field;
  13118. legends[position] = legends[position] || [];
  13119. var symbol = 'circle';
  13120. if (legendCfg[field] && legendCfg[field].marker) {
  13121. symbol = legendCfg[field].marker;
  13122. } else if (legendCfg.marker) {
  13123. symbol = legendCfg.marker;
  13124. }
  13125. each(items, function (item) {
  13126. if (isPlainObject(symbol)) {
  13127. mix(item.marker, symbol);
  13128. } else {
  13129. item.marker.symbol = symbol;
  13130. }
  13131. if (filteredVals) {
  13132. item.checked = !self._isFiltered(scale, filteredVals, item.dataValue);
  13133. }
  13134. });
  13135. var legendItems = chart.get('legendItems');
  13136. legendItems[field] = items;
  13137. var lastCfg = deepMix({}, Global.legend[position], legendCfg[field] || legendCfg, {
  13138. maxLength: self._getMaxLength(position),
  13139. items: items,
  13140. field: field,
  13141. filteredVals: filteredVals,
  13142. parent: container
  13143. });
  13144. if (lastCfg.showTitle) {
  13145. deepMix(lastCfg, {
  13146. title: scale.alias || scale.field
  13147. });
  13148. }
  13149. var legend = new List(lastCfg);
  13150. legends[position].push(legend);
  13151. return legend;
  13152. };
  13153. _proto._alignLegend = function _alignLegend(legend, pre, position) {
  13154. var self = this;
  13155. var _self$plotRange = self.plotRange,
  13156. tl = _self$plotRange.tl,
  13157. bl = _self$plotRange.bl;
  13158. var chart = self.chart;
  13159. var offsetX = legend.offsetX || 0;
  13160. var offsetY = legend.offsetY || 0;
  13161. var chartWidth = chart.get('width');
  13162. var chartHeight = chart.get('height');
  13163. var appendPadding = parsePadding(chart.get('appendPadding'));
  13164. var legendHeight = legend.getHeight();
  13165. var legendWidth = legend.getWidth();
  13166. var x = 0;
  13167. var y = 0;
  13168. if (position === 'left' || position === 'right') {
  13169. var verticalAlign = legend.verticalAlign || 'middle';
  13170. var height = Math.abs(tl.y - bl.y);
  13171. x = position === 'left' ? appendPadding[3] : chartWidth - legendWidth - appendPadding[1];
  13172. y = (height - legendHeight) / 2 + tl.y;
  13173. if (verticalAlign === 'top') {
  13174. y = tl.y;
  13175. } else if (verticalAlign === 'bottom') {
  13176. y = bl.y - legendHeight;
  13177. }
  13178. if (pre) {
  13179. y = pre.get('y') - legendHeight - LEGEND_GAP;
  13180. }
  13181. } else {
  13182. var align = legend.align || 'left';
  13183. x = appendPadding[3];
  13184. if (align === 'center') {
  13185. x = chartWidth / 2 - legendWidth / 2;
  13186. } else if (align === 'right') {
  13187. x = chartWidth - (legendWidth + appendPadding[1]);
  13188. }
  13189. y = position === 'top' ? appendPadding[0] + Math.abs(legend.container.getBBox().minY) : chartHeight - legendHeight;
  13190. if (pre) {
  13191. var preWidth = pre.getWidth();
  13192. x = pre.x + preWidth + LEGEND_GAP;
  13193. }
  13194. }
  13195. if (position === 'bottom' && offsetY > 0) {
  13196. offsetY = 0;
  13197. }
  13198. if (position === 'right' && offsetX > 0) {
  13199. offsetX = 0;
  13200. }
  13201. legend.moveTo(x + offsetX, y + offsetY);
  13202. };
  13203. _proto.alignLegends = function alignLegends() {
  13204. var self = this;
  13205. var legends = self.legends;
  13206. each(legends, function (legendItems, position) {
  13207. each(legendItems, function (legend, index) {
  13208. var pre = legendItems[index - 1];
  13209. self._alignLegend(legend, pre, position);
  13210. });
  13211. });
  13212. return self;
  13213. };
  13214. _proto.bindEvents = function bindEvents() {
  13215. var legendCfg = this.legendCfg;
  13216. var triggerOn = legendCfg.triggerOn || 'touchstart';
  13217. addEventListener(this.canvasDom, triggerOn, this.handleEvent);
  13218. };
  13219. _proto.unBindEvents = function unBindEvents() {
  13220. var legendCfg = this.legendCfg;
  13221. var triggerOn = legendCfg.triggerOn || 'touchstart';
  13222. removeEventListener(this.canvasDom, triggerOn, this.handleEvent);
  13223. };
  13224. return LegendController;
  13225. }();
  13226. function init$2(chart) {
  13227. var legendController = new LegendController({
  13228. container: chart.get('backPlot').addGroup(),
  13229. plotRange: chart.get('plotRange'),
  13230. chart: chart
  13231. });
  13232. chart.set('legendController', legendController);
  13233. chart.legend = function (field, cfg) {
  13234. var legendCfg = legendController.legendCfg;
  13235. legendController.enable = true;
  13236. if (isBoolean(field)) {
  13237. legendController.enable = field;
  13238. legendCfg = cfg || {};
  13239. } else if (isObject(field)) {
  13240. legendCfg = field;
  13241. } else {
  13242. legendCfg[field] = cfg;
  13243. }
  13244. legendController.legendCfg = legendCfg;
  13245. return this;
  13246. };
  13247. }
  13248. function beforeGeomDraw(chart) {
  13249. var legendController = chart.get('legendController');
  13250. if (!legendController.enable) return null; // legend is not displayed
  13251. var legendCfg = legendController.legendCfg,
  13252. container = legendController.container;
  13253. if (legendCfg && legendCfg.custom) {
  13254. legendController.addCustomLegend();
  13255. } else {
  13256. var legendItems = chart.getLegendItems();
  13257. var scales = chart.get('scales');
  13258. var filters = chart.get('filters');
  13259. each(legendItems, function (items, field) {
  13260. var scale = scales[field];
  13261. var values = scale.values;
  13262. var filteredVals;
  13263. if (filters && filters[field]) {
  13264. filteredVals = values.filter(function (v) {
  13265. return !filters[field](v);
  13266. });
  13267. } else {
  13268. filteredVals = [];
  13269. }
  13270. legendController.addLegend(scale, items, filteredVals);
  13271. });
  13272. }
  13273. if (legendCfg && legendCfg.clickable !== false) {
  13274. legendController.bindEvents();
  13275. }
  13276. var legends = legendController.legends;
  13277. var legendRange = {
  13278. top: 0,
  13279. right: 0,
  13280. bottom: 0,
  13281. left: 0
  13282. };
  13283. each(legends, function (legendItems, position) {
  13284. var padding = 0;
  13285. each(legendItems, function (legend) {
  13286. var width = legend.getWidth();
  13287. var height = legend.getHeight();
  13288. if (position === 'top' || position === 'bottom') {
  13289. padding = Math.max(padding, height);
  13290. if (legend.offsetY > 0) {
  13291. padding += legend.offsetY;
  13292. }
  13293. } else {
  13294. padding = Math.max(padding, width);
  13295. if (legend.offsetX > 0) {
  13296. padding += legend.offsetX;
  13297. }
  13298. }
  13299. });
  13300. legendRange[position] = padding + getPaddingByPos(position, chart.get('appendPadding'));
  13301. });
  13302. chart.set('legendRange', legendRange);
  13303. if (Object.keys(legends).length) {
  13304. container.set('ariaLabel', lang.legend.prefix);
  13305. } else {
  13306. container.set('ariaLabel', null);
  13307. }
  13308. }
  13309. function afterGeomDraw$2(chart) {
  13310. var legendController = chart.get('legendController');
  13311. legendController.alignLegends();
  13312. }
  13313. function clearInner$1(chart) {
  13314. var legendController = chart.get('legendController');
  13315. legendController.clear();
  13316. chart.set('legendRange', null);
  13317. }
  13318. var legend = {
  13319. init: init$2,
  13320. beforeGeomDraw: beforeGeomDraw,
  13321. afterGeomDraw: afterGeomDraw$2,
  13322. clearInner: clearInner$1
  13323. };
  13324. var Legend = /*#__PURE__*/Object.freeze({
  13325. __proto__: null,
  13326. init: init$2,
  13327. beforeGeomDraw: beforeGeomDraw,
  13328. afterGeomDraw: afterGeomDraw$2,
  13329. clearInner: clearInner$1,
  13330. 'default': legend
  13331. });
  13332. var clock = typeof performance === 'object' && performance.now ? performance : Date;
  13333. var Timeline = /*#__PURE__*/function () {
  13334. function Timeline() {
  13335. this.anims = [];
  13336. this.time = null;
  13337. this.playing = false;
  13338. this.canvas = [];
  13339. }
  13340. var _proto = Timeline.prototype;
  13341. _proto.play = function play() {
  13342. var self = this;
  13343. self.time = clock.now();
  13344. self.playing = true;
  13345. function step() {
  13346. if (self.playing) {
  13347. requestAnimationFrame(step);
  13348. self.update();
  13349. }
  13350. }
  13351. requestAnimationFrame(step);
  13352. };
  13353. _proto.stop = function stop() {
  13354. this.playing = false;
  13355. this.time = null;
  13356. this.canvas = [];
  13357. };
  13358. _proto.pushAnim = function pushAnim(animInfo) {
  13359. // 先启动动画
  13360. if (!this.playing) {
  13361. this.play();
  13362. }
  13363. var delay = animInfo.delay,
  13364. duration = animInfo.duration;
  13365. var startTime = this.time + delay;
  13366. var endTime = startTime + duration;
  13367. animInfo.startTime = startTime;
  13368. animInfo.endTime = endTime;
  13369. this.anims.push(animInfo);
  13370. };
  13371. _proto.update = function update() {
  13372. var currentTime = clock.now();
  13373. this.canvas = [];
  13374. if (!this.anims.length) {
  13375. this.stop();
  13376. return;
  13377. }
  13378. for (var i = 0; i < this.anims.length; i++) {
  13379. var propertyAnim = this.anims[i];
  13380. if (currentTime < propertyAnim.startTime || propertyAnim.hasEnded) {
  13381. continue;
  13382. }
  13383. var shape = propertyAnim.shape; // shape
  13384. if (shape.get('destroyed')) {
  13385. this.anims.splice(i, 1);
  13386. i--;
  13387. continue;
  13388. }
  13389. var startState = propertyAnim.startState,
  13390. endState = propertyAnim.endState,
  13391. interpolate = propertyAnim.interpolate,
  13392. duration = propertyAnim.duration;
  13393. if (currentTime >= propertyAnim.startTime && !propertyAnim.hasStarted) {
  13394. propertyAnim.hasStarted = true;
  13395. if (propertyAnim.onStart) {
  13396. propertyAnim.onStart();
  13397. }
  13398. }
  13399. var t = (currentTime - propertyAnim.startTime) / duration;
  13400. t = Math.max(0, Math.min(t, 1));
  13401. t = propertyAnim.easing(t);
  13402. if (propertyAnim.onFrame) {
  13403. propertyAnim.onFrame(t);
  13404. } else {
  13405. for (var key in interpolate) {
  13406. var diff = interpolate[key];
  13407. var value = diff(t);
  13408. var newValue = void 0;
  13409. if (key === 'points') {
  13410. newValue = [];
  13411. var aLen = Math.max(startState.points.length, endState.points.length);
  13412. for (var j = 0; j < aLen; j += 2) {
  13413. newValue.push({
  13414. x: value[j],
  13415. y: value[j + 1]
  13416. });
  13417. }
  13418. } else {
  13419. newValue = value;
  13420. }
  13421. shape._attrs.attrs[key] = newValue;
  13422. shape._attrs.bbox = null; // should clear calculated bbox
  13423. }
  13424. }
  13425. var canvas = shape.get('canvas');
  13426. if (this.canvas.indexOf(canvas) === -1) {
  13427. this.canvas.push(canvas);
  13428. }
  13429. if (propertyAnim.onUpdate) {
  13430. propertyAnim.onUpdate(t);
  13431. }
  13432. if (currentTime >= propertyAnim.endTime && !propertyAnim.hasEnded) {
  13433. propertyAnim.hasEnded = true;
  13434. if (propertyAnim.onEnd) {
  13435. propertyAnim.onEnd();
  13436. }
  13437. }
  13438. if (t === 1) {
  13439. // end
  13440. this.anims.splice(i, 1);
  13441. i--;
  13442. }
  13443. }
  13444. this.canvas.map(function (c) {
  13445. c.draw();
  13446. return c;
  13447. });
  13448. this.time = clock.now();
  13449. };
  13450. return Timeline;
  13451. }();
  13452. function linear$1(k) {
  13453. return k;
  13454. }
  13455. function quadraticIn(k) {
  13456. return k * k;
  13457. }
  13458. function quadraticOut(k) {
  13459. return k * (2 - k);
  13460. }
  13461. function quadraticInOut(k) {
  13462. if ((k *= 2) < 1) {
  13463. return 0.5 * k * k;
  13464. }
  13465. return -0.5 * (--k * (k - 2) - 1);
  13466. }
  13467. function cubicIn(k) {
  13468. return k * k * k;
  13469. }
  13470. function cubicOut(k) {
  13471. return --k * k * k + 1;
  13472. }
  13473. function cubicInOut(k) {
  13474. if ((k *= 2) < 1) {
  13475. return 0.5 * k * k * k;
  13476. }
  13477. return 0.5 * ((k -= 2) * k * k + 2);
  13478. }
  13479. function elasticIn(k) {
  13480. var s;
  13481. var a = 0.1;
  13482. var p = 0.4;
  13483. if (k === 0) return 0;
  13484. if (k === 1) return 1;
  13485. if (!a || a < 1) {
  13486. a = 1;
  13487. s = p / 4;
  13488. } else {
  13489. s = p / (2 * Math.PI) * Math.asin(1 / a);
  13490. }
  13491. return -(a * Math.pow(2, 10 * (k -= 1)) * Math.sin((k - s) * (2 * Math.PI) / p));
  13492. }
  13493. function elasticOut(k) {
  13494. var s;
  13495. var a = 0.1;
  13496. var p = 0.4;
  13497. if (k === 0) return 0;
  13498. if (k === 1) return 1;
  13499. if (!a || a < 1) {
  13500. a = 1;
  13501. s = p / 4;
  13502. } else {
  13503. s = p / (2 * Math.PI) * Math.asin(1 / a);
  13504. }
  13505. return a * Math.pow(2, -10 * k) * Math.sin((k - s) * (2 * Math.PI) / p) + 1;
  13506. }
  13507. function elasticInOut(k) {
  13508. var s;
  13509. var a = 0.1;
  13510. var p = 0.4;
  13511. if (k === 0) return 0;
  13512. if (k === 1) return 1;
  13513. if (!a || a < 1) {
  13514. a = 1;
  13515. s = p / 4;
  13516. } else {
  13517. s = p / (2 * Math.PI) * Math.asin(1 / a);
  13518. }
  13519. if ((k *= 2) < 1) {
  13520. return -0.5 * (a * Math.pow(2, 10 * (k -= 1)) * Math.sin((k - s) * (2 * Math.PI) / p));
  13521. }
  13522. return a * Math.pow(2, -10 * (k -= 1)) * Math.sin((k - s) * (2 * Math.PI) / p) * 0.5 + 1;
  13523. }
  13524. function backIn(k) {
  13525. var s = 1.70158;
  13526. return k * k * ((s + 1) * k - s);
  13527. }
  13528. function backOut(k) {
  13529. var s = 1.70158;
  13530. return (k = k - 1) * k * ((s + 1) * k + s) + 1;
  13531. }
  13532. function backInOut(k) {
  13533. var s = 1.70158 * 1.525;
  13534. if ((k *= 2) < 1) {
  13535. return 0.5 * (k * k * ((s + 1) * k - s));
  13536. }
  13537. return 0.5 * ((k -= 2) * k * ((s + 1) * k + s) + 2);
  13538. }
  13539. function bounceIn(k) {
  13540. return 1 - bounceOut(1 - k);
  13541. }
  13542. function bounceOut(k) {
  13543. if ((k /= 1) < 1 / 2.75) {
  13544. return 7.5625 * k * k;
  13545. } else if (k < 2 / 2.75) {
  13546. return 7.5625 * (k -= 1.5 / 2.75) * k + 0.75;
  13547. } else if (k < 2.5 / 2.75) {
  13548. return 7.5625 * (k -= 2.25 / 2.75) * k + 0.9375;
  13549. }
  13550. return 7.5625 * (k -= 2.625 / 2.75) * k + 0.984375;
  13551. }
  13552. function bounceInOut(k) {
  13553. if (k < 0.5) {
  13554. return bounceIn(k * 2) * 0.5;
  13555. }
  13556. return bounceOut(k * 2 - 1) * 0.5 + 0.5;
  13557. }
  13558. var Easing = /*#__PURE__*/Object.freeze({
  13559. __proto__: null,
  13560. linear: linear$1,
  13561. quadraticIn: quadraticIn,
  13562. quadraticOut: quadraticOut,
  13563. quadraticInOut: quadraticInOut,
  13564. cubicIn: cubicIn,
  13565. cubicOut: cubicOut,
  13566. cubicInOut: cubicInOut,
  13567. elasticIn: elasticIn,
  13568. elasticOut: elasticOut,
  13569. elasticInOut: elasticInOut,
  13570. backIn: backIn,
  13571. backOut: backOut,
  13572. backInOut: backInOut,
  13573. bounceIn: bounceIn,
  13574. bounceOut: bounceOut,
  13575. bounceInOut: bounceInOut
  13576. });
  13577. function plainArray(arr) {
  13578. var result = [];
  13579. for (var i = 0, len = arr.length; i < len; i++) {
  13580. if (arr[i]) {
  13581. result.push(arr[i].x);
  13582. result.push(arr[i].y);
  13583. }
  13584. }
  13585. return result;
  13586. }
  13587. function interpolateNumber(a, b) {
  13588. a = +a;
  13589. b -= a;
  13590. return function (t) {
  13591. return a + b * t;
  13592. };
  13593. }
  13594. function interpolateArray(a, b) {
  13595. var nb = b ? b.length : 0;
  13596. var na = a ? Math.min(nb, a.length) : 0;
  13597. var x = new Array(na);
  13598. var c = new Array(nb);
  13599. var i;
  13600. for (i = 0; i < na; ++i) {
  13601. x[i] = interpolateNumber(a[i], b[i]);
  13602. }
  13603. for (; i < nb; ++i) {
  13604. c[i] = b[i];
  13605. }
  13606. return function (t) {
  13607. for (i = 0; i < na; ++i) {
  13608. c[i] = x[i](t);
  13609. }
  13610. return c;
  13611. };
  13612. }
  13613. var Animator = /*#__PURE__*/function () {
  13614. function Animator(shape, source, timeline) {
  13615. this.hasStarted = false;
  13616. this.hasEnded = false;
  13617. this.shape = shape;
  13618. this.source = source;
  13619. this.timeline = timeline;
  13620. this.animate = null;
  13621. } // delay, attrs, duration, easing
  13622. var _proto = Animator.prototype;
  13623. _proto.to = function to(cfg) {
  13624. if (cfg === void 0) {
  13625. cfg = {};
  13626. }
  13627. var delay = cfg.delay || 0;
  13628. var attrs = cfg.attrs || {};
  13629. var duration = cfg.duration || 1000;
  13630. var easing; // 缓动函数
  13631. if (typeof cfg.easing === 'function') {
  13632. easing = cfg.easing;
  13633. } else {
  13634. easing = Easing[cfg.easing] || linear$1;
  13635. }
  13636. var animInfo = {
  13637. shape: this.shape,
  13638. delay: delay,
  13639. duration: duration,
  13640. easing: easing
  13641. };
  13642. var interpolate = {}; // 差值函数
  13643. for (var attrName in attrs) {
  13644. var startValue = this.source[attrName];
  13645. var endValue = attrs[attrName];
  13646. if (attrName === 'points') {
  13647. startValue = plainArray(startValue);
  13648. endValue = plainArray(endValue);
  13649. interpolate.points = interpolateArray(startValue, endValue);
  13650. this.source.points = startValue;
  13651. attrs.points = endValue;
  13652. } else if (attrName === 'matrix') {
  13653. interpolate.matrix = interpolateArray(startValue, endValue);
  13654. } else {
  13655. interpolate[attrName] = interpolateNumber(startValue, endValue);
  13656. }
  13657. }
  13658. animInfo.interpolate = interpolate;
  13659. animInfo.startState = this.source;
  13660. animInfo.endState = attrs;
  13661. this.timeline.pushAnim(animInfo);
  13662. this.animate = animInfo;
  13663. return this;
  13664. };
  13665. _proto.onFrame = function onFrame(callback) {
  13666. // 自定义每一帧动画的动作
  13667. if (this.animate) {
  13668. this.animate.onFrame = function (frame) {
  13669. callback(frame);
  13670. };
  13671. }
  13672. return this;
  13673. };
  13674. _proto.onStart = function onStart(callback) {
  13675. if (this.animate) {
  13676. this.animate.onStart = function () {
  13677. callback();
  13678. };
  13679. }
  13680. return this;
  13681. };
  13682. _proto.onUpdate = function onUpdate(callback) {
  13683. if (this.animate) {
  13684. this.animate.onUpdate = function (frame) {
  13685. callback(frame);
  13686. };
  13687. }
  13688. return this;
  13689. };
  13690. _proto.onEnd = function onEnd(callback) {
  13691. if (this.animate) {
  13692. this.animate.onEnd = function () {
  13693. callback();
  13694. };
  13695. }
  13696. return this;
  13697. };
  13698. return Animator;
  13699. }();
  13700. var defaultAnimationCfg = {
  13701. appear: {
  13702. duration: 450,
  13703. easing: 'quadraticOut'
  13704. },
  13705. // 'appear' animation options
  13706. update: {
  13707. duration: 300,
  13708. easing: 'quadraticOut'
  13709. },
  13710. // 'update' animation options
  13711. enter: {
  13712. duration: 300,
  13713. easing: 'quadraticOut'
  13714. },
  13715. // 'enter' animation options
  13716. leave: {
  13717. duration: 350,
  13718. easing: 'quadraticIn'
  13719. } // 'leave' animation options
  13720. };
  13721. var Animate = {
  13722. defaultCfg: {},
  13723. Action: {},
  13724. getAnimation: function getAnimation(geomType, coord, animationType) {
  13725. var geomAnimateCfg = this.defaultCfg[geomType];
  13726. if (geomAnimateCfg) {
  13727. var animation = geomAnimateCfg[animationType];
  13728. if (isFunction(animation)) {
  13729. return animation(coord);
  13730. }
  13731. }
  13732. return false;
  13733. },
  13734. getAnimateCfg: function getAnimateCfg(geomType, animationType) {
  13735. var defaultCfg = defaultAnimationCfg[animationType];
  13736. var geomConfig = this.defaultCfg[geomType];
  13737. if (geomConfig && geomConfig.cfg && geomConfig.cfg[animationType]) {
  13738. return deepMix({}, defaultCfg, geomConfig.cfg[animationType]);
  13739. }
  13740. return defaultCfg;
  13741. },
  13742. registerAnimation: function registerAnimation(animationName, animationFun) {
  13743. var _extends2;
  13744. if (!this.Action) {
  13745. this.Action = {};
  13746. }
  13747. this.Action = _extends({}, this.Action, (_extends2 = {}, _extends2[animationName] = animationFun, _extends2));
  13748. }
  13749. };
  13750. /**
  13751. * Utility
  13752. * @author sima.zhang1990@gmail.com
  13753. */
  13754. function getCoordInfo(coord) {
  13755. var start = coord.start;
  13756. var end = coord.end;
  13757. return {
  13758. start: start,
  13759. end: end,
  13760. width: end.x - start.x,
  13761. height: Math.abs(end.y - start.y)
  13762. };
  13763. }
  13764. function getScaledMatrix(shape, v, direct) {
  13765. var scaledMatrix;
  13766. shape.apply(v);
  13767. var x = v[0];
  13768. var y = v[1];
  13769. if (direct === 'x') {
  13770. shape.transform([['t', x, y], ['s', 0.01, 1], ['t', -x, -y]]);
  13771. var matrix = shape.getMatrix();
  13772. scaledMatrix = Matrix.transform(matrix, [['t', x, y], ['s', 100, 1], ['t', -x, -y]]);
  13773. } else if (direct === 'y') {
  13774. shape.transform([['t', x, y], ['s', 1, 0.01], ['t', -x, -y]]);
  13775. var _matrix = shape.getMatrix();
  13776. scaledMatrix = Matrix.transform(_matrix, [['t', x, y], ['s', 1, 100], ['t', -x, -y]]);
  13777. } else if (direct === 'xy') {
  13778. shape.transform([['t', x, y], ['s', 0.01, 0.01], ['t', -x, -y]]);
  13779. var _matrix2 = shape.getMatrix();
  13780. scaledMatrix = Matrix.transform(_matrix2, [['t', x, y], ['s', 100, 100], ['t', -x, -y]]);
  13781. }
  13782. return scaledMatrix;
  13783. }
  13784. function getAnimateParam(animateCfg, index, id) {
  13785. var result = {};
  13786. if (animateCfg.delay) {
  13787. result.delay = isFunction(animateCfg.delay) ? animateCfg.delay(index, id) : animateCfg.delay;
  13788. }
  13789. result.easing = animateCfg.easing;
  13790. result.duration = animateCfg.duration;
  13791. result.delay = animateCfg.delay;
  13792. return result;
  13793. }
  13794. function doAnimation(shape, endState, animateCfg, callback) {
  13795. var id = shape._id;
  13796. var index = shape.get('index');
  13797. var _getAnimateParam = getAnimateParam(animateCfg, index, id),
  13798. easing = _getAnimateParam.easing,
  13799. delay = _getAnimateParam.delay,
  13800. duration = _getAnimateParam.duration;
  13801. var anim = shape.animate().to({
  13802. attrs: endState,
  13803. duration: duration,
  13804. delay: delay,
  13805. easing: easing
  13806. });
  13807. if (callback) {
  13808. anim.onEnd(function () {
  13809. callback();
  13810. });
  13811. }
  13812. }
  13813. /**
  13814. * Animation functions for shape
  13815. * @author sima.zhang1990@gmail.com
  13816. */
  13817. /*
  13818. function waveIn(shape, animateCfg, coord) {
  13819. const clip = Helpers.getClip(coord);
  13820. clip.set('canvas', shape.get('canvas'));
  13821. shape.attr('clip', clip);
  13822. const onEnd = function() {
  13823. shape.attr('clip', null);
  13824. clip.remove(true);
  13825. };
  13826. Helpers.doAnimation(clip, clip.endState, animateCfg, onEnd);
  13827. }
  13828. function scaleInX(shape, animateCfg) {
  13829. const box = shape.getBBox();
  13830. const points = shape.get('origin').points;
  13831. let x;
  13832. const y = (box.minY + box.maxY) / 2;
  13833. if (points[0].y - points[1].y > 0) { // 当顶点在零点之下
  13834. x = box.maxX;
  13835. } else {
  13836. x = box.minX;
  13837. }
  13838. const scaledMatrix = Helpers.getScaledMatrix(shape, [ x, y ], 'x');
  13839. Helpers.doAnimation(shape, { matrix: scaledMatrix }, animateCfg);
  13840. }
  13841. function scaleInY(shape, animateCfg) {
  13842. const box = shape.getBBox();
  13843. const points = shape.get('origin').points;
  13844. const x = (box.minX + box.maxX) / 2;
  13845. let y;
  13846. if (points[0].y - points[1].y <= 0) { // 当顶点在零点之下
  13847. y = box.maxY;
  13848. } else {
  13849. y = box.minY;
  13850. }
  13851. const scaledMatrix = Helpers.getScaledMatrix(shape, [ x, y ], 'x');
  13852. Helpers.doAnimation(shape, { matrix: scaledMatrix }, animateCfg);
  13853. }
  13854. */
  13855. function fadeIn(shape, animateCfg) {
  13856. var fillOpacity = isNil(shape.attr('fillOpacity')) ? 1 : shape.attr('fillOpacity');
  13857. var strokeOpacity = isNil(shape.attr('strokeOpacity')) ? 1 : shape.attr('strokeOpacity');
  13858. shape.attr('fillOpacity', 0);
  13859. shape.attr('strokeOpacity', 0);
  13860. var endState = {
  13861. fillOpacity: fillOpacity,
  13862. strokeOpacity: strokeOpacity
  13863. };
  13864. doAnimation(shape, endState, animateCfg);
  13865. }
  13866. var ShapeAction = /*#__PURE__*/Object.freeze({
  13867. __proto__: null,
  13868. fadeIn: fadeIn
  13869. });
  13870. /**
  13871. * Group animate functions
  13872. * @author sima.zhang1990@gmail.com
  13873. */
  13874. function _groupScaleIn(container, animateCfg, coord, zeroY, type) {
  13875. var _getCoordInfo = getCoordInfo(coord),
  13876. start = _getCoordInfo.start,
  13877. end = _getCoordInfo.end,
  13878. width = _getCoordInfo.width,
  13879. height = _getCoordInfo.height;
  13880. var x;
  13881. var y;
  13882. var clip = new Shape$2.Rect({
  13883. attrs: {
  13884. x: start.x,
  13885. y: end.y,
  13886. width: width,
  13887. height: height
  13888. }
  13889. });
  13890. if (type === 'y') {
  13891. x = start.x + width / 2;
  13892. y = zeroY.y < start.y ? zeroY.y : start.y;
  13893. } else if (type === 'x') {
  13894. x = zeroY.x > start.x ? zeroY.x : start.x;
  13895. y = start.y + height / 2;
  13896. } else if (type === 'xy') {
  13897. if (coord.isPolar) {
  13898. x = coord.center.x;
  13899. y = coord.center.y;
  13900. } else {
  13901. x = (start.x + end.x) / 2;
  13902. y = (start.y + end.y) / 2;
  13903. }
  13904. }
  13905. var endMatrix = getScaledMatrix(clip, [x, y], type);
  13906. clip.isClip = true;
  13907. clip.endState = {
  13908. matrix: endMatrix
  13909. };
  13910. clip.set('canvas', container.get('canvas'));
  13911. container.attr('clip', clip);
  13912. var onEnd = function onEnd() {
  13913. container.attr('clip', null);
  13914. clip.remove(true);
  13915. };
  13916. doAnimation(clip, clip.endState, animateCfg, onEnd);
  13917. }
  13918. function _shapeScale(container, animateCfg, type) {
  13919. var shapes = container.get('children');
  13920. var x;
  13921. var y;
  13922. var endMatrix;
  13923. for (var i = 0, len = shapes.length; i < len; i++) {
  13924. var shape = shapes[i];
  13925. var box = shape.getBBox();
  13926. x = (box.minX + box.maxX) / 2;
  13927. y = (box.minY + box.maxY) / 2;
  13928. endMatrix = getScaledMatrix(shape, [x, y], type);
  13929. doAnimation(shape, {
  13930. matrix: endMatrix
  13931. }, animateCfg);
  13932. }
  13933. }
  13934. function groupScaleInX(container, animateCfg, coord, zeroY) {
  13935. _groupScaleIn(container, animateCfg, coord, zeroY, 'x');
  13936. }
  13937. function groupScaleInY(container, animateCfg, coord, zeroY) {
  13938. _groupScaleIn(container, animateCfg, coord, zeroY, 'y');
  13939. }
  13940. function groupScaleInXY(container, animateCfg, coord, zeroY) {
  13941. _groupScaleIn(container, animateCfg, coord, zeroY, 'xy');
  13942. }
  13943. function shapesScaleInX(container, animateCfg) {
  13944. _shapeScale(container, animateCfg, 'x');
  13945. }
  13946. function shapesScaleInY(container, animateCfg) {
  13947. _shapeScale(container, animateCfg, 'y');
  13948. }
  13949. function shapesScaleInXY(container, animateCfg) {
  13950. _shapeScale(container, animateCfg, 'xy');
  13951. }
  13952. function groupWaveIn(container, animateCfg, coord) {
  13953. var clip = getClip(coord);
  13954. clip.set('canvas', container.get('canvas'));
  13955. container.attr('clip', clip);
  13956. var onEnd = function onEnd() {
  13957. container.attr('clip', null);
  13958. clip.remove(true);
  13959. };
  13960. var endState = {};
  13961. if (coord.isPolar) {
  13962. var startAngle = coord.startAngle,
  13963. endAngle = coord.endAngle;
  13964. endState.endAngle = endAngle;
  13965. clip.attr('endAngle', startAngle);
  13966. } else {
  13967. var start = coord.start,
  13968. end = coord.end;
  13969. var width = Math.abs(start.x - end.x);
  13970. var height = Math.abs(start.y - end.y);
  13971. if (coord.isTransposed) {
  13972. clip.attr('height', 0);
  13973. endState.height = height;
  13974. } else {
  13975. clip.attr('width', 0);
  13976. endState.width = width;
  13977. }
  13978. }
  13979. doAnimation(clip, endState, animateCfg, onEnd);
  13980. }
  13981. var GroupAction = /*#__PURE__*/Object.freeze({
  13982. __proto__: null,
  13983. groupWaveIn: groupWaveIn,
  13984. groupScaleInX: groupScaleInX,
  13985. groupScaleInY: groupScaleInY,
  13986. groupScaleInXY: groupScaleInXY,
  13987. shapesScaleInX: shapesScaleInX,
  13988. shapesScaleInY: shapesScaleInY,
  13989. shapesScaleInXY: shapesScaleInXY
  13990. });
  13991. /**
  13992. * Handle the detail animations
  13993. * @author sima.zhang1990@gmail.com
  13994. */
  13995. var timeline;
  13996. Element.prototype.animate = function () {
  13997. var attrs = mix({}, this.get('attrs'));
  13998. return new Animator(this, attrs, timeline);
  13999. };
  14000. Chart.prototype.animate = function (cfg) {
  14001. this.set('animate', cfg);
  14002. return this;
  14003. };
  14004. Animate.Action = ShapeAction;
  14005. Animate.defaultCfg = {
  14006. interval: {
  14007. enter: function enter(coord) {
  14008. if (coord.isPolar && coord.transposed) {
  14009. // for pie chart
  14010. return function (shape) {
  14011. shape.set('zIndex', -1);
  14012. var container = shape.get('parent');
  14013. container.sort();
  14014. };
  14015. }
  14016. return fadeIn;
  14017. }
  14018. },
  14019. area: {
  14020. enter: function enter(coord) {
  14021. if (coord.isPolar) return null;
  14022. return fadeIn;
  14023. }
  14024. },
  14025. line: {
  14026. enter: function enter(coord) {
  14027. if (coord.isPolar) return null;
  14028. return fadeIn;
  14029. }
  14030. },
  14031. path: {
  14032. enter: function enter(coord) {
  14033. if (coord.isPolar) return null;
  14034. return fadeIn;
  14035. }
  14036. }
  14037. };
  14038. var GROUP_ANIMATION = {
  14039. line: function line(coord) {
  14040. if (coord.isPolar) {
  14041. return groupScaleInXY;
  14042. }
  14043. return groupWaveIn;
  14044. },
  14045. area: function area(coord) {
  14046. if (coord.isPolar) {
  14047. return groupScaleInXY;
  14048. }
  14049. return groupWaveIn;
  14050. },
  14051. path: function path(coord) {
  14052. if (coord.isPolar) {
  14053. return groupScaleInXY;
  14054. }
  14055. return groupWaveIn;
  14056. },
  14057. point: function point() {
  14058. return shapesScaleInXY;
  14059. },
  14060. interval: function interval(coord) {
  14061. var result;
  14062. if (coord.isPolar) {
  14063. // polar coodinate
  14064. result = groupScaleInXY;
  14065. if (coord.transposed) {
  14066. // pie chart
  14067. result = groupWaveIn;
  14068. }
  14069. } else {
  14070. result = coord.transposed ? groupScaleInX : groupScaleInY;
  14071. }
  14072. return result;
  14073. },
  14074. schema: function schema() {
  14075. return groupWaveIn;
  14076. }
  14077. };
  14078. function diff(fromAttrs, toAttrs) {
  14079. var endState = {};
  14080. for (var k in toAttrs) {
  14081. if (isNumber(fromAttrs[k]) && fromAttrs[k] !== toAttrs[k]) {
  14082. endState[k] = toAttrs[k];
  14083. } else if (isArray(fromAttrs[k]) && JSON.stringify(fromAttrs[k]) !== JSON.stringify(toAttrs[k])) {
  14084. endState[k] = toAttrs[k];
  14085. }
  14086. }
  14087. return endState;
  14088. } // Add a unique id identifier to each shape
  14089. function _getShapeId(geom, dataObj, geomIdx) {
  14090. var type = geom.get('type');
  14091. var id = 'geom' + geomIdx + '-' + type;
  14092. var xScale = geom.getXScale();
  14093. var yScale = geom.getYScale();
  14094. var xField = xScale.field || 'x';
  14095. var yField = yScale.field || 'y';
  14096. var yVal = dataObj[yField];
  14097. var xVal;
  14098. if (xScale.isIdentity) {
  14099. xVal = xScale.value;
  14100. } else {
  14101. xVal = dataObj[xField];
  14102. }
  14103. if (type === 'interval' || type === 'schema') {
  14104. id += '-' + xVal;
  14105. } else if (type === 'line' || type === 'area' || type === 'path') {
  14106. id += '-' + type;
  14107. } else {
  14108. id += xScale.isCategory ? '-' + xVal : '-' + xVal + '-' + yVal;
  14109. }
  14110. var groupScales = geom._getGroupScales();
  14111. each(groupScales, function (groupScale) {
  14112. var field = groupScale.field;
  14113. if (groupScale.type !== 'identity') {
  14114. id += '-' + dataObj[field];
  14115. }
  14116. });
  14117. return id;
  14118. } // get geometry's shapes
  14119. function getShapes(geoms, chart, coord) {
  14120. var shapes = [];
  14121. each(geoms, function (geom, geomIdx) {
  14122. var geomContainer = geom.get('container');
  14123. var geomShapes = geomContainer.get('children');
  14124. var type = geom.get('type');
  14125. var animateCfg = isNil(geom.get('animateCfg')) ? _getAnimateCfgByShapeType(type, chart) : geom.get('animateCfg');
  14126. if (animateCfg !== false) {
  14127. each(geomShapes, function (shape, index) {
  14128. if (shape.get('className') === type) {
  14129. shape._id = _getShapeId(geom, shape.get('origin')._origin, geomIdx);
  14130. shape.set('coord', coord);
  14131. shape.set('animateCfg', animateCfg);
  14132. shape.set('index', index);
  14133. shapes.push(shape);
  14134. }
  14135. });
  14136. }
  14137. geom.set('shapes', geomShapes);
  14138. });
  14139. return shapes;
  14140. }
  14141. function cache(shapes) {
  14142. var rst = {};
  14143. for (var i = 0, len = shapes.length; i < len; i++) {
  14144. var shape = shapes[i];
  14145. if (!shape._id || shape.isClip) continue;
  14146. var id = shape._id;
  14147. rst[id] = {
  14148. _id: id,
  14149. type: shape.get('type'),
  14150. // the type of shape
  14151. attrs: mix({}, shape._attrs.attrs),
  14152. // the graphics attributes of shape
  14153. className: shape.get('className'),
  14154. geomType: shape.get('className'),
  14155. index: shape.get('index'),
  14156. coord: shape.get('coord'),
  14157. animateCfg: shape.get('animateCfg')
  14158. };
  14159. }
  14160. return rst;
  14161. }
  14162. function getAnimate(geomType, coord, animationType, animationName) {
  14163. var result;
  14164. if (isFunction(animationName)) {
  14165. result = animationName;
  14166. } else if (isString(animationName)) {
  14167. result = Animate.Action[animationName];
  14168. } else {
  14169. result = Animate.getAnimation(geomType, coord, animationType);
  14170. }
  14171. return result;
  14172. }
  14173. function getAnimateCfg(geomType, animationType, animateCfg) {
  14174. if (animateCfg === false || isObject(animateCfg) && animateCfg[animationType] === false) {
  14175. return false;
  14176. }
  14177. var defaultCfg = Animate.getAnimateCfg(geomType, animationType);
  14178. if (animateCfg && animateCfg[animationType]) {
  14179. return deepMix({}, defaultCfg, animateCfg[animationType]);
  14180. }
  14181. return defaultCfg;
  14182. }
  14183. function addAnimate(cache, shapes, canvas) {
  14184. var animate;
  14185. var animateCfg; // the order of animation: leave -> update -> enter
  14186. var updateShapes = [];
  14187. var newShapes = [];
  14188. each(shapes, function (shape) {
  14189. var result = cache[shape._id];
  14190. if (!result) {
  14191. newShapes.push(shape);
  14192. } else {
  14193. shape.set('cacheShape', result);
  14194. updateShapes.push(shape);
  14195. delete cache[shape._id];
  14196. }
  14197. }); // first do the leave animation
  14198. each(cache, function (deletedShape) {
  14199. var className = deletedShape.className,
  14200. coord = deletedShape.coord,
  14201. _id = deletedShape._id,
  14202. attrs = deletedShape.attrs,
  14203. index = deletedShape.index,
  14204. type = deletedShape.type;
  14205. animateCfg = getAnimateCfg(className, 'leave', deletedShape.animateCfg);
  14206. if (animateCfg === false) return true;
  14207. animate = getAnimate(className, coord, 'leave', animateCfg.animation);
  14208. if (isFunction(animate)) {
  14209. var tempShape = canvas.addShape(type, {
  14210. attrs: attrs,
  14211. index: index,
  14212. canvas: canvas,
  14213. className: className
  14214. });
  14215. tempShape._id = _id;
  14216. animate(tempShape, animateCfg, coord);
  14217. }
  14218. }); // then do the update animation
  14219. each(updateShapes, function (updateShape) {
  14220. var className = updateShape.get('className');
  14221. animateCfg = getAnimateCfg(className, 'update', updateShape.get('animateCfg'));
  14222. if (animateCfg === false) return true;
  14223. var coord = updateShape.get('coord');
  14224. var cacheAttrs = updateShape.get('cacheShape').attrs;
  14225. var endState = diff(cacheAttrs, updateShape._attrs.attrs); // 判断如果属性相同的话就不进行变换
  14226. if (Object.keys(endState).length) {
  14227. animate = getAnimate(className, coord, 'update', animateCfg.animation);
  14228. if (isFunction(animate)) {
  14229. animate(updateShape, animateCfg, coord);
  14230. } else {
  14231. var startState = {};
  14232. each(endState, function (value, key) {
  14233. startState[key] = cacheAttrs[key];
  14234. });
  14235. updateShape.attr(startState);
  14236. updateShape.animate().to({
  14237. attrs: endState,
  14238. duration: animateCfg.duration,
  14239. easing: animateCfg.easing,
  14240. delay: animateCfg.delay
  14241. }).onEnd(function () {
  14242. updateShape.set('cacheShape', null);
  14243. });
  14244. }
  14245. }
  14246. }); // last, enter animation
  14247. each(newShapes, function (newShape) {
  14248. // 新图形元素的进场元素
  14249. var className = newShape.get('className');
  14250. var coord = newShape.get('coord');
  14251. animateCfg = getAnimateCfg(className, 'enter', newShape.get('animateCfg'));
  14252. if (animateCfg === false) return true;
  14253. animate = getAnimate(className, coord, 'enter', animateCfg.animation);
  14254. if (isFunction(animate)) {
  14255. if (className === 'interval' && coord.isPolar && coord.transposed) {
  14256. var index = newShape.get('index');
  14257. var lastShape = updateShapes[index - 1];
  14258. animate(newShape, animateCfg, lastShape);
  14259. } else {
  14260. animate(newShape, animateCfg, coord);
  14261. }
  14262. }
  14263. });
  14264. }
  14265. function _getAnimateCfgByShapeType(type, chart) {
  14266. if (!type) {
  14267. return null;
  14268. }
  14269. var animateCfg = chart.get('animate');
  14270. if (type.indexOf('guide-tag') > -1) {
  14271. type = 'guide-tag';
  14272. }
  14273. if (isObject(animateCfg)) {
  14274. return animateCfg[type];
  14275. }
  14276. if (animateCfg === false) {
  14277. return false;
  14278. }
  14279. return null;
  14280. }
  14281. function afterCanvasInit()
  14282. /* chart */
  14283. {
  14284. timeline = new Timeline();
  14285. timeline.play();
  14286. }
  14287. function beforeCanvasDraw(chart) {
  14288. if (chart.get('animate') === false) {
  14289. return;
  14290. }
  14291. var isUpdate = chart.get('isUpdate');
  14292. var canvas = chart.get('canvas');
  14293. var coord = chart.get('coord');
  14294. var geoms = chart.get('geoms');
  14295. var caches = canvas.get('caches') || [];
  14296. if (caches.length === 0) {
  14297. isUpdate = false;
  14298. }
  14299. var cacheShapes = getShapes(geoms, chart, coord);
  14300. var _chart$get = chart.get('axisController'),
  14301. frontPlot = _chart$get.frontPlot,
  14302. backPlot = _chart$get.backPlot;
  14303. var axisShapes = frontPlot.get('children').concat(backPlot.get('children'));
  14304. var guideShapes = [];
  14305. if (chart.get('guideController')) {
  14306. guideShapes = chart.get('guideController').guideShapes;
  14307. }
  14308. var componentShapes = [];
  14309. axisShapes.concat(guideShapes).forEach(function (s) {
  14310. var className = s.get('className');
  14311. var animateCfg = _getAnimateCfgByShapeType(className, chart);
  14312. s.set('coord', coord);
  14313. s.set('animateCfg', animateCfg);
  14314. componentShapes.push(s);
  14315. cacheShapes.push(s);
  14316. });
  14317. canvas.set('caches', cache(cacheShapes));
  14318. if (isUpdate) {
  14319. addAnimate(caches, cacheShapes, canvas);
  14320. } else {
  14321. // do the appear animation
  14322. var animateCfg;
  14323. var animate;
  14324. each(geoms, function (geom) {
  14325. var type = geom.get('type');
  14326. var geomCfg = isNil(geom.get('animateCfg')) ? _getAnimateCfgByShapeType(type, chart) : geom.get('animateCfg');
  14327. if (geomCfg !== false) {
  14328. animateCfg = getAnimateCfg(type, 'appear', geomCfg);
  14329. animate = getAnimate(type, coord, 'appear', animateCfg.animation);
  14330. if (isFunction(animate)) {
  14331. var shapes = geom.get('shapes');
  14332. each(shapes, function (shape) {
  14333. animate(shape, animateCfg, coord);
  14334. });
  14335. } else if (GROUP_ANIMATION[type]) {
  14336. // do the default animation
  14337. animate = GroupAction[animateCfg.animation] || GROUP_ANIMATION[type](coord);
  14338. var yScale = geom.getYScale();
  14339. var zeroY = coord.convertPoint({
  14340. x: 0,
  14341. y: yScale.scale(geom.getYMinValue())
  14342. });
  14343. var container = geom.get('container');
  14344. animate && animate(container, animateCfg, coord, zeroY);
  14345. }
  14346. }
  14347. }); // do the animation of components
  14348. each(componentShapes, function (shape) {
  14349. var animateCfg = shape.get('animateCfg');
  14350. var className = shape.get('className');
  14351. if (animateCfg && animateCfg.appear) {
  14352. // if user configure
  14353. var defaultCfg = Animate.getAnimateCfg(className, 'appear');
  14354. var appearCfg = deepMix({}, defaultCfg, animateCfg.appear);
  14355. var _animate = getAnimate(className, coord, 'appear', appearCfg.animation);
  14356. if (isFunction(_animate)) {
  14357. _animate(shape, appearCfg, coord);
  14358. }
  14359. }
  14360. });
  14361. }
  14362. }
  14363. function afterCanvasDestroyed()
  14364. /* chart */
  14365. {
  14366. timeline.stop();
  14367. }
  14368. var detail = {
  14369. afterCanvasInit: afterCanvasInit,
  14370. beforeCanvasDraw: beforeCanvasDraw,
  14371. afterCanvasDestroyed: afterCanvasDestroyed
  14372. };
  14373. var Animation = /*#__PURE__*/Object.freeze({
  14374. __proto__: null,
  14375. afterCanvasInit: afterCanvasInit,
  14376. beforeCanvasDraw: beforeCanvasDraw,
  14377. afterCanvasDestroyed: afterCanvasDestroyed,
  14378. 'default': detail
  14379. });
  14380. function getScale(chart, field) {
  14381. var scales = chart.get('scales');
  14382. return scales[field];
  14383. }
  14384. function getFieldRange(scale, limitRange, type) {
  14385. if (!scale) return [0, 1];
  14386. var minRatio = 0;
  14387. var maxRatio = 0;
  14388. if (type === 'linear') {
  14389. var min = limitRange.min,
  14390. max = limitRange.max;
  14391. minRatio = (scale.min - min) / (max - min);
  14392. maxRatio = (scale.max - min) / (max - min);
  14393. } else {
  14394. var originValues = limitRange;
  14395. var values = scale.values || [];
  14396. var firstIndex = originValues.indexOf(values[0]);
  14397. var lastIndex = originValues.indexOf(values[values.length - 1]);
  14398. minRatio = firstIndex / (originValues.length - 1);
  14399. maxRatio = lastIndex / (originValues.length - 1);
  14400. }
  14401. return [minRatio, maxRatio];
  14402. }
  14403. function getLimitRange(data, scale) {
  14404. var result;
  14405. var field = scale.field,
  14406. type = scale.type;
  14407. var values$1 = values(data, field);
  14408. if (type === 'linear') {
  14409. result = getRange$1(values$1);
  14410. if (scale.min < result.min) {
  14411. result.min = scale.min;
  14412. }
  14413. if (scale.max > result.max) {
  14414. result.max = scale.max;
  14415. }
  14416. } else if (type === 'timeCat') {
  14417. each(values$1, function (v, i) {
  14418. values$1[i] = toTimeStamp(v);
  14419. });
  14420. values$1.sort(function (v1, v2) {
  14421. return v1 - v2;
  14422. });
  14423. result = values$1;
  14424. } else {
  14425. result = values$1;
  14426. }
  14427. return result;
  14428. }
  14429. var DEFAULT_CFG$1 = {
  14430. mode: 'x',
  14431. xStyle: {
  14432. backgroundColor: 'rgba(202, 215, 239, .2)',
  14433. fillerColor: 'rgba(202, 215, 239, .5)',
  14434. size: 4,
  14435. lineCap: 'round',
  14436. offsetX: 0,
  14437. offsetY: 8
  14438. },
  14439. yStyle: {
  14440. backgroundColor: 'rgba(202, 215, 239, .2)',
  14441. fillerColor: 'rgba(202, 215, 239, .5)',
  14442. size: 4,
  14443. lineCap: 'round',
  14444. offsetX: 8,
  14445. offsetY: 0
  14446. }
  14447. };
  14448. function init$3(chart) {
  14449. chart.set('_limitRange', {});
  14450. chart.scrollBar = function (cfg) {
  14451. if (cfg === true) {
  14452. cfg = DEFAULT_CFG$1;
  14453. } else if (isObject(cfg)) {
  14454. cfg = deepMix({}, DEFAULT_CFG$1, cfg);
  14455. }
  14456. this.set('_scrollBarCfg', cfg);
  14457. };
  14458. }
  14459. function clear$1(chart) {
  14460. chart.set('_limitRange', {});
  14461. }
  14462. function changeData(chart) {
  14463. chart.set('_limitRange', {});
  14464. }
  14465. function clearInner$2(chart) {
  14466. var hBar = chart.get('_horizontalBar');
  14467. var vBar = chart.get('_verticalBar');
  14468. hBar && hBar.remove(true);
  14469. vBar && vBar.remove(true);
  14470. chart.set('_horizontalBar', null);
  14471. chart.set('_verticalBar', null);
  14472. }
  14473. function afterGeomDraw$3(chart) {
  14474. var scrollBarCfg = chart.get('_scrollBarCfg');
  14475. if (!scrollBarCfg) return;
  14476. var data = chart.get('data');
  14477. var plotRange = chart.get('plotRange');
  14478. var backPlot = chart.get('backPlot');
  14479. var canvas = chart.get('canvas');
  14480. var canvasHeight = canvas.get('height');
  14481. var limitRange = chart.get('_limitRange');
  14482. var mode = scrollBarCfg.mode;
  14483. if (directionEnabled(mode, 'x')) {
  14484. var _scrollBarCfg$xStyle = scrollBarCfg.xStyle,
  14485. offsetX = _scrollBarCfg$xStyle.offsetX,
  14486. offsetY = _scrollBarCfg$xStyle.offsetY,
  14487. lineCap = _scrollBarCfg$xStyle.lineCap,
  14488. backgroundColor = _scrollBarCfg$xStyle.backgroundColor,
  14489. fillerColor = _scrollBarCfg$xStyle.fillerColor,
  14490. size = _scrollBarCfg$xStyle.size;
  14491. var xScale = chart.getXScale();
  14492. var xLimitRange = limitRange[xScale.field];
  14493. if (!xLimitRange) {
  14494. xLimitRange = getLimitRange(data, xScale);
  14495. limitRange[xScale.field] = xLimitRange;
  14496. }
  14497. var currentRange = getFieldRange(xScale, xLimitRange, xScale.type);
  14498. var horizontalBar = chart.get('_horizontalBar');
  14499. var yPos = canvasHeight - size / 2 + offsetY;
  14500. if (horizontalBar) {
  14501. var progressLine = horizontalBar.get('children')[1];
  14502. progressLine.attr({
  14503. x1: Math.max(plotRange.bl.x + plotRange.width * currentRange[0] + offsetX, plotRange.bl.x),
  14504. x2: Math.min(plotRange.bl.x + plotRange.width * currentRange[1] + offsetX, plotRange.br.x)
  14505. });
  14506. } else {
  14507. horizontalBar = backPlot.addGroup({
  14508. className: 'horizontalBar'
  14509. });
  14510. horizontalBar.addShape('line', {
  14511. attrs: {
  14512. x1: plotRange.bl.x + offsetX,
  14513. y1: yPos,
  14514. x2: plotRange.br.x + offsetX,
  14515. y2: yPos,
  14516. lineWidth: size,
  14517. stroke: backgroundColor,
  14518. lineCap: lineCap
  14519. }
  14520. });
  14521. horizontalBar.addShape('line', {
  14522. attrs: {
  14523. x1: Math.max(plotRange.bl.x + plotRange.width * currentRange[0] + offsetX, plotRange.bl.x),
  14524. y1: yPos,
  14525. x2: Math.min(plotRange.bl.x + plotRange.width * currentRange[1] + offsetX, plotRange.br.x),
  14526. y2: yPos,
  14527. lineWidth: size,
  14528. stroke: fillerColor,
  14529. lineCap: lineCap
  14530. }
  14531. });
  14532. chart.set('_horizontalBar', horizontalBar);
  14533. }
  14534. }
  14535. if (directionEnabled(mode, 'y')) {
  14536. var _scrollBarCfg$yStyle = scrollBarCfg.yStyle,
  14537. _offsetX = _scrollBarCfg$yStyle.offsetX,
  14538. _offsetY = _scrollBarCfg$yStyle.offsetY,
  14539. _lineCap = _scrollBarCfg$yStyle.lineCap,
  14540. _backgroundColor = _scrollBarCfg$yStyle.backgroundColor,
  14541. _fillerColor = _scrollBarCfg$yStyle.fillerColor,
  14542. _size = _scrollBarCfg$yStyle.size;
  14543. var yScale = chart.getYScales()[0];
  14544. var yLimitRange = limitRange[yScale.field];
  14545. if (!yLimitRange) {
  14546. yLimitRange = getLimitRange(data, yScale);
  14547. limitRange[yScale.field] = yLimitRange;
  14548. }
  14549. var _currentRange = getFieldRange(yScale, yLimitRange, yScale.type);
  14550. var verticalBar = chart.get('_verticalBar');
  14551. var xPos = _size / 2 + _offsetX;
  14552. if (verticalBar) {
  14553. var _progressLine = verticalBar.get('children')[1];
  14554. _progressLine.attr({
  14555. y1: Math.max(plotRange.tl.y + plotRange.height * _currentRange[0] + _offsetY, plotRange.tl.y),
  14556. y2: Math.min(plotRange.tl.y + plotRange.height * _currentRange[1] + _offsetY, plotRange.bl.y)
  14557. });
  14558. } else {
  14559. verticalBar = backPlot.addGroup({
  14560. className: 'verticalBar'
  14561. });
  14562. verticalBar.addShape('line', {
  14563. attrs: {
  14564. x1: xPos,
  14565. y1: plotRange.tl.y + _offsetY,
  14566. x2: xPos,
  14567. y2: plotRange.bl.y + _offsetY,
  14568. lineWidth: _size,
  14569. stroke: _backgroundColor,
  14570. lineCap: _lineCap
  14571. }
  14572. });
  14573. verticalBar.addShape('line', {
  14574. attrs: {
  14575. x1: xPos,
  14576. y1: Math.max(plotRange.tl.y + plotRange.height * _currentRange[0] + _offsetY, plotRange.tl.y),
  14577. x2: xPos,
  14578. y2: Math.min(plotRange.tl.y + plotRange.height * _currentRange[1] + _offsetY, plotRange.bl.y),
  14579. lineWidth: _size,
  14580. stroke: _fillerColor,
  14581. lineCap: _lineCap
  14582. }
  14583. });
  14584. chart.set('_verticalBar', verticalBar);
  14585. }
  14586. }
  14587. }
  14588. var scrollBar = {
  14589. init: init$3,
  14590. clear: clear$1,
  14591. changeData: changeData,
  14592. clearInner: clearInner$2,
  14593. afterGeomDraw: afterGeomDraw$3
  14594. };
  14595. var ScrollBar = /*#__PURE__*/Object.freeze({
  14596. __proto__: null,
  14597. init: init$3,
  14598. clear: clear$1,
  14599. changeData: changeData,
  14600. clearInner: clearInner$2,
  14601. afterGeomDraw: afterGeomDraw$3,
  14602. 'default': scrollBar
  14603. });
  14604. var DEFAULT_CFG$2 = {
  14605. anchorOffset: 5,
  14606. // 锚点的偏移量
  14607. inflectionOffset: 15,
  14608. // 拐点的偏移量
  14609. sidePadding: 20,
  14610. // 文本距离画布四边的距离
  14611. lineHeight: 32,
  14612. // 文本的行高
  14613. adjustOffset: 15,
  14614. // 发生调整时的偏移量
  14615. skipOverlapLabels: false,
  14616. // 是否不展示重叠的文本
  14617. triggerOn: 'touchstart',
  14618. // 点击行为触发的时间类型
  14619. activeShape: false,
  14620. // 当有图形被选中的时候,是否激活图形
  14621. activeStyle: {
  14622. offset: 1,
  14623. appendRadius: 8,
  14624. fillOpacity: 0.5
  14625. },
  14626. label1OffsetY: -1,
  14627. label2OffsetY: 1
  14628. };
  14629. function getEndPoint(center, angle, r) {
  14630. return {
  14631. x: center.x + r * Math.cos(angle),
  14632. y: center.y + r * Math.sin(angle)
  14633. };
  14634. } // 计算中间角度
  14635. function getMiddleAngle(startAngle, endAngle) {
  14636. if (endAngle < startAngle) {
  14637. endAngle += Math.PI * 2;
  14638. }
  14639. return (endAngle + startAngle) / 2;
  14640. } // 判断两个矩形是否相交
  14641. function isOverlap(label1, label2) {
  14642. var label1BBox = label1.getBBox();
  14643. var label2BBox = label2.getBBox();
  14644. return Math.max(label1BBox.minX, label2BBox.minX) <= Math.min(label1BBox.maxX, label2BBox.maxX) && Math.max(label1BBox.minY, label2BBox.minY) <= Math.min(label1BBox.maxY, label2BBox.maxY);
  14645. }
  14646. var controller = /*#__PURE__*/function () {
  14647. function controller(cfg) {
  14648. var _this = this;
  14649. _defineProperty(this, "_handleEvent", function (ev) {
  14650. var self = _this;
  14651. var chart = self.chart,
  14652. drawnLabels = self.drawnLabels,
  14653. pieLabelCfg = self.pieLabelCfg;
  14654. var onClick = pieLabelCfg.onClick,
  14655. activeShape = pieLabelCfg.activeShape;
  14656. var canvasEvent = createEvent(ev, chart);
  14657. var x = canvasEvent.x,
  14658. y = canvasEvent.y; // 查找被点击的 label
  14659. var clickedShape;
  14660. for (var i = 0, len = drawnLabels.length; i < len; i++) {
  14661. var shape = drawnLabels[i];
  14662. var bbox = shape.getBBox(); // 通过最小包围盒来判断击中情况
  14663. if (x >= bbox.minX && x <= bbox.maxX && y >= bbox.minY && y <= bbox.maxY) {
  14664. clickedShape = shape;
  14665. break;
  14666. }
  14667. }
  14668. var pieData = chart.getSnapRecords({
  14669. x: x,
  14670. y: y
  14671. });
  14672. if (clickedShape) {
  14673. canvasEvent.data = clickedShape.get('data');
  14674. } else if (pieData.length) {
  14675. // 击中饼图扇形区域
  14676. canvasEvent.data = pieData[0]._origin;
  14677. }
  14678. onClick && onClick(canvasEvent);
  14679. canvasEvent.data && activeShape && _this._activeShape(canvasEvent.data);
  14680. });
  14681. mix(this, cfg);
  14682. var _chart = this.chart;
  14683. this.canvasDom = _chart.get('canvas').get('el');
  14684. }
  14685. var _proto = controller.prototype;
  14686. _proto.renderLabels = function renderLabels() {
  14687. var self = this;
  14688. var chart = self.chart,
  14689. pieLabelCfg = self.pieLabelCfg,
  14690. labelGroup = self.labelGroup;
  14691. var halves = [[], // left
  14692. [] // right
  14693. ]; // 存储左右 labels
  14694. var geom = chart.get('geoms')[0];
  14695. var shapes = geom.get('container').get('children');
  14696. var anchorOffset = pieLabelCfg.anchorOffset,
  14697. inflectionOffset = pieLabelCfg.inflectionOffset,
  14698. label1 = pieLabelCfg.label1,
  14699. label2 = pieLabelCfg.label2,
  14700. lineHeight = pieLabelCfg.lineHeight,
  14701. skipOverlapLabels = pieLabelCfg.skipOverlapLabels,
  14702. label1OffsetY = pieLabelCfg.label1OffsetY,
  14703. label2OffsetY = pieLabelCfg.label2OffsetY;
  14704. var coord = chart.get('coord');
  14705. var center = coord.center,
  14706. radius = coord.circleRadius;
  14707. shapes.forEach(function (shape) {
  14708. var _shape$_attrs$attrs = shape._attrs.attrs,
  14709. startAngle = _shape$_attrs$attrs.startAngle,
  14710. endAngle = _shape$_attrs$attrs.endAngle;
  14711. var middleAngle = getMiddleAngle(startAngle, endAngle);
  14712. var anchorPoint = getEndPoint(center, middleAngle, radius + anchorOffset);
  14713. var inflectionPoint = getEndPoint(center, middleAngle, radius + inflectionOffset);
  14714. var origin = shape.get('origin');
  14715. var _origin = origin._origin,
  14716. color = origin.color;
  14717. var label = {
  14718. _anchor: anchorPoint,
  14719. _inflection: inflectionPoint,
  14720. _data: _origin,
  14721. x: inflectionPoint.x,
  14722. y: inflectionPoint.y,
  14723. r: radius + inflectionOffset,
  14724. fill: color
  14725. };
  14726. var textGroup = new Group({
  14727. context: chart.get('canvas').get('context'),
  14728. // 兼容 node、小程序环境
  14729. data: _origin // 存储原始数据
  14730. });
  14731. var textAttrs = {
  14732. x: 0,
  14733. y: 0,
  14734. fontSize: 12,
  14735. lineHeight: 12,
  14736. fill: '#808080'
  14737. };
  14738. if (isFunction(label1)) {
  14739. textGroup.addShape('Text', {
  14740. attrs: mix({
  14741. textBaseline: 'bottom'
  14742. }, textAttrs, label1(_origin, color)),
  14743. data: _origin,
  14744. // 存储原始数据
  14745. offsetY: label1OffsetY
  14746. });
  14747. }
  14748. if (isFunction(label2)) {
  14749. textGroup.addShape('Text', {
  14750. attrs: mix({
  14751. textBaseline: 'top'
  14752. }, textAttrs, label2(_origin, color)),
  14753. data: _origin,
  14754. // 存储原始数据
  14755. offsetY: label2OffsetY
  14756. });
  14757. }
  14758. label.textGroup = textGroup; // 判断文本的方向
  14759. if (anchorPoint.x < center.x) {
  14760. label._side = 'left';
  14761. halves[0].push(label);
  14762. } else {
  14763. label._side = 'right';
  14764. halves[1].push(label);
  14765. }
  14766. });
  14767. var drawnLabels = [];
  14768. if (skipOverlapLabels) {
  14769. var lastLabel; // 存储上一个 label 对象,用于检测文本是否重叠
  14770. var labels = halves[1].concat(halves[0]); // 顺时针
  14771. for (var i = 0, len = labels.length; i < len; i++) {
  14772. var label = labels[i];
  14773. var textGroup = self._drawLabel(label);
  14774. if (lastLabel) {
  14775. if (isOverlap(textGroup, lastLabel)) {
  14776. // 重叠了就不绘制
  14777. continue;
  14778. }
  14779. }
  14780. labelGroup.add(textGroup);
  14781. self._drawLabelLine(label);
  14782. lastLabel = textGroup;
  14783. drawnLabels.push(textGroup);
  14784. }
  14785. } else {
  14786. var height = chart.get('height');
  14787. var maxCountForOneSide = parseInt(height / lineHeight, 10);
  14788. halves.forEach(function (half) {
  14789. if (half.length > maxCountForOneSide) {
  14790. half.splice(maxCountForOneSide, half.length - maxCountForOneSide);
  14791. }
  14792. half.sort(function (a, b) {
  14793. return a.y - b.y;
  14794. });
  14795. var labels = self._antiCollision(half);
  14796. drawnLabels = drawnLabels.concat(labels);
  14797. });
  14798. }
  14799. this.drawnLabels = drawnLabels;
  14800. };
  14801. _proto.bindEvents = function bindEvents() {
  14802. var pieLabelCfg = this.pieLabelCfg;
  14803. var triggerOn = pieLabelCfg.triggerOn || 'touchstart';
  14804. addEventListener(this.canvasDom, triggerOn, this._handleEvent);
  14805. };
  14806. _proto.unBindEvents = function unBindEvents() {
  14807. var pieLabelCfg = this.pieLabelCfg;
  14808. var triggerOn = pieLabelCfg.triggerOn || 'touchstart';
  14809. removeEventListener(this.canvasDom, triggerOn, this._handleEvent);
  14810. };
  14811. _proto.clear = function clear() {
  14812. this.labelGroup && this.labelGroup.clear();
  14813. this.halo && this.halo.remove(true);
  14814. this.lastSelectedData = null;
  14815. this.drawnLabels = [];
  14816. this.unBindEvents();
  14817. };
  14818. _proto._drawLabel = function _drawLabel(label) {
  14819. var pieLabelCfg = this.pieLabelCfg,
  14820. chart = this.chart;
  14821. var canvasWidth = chart.get('width');
  14822. var sidePadding = pieLabelCfg.sidePadding;
  14823. var y = label.y,
  14824. textGroup = label.textGroup;
  14825. var children = textGroup.get('children');
  14826. var textAttrs = {
  14827. textAlign: label._side === 'left' ? 'left' : 'right',
  14828. x: label._side === 'left' ? sidePadding : canvasWidth - sidePadding
  14829. };
  14830. children.forEach(function (child) {
  14831. child.attr(textAttrs);
  14832. child.attr('y', y + child.get('offsetY'));
  14833. });
  14834. return textGroup;
  14835. };
  14836. _proto._drawLabelLine = function _drawLabelLine(label, maxLabelWidth) {
  14837. var chart = this.chart,
  14838. pieLabelCfg = this.pieLabelCfg,
  14839. labelGroup = this.labelGroup;
  14840. var canvasWidth = chart.get('width');
  14841. var sidePadding = pieLabelCfg.sidePadding,
  14842. adjustOffset = pieLabelCfg.adjustOffset,
  14843. lineStyle = pieLabelCfg.lineStyle,
  14844. anchorStyle = pieLabelCfg.anchorStyle,
  14845. skipOverlapLabels = pieLabelCfg.skipOverlapLabels;
  14846. var _anchor = label._anchor,
  14847. _inflection = label._inflection,
  14848. fill = label.fill,
  14849. y = label.y;
  14850. var lastPoint = {
  14851. x: label._side === 'left' ? sidePadding : canvasWidth - sidePadding,
  14852. y: y
  14853. };
  14854. var points = [_anchor, _inflection, lastPoint];
  14855. if (!skipOverlapLabels && _inflection.y !== y) {
  14856. // 展示全部文本文本位置做过调整
  14857. if (_inflection.y < y) {
  14858. // 文本被调整下去了,则添加拐点连接线
  14859. var point1 = _inflection;
  14860. var point2 = {
  14861. x: label._side === 'left' ? lastPoint.x + maxLabelWidth + adjustOffset : lastPoint.x - maxLabelWidth - adjustOffset,
  14862. y: _inflection.y
  14863. };
  14864. var point3 = {
  14865. x: label._side === 'left' ? lastPoint.x + maxLabelWidth : lastPoint.x - maxLabelWidth,
  14866. y: lastPoint.y
  14867. };
  14868. points = [_anchor, point1, point2, point3, lastPoint];
  14869. if (label._side === 'right' && point2.x < point1.x || label._side === 'left' && point2.x > point1.x) {
  14870. points = [_anchor, point3, lastPoint];
  14871. }
  14872. } else {
  14873. points = [_anchor, {
  14874. x: _inflection.x,
  14875. y: y
  14876. }, lastPoint];
  14877. }
  14878. }
  14879. labelGroup.addShape('Polyline', {
  14880. attrs: mix({
  14881. points: points,
  14882. lineWidth: 1,
  14883. stroke: fill
  14884. }, lineStyle)
  14885. }); // 绘制锚点
  14886. labelGroup.addShape('Circle', {
  14887. attrs: mix({
  14888. x: _anchor.x,
  14889. y: _anchor.y,
  14890. r: 2,
  14891. fill: fill
  14892. }, anchorStyle)
  14893. });
  14894. };
  14895. _proto._antiCollision = function _antiCollision(half) {
  14896. var self = this;
  14897. var chart = self.chart,
  14898. pieLabelCfg = self.pieLabelCfg;
  14899. var coord = chart.get('coord');
  14900. var canvasHeight = chart.get('height');
  14901. var center = coord.center,
  14902. r = coord.circleRadius;
  14903. var inflectionOffset = pieLabelCfg.inflectionOffset,
  14904. lineHeight = pieLabelCfg.lineHeight;
  14905. var startY = center.y - r - inflectionOffset - lineHeight;
  14906. var overlapping = true;
  14907. var totalH = canvasHeight;
  14908. var i;
  14909. var maxY = 0;
  14910. var minY = Number.MIN_VALUE;
  14911. var maxLabelWidth = 0;
  14912. var boxes = half.map(function (label) {
  14913. var labelY = label.y;
  14914. if (labelY > maxY) {
  14915. maxY = labelY;
  14916. }
  14917. if (labelY < minY) {
  14918. minY = labelY;
  14919. }
  14920. var textGroup = label.textGroup;
  14921. var labelWidth = textGroup.getBBox().width;
  14922. if (labelWidth >= maxLabelWidth) {
  14923. maxLabelWidth = labelWidth;
  14924. }
  14925. return {
  14926. size: lineHeight,
  14927. targets: [labelY - startY]
  14928. };
  14929. });
  14930. if (maxY - startY > totalH) {
  14931. totalH = maxY - startY;
  14932. }
  14933. var iteratorBoxed = function iteratorBoxed(boxes) {
  14934. boxes.forEach(function (box) {
  14935. var target = (Math.min.apply(minY, box.targets) + Math.max.apply(minY, box.targets)) / 2;
  14936. box.pos = Math.min(Math.max(minY, target - box.size / 2), totalH - box.size);
  14937. });
  14938. };
  14939. while (overlapping) {
  14940. iteratorBoxed(boxes); // detect overlapping and join boxes
  14941. overlapping = false;
  14942. i = boxes.length;
  14943. while (i--) {
  14944. if (i > 0) {
  14945. var previousBox = boxes[i - 1];
  14946. var box = boxes[i];
  14947. if (previousBox.pos + previousBox.size > box.pos) {
  14948. // overlapping
  14949. previousBox.size += box.size;
  14950. previousBox.targets = previousBox.targets.concat(box.targets); // overflow, shift up
  14951. if (previousBox.pos + previousBox.size > totalH) {
  14952. previousBox.pos = totalH - previousBox.size;
  14953. }
  14954. boxes.splice(i, 1); // removing box
  14955. overlapping = true;
  14956. }
  14957. }
  14958. }
  14959. }
  14960. i = 0;
  14961. boxes.forEach(function (b) {
  14962. var posInCompositeBox = startY; // middle of the label
  14963. b.targets.forEach(function () {
  14964. half[i].y = b.pos + posInCompositeBox + lineHeight / 2;
  14965. posInCompositeBox += lineHeight;
  14966. i++;
  14967. });
  14968. });
  14969. var drawnLabels = [];
  14970. half.forEach(function (label) {
  14971. var textGroup = self._drawLabel(label);
  14972. var labelGroup = self.labelGroup;
  14973. labelGroup.add(textGroup);
  14974. self._drawLabelLine(label, maxLabelWidth);
  14975. drawnLabels.push(textGroup);
  14976. });
  14977. return drawnLabels;
  14978. };
  14979. _proto._getSelectedShapeByData = function _getSelectedShapeByData(data) {
  14980. var selectedShape = null;
  14981. var chart = this.chart;
  14982. var geom = chart.get('geoms')[0];
  14983. var container = geom.get('container');
  14984. var children = container.get('children');
  14985. each(children, function (child) {
  14986. if (child.get('isShape') && child.get('className') === geom.get('type')) {
  14987. // get geometry's shape
  14988. var shapeData = child.get('origin')._origin;
  14989. if (isObjectValueEqual(shapeData, data)) {
  14990. selectedShape = child;
  14991. return false;
  14992. }
  14993. }
  14994. });
  14995. return selectedShape;
  14996. };
  14997. _proto._activeShape = function _activeShape(data) {
  14998. var chart = this.chart,
  14999. lastSelectedData = this.lastSelectedData,
  15000. pieLabelCfg = this.pieLabelCfg;
  15001. if (data === lastSelectedData) {
  15002. return;
  15003. }
  15004. this.lastSelectedData = data;
  15005. var activeStyle = pieLabelCfg.activeStyle;
  15006. var selectedShape = this._getSelectedShapeByData(data);
  15007. var _selectedShape$_attrs = selectedShape._attrs.attrs,
  15008. x = _selectedShape$_attrs.x,
  15009. y = _selectedShape$_attrs.y,
  15010. startAngle = _selectedShape$_attrs.startAngle,
  15011. endAngle = _selectedShape$_attrs.endAngle,
  15012. r = _selectedShape$_attrs.r,
  15013. fill = _selectedShape$_attrs.fill;
  15014. var frontPlot = chart.get('frontPlot');
  15015. this.halo && this.halo.remove(true);
  15016. var halo = frontPlot.addShape('sector', {
  15017. attrs: mix({
  15018. x: x,
  15019. y: y,
  15020. r: r + activeStyle.offset + activeStyle.appendRadius,
  15021. r0: r + activeStyle.offset,
  15022. fill: fill,
  15023. startAngle: startAngle,
  15024. endAngle: endAngle
  15025. }, activeStyle)
  15026. });
  15027. this.halo = halo;
  15028. chart.get('canvas').draw();
  15029. };
  15030. return controller;
  15031. }();
  15032. function init$4(chart) {
  15033. var frontPlot = chart.get('frontPlot');
  15034. var labelGroup = frontPlot.addGroup({
  15035. className: 'pie-label',
  15036. zIndex: 0
  15037. });
  15038. var pieLabelController = new controller({
  15039. chart: chart,
  15040. labelGroup: labelGroup
  15041. });
  15042. chart.set('pieLabelController', pieLabelController);
  15043. chart.pieLabel = function (cfg) {
  15044. cfg = deepMix({}, DEFAULT_CFG$2, cfg);
  15045. pieLabelController.pieLabelCfg = cfg;
  15046. return this;
  15047. };
  15048. }
  15049. function afterGeomDraw$4(chart) {
  15050. var controller = chart.get('pieLabelController');
  15051. if (controller.pieLabelCfg) {
  15052. // 用户配置了饼图文本
  15053. controller.renderLabels();
  15054. controller.bindEvents(); // 绑定事件
  15055. }
  15056. }
  15057. function clearInner$3(chart) {
  15058. var controller = chart.get('pieLabelController');
  15059. if (controller.pieLabelCfg) {
  15060. // 用户配置了饼图文本
  15061. controller.clear();
  15062. }
  15063. }
  15064. var pieLabel = {
  15065. init: init$4,
  15066. afterGeomDraw: afterGeomDraw$4,
  15067. clearInner: clearInner$3
  15068. };
  15069. var PieLabel = /*#__PURE__*/Object.freeze({
  15070. __proto__: null,
  15071. init: init$4,
  15072. afterGeomDraw: afterGeomDraw$4,
  15073. clearInner: clearInner$3,
  15074. 'default': pieLabel
  15075. });
  15076. var DEFAULT_CFG$3 = {
  15077. label: null,
  15078. offsetX: 0,
  15079. offsetY: 0
  15080. };
  15081. var DEFAULT_LABEL_CFG = {
  15082. textBaseline: 'middle',
  15083. fill: '#808080'
  15084. }; // 2个点的中心点
  15085. function getMiddlePoint$1(a, b) {
  15086. var x = (a.x - b.x) / 2 + b.x;
  15087. var y = (a.y - b.y) / 2 + b.y;
  15088. return {
  15089. x: x,
  15090. y: y
  15091. };
  15092. } // function getLabelPoint(points, nextPoints) {
  15093. // let start;
  15094. // if (nextPoints && nextPoints.length) {
  15095. // start = getMiddlePoint(points[1], nextPoints[1]);
  15096. // } else {
  15097. // const nextPoint = getMiddlePoint(points[2], points[3]);
  15098. // start = getMiddlePoint(points[1], nextPoint);
  15099. // }
  15100. // const end = getMiddlePoint(points[1], points[2]);
  15101. // return { start, end };
  15102. // }
  15103. var Controller = /*#__PURE__*/function () {
  15104. function Controller(_ref) {
  15105. var chart = _ref.chart,
  15106. container = _ref.container;
  15107. this.cfg = null;
  15108. this.chart = chart;
  15109. this.container = container;
  15110. }
  15111. var _proto = Controller.prototype;
  15112. _proto.draw = function draw() {
  15113. var chart = this.chart,
  15114. container = this.container,
  15115. cfg = this.cfg;
  15116. if (!cfg) return;
  15117. var labelCfg = mix({}, DEFAULT_CFG$3, cfg);
  15118. var geom = chart.get('geoms')[0];
  15119. var shapes = geom.get('container').get('children');
  15120. shapes.forEach(function (shape) {
  15121. var origin = shape.get('origin');
  15122. var attrs = shape.get('attrs');
  15123. var _origin = origin._origin,
  15124. color = origin.color;
  15125. var points = attrs.points;
  15126. if (labelCfg.label) {
  15127. var labelAttrs = labelCfg.label(_origin, color);
  15128. var point = getMiddlePoint$1(points[1], points[2]);
  15129. container.addShape('Text', {
  15130. attrs: mix({
  15131. x: point.x + labelCfg.offsetX,
  15132. y: point.y + labelCfg.offsetY
  15133. }, DEFAULT_LABEL_CFG, labelAttrs)
  15134. });
  15135. }
  15136. if (labelCfg.guide) {
  15137. var _labelAttrs = labelCfg.guide(_origin, color);
  15138. var _point = getMiddlePoint$1(getMiddlePoint$1(points[0], points[1]), getMiddlePoint$1(points[2], points[3] || points[2]));
  15139. container.addShape('Text', {
  15140. attrs: mix({
  15141. x: _point.x,
  15142. y: _point.y,
  15143. textBaseline: 'middle',
  15144. textAlign: 'center'
  15145. }, DEFAULT_LABEL_CFG, _labelAttrs)
  15146. });
  15147. }
  15148. });
  15149. };
  15150. _proto.clear = function clear() {
  15151. var container = this.container;
  15152. container.clear();
  15153. };
  15154. return Controller;
  15155. }();
  15156. function init$5(chart) {
  15157. var frontPlot = chart.get('frontPlot');
  15158. var labelGroup = frontPlot.addGroup({
  15159. className: 'label',
  15160. zIndex: 0
  15161. });
  15162. var labelController = new Controller({
  15163. chart: chart,
  15164. container: labelGroup
  15165. });
  15166. chart.set('intervalLabelController', labelController);
  15167. chart.intervalLabel = function (cfg) {
  15168. labelController.cfg = cfg;
  15169. };
  15170. }
  15171. function afterGeomDraw$5(chart) {
  15172. var labelController = chart.get('intervalLabelController');
  15173. labelController.draw();
  15174. }
  15175. function clearInner$4(chart) {
  15176. var labelController = chart.get('intervalLabelController');
  15177. labelController.clear();
  15178. }
  15179. var intervalLabel = {
  15180. init: init$5,
  15181. afterGeomDraw: afterGeomDraw$5,
  15182. clearInner: clearInner$4
  15183. };
  15184. var intervalLabel$1 = /*#__PURE__*/Object.freeze({
  15185. __proto__: null,
  15186. init: init$5,
  15187. afterGeomDraw: afterGeomDraw$5,
  15188. clearInner: clearInner$4,
  15189. 'default': intervalLabel
  15190. });
  15191. function createCommonjsModule(fn, module) {
  15192. return module = { exports: {} }, fn(module, module.exports), module.exports;
  15193. }
  15194. var hammer = createCommonjsModule(function (module) {
  15195. /*! Hammer.JS - v2.0.7 - 2016-04-22
  15196. * http://hammerjs.github.io/
  15197. *
  15198. * Copyright (c) 2016 Jorik Tangelder;
  15199. * Licensed under the MIT license */
  15200. (function (window, document, exportName, undefined$1) {
  15201. var VENDOR_PREFIXES = ['', 'webkit', 'Moz', 'MS', 'ms', 'o'];
  15202. var TEST_ELEMENT = document.createElement('div');
  15203. var TYPE_FUNCTION = 'function';
  15204. var round = Math.round;
  15205. var abs = Math.abs;
  15206. var now = Date.now;
  15207. /**
  15208. * set a timeout with a given scope
  15209. * @param {Function} fn
  15210. * @param {Number} timeout
  15211. * @param {Object} context
  15212. * @returns {number}
  15213. */
  15214. function setTimeoutContext(fn, timeout, context) {
  15215. return setTimeout(bindFn(fn, context), timeout);
  15216. }
  15217. /**
  15218. * if the argument is an array, we want to execute the fn on each entry
  15219. * if it aint an array we don't want to do a thing.
  15220. * this is used by all the methods that accept a single and array argument.
  15221. * @param {*|Array} arg
  15222. * @param {String} fn
  15223. * @param {Object} [context]
  15224. * @returns {Boolean}
  15225. */
  15226. function invokeArrayArg(arg, fn, context) {
  15227. if (Array.isArray(arg)) {
  15228. each(arg, context[fn], context);
  15229. return true;
  15230. }
  15231. return false;
  15232. }
  15233. /**
  15234. * walk objects and arrays
  15235. * @param {Object} obj
  15236. * @param {Function} iterator
  15237. * @param {Object} context
  15238. */
  15239. function each(obj, iterator, context) {
  15240. var i;
  15241. if (!obj) {
  15242. return;
  15243. }
  15244. if (obj.forEach) {
  15245. obj.forEach(iterator, context);
  15246. } else if (obj.length !== undefined$1) {
  15247. i = 0;
  15248. while (i < obj.length) {
  15249. iterator.call(context, obj[i], i, obj);
  15250. i++;
  15251. }
  15252. } else {
  15253. for (i in obj) {
  15254. obj.hasOwnProperty(i) && iterator.call(context, obj[i], i, obj);
  15255. }
  15256. }
  15257. }
  15258. /**
  15259. * wrap a method with a deprecation warning and stack trace
  15260. * @param {Function} method
  15261. * @param {String} name
  15262. * @param {String} message
  15263. * @returns {Function} A new function wrapping the supplied method.
  15264. */
  15265. function deprecate(method, name, message) {
  15266. var deprecationMessage = 'DEPRECATED METHOD: ' + name + '\n' + message + ' AT \n';
  15267. return function () {
  15268. var e = new Error('get-stack-trace');
  15269. var stack = e && e.stack ? e.stack.replace(/^[^\(]+?[\n$]/gm, '').replace(/^\s+at\s+/gm, '').replace(/^Object.<anonymous>\s*\(/gm, '{anonymous}()@') : 'Unknown Stack Trace';
  15270. var log = window.console && (window.console.warn || window.console.log);
  15271. if (log) {
  15272. log.call(window.console, deprecationMessage, stack);
  15273. }
  15274. return method.apply(this, arguments);
  15275. };
  15276. }
  15277. /**
  15278. * extend object.
  15279. * means that properties in dest will be overwritten by the ones in src.
  15280. * @param {Object} target
  15281. * @param {...Object} objects_to_assign
  15282. * @returns {Object} target
  15283. */
  15284. var assign;
  15285. if (typeof Object.assign !== 'function') {
  15286. assign = function assign(target) {
  15287. if (target === undefined$1 || target === null) {
  15288. throw new TypeError('Cannot convert undefined or null to object');
  15289. }
  15290. var output = Object(target);
  15291. for (var index = 1; index < arguments.length; index++) {
  15292. var source = arguments[index];
  15293. if (source !== undefined$1 && source !== null) {
  15294. for (var nextKey in source) {
  15295. if (source.hasOwnProperty(nextKey)) {
  15296. output[nextKey] = source[nextKey];
  15297. }
  15298. }
  15299. }
  15300. }
  15301. return output;
  15302. };
  15303. } else {
  15304. assign = Object.assign;
  15305. }
  15306. /**
  15307. * extend object.
  15308. * means that properties in dest will be overwritten by the ones in src.
  15309. * @param {Object} dest
  15310. * @param {Object} src
  15311. * @param {Boolean} [merge=false]
  15312. * @returns {Object} dest
  15313. */
  15314. var extend = deprecate(function extend(dest, src, merge) {
  15315. var keys = Object.keys(src);
  15316. var i = 0;
  15317. while (i < keys.length) {
  15318. if (!merge || merge && dest[keys[i]] === undefined$1) {
  15319. dest[keys[i]] = src[keys[i]];
  15320. }
  15321. i++;
  15322. }
  15323. return dest;
  15324. }, 'extend', 'Use `assign`.');
  15325. /**
  15326. * merge the values from src in the dest.
  15327. * means that properties that exist in dest will not be overwritten by src
  15328. * @param {Object} dest
  15329. * @param {Object} src
  15330. * @returns {Object} dest
  15331. */
  15332. var merge = deprecate(function merge(dest, src) {
  15333. return extend(dest, src, true);
  15334. }, 'merge', 'Use `assign`.');
  15335. /**
  15336. * simple class inheritance
  15337. * @param {Function} child
  15338. * @param {Function} base
  15339. * @param {Object} [properties]
  15340. */
  15341. function inherit(child, base, properties) {
  15342. var baseP = base.prototype,
  15343. childP;
  15344. childP = child.prototype = Object.create(baseP);
  15345. childP.constructor = child;
  15346. childP._super = baseP;
  15347. if (properties) {
  15348. assign(childP, properties);
  15349. }
  15350. }
  15351. /**
  15352. * simple function bind
  15353. * @param {Function} fn
  15354. * @param {Object} context
  15355. * @returns {Function}
  15356. */
  15357. function bindFn(fn, context) {
  15358. return function boundFn() {
  15359. return fn.apply(context, arguments);
  15360. };
  15361. }
  15362. /**
  15363. * let a boolean value also be a function that must return a boolean
  15364. * this first item in args will be used as the context
  15365. * @param {Boolean|Function} val
  15366. * @param {Array} [args]
  15367. * @returns {Boolean}
  15368. */
  15369. function boolOrFn(val, args) {
  15370. if (typeof val == TYPE_FUNCTION) {
  15371. return val.apply(args ? args[0] || undefined$1 : undefined$1, args);
  15372. }
  15373. return val;
  15374. }
  15375. /**
  15376. * use the val2 when val1 is undefined
  15377. * @param {*} val1
  15378. * @param {*} val2
  15379. * @returns {*}
  15380. */
  15381. function ifUndefined(val1, val2) {
  15382. return val1 === undefined$1 ? val2 : val1;
  15383. }
  15384. /**
  15385. * addEventListener with multiple events at once
  15386. * @param {EventTarget} target
  15387. * @param {String} types
  15388. * @param {Function} handler
  15389. */
  15390. function addEventListeners(target, types, handler) {
  15391. each(splitStr(types), function (type) {
  15392. target.addEventListener(type, handler, false);
  15393. });
  15394. }
  15395. /**
  15396. * removeEventListener with multiple events at once
  15397. * @param {EventTarget} target
  15398. * @param {String} types
  15399. * @param {Function} handler
  15400. */
  15401. function removeEventListeners(target, types, handler) {
  15402. each(splitStr(types), function (type) {
  15403. target.removeEventListener(type, handler, false);
  15404. });
  15405. }
  15406. /**
  15407. * find if a node is in the given parent
  15408. * @method hasParent
  15409. * @param {HTMLElement} node
  15410. * @param {HTMLElement} parent
  15411. * @return {Boolean} found
  15412. */
  15413. function hasParent(node, parent) {
  15414. while (node) {
  15415. if (node == parent) {
  15416. return true;
  15417. }
  15418. node = node.parentNode;
  15419. }
  15420. return false;
  15421. }
  15422. /**
  15423. * small indexOf wrapper
  15424. * @param {String} str
  15425. * @param {String} find
  15426. * @returns {Boolean} found
  15427. */
  15428. function inStr(str, find) {
  15429. return str.indexOf(find) > -1;
  15430. }
  15431. /**
  15432. * split string on whitespace
  15433. * @param {String} str
  15434. * @returns {Array} words
  15435. */
  15436. function splitStr(str) {
  15437. return str.trim().split(/\s+/g);
  15438. }
  15439. /**
  15440. * find if a array contains the object using indexOf or a simple polyFill
  15441. * @param {Array} src
  15442. * @param {String} find
  15443. * @param {String} [findByKey]
  15444. * @return {Boolean|Number} false when not found, or the index
  15445. */
  15446. function inArray(src, find, findByKey) {
  15447. if (src.indexOf && !findByKey) {
  15448. return src.indexOf(find);
  15449. } else {
  15450. var i = 0;
  15451. while (i < src.length) {
  15452. if (findByKey && src[i][findByKey] == find || !findByKey && src[i] === find) {
  15453. return i;
  15454. }
  15455. i++;
  15456. }
  15457. return -1;
  15458. }
  15459. }
  15460. /**
  15461. * convert array-like objects to real arrays
  15462. * @param {Object} obj
  15463. * @returns {Array}
  15464. */
  15465. function toArray(obj) {
  15466. return Array.prototype.slice.call(obj, 0);
  15467. }
  15468. /**
  15469. * unique array with objects based on a key (like 'id') or just by the array's value
  15470. * @param {Array} src [{id:1},{id:2},{id:1}]
  15471. * @param {String} [key]
  15472. * @param {Boolean} [sort=False]
  15473. * @returns {Array} [{id:1},{id:2}]
  15474. */
  15475. function uniqueArray(src, key, sort) {
  15476. var results = [];
  15477. var values = [];
  15478. var i = 0;
  15479. while (i < src.length) {
  15480. var val = key ? src[i][key] : src[i];
  15481. if (inArray(values, val) < 0) {
  15482. results.push(src[i]);
  15483. }
  15484. values[i] = val;
  15485. i++;
  15486. }
  15487. if (sort) {
  15488. if (!key) {
  15489. results = results.sort();
  15490. } else {
  15491. results = results.sort(function sortUniqueArray(a, b) {
  15492. return a[key] > b[key];
  15493. });
  15494. }
  15495. }
  15496. return results;
  15497. }
  15498. /**
  15499. * get the prefixed property
  15500. * @param {Object} obj
  15501. * @param {String} property
  15502. * @returns {String|Undefined} prefixed
  15503. */
  15504. function prefixed(obj, property) {
  15505. var prefix, prop;
  15506. var camelProp = property[0].toUpperCase() + property.slice(1);
  15507. var i = 0;
  15508. while (i < VENDOR_PREFIXES.length) {
  15509. prefix = VENDOR_PREFIXES[i];
  15510. prop = prefix ? prefix + camelProp : property;
  15511. if (prop in obj) {
  15512. return prop;
  15513. }
  15514. i++;
  15515. }
  15516. return undefined$1;
  15517. }
  15518. /**
  15519. * get a unique id
  15520. * @returns {number} uniqueId
  15521. */
  15522. var _uniqueId = 1;
  15523. function uniqueId() {
  15524. return _uniqueId++;
  15525. }
  15526. /**
  15527. * get the window object of an element
  15528. * @param {HTMLElement} element
  15529. * @returns {DocumentView|Window}
  15530. */
  15531. function getWindowForElement(element) {
  15532. var doc = element.ownerDocument || element;
  15533. return doc.defaultView || doc.parentWindow || window;
  15534. }
  15535. var MOBILE_REGEX = /mobile|tablet|ip(ad|hone|od)|android/i;
  15536. var SUPPORT_TOUCH = ('ontouchstart' in window);
  15537. var SUPPORT_POINTER_EVENTS = prefixed(window, 'PointerEvent') !== undefined$1;
  15538. var SUPPORT_ONLY_TOUCH = SUPPORT_TOUCH && MOBILE_REGEX.test(navigator.userAgent);
  15539. var INPUT_TYPE_TOUCH = 'touch';
  15540. var INPUT_TYPE_PEN = 'pen';
  15541. var INPUT_TYPE_MOUSE = 'mouse';
  15542. var INPUT_TYPE_KINECT = 'kinect';
  15543. var COMPUTE_INTERVAL = 25;
  15544. var INPUT_START = 1;
  15545. var INPUT_MOVE = 2;
  15546. var INPUT_END = 4;
  15547. var INPUT_CANCEL = 8;
  15548. var DIRECTION_NONE = 1;
  15549. var DIRECTION_LEFT = 2;
  15550. var DIRECTION_RIGHT = 4;
  15551. var DIRECTION_UP = 8;
  15552. var DIRECTION_DOWN = 16;
  15553. var DIRECTION_HORIZONTAL = DIRECTION_LEFT | DIRECTION_RIGHT;
  15554. var DIRECTION_VERTICAL = DIRECTION_UP | DIRECTION_DOWN;
  15555. var DIRECTION_ALL = DIRECTION_HORIZONTAL | DIRECTION_VERTICAL;
  15556. var PROPS_XY = ['x', 'y'];
  15557. var PROPS_CLIENT_XY = ['clientX', 'clientY'];
  15558. /**
  15559. * create new input type manager
  15560. * @param {Manager} manager
  15561. * @param {Function} callback
  15562. * @returns {Input}
  15563. * @constructor
  15564. */
  15565. function Input(manager, callback) {
  15566. var self = this;
  15567. this.manager = manager;
  15568. this.callback = callback;
  15569. this.element = manager.element;
  15570. this.target = manager.options.inputTarget; // smaller wrapper around the handler, for the scope and the enabled state of the manager,
  15571. // so when disabled the input events are completely bypassed.
  15572. this.domHandler = function (ev) {
  15573. if (boolOrFn(manager.options.enable, [manager])) {
  15574. self.handler(ev);
  15575. }
  15576. };
  15577. this.init();
  15578. }
  15579. Input.prototype = {
  15580. /**
  15581. * should handle the inputEvent data and trigger the callback
  15582. * @virtual
  15583. */
  15584. handler: function () {},
  15585. /**
  15586. * bind the events
  15587. */
  15588. init: function () {
  15589. this.evEl && addEventListeners(this.element, this.evEl, this.domHandler);
  15590. this.evTarget && addEventListeners(this.target, this.evTarget, this.domHandler);
  15591. this.evWin && addEventListeners(getWindowForElement(this.element), this.evWin, this.domHandler);
  15592. },
  15593. /**
  15594. * unbind the events
  15595. */
  15596. destroy: function () {
  15597. this.evEl && removeEventListeners(this.element, this.evEl, this.domHandler);
  15598. this.evTarget && removeEventListeners(this.target, this.evTarget, this.domHandler);
  15599. this.evWin && removeEventListeners(getWindowForElement(this.element), this.evWin, this.domHandler);
  15600. }
  15601. };
  15602. /**
  15603. * create new input type manager
  15604. * called by the Manager constructor
  15605. * @param {Hammer} manager
  15606. * @returns {Input}
  15607. */
  15608. function createInputInstance(manager) {
  15609. var Type;
  15610. var inputClass = manager.options.inputClass;
  15611. if (inputClass) {
  15612. Type = inputClass;
  15613. } else if (SUPPORT_POINTER_EVENTS) {
  15614. Type = PointerEventInput;
  15615. } else if (SUPPORT_ONLY_TOUCH) {
  15616. Type = TouchInput;
  15617. } else if (!SUPPORT_TOUCH) {
  15618. Type = MouseInput;
  15619. } else {
  15620. Type = TouchMouseInput;
  15621. }
  15622. return new Type(manager, inputHandler);
  15623. }
  15624. /**
  15625. * handle input events
  15626. * @param {Manager} manager
  15627. * @param {String} eventType
  15628. * @param {Object} input
  15629. */
  15630. function inputHandler(manager, eventType, input) {
  15631. var pointersLen = input.pointers.length;
  15632. var changedPointersLen = input.changedPointers.length;
  15633. var isFirst = eventType & INPUT_START && pointersLen - changedPointersLen === 0;
  15634. var isFinal = eventType & (INPUT_END | INPUT_CANCEL) && pointersLen - changedPointersLen === 0;
  15635. input.isFirst = !!isFirst;
  15636. input.isFinal = !!isFinal;
  15637. if (isFirst) {
  15638. manager.session = {};
  15639. } // source event is the normalized value of the domEvents
  15640. // like 'touchstart, mouseup, pointerdown'
  15641. input.eventType = eventType; // compute scale, rotation etc
  15642. computeInputData(manager, input); // emit secret event
  15643. manager.emit('hammer.input', input);
  15644. manager.recognize(input);
  15645. manager.session.prevInput = input;
  15646. }
  15647. /**
  15648. * extend the data with some usable properties like scale, rotate, velocity etc
  15649. * @param {Object} manager
  15650. * @param {Object} input
  15651. */
  15652. function computeInputData(manager, input) {
  15653. var session = manager.session;
  15654. var pointers = input.pointers;
  15655. var pointersLength = pointers.length; // store the first input to calculate the distance and direction
  15656. if (!session.firstInput) {
  15657. session.firstInput = simpleCloneInputData(input);
  15658. } // to compute scale and rotation we need to store the multiple touches
  15659. if (pointersLength > 1 && !session.firstMultiple) {
  15660. session.firstMultiple = simpleCloneInputData(input);
  15661. } else if (pointersLength === 1) {
  15662. session.firstMultiple = false;
  15663. }
  15664. var firstInput = session.firstInput;
  15665. var firstMultiple = session.firstMultiple;
  15666. var offsetCenter = firstMultiple ? firstMultiple.center : firstInput.center;
  15667. var center = input.center = getCenter(pointers);
  15668. input.timeStamp = now();
  15669. input.deltaTime = input.timeStamp - firstInput.timeStamp;
  15670. input.angle = getAngle(offsetCenter, center);
  15671. input.distance = getDistance(offsetCenter, center);
  15672. computeDeltaXY(session, input);
  15673. input.offsetDirection = getDirection(input.deltaX, input.deltaY);
  15674. var overallVelocity = getVelocity(input.deltaTime, input.deltaX, input.deltaY);
  15675. input.overallVelocityX = overallVelocity.x;
  15676. input.overallVelocityY = overallVelocity.y;
  15677. input.overallVelocity = abs(overallVelocity.x) > abs(overallVelocity.y) ? overallVelocity.x : overallVelocity.y;
  15678. input.scale = firstMultiple ? getScale(firstMultiple.pointers, pointers) : 1;
  15679. input.rotation = firstMultiple ? getRotation(firstMultiple.pointers, pointers) : 0;
  15680. input.maxPointers = !session.prevInput ? input.pointers.length : input.pointers.length > session.prevInput.maxPointers ? input.pointers.length : session.prevInput.maxPointers;
  15681. computeIntervalInputData(session, input); // find the correct target
  15682. var target = manager.element;
  15683. if (hasParent(input.srcEvent.target, target)) {
  15684. target = input.srcEvent.target;
  15685. }
  15686. input.target = target;
  15687. }
  15688. function computeDeltaXY(session, input) {
  15689. var center = input.center;
  15690. var offset = session.offsetDelta || {};
  15691. var prevDelta = session.prevDelta || {};
  15692. var prevInput = session.prevInput || {};
  15693. if (input.eventType === INPUT_START || prevInput.eventType === INPUT_END) {
  15694. prevDelta = session.prevDelta = {
  15695. x: prevInput.deltaX || 0,
  15696. y: prevInput.deltaY || 0
  15697. };
  15698. offset = session.offsetDelta = {
  15699. x: center.x,
  15700. y: center.y
  15701. };
  15702. }
  15703. input.deltaX = prevDelta.x + (center.x - offset.x);
  15704. input.deltaY = prevDelta.y + (center.y - offset.y);
  15705. }
  15706. /**
  15707. * velocity is calculated every x ms
  15708. * @param {Object} session
  15709. * @param {Object} input
  15710. */
  15711. function computeIntervalInputData(session, input) {
  15712. var last = session.lastInterval || input,
  15713. deltaTime = input.timeStamp - last.timeStamp,
  15714. velocity,
  15715. velocityX,
  15716. velocityY,
  15717. direction;
  15718. if (input.eventType != INPUT_CANCEL && (deltaTime > COMPUTE_INTERVAL || last.velocity === undefined$1)) {
  15719. var deltaX = input.deltaX - last.deltaX;
  15720. var deltaY = input.deltaY - last.deltaY;
  15721. var v = getVelocity(deltaTime, deltaX, deltaY);
  15722. velocityX = v.x;
  15723. velocityY = v.y;
  15724. velocity = abs(v.x) > abs(v.y) ? v.x : v.y;
  15725. direction = getDirection(deltaX, deltaY);
  15726. session.lastInterval = input;
  15727. } else {
  15728. // use latest velocity info if it doesn't overtake a minimum period
  15729. velocity = last.velocity;
  15730. velocityX = last.velocityX;
  15731. velocityY = last.velocityY;
  15732. direction = last.direction;
  15733. }
  15734. input.velocity = velocity;
  15735. input.velocityX = velocityX;
  15736. input.velocityY = velocityY;
  15737. input.direction = direction;
  15738. }
  15739. /**
  15740. * create a simple clone from the input used for storage of firstInput and firstMultiple
  15741. * @param {Object} input
  15742. * @returns {Object} clonedInputData
  15743. */
  15744. function simpleCloneInputData(input) {
  15745. // make a simple copy of the pointers because we will get a reference if we don't
  15746. // we only need clientXY for the calculations
  15747. var pointers = [];
  15748. var i = 0;
  15749. while (i < input.pointers.length) {
  15750. pointers[i] = {
  15751. clientX: round(input.pointers[i].clientX),
  15752. clientY: round(input.pointers[i].clientY)
  15753. };
  15754. i++;
  15755. }
  15756. return {
  15757. timeStamp: now(),
  15758. pointers: pointers,
  15759. center: getCenter(pointers),
  15760. deltaX: input.deltaX,
  15761. deltaY: input.deltaY
  15762. };
  15763. }
  15764. /**
  15765. * get the center of all the pointers
  15766. * @param {Array} pointers
  15767. * @return {Object} center contains `x` and `y` properties
  15768. */
  15769. function getCenter(pointers) {
  15770. var pointersLength = pointers.length; // no need to loop when only one touch
  15771. if (pointersLength === 1) {
  15772. return {
  15773. x: round(pointers[0].clientX),
  15774. y: round(pointers[0].clientY)
  15775. };
  15776. }
  15777. var x = 0,
  15778. y = 0,
  15779. i = 0;
  15780. while (i < pointersLength) {
  15781. x += pointers[i].clientX;
  15782. y += pointers[i].clientY;
  15783. i++;
  15784. }
  15785. return {
  15786. x: round(x / pointersLength),
  15787. y: round(y / pointersLength)
  15788. };
  15789. }
  15790. /**
  15791. * calculate the velocity between two points. unit is in px per ms.
  15792. * @param {Number} deltaTime
  15793. * @param {Number} x
  15794. * @param {Number} y
  15795. * @return {Object} velocity `x` and `y`
  15796. */
  15797. function getVelocity(deltaTime, x, y) {
  15798. return {
  15799. x: x / deltaTime || 0,
  15800. y: y / deltaTime || 0
  15801. };
  15802. }
  15803. /**
  15804. * get the direction between two points
  15805. * @param {Number} x
  15806. * @param {Number} y
  15807. * @return {Number} direction
  15808. */
  15809. function getDirection(x, y) {
  15810. if (x === y) {
  15811. return DIRECTION_NONE;
  15812. }
  15813. if (abs(x) >= abs(y)) {
  15814. return x < 0 ? DIRECTION_LEFT : DIRECTION_RIGHT;
  15815. }
  15816. return y < 0 ? DIRECTION_UP : DIRECTION_DOWN;
  15817. }
  15818. /**
  15819. * calculate the absolute distance between two points
  15820. * @param {Object} p1 {x, y}
  15821. * @param {Object} p2 {x, y}
  15822. * @param {Array} [props] containing x and y keys
  15823. * @return {Number} distance
  15824. */
  15825. function getDistance(p1, p2, props) {
  15826. if (!props) {
  15827. props = PROPS_XY;
  15828. }
  15829. var x = p2[props[0]] - p1[props[0]],
  15830. y = p2[props[1]] - p1[props[1]];
  15831. return Math.sqrt(x * x + y * y);
  15832. }
  15833. /**
  15834. * calculate the angle between two coordinates
  15835. * @param {Object} p1
  15836. * @param {Object} p2
  15837. * @param {Array} [props] containing x and y keys
  15838. * @return {Number} angle
  15839. */
  15840. function getAngle(p1, p2, props) {
  15841. if (!props) {
  15842. props = PROPS_XY;
  15843. }
  15844. var x = p2[props[0]] - p1[props[0]],
  15845. y = p2[props[1]] - p1[props[1]];
  15846. return Math.atan2(y, x) * 180 / Math.PI;
  15847. }
  15848. /**
  15849. * calculate the rotation degrees between two pointersets
  15850. * @param {Array} start array of pointers
  15851. * @param {Array} end array of pointers
  15852. * @return {Number} rotation
  15853. */
  15854. function getRotation(start, end) {
  15855. return getAngle(end[1], end[0], PROPS_CLIENT_XY) + getAngle(start[1], start[0], PROPS_CLIENT_XY);
  15856. }
  15857. /**
  15858. * calculate the scale factor between two pointersets
  15859. * no scale is 1, and goes down to 0 when pinched together, and bigger when pinched out
  15860. * @param {Array} start array of pointers
  15861. * @param {Array} end array of pointers
  15862. * @return {Number} scale
  15863. */
  15864. function getScale(start, end) {
  15865. return getDistance(end[0], end[1], PROPS_CLIENT_XY) / getDistance(start[0], start[1], PROPS_CLIENT_XY);
  15866. }
  15867. var MOUSE_INPUT_MAP = {
  15868. mousedown: INPUT_START,
  15869. mousemove: INPUT_MOVE,
  15870. mouseup: INPUT_END
  15871. };
  15872. var MOUSE_ELEMENT_EVENTS = 'mousedown';
  15873. var MOUSE_WINDOW_EVENTS = 'mousemove mouseup';
  15874. /**
  15875. * Mouse events input
  15876. * @constructor
  15877. * @extends Input
  15878. */
  15879. function MouseInput() {
  15880. this.evEl = MOUSE_ELEMENT_EVENTS;
  15881. this.evWin = MOUSE_WINDOW_EVENTS;
  15882. this.pressed = false; // mousedown state
  15883. Input.apply(this, arguments);
  15884. }
  15885. inherit(MouseInput, Input, {
  15886. /**
  15887. * handle mouse events
  15888. * @param {Object} ev
  15889. */
  15890. handler: function MEhandler(ev) {
  15891. var eventType = MOUSE_INPUT_MAP[ev.type]; // on start we want to have the left mouse button down
  15892. if (eventType & INPUT_START && ev.button === 0) {
  15893. this.pressed = true;
  15894. }
  15895. if (eventType & INPUT_MOVE && ev.which !== 1) {
  15896. eventType = INPUT_END;
  15897. } // mouse must be down
  15898. if (!this.pressed) {
  15899. return;
  15900. }
  15901. if (eventType & INPUT_END) {
  15902. this.pressed = false;
  15903. }
  15904. this.callback(this.manager, eventType, {
  15905. pointers: [ev],
  15906. changedPointers: [ev],
  15907. pointerType: INPUT_TYPE_MOUSE,
  15908. srcEvent: ev
  15909. });
  15910. }
  15911. });
  15912. var POINTER_INPUT_MAP = {
  15913. pointerdown: INPUT_START,
  15914. pointermove: INPUT_MOVE,
  15915. pointerup: INPUT_END,
  15916. pointercancel: INPUT_CANCEL,
  15917. pointerout: INPUT_CANCEL
  15918. }; // in IE10 the pointer types is defined as an enum
  15919. var IE10_POINTER_TYPE_ENUM = {
  15920. 2: INPUT_TYPE_TOUCH,
  15921. 3: INPUT_TYPE_PEN,
  15922. 4: INPUT_TYPE_MOUSE,
  15923. 5: INPUT_TYPE_KINECT // see https://twitter.com/jacobrossi/status/480596438489890816
  15924. };
  15925. var POINTER_ELEMENT_EVENTS = 'pointerdown';
  15926. var POINTER_WINDOW_EVENTS = 'pointermove pointerup pointercancel'; // IE10 has prefixed support, and case-sensitive
  15927. if (window.MSPointerEvent && !window.PointerEvent) {
  15928. POINTER_ELEMENT_EVENTS = 'MSPointerDown';
  15929. POINTER_WINDOW_EVENTS = 'MSPointerMove MSPointerUp MSPointerCancel';
  15930. }
  15931. /**
  15932. * Pointer events input
  15933. * @constructor
  15934. * @extends Input
  15935. */
  15936. function PointerEventInput() {
  15937. this.evEl = POINTER_ELEMENT_EVENTS;
  15938. this.evWin = POINTER_WINDOW_EVENTS;
  15939. Input.apply(this, arguments);
  15940. this.store = this.manager.session.pointerEvents = [];
  15941. }
  15942. inherit(PointerEventInput, Input, {
  15943. /**
  15944. * handle mouse events
  15945. * @param {Object} ev
  15946. */
  15947. handler: function PEhandler(ev) {
  15948. var store = this.store;
  15949. var removePointer = false;
  15950. var eventTypeNormalized = ev.type.toLowerCase().replace('ms', '');
  15951. var eventType = POINTER_INPUT_MAP[eventTypeNormalized];
  15952. var pointerType = IE10_POINTER_TYPE_ENUM[ev.pointerType] || ev.pointerType;
  15953. var isTouch = pointerType == INPUT_TYPE_TOUCH; // get index of the event in the store
  15954. var storeIndex = inArray(store, ev.pointerId, 'pointerId'); // start and mouse must be down
  15955. if (eventType & INPUT_START && (ev.button === 0 || isTouch)) {
  15956. if (storeIndex < 0) {
  15957. store.push(ev);
  15958. storeIndex = store.length - 1;
  15959. }
  15960. } else if (eventType & (INPUT_END | INPUT_CANCEL)) {
  15961. removePointer = true;
  15962. } // it not found, so the pointer hasn't been down (so it's probably a hover)
  15963. if (storeIndex < 0) {
  15964. return;
  15965. } // update the event in the store
  15966. store[storeIndex] = ev;
  15967. this.callback(this.manager, eventType, {
  15968. pointers: store,
  15969. changedPointers: [ev],
  15970. pointerType: pointerType,
  15971. srcEvent: ev
  15972. });
  15973. if (removePointer) {
  15974. // remove from the store
  15975. store.splice(storeIndex, 1);
  15976. }
  15977. }
  15978. });
  15979. var SINGLE_TOUCH_INPUT_MAP = {
  15980. touchstart: INPUT_START,
  15981. touchmove: INPUT_MOVE,
  15982. touchend: INPUT_END,
  15983. touchcancel: INPUT_CANCEL
  15984. };
  15985. var SINGLE_TOUCH_TARGET_EVENTS = 'touchstart';
  15986. var SINGLE_TOUCH_WINDOW_EVENTS = 'touchstart touchmove touchend touchcancel';
  15987. /**
  15988. * Touch events input
  15989. * @constructor
  15990. * @extends Input
  15991. */
  15992. function SingleTouchInput() {
  15993. this.evTarget = SINGLE_TOUCH_TARGET_EVENTS;
  15994. this.evWin = SINGLE_TOUCH_WINDOW_EVENTS;
  15995. this.started = false;
  15996. Input.apply(this, arguments);
  15997. }
  15998. inherit(SingleTouchInput, Input, {
  15999. handler: function TEhandler(ev) {
  16000. var type = SINGLE_TOUCH_INPUT_MAP[ev.type]; // should we handle the touch events?
  16001. if (type === INPUT_START) {
  16002. this.started = true;
  16003. }
  16004. if (!this.started) {
  16005. return;
  16006. }
  16007. var touches = normalizeSingleTouches.call(this, ev, type); // when done, reset the started state
  16008. if (type & (INPUT_END | INPUT_CANCEL) && touches[0].length - touches[1].length === 0) {
  16009. this.started = false;
  16010. }
  16011. this.callback(this.manager, type, {
  16012. pointers: touches[0],
  16013. changedPointers: touches[1],
  16014. pointerType: INPUT_TYPE_TOUCH,
  16015. srcEvent: ev
  16016. });
  16017. }
  16018. });
  16019. /**
  16020. * @this {TouchInput}
  16021. * @param {Object} ev
  16022. * @param {Number} type flag
  16023. * @returns {undefined|Array} [all, changed]
  16024. */
  16025. function normalizeSingleTouches(ev, type) {
  16026. var all = toArray(ev.touches);
  16027. var changed = toArray(ev.changedTouches);
  16028. if (type & (INPUT_END | INPUT_CANCEL)) {
  16029. all = uniqueArray(all.concat(changed), 'identifier', true);
  16030. }
  16031. return [all, changed];
  16032. }
  16033. var TOUCH_INPUT_MAP = {
  16034. touchstart: INPUT_START,
  16035. touchmove: INPUT_MOVE,
  16036. touchend: INPUT_END,
  16037. touchcancel: INPUT_CANCEL
  16038. };
  16039. var TOUCH_TARGET_EVENTS = 'touchstart touchmove touchend touchcancel';
  16040. /**
  16041. * Multi-user touch events input
  16042. * @constructor
  16043. * @extends Input
  16044. */
  16045. function TouchInput() {
  16046. this.evTarget = TOUCH_TARGET_EVENTS;
  16047. this.targetIds = {};
  16048. Input.apply(this, arguments);
  16049. }
  16050. inherit(TouchInput, Input, {
  16051. handler: function MTEhandler(ev) {
  16052. var type = TOUCH_INPUT_MAP[ev.type];
  16053. var touches = getTouches.call(this, ev, type);
  16054. if (!touches) {
  16055. return;
  16056. }
  16057. this.callback(this.manager, type, {
  16058. pointers: touches[0],
  16059. changedPointers: touches[1],
  16060. pointerType: INPUT_TYPE_TOUCH,
  16061. srcEvent: ev
  16062. });
  16063. }
  16064. });
  16065. /**
  16066. * @this {TouchInput}
  16067. * @param {Object} ev
  16068. * @param {Number} type flag
  16069. * @returns {undefined|Array} [all, changed]
  16070. */
  16071. function getTouches(ev, type) {
  16072. var allTouches = toArray(ev.touches);
  16073. var targetIds = this.targetIds; // when there is only one touch, the process can be simplified
  16074. if (type & (INPUT_START | INPUT_MOVE) && allTouches.length === 1) {
  16075. targetIds[allTouches[0].identifier] = true;
  16076. return [allTouches, allTouches];
  16077. }
  16078. var i,
  16079. targetTouches,
  16080. changedTouches = toArray(ev.changedTouches),
  16081. changedTargetTouches = [],
  16082. target = this.target; // get target touches from touches
  16083. targetTouches = allTouches.filter(function (touch) {
  16084. return hasParent(touch.target, target);
  16085. }); // collect touches
  16086. if (type === INPUT_START) {
  16087. i = 0;
  16088. while (i < targetTouches.length) {
  16089. targetIds[targetTouches[i].identifier] = true;
  16090. i++;
  16091. }
  16092. } // filter changed touches to only contain touches that exist in the collected target ids
  16093. i = 0;
  16094. while (i < changedTouches.length) {
  16095. if (targetIds[changedTouches[i].identifier]) {
  16096. changedTargetTouches.push(changedTouches[i]);
  16097. } // cleanup removed touches
  16098. if (type & (INPUT_END | INPUT_CANCEL)) {
  16099. delete targetIds[changedTouches[i].identifier];
  16100. }
  16101. i++;
  16102. }
  16103. if (!changedTargetTouches.length) {
  16104. return;
  16105. }
  16106. return [// merge targetTouches with changedTargetTouches so it contains ALL touches, including 'end' and 'cancel'
  16107. uniqueArray(targetTouches.concat(changedTargetTouches), 'identifier', true), changedTargetTouches];
  16108. }
  16109. /**
  16110. * Combined touch and mouse input
  16111. *
  16112. * Touch has a higher priority then mouse, and while touching no mouse events are allowed.
  16113. * This because touch devices also emit mouse events while doing a touch.
  16114. *
  16115. * @constructor
  16116. * @extends Input
  16117. */
  16118. var DEDUP_TIMEOUT = 2500;
  16119. var DEDUP_DISTANCE = 25;
  16120. function TouchMouseInput() {
  16121. Input.apply(this, arguments);
  16122. var handler = bindFn(this.handler, this);
  16123. this.touch = new TouchInput(this.manager, handler);
  16124. this.mouse = new MouseInput(this.manager, handler);
  16125. this.primaryTouch = null;
  16126. this.lastTouches = [];
  16127. }
  16128. inherit(TouchMouseInput, Input, {
  16129. /**
  16130. * handle mouse and touch events
  16131. * @param {Hammer} manager
  16132. * @param {String} inputEvent
  16133. * @param {Object} inputData
  16134. */
  16135. handler: function TMEhandler(manager, inputEvent, inputData) {
  16136. var isTouch = inputData.pointerType == INPUT_TYPE_TOUCH,
  16137. isMouse = inputData.pointerType == INPUT_TYPE_MOUSE;
  16138. if (isMouse && inputData.sourceCapabilities && inputData.sourceCapabilities.firesTouchEvents) {
  16139. return;
  16140. } // when we're in a touch event, record touches to de-dupe synthetic mouse event
  16141. if (isTouch) {
  16142. recordTouches.call(this, inputEvent, inputData);
  16143. } else if (isMouse && isSyntheticEvent.call(this, inputData)) {
  16144. return;
  16145. }
  16146. this.callback(manager, inputEvent, inputData);
  16147. },
  16148. /**
  16149. * remove the event listeners
  16150. */
  16151. destroy: function destroy() {
  16152. this.touch.destroy();
  16153. this.mouse.destroy();
  16154. }
  16155. });
  16156. function recordTouches(eventType, eventData) {
  16157. if (eventType & INPUT_START) {
  16158. this.primaryTouch = eventData.changedPointers[0].identifier;
  16159. setLastTouch.call(this, eventData);
  16160. } else if (eventType & (INPUT_END | INPUT_CANCEL)) {
  16161. setLastTouch.call(this, eventData);
  16162. }
  16163. }
  16164. function setLastTouch(eventData) {
  16165. var touch = eventData.changedPointers[0];
  16166. if (touch.identifier === this.primaryTouch) {
  16167. var lastTouch = {
  16168. x: touch.clientX,
  16169. y: touch.clientY
  16170. };
  16171. this.lastTouches.push(lastTouch);
  16172. var lts = this.lastTouches;
  16173. var removeLastTouch = function () {
  16174. var i = lts.indexOf(lastTouch);
  16175. if (i > -1) {
  16176. lts.splice(i, 1);
  16177. }
  16178. };
  16179. setTimeout(removeLastTouch, DEDUP_TIMEOUT);
  16180. }
  16181. }
  16182. function isSyntheticEvent(eventData) {
  16183. var x = eventData.srcEvent.clientX,
  16184. y = eventData.srcEvent.clientY;
  16185. for (var i = 0; i < this.lastTouches.length; i++) {
  16186. var t = this.lastTouches[i];
  16187. var dx = Math.abs(x - t.x),
  16188. dy = Math.abs(y - t.y);
  16189. if (dx <= DEDUP_DISTANCE && dy <= DEDUP_DISTANCE) {
  16190. return true;
  16191. }
  16192. }
  16193. return false;
  16194. }
  16195. var PREFIXED_TOUCH_ACTION = prefixed(TEST_ELEMENT.style, 'touchAction');
  16196. var NATIVE_TOUCH_ACTION = PREFIXED_TOUCH_ACTION !== undefined$1; // magical touchAction value
  16197. var TOUCH_ACTION_COMPUTE = 'compute';
  16198. var TOUCH_ACTION_AUTO = 'auto';
  16199. var TOUCH_ACTION_MANIPULATION = 'manipulation'; // not implemented
  16200. var TOUCH_ACTION_NONE = 'none';
  16201. var TOUCH_ACTION_PAN_X = 'pan-x';
  16202. var TOUCH_ACTION_PAN_Y = 'pan-y';
  16203. var TOUCH_ACTION_MAP = getTouchActionProps();
  16204. /**
  16205. * Touch Action
  16206. * sets the touchAction property or uses the js alternative
  16207. * @param {Manager} manager
  16208. * @param {String} value
  16209. * @constructor
  16210. */
  16211. function TouchAction(manager, value) {
  16212. this.manager = manager;
  16213. this.set(value);
  16214. }
  16215. TouchAction.prototype = {
  16216. /**
  16217. * set the touchAction value on the element or enable the polyfill
  16218. * @param {String} value
  16219. */
  16220. set: function (value) {
  16221. // find out the touch-action by the event handlers
  16222. if (value == TOUCH_ACTION_COMPUTE) {
  16223. value = this.compute();
  16224. }
  16225. if (NATIVE_TOUCH_ACTION && this.manager.element.style && TOUCH_ACTION_MAP[value]) {
  16226. this.manager.element.style[PREFIXED_TOUCH_ACTION] = value;
  16227. }
  16228. this.actions = value.toLowerCase().trim();
  16229. },
  16230. /**
  16231. * just re-set the touchAction value
  16232. */
  16233. update: function () {
  16234. this.set(this.manager.options.touchAction);
  16235. },
  16236. /**
  16237. * compute the value for the touchAction property based on the recognizer's settings
  16238. * @returns {String} value
  16239. */
  16240. compute: function () {
  16241. var actions = [];
  16242. each(this.manager.recognizers, function (recognizer) {
  16243. if (boolOrFn(recognizer.options.enable, [recognizer])) {
  16244. actions = actions.concat(recognizer.getTouchAction());
  16245. }
  16246. });
  16247. return cleanTouchActions(actions.join(' '));
  16248. },
  16249. /**
  16250. * this method is called on each input cycle and provides the preventing of the browser behavior
  16251. * @param {Object} input
  16252. */
  16253. preventDefaults: function (input) {
  16254. var srcEvent = input.srcEvent;
  16255. var direction = input.offsetDirection; // if the touch action did prevented once this session
  16256. if (this.manager.session.prevented) {
  16257. srcEvent.preventDefault();
  16258. return;
  16259. }
  16260. var actions = this.actions;
  16261. var hasNone = inStr(actions, TOUCH_ACTION_NONE) && !TOUCH_ACTION_MAP[TOUCH_ACTION_NONE];
  16262. var hasPanY = inStr(actions, TOUCH_ACTION_PAN_Y) && !TOUCH_ACTION_MAP[TOUCH_ACTION_PAN_Y];
  16263. var hasPanX = inStr(actions, TOUCH_ACTION_PAN_X) && !TOUCH_ACTION_MAP[TOUCH_ACTION_PAN_X];
  16264. if (hasNone) {
  16265. //do not prevent defaults if this is a tap gesture
  16266. var isTapPointer = input.pointers.length === 1;
  16267. var isTapMovement = input.distance < 2;
  16268. var isTapTouchTime = input.deltaTime < 250;
  16269. if (isTapPointer && isTapMovement && isTapTouchTime) {
  16270. return;
  16271. }
  16272. }
  16273. if (hasPanX && hasPanY) {
  16274. // `pan-x pan-y` means browser handles all scrolling/panning, do not prevent
  16275. return;
  16276. }
  16277. if (hasNone || hasPanY && direction & DIRECTION_HORIZONTAL || hasPanX && direction & DIRECTION_VERTICAL) {
  16278. return this.preventSrc(srcEvent);
  16279. }
  16280. },
  16281. /**
  16282. * call preventDefault to prevent the browser's default behavior (scrolling in most cases)
  16283. * @param {Object} srcEvent
  16284. */
  16285. preventSrc: function (srcEvent) {
  16286. this.manager.session.prevented = true;
  16287. srcEvent.preventDefault();
  16288. }
  16289. };
  16290. /**
  16291. * when the touchActions are collected they are not a valid value, so we need to clean things up. *
  16292. * @param {String} actions
  16293. * @returns {*}
  16294. */
  16295. function cleanTouchActions(actions) {
  16296. // none
  16297. if (inStr(actions, TOUCH_ACTION_NONE)) {
  16298. return TOUCH_ACTION_NONE;
  16299. }
  16300. var hasPanX = inStr(actions, TOUCH_ACTION_PAN_X);
  16301. var hasPanY = inStr(actions, TOUCH_ACTION_PAN_Y); // if both pan-x and pan-y are set (different recognizers
  16302. // for different directions, e.g. horizontal pan but vertical swipe?)
  16303. // we need none (as otherwise with pan-x pan-y combined none of these
  16304. // recognizers will work, since the browser would handle all panning
  16305. if (hasPanX && hasPanY) {
  16306. return TOUCH_ACTION_NONE;
  16307. } // pan-x OR pan-y
  16308. if (hasPanX || hasPanY) {
  16309. return hasPanX ? TOUCH_ACTION_PAN_X : TOUCH_ACTION_PAN_Y;
  16310. } // manipulation
  16311. if (inStr(actions, TOUCH_ACTION_MANIPULATION)) {
  16312. return TOUCH_ACTION_MANIPULATION;
  16313. }
  16314. return TOUCH_ACTION_AUTO;
  16315. }
  16316. function getTouchActionProps() {
  16317. if (!NATIVE_TOUCH_ACTION) {
  16318. return false;
  16319. }
  16320. var touchMap = {};
  16321. var cssSupports = window.CSS && window.CSS.supports;
  16322. ['auto', 'manipulation', 'pan-y', 'pan-x', 'pan-x pan-y', 'none'].forEach(function (val) {
  16323. // If css.supports is not supported but there is native touch-action assume it supports
  16324. // all values. This is the case for IE 10 and 11.
  16325. touchMap[val] = cssSupports ? window.CSS.supports('touch-action', val) : true;
  16326. });
  16327. return touchMap;
  16328. }
  16329. /**
  16330. * Recognizer flow explained; *
  16331. * All recognizers have the initial state of POSSIBLE when a input session starts.
  16332. * The definition of a input session is from the first input until the last input, with all it's movement in it. *
  16333. * Example session for mouse-input: mousedown -> mousemove -> mouseup
  16334. *
  16335. * On each recognizing cycle (see Manager.recognize) the .recognize() method is executed
  16336. * which determines with state it should be.
  16337. *
  16338. * If the recognizer has the state FAILED, CANCELLED or RECOGNIZED (equals ENDED), it is reset to
  16339. * POSSIBLE to give it another change on the next cycle.
  16340. *
  16341. * Possible
  16342. * |
  16343. * +-----+---------------+
  16344. * | |
  16345. * +-----+-----+ |
  16346. * | | |
  16347. * Failed Cancelled |
  16348. * +-------+------+
  16349. * | |
  16350. * Recognized Began
  16351. * |
  16352. * Changed
  16353. * |
  16354. * Ended/Recognized
  16355. */
  16356. var STATE_POSSIBLE = 1;
  16357. var STATE_BEGAN = 2;
  16358. var STATE_CHANGED = 4;
  16359. var STATE_ENDED = 8;
  16360. var STATE_RECOGNIZED = STATE_ENDED;
  16361. var STATE_CANCELLED = 16;
  16362. var STATE_FAILED = 32;
  16363. /**
  16364. * Recognizer
  16365. * Every recognizer needs to extend from this class.
  16366. * @constructor
  16367. * @param {Object} options
  16368. */
  16369. function Recognizer(options) {
  16370. this.options = assign({}, this.defaults, options || {});
  16371. this.id = uniqueId();
  16372. this.manager = null; // default is enable true
  16373. this.options.enable = ifUndefined(this.options.enable, true);
  16374. this.state = STATE_POSSIBLE;
  16375. this.simultaneous = {};
  16376. this.requireFail = [];
  16377. }
  16378. Recognizer.prototype = {
  16379. /**
  16380. * @virtual
  16381. * @type {Object}
  16382. */
  16383. defaults: {},
  16384. /**
  16385. * set options
  16386. * @param {Object} options
  16387. * @return {Recognizer}
  16388. */
  16389. set: function (options) {
  16390. assign(this.options, options); // also update the touchAction, in case something changed about the directions/enabled state
  16391. this.manager && this.manager.touchAction.update();
  16392. return this;
  16393. },
  16394. /**
  16395. * recognize simultaneous with an other recognizer.
  16396. * @param {Recognizer} otherRecognizer
  16397. * @returns {Recognizer} this
  16398. */
  16399. recognizeWith: function (otherRecognizer) {
  16400. if (invokeArrayArg(otherRecognizer, 'recognizeWith', this)) {
  16401. return this;
  16402. }
  16403. var simultaneous = this.simultaneous;
  16404. otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this);
  16405. if (!simultaneous[otherRecognizer.id]) {
  16406. simultaneous[otherRecognizer.id] = otherRecognizer;
  16407. otherRecognizer.recognizeWith(this);
  16408. }
  16409. return this;
  16410. },
  16411. /**
  16412. * drop the simultaneous link. it doesnt remove the link on the other recognizer.
  16413. * @param {Recognizer} otherRecognizer
  16414. * @returns {Recognizer} this
  16415. */
  16416. dropRecognizeWith: function (otherRecognizer) {
  16417. if (invokeArrayArg(otherRecognizer, 'dropRecognizeWith', this)) {
  16418. return this;
  16419. }
  16420. otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this);
  16421. delete this.simultaneous[otherRecognizer.id];
  16422. return this;
  16423. },
  16424. /**
  16425. * recognizer can only run when an other is failing
  16426. * @param {Recognizer} otherRecognizer
  16427. * @returns {Recognizer} this
  16428. */
  16429. requireFailure: function (otherRecognizer) {
  16430. if (invokeArrayArg(otherRecognizer, 'requireFailure', this)) {
  16431. return this;
  16432. }
  16433. var requireFail = this.requireFail;
  16434. otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this);
  16435. if (inArray(requireFail, otherRecognizer) === -1) {
  16436. requireFail.push(otherRecognizer);
  16437. otherRecognizer.requireFailure(this);
  16438. }
  16439. return this;
  16440. },
  16441. /**
  16442. * drop the requireFailure link. it does not remove the link on the other recognizer.
  16443. * @param {Recognizer} otherRecognizer
  16444. * @returns {Recognizer} this
  16445. */
  16446. dropRequireFailure: function (otherRecognizer) {
  16447. if (invokeArrayArg(otherRecognizer, 'dropRequireFailure', this)) {
  16448. return this;
  16449. }
  16450. otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this);
  16451. var index = inArray(this.requireFail, otherRecognizer);
  16452. if (index > -1) {
  16453. this.requireFail.splice(index, 1);
  16454. }
  16455. return this;
  16456. },
  16457. /**
  16458. * has require failures boolean
  16459. * @returns {boolean}
  16460. */
  16461. hasRequireFailures: function () {
  16462. return this.requireFail.length > 0;
  16463. },
  16464. /**
  16465. * if the recognizer can recognize simultaneous with an other recognizer
  16466. * @param {Recognizer} otherRecognizer
  16467. * @returns {Boolean}
  16468. */
  16469. canRecognizeWith: function (otherRecognizer) {
  16470. return !!this.simultaneous[otherRecognizer.id];
  16471. },
  16472. /**
  16473. * You should use `tryEmit` instead of `emit` directly to check
  16474. * that all the needed recognizers has failed before emitting.
  16475. * @param {Object} input
  16476. */
  16477. emit: function (input) {
  16478. var self = this;
  16479. var state = this.state;
  16480. function emit(event) {
  16481. self.manager.emit(event, input);
  16482. } // 'panstart' and 'panmove'
  16483. if (state < STATE_ENDED) {
  16484. emit(self.options.event + stateStr(state));
  16485. }
  16486. emit(self.options.event); // simple 'eventName' events
  16487. if (input.additionalEvent) {
  16488. // additional event(panleft, panright, pinchin, pinchout...)
  16489. emit(input.additionalEvent);
  16490. } // panend and pancancel
  16491. if (state >= STATE_ENDED) {
  16492. emit(self.options.event + stateStr(state));
  16493. }
  16494. },
  16495. /**
  16496. * Check that all the require failure recognizers has failed,
  16497. * if true, it emits a gesture event,
  16498. * otherwise, setup the state to FAILED.
  16499. * @param {Object} input
  16500. */
  16501. tryEmit: function (input) {
  16502. if (this.canEmit()) {
  16503. return this.emit(input);
  16504. } // it's failing anyway
  16505. this.state = STATE_FAILED;
  16506. },
  16507. /**
  16508. * can we emit?
  16509. * @returns {boolean}
  16510. */
  16511. canEmit: function () {
  16512. var i = 0;
  16513. while (i < this.requireFail.length) {
  16514. if (!(this.requireFail[i].state & (STATE_FAILED | STATE_POSSIBLE))) {
  16515. return false;
  16516. }
  16517. i++;
  16518. }
  16519. return true;
  16520. },
  16521. /**
  16522. * update the recognizer
  16523. * @param {Object} inputData
  16524. */
  16525. recognize: function (inputData) {
  16526. // make a new copy of the inputData
  16527. // so we can change the inputData without messing up the other recognizers
  16528. var inputDataClone = assign({}, inputData); // is is enabled and allow recognizing?
  16529. if (!boolOrFn(this.options.enable, [this, inputDataClone])) {
  16530. this.reset();
  16531. this.state = STATE_FAILED;
  16532. return;
  16533. } // reset when we've reached the end
  16534. if (this.state & (STATE_RECOGNIZED | STATE_CANCELLED | STATE_FAILED)) {
  16535. this.state = STATE_POSSIBLE;
  16536. }
  16537. this.state = this.process(inputDataClone); // the recognizer has recognized a gesture
  16538. // so trigger an event
  16539. if (this.state & (STATE_BEGAN | STATE_CHANGED | STATE_ENDED | STATE_CANCELLED)) {
  16540. this.tryEmit(inputDataClone);
  16541. }
  16542. },
  16543. /**
  16544. * return the state of the recognizer
  16545. * the actual recognizing happens in this method
  16546. * @virtual
  16547. * @param {Object} inputData
  16548. * @returns {Const} STATE
  16549. */
  16550. process: function (inputData) {},
  16551. // jshint ignore:line
  16552. /**
  16553. * return the preferred touch-action
  16554. * @virtual
  16555. * @returns {Array}
  16556. */
  16557. getTouchAction: function () {},
  16558. /**
  16559. * called when the gesture isn't allowed to recognize
  16560. * like when another is being recognized or it is disabled
  16561. * @virtual
  16562. */
  16563. reset: function () {}
  16564. };
  16565. /**
  16566. * get a usable string, used as event postfix
  16567. * @param {Const} state
  16568. * @returns {String} state
  16569. */
  16570. function stateStr(state) {
  16571. if (state & STATE_CANCELLED) {
  16572. return 'cancel';
  16573. } else if (state & STATE_ENDED) {
  16574. return 'end';
  16575. } else if (state & STATE_CHANGED) {
  16576. return 'move';
  16577. } else if (state & STATE_BEGAN) {
  16578. return 'start';
  16579. }
  16580. return '';
  16581. }
  16582. /**
  16583. * direction cons to string
  16584. * @param {Const} direction
  16585. * @returns {String}
  16586. */
  16587. function directionStr(direction) {
  16588. if (direction == DIRECTION_DOWN) {
  16589. return 'down';
  16590. } else if (direction == DIRECTION_UP) {
  16591. return 'up';
  16592. } else if (direction == DIRECTION_LEFT) {
  16593. return 'left';
  16594. } else if (direction == DIRECTION_RIGHT) {
  16595. return 'right';
  16596. }
  16597. return '';
  16598. }
  16599. /**
  16600. * get a recognizer by name if it is bound to a manager
  16601. * @param {Recognizer|String} otherRecognizer
  16602. * @param {Recognizer} recognizer
  16603. * @returns {Recognizer}
  16604. */
  16605. function getRecognizerByNameIfManager(otherRecognizer, recognizer) {
  16606. var manager = recognizer.manager;
  16607. if (manager) {
  16608. return manager.get(otherRecognizer);
  16609. }
  16610. return otherRecognizer;
  16611. }
  16612. /**
  16613. * This recognizer is just used as a base for the simple attribute recognizers.
  16614. * @constructor
  16615. * @extends Recognizer
  16616. */
  16617. function AttrRecognizer() {
  16618. Recognizer.apply(this, arguments);
  16619. }
  16620. inherit(AttrRecognizer, Recognizer, {
  16621. /**
  16622. * @namespace
  16623. * @memberof AttrRecognizer
  16624. */
  16625. defaults: {
  16626. /**
  16627. * @type {Number}
  16628. * @default 1
  16629. */
  16630. pointers: 1
  16631. },
  16632. /**
  16633. * Used to check if it the recognizer receives valid input, like input.distance > 10.
  16634. * @memberof AttrRecognizer
  16635. * @param {Object} input
  16636. * @returns {Boolean} recognized
  16637. */
  16638. attrTest: function (input) {
  16639. var optionPointers = this.options.pointers;
  16640. return optionPointers === 0 || input.pointers.length === optionPointers;
  16641. },
  16642. /**
  16643. * Process the input and return the state for the recognizer
  16644. * @memberof AttrRecognizer
  16645. * @param {Object} input
  16646. * @returns {*} State
  16647. */
  16648. process: function (input) {
  16649. var state = this.state;
  16650. var eventType = input.eventType;
  16651. var isRecognized = state & (STATE_BEGAN | STATE_CHANGED);
  16652. var isValid = this.attrTest(input); // on cancel input and we've recognized before, return STATE_CANCELLED
  16653. if (isRecognized && (eventType & INPUT_CANCEL || !isValid)) {
  16654. return state | STATE_CANCELLED;
  16655. } else if (isRecognized || isValid) {
  16656. if (eventType & INPUT_END) {
  16657. return state | STATE_ENDED;
  16658. } else if (!(state & STATE_BEGAN)) {
  16659. return STATE_BEGAN;
  16660. }
  16661. return state | STATE_CHANGED;
  16662. }
  16663. return STATE_FAILED;
  16664. }
  16665. });
  16666. /**
  16667. * Pan
  16668. * Recognized when the pointer is down and moved in the allowed direction.
  16669. * @constructor
  16670. * @extends AttrRecognizer
  16671. */
  16672. function PanRecognizer() {
  16673. AttrRecognizer.apply(this, arguments);
  16674. this.pX = null;
  16675. this.pY = null;
  16676. }
  16677. inherit(PanRecognizer, AttrRecognizer, {
  16678. /**
  16679. * @namespace
  16680. * @memberof PanRecognizer
  16681. */
  16682. defaults: {
  16683. event: 'pan',
  16684. threshold: 10,
  16685. pointers: 1,
  16686. direction: DIRECTION_ALL
  16687. },
  16688. getTouchAction: function () {
  16689. var direction = this.options.direction;
  16690. var actions = [];
  16691. if (direction & DIRECTION_HORIZONTAL) {
  16692. actions.push(TOUCH_ACTION_PAN_Y);
  16693. }
  16694. if (direction & DIRECTION_VERTICAL) {
  16695. actions.push(TOUCH_ACTION_PAN_X);
  16696. }
  16697. return actions;
  16698. },
  16699. directionTest: function (input) {
  16700. var options = this.options;
  16701. var hasMoved = true;
  16702. var distance = input.distance;
  16703. var direction = input.direction;
  16704. var x = input.deltaX;
  16705. var y = input.deltaY; // lock to axis?
  16706. if (!(direction & options.direction)) {
  16707. if (options.direction & DIRECTION_HORIZONTAL) {
  16708. direction = x === 0 ? DIRECTION_NONE : x < 0 ? DIRECTION_LEFT : DIRECTION_RIGHT;
  16709. hasMoved = x != this.pX;
  16710. distance = Math.abs(input.deltaX);
  16711. } else {
  16712. direction = y === 0 ? DIRECTION_NONE : y < 0 ? DIRECTION_UP : DIRECTION_DOWN;
  16713. hasMoved = y != this.pY;
  16714. distance = Math.abs(input.deltaY);
  16715. }
  16716. }
  16717. input.direction = direction;
  16718. return hasMoved && distance > options.threshold && direction & options.direction;
  16719. },
  16720. attrTest: function (input) {
  16721. return AttrRecognizer.prototype.attrTest.call(this, input) && (this.state & STATE_BEGAN || !(this.state & STATE_BEGAN) && this.directionTest(input));
  16722. },
  16723. emit: function (input) {
  16724. this.pX = input.deltaX;
  16725. this.pY = input.deltaY;
  16726. var direction = directionStr(input.direction);
  16727. if (direction) {
  16728. input.additionalEvent = this.options.event + direction;
  16729. }
  16730. this._super.emit.call(this, input);
  16731. }
  16732. });
  16733. /**
  16734. * Pinch
  16735. * Recognized when two or more pointers are moving toward (zoom-in) or away from each other (zoom-out).
  16736. * @constructor
  16737. * @extends AttrRecognizer
  16738. */
  16739. function PinchRecognizer() {
  16740. AttrRecognizer.apply(this, arguments);
  16741. }
  16742. inherit(PinchRecognizer, AttrRecognizer, {
  16743. /**
  16744. * @namespace
  16745. * @memberof PinchRecognizer
  16746. */
  16747. defaults: {
  16748. event: 'pinch',
  16749. threshold: 0,
  16750. pointers: 2
  16751. },
  16752. getTouchAction: function () {
  16753. return [TOUCH_ACTION_NONE];
  16754. },
  16755. attrTest: function (input) {
  16756. return this._super.attrTest.call(this, input) && (Math.abs(input.scale - 1) > this.options.threshold || this.state & STATE_BEGAN);
  16757. },
  16758. emit: function (input) {
  16759. if (input.scale !== 1) {
  16760. var inOut = input.scale < 1 ? 'in' : 'out';
  16761. input.additionalEvent = this.options.event + inOut;
  16762. }
  16763. this._super.emit.call(this, input);
  16764. }
  16765. });
  16766. /**
  16767. * Press
  16768. * Recognized when the pointer is down for x ms without any movement.
  16769. * @constructor
  16770. * @extends Recognizer
  16771. */
  16772. function PressRecognizer() {
  16773. Recognizer.apply(this, arguments);
  16774. this._timer = null;
  16775. this._input = null;
  16776. }
  16777. inherit(PressRecognizer, Recognizer, {
  16778. /**
  16779. * @namespace
  16780. * @memberof PressRecognizer
  16781. */
  16782. defaults: {
  16783. event: 'press',
  16784. pointers: 1,
  16785. time: 251,
  16786. // minimal time of the pointer to be pressed
  16787. threshold: 9 // a minimal movement is ok, but keep it low
  16788. },
  16789. getTouchAction: function () {
  16790. return [TOUCH_ACTION_AUTO];
  16791. },
  16792. process: function (input) {
  16793. var options = this.options;
  16794. var validPointers = input.pointers.length === options.pointers;
  16795. var validMovement = input.distance < options.threshold;
  16796. var validTime = input.deltaTime > options.time;
  16797. this._input = input; // we only allow little movement
  16798. // and we've reached an end event, so a tap is possible
  16799. if (!validMovement || !validPointers || input.eventType & (INPUT_END | INPUT_CANCEL) && !validTime) {
  16800. this.reset();
  16801. } else if (input.eventType & INPUT_START) {
  16802. this.reset();
  16803. this._timer = setTimeoutContext(function () {
  16804. this.state = STATE_RECOGNIZED;
  16805. this.tryEmit();
  16806. }, options.time, this);
  16807. } else if (input.eventType & INPUT_END) {
  16808. return STATE_RECOGNIZED;
  16809. }
  16810. return STATE_FAILED;
  16811. },
  16812. reset: function () {
  16813. clearTimeout(this._timer);
  16814. },
  16815. emit: function (input) {
  16816. if (this.state !== STATE_RECOGNIZED) {
  16817. return;
  16818. }
  16819. if (input && input.eventType & INPUT_END) {
  16820. this.manager.emit(this.options.event + 'up', input);
  16821. } else {
  16822. this._input.timeStamp = now();
  16823. this.manager.emit(this.options.event, this._input);
  16824. }
  16825. }
  16826. });
  16827. /**
  16828. * Rotate
  16829. * Recognized when two or more pointer are moving in a circular motion.
  16830. * @constructor
  16831. * @extends AttrRecognizer
  16832. */
  16833. function RotateRecognizer() {
  16834. AttrRecognizer.apply(this, arguments);
  16835. }
  16836. inherit(RotateRecognizer, AttrRecognizer, {
  16837. /**
  16838. * @namespace
  16839. * @memberof RotateRecognizer
  16840. */
  16841. defaults: {
  16842. event: 'rotate',
  16843. threshold: 0,
  16844. pointers: 2
  16845. },
  16846. getTouchAction: function () {
  16847. return [TOUCH_ACTION_NONE];
  16848. },
  16849. attrTest: function (input) {
  16850. return this._super.attrTest.call(this, input) && (Math.abs(input.rotation) > this.options.threshold || this.state & STATE_BEGAN);
  16851. }
  16852. });
  16853. /**
  16854. * Swipe
  16855. * Recognized when the pointer is moving fast (velocity), with enough distance in the allowed direction.
  16856. * @constructor
  16857. * @extends AttrRecognizer
  16858. */
  16859. function SwipeRecognizer() {
  16860. AttrRecognizer.apply(this, arguments);
  16861. }
  16862. inherit(SwipeRecognizer, AttrRecognizer, {
  16863. /**
  16864. * @namespace
  16865. * @memberof SwipeRecognizer
  16866. */
  16867. defaults: {
  16868. event: 'swipe',
  16869. threshold: 10,
  16870. velocity: 0.3,
  16871. direction: DIRECTION_HORIZONTAL | DIRECTION_VERTICAL,
  16872. pointers: 1
  16873. },
  16874. getTouchAction: function () {
  16875. return PanRecognizer.prototype.getTouchAction.call(this);
  16876. },
  16877. attrTest: function (input) {
  16878. var direction = this.options.direction;
  16879. var velocity;
  16880. if (direction & (DIRECTION_HORIZONTAL | DIRECTION_VERTICAL)) {
  16881. velocity = input.overallVelocity;
  16882. } else if (direction & DIRECTION_HORIZONTAL) {
  16883. velocity = input.overallVelocityX;
  16884. } else if (direction & DIRECTION_VERTICAL) {
  16885. velocity = input.overallVelocityY;
  16886. }
  16887. return this._super.attrTest.call(this, input) && direction & input.offsetDirection && input.distance > this.options.threshold && input.maxPointers == this.options.pointers && abs(velocity) > this.options.velocity && input.eventType & INPUT_END;
  16888. },
  16889. emit: function (input) {
  16890. var direction = directionStr(input.offsetDirection);
  16891. if (direction) {
  16892. this.manager.emit(this.options.event + direction, input);
  16893. }
  16894. this.manager.emit(this.options.event, input);
  16895. }
  16896. });
  16897. /**
  16898. * A tap is ecognized when the pointer is doing a small tap/click. Multiple taps are recognized if they occur
  16899. * between the given interval and position. The delay option can be used to recognize multi-taps without firing
  16900. * a single tap.
  16901. *
  16902. * The eventData from the emitted event contains the property `tapCount`, which contains the amount of
  16903. * multi-taps being recognized.
  16904. * @constructor
  16905. * @extends Recognizer
  16906. */
  16907. function TapRecognizer() {
  16908. Recognizer.apply(this, arguments); // previous time and center,
  16909. // used for tap counting
  16910. this.pTime = false;
  16911. this.pCenter = false;
  16912. this._timer = null;
  16913. this._input = null;
  16914. this.count = 0;
  16915. }
  16916. inherit(TapRecognizer, Recognizer, {
  16917. /**
  16918. * @namespace
  16919. * @memberof PinchRecognizer
  16920. */
  16921. defaults: {
  16922. event: 'tap',
  16923. pointers: 1,
  16924. taps: 1,
  16925. interval: 300,
  16926. // max time between the multi-tap taps
  16927. time: 250,
  16928. // max time of the pointer to be down (like finger on the screen)
  16929. threshold: 9,
  16930. // a minimal movement is ok, but keep it low
  16931. posThreshold: 10 // a multi-tap can be a bit off the initial position
  16932. },
  16933. getTouchAction: function () {
  16934. return [TOUCH_ACTION_MANIPULATION];
  16935. },
  16936. process: function (input) {
  16937. var options = this.options;
  16938. var validPointers = input.pointers.length === options.pointers;
  16939. var validMovement = input.distance < options.threshold;
  16940. var validTouchTime = input.deltaTime < options.time;
  16941. this.reset();
  16942. if (input.eventType & INPUT_START && this.count === 0) {
  16943. return this.failTimeout();
  16944. } // we only allow little movement
  16945. // and we've reached an end event, so a tap is possible
  16946. if (validMovement && validTouchTime && validPointers) {
  16947. if (input.eventType != INPUT_END) {
  16948. return this.failTimeout();
  16949. }
  16950. var validInterval = this.pTime ? input.timeStamp - this.pTime < options.interval : true;
  16951. var validMultiTap = !this.pCenter || getDistance(this.pCenter, input.center) < options.posThreshold;
  16952. this.pTime = input.timeStamp;
  16953. this.pCenter = input.center;
  16954. if (!validMultiTap || !validInterval) {
  16955. this.count = 1;
  16956. } else {
  16957. this.count += 1;
  16958. }
  16959. this._input = input; // if tap count matches we have recognized it,
  16960. // else it has began recognizing...
  16961. var tapCount = this.count % options.taps;
  16962. if (tapCount === 0) {
  16963. // no failing requirements, immediately trigger the tap event
  16964. // or wait as long as the multitap interval to trigger
  16965. if (!this.hasRequireFailures()) {
  16966. return STATE_RECOGNIZED;
  16967. } else {
  16968. this._timer = setTimeoutContext(function () {
  16969. this.state = STATE_RECOGNIZED;
  16970. this.tryEmit();
  16971. }, options.interval, this);
  16972. return STATE_BEGAN;
  16973. }
  16974. }
  16975. }
  16976. return STATE_FAILED;
  16977. },
  16978. failTimeout: function () {
  16979. this._timer = setTimeoutContext(function () {
  16980. this.state = STATE_FAILED;
  16981. }, this.options.interval, this);
  16982. return STATE_FAILED;
  16983. },
  16984. reset: function () {
  16985. clearTimeout(this._timer);
  16986. },
  16987. emit: function () {
  16988. if (this.state == STATE_RECOGNIZED) {
  16989. this._input.tapCount = this.count;
  16990. this.manager.emit(this.options.event, this._input);
  16991. }
  16992. }
  16993. });
  16994. /**
  16995. * Simple way to create a manager with a default set of recognizers.
  16996. * @param {HTMLElement} element
  16997. * @param {Object} [options]
  16998. * @constructor
  16999. */
  17000. function Hammer(element, options) {
  17001. options = options || {};
  17002. options.recognizers = ifUndefined(options.recognizers, Hammer.defaults.preset);
  17003. return new Manager(element, options);
  17004. }
  17005. /**
  17006. * @const {string}
  17007. */
  17008. Hammer.VERSION = '2.0.7';
  17009. /**
  17010. * default settings
  17011. * @namespace
  17012. */
  17013. Hammer.defaults = {
  17014. /**
  17015. * set if DOM events are being triggered.
  17016. * But this is slower and unused by simple implementations, so disabled by default.
  17017. * @type {Boolean}
  17018. * @default false
  17019. */
  17020. domEvents: false,
  17021. /**
  17022. * The value for the touchAction property/fallback.
  17023. * When set to `compute` it will magically set the correct value based on the added recognizers.
  17024. * @type {String}
  17025. * @default compute
  17026. */
  17027. touchAction: TOUCH_ACTION_COMPUTE,
  17028. /**
  17029. * @type {Boolean}
  17030. * @default true
  17031. */
  17032. enable: true,
  17033. /**
  17034. * EXPERIMENTAL FEATURE -- can be removed/changed
  17035. * Change the parent input target element.
  17036. * If Null, then it is being set the to main element.
  17037. * @type {Null|EventTarget}
  17038. * @default null
  17039. */
  17040. inputTarget: null,
  17041. /**
  17042. * force an input class
  17043. * @type {Null|Function}
  17044. * @default null
  17045. */
  17046. inputClass: null,
  17047. /**
  17048. * Default recognizer setup when calling `Hammer()`
  17049. * When creating a new Manager these will be skipped.
  17050. * @type {Array}
  17051. */
  17052. preset: [// RecognizerClass, options, [recognizeWith, ...], [requireFailure, ...]
  17053. [RotateRecognizer, {
  17054. enable: false
  17055. }], [PinchRecognizer, {
  17056. enable: false
  17057. }, ['rotate']], [SwipeRecognizer, {
  17058. direction: DIRECTION_HORIZONTAL
  17059. }], [PanRecognizer, {
  17060. direction: DIRECTION_HORIZONTAL
  17061. }, ['swipe']], [TapRecognizer], [TapRecognizer, {
  17062. event: 'doubletap',
  17063. taps: 2
  17064. }, ['tap']], [PressRecognizer]],
  17065. /**
  17066. * Some CSS properties can be used to improve the working of Hammer.
  17067. * Add them to this method and they will be set when creating a new Manager.
  17068. * @namespace
  17069. */
  17070. cssProps: {
  17071. /**
  17072. * Disables text selection to improve the dragging gesture. Mainly for desktop browsers.
  17073. * @type {String}
  17074. * @default 'none'
  17075. */
  17076. userSelect: 'none',
  17077. /**
  17078. * Disable the Windows Phone grippers when pressing an element.
  17079. * @type {String}
  17080. * @default 'none'
  17081. */
  17082. touchSelect: 'none',
  17083. /**
  17084. * Disables the default callout shown when you touch and hold a touch target.
  17085. * On iOS, when you touch and hold a touch target such as a link, Safari displays
  17086. * a callout containing information about the link. This property allows you to disable that callout.
  17087. * @type {String}
  17088. * @default 'none'
  17089. */
  17090. touchCallout: 'none',
  17091. /**
  17092. * Specifies whether zooming is enabled. Used by IE10>
  17093. * @type {String}
  17094. * @default 'none'
  17095. */
  17096. contentZooming: 'none',
  17097. /**
  17098. * Specifies that an entire element should be draggable instead of its contents. Mainly for desktop browsers.
  17099. * @type {String}
  17100. * @default 'none'
  17101. */
  17102. userDrag: 'none',
  17103. /**
  17104. * Overrides the highlight color shown when the user taps a link or a JavaScript
  17105. * clickable element in iOS. This property obeys the alpha value, if specified.
  17106. * @type {String}
  17107. * @default 'rgba(0,0,0,0)'
  17108. */
  17109. tapHighlightColor: 'rgba(0,0,0,0)'
  17110. }
  17111. };
  17112. var STOP = 1;
  17113. var FORCED_STOP = 2;
  17114. /**
  17115. * Manager
  17116. * @param {HTMLElement} element
  17117. * @param {Object} [options]
  17118. * @constructor
  17119. */
  17120. function Manager(element, options) {
  17121. this.options = assign({}, Hammer.defaults, options || {});
  17122. this.options.inputTarget = this.options.inputTarget || element;
  17123. this.handlers = {};
  17124. this.session = {};
  17125. this.recognizers = [];
  17126. this.oldCssProps = {};
  17127. this.element = element;
  17128. this.input = createInputInstance(this);
  17129. this.touchAction = new TouchAction(this, this.options.touchAction);
  17130. toggleCssProps(this, true);
  17131. each(this.options.recognizers, function (item) {
  17132. var recognizer = this.add(new item[0](item[1]));
  17133. item[2] && recognizer.recognizeWith(item[2]);
  17134. item[3] && recognizer.requireFailure(item[3]);
  17135. }, this);
  17136. }
  17137. Manager.prototype = {
  17138. /**
  17139. * set options
  17140. * @param {Object} options
  17141. * @returns {Manager}
  17142. */
  17143. set: function (options) {
  17144. assign(this.options, options); // Options that need a little more setup
  17145. if (options.touchAction) {
  17146. this.touchAction.update();
  17147. }
  17148. if (options.inputTarget) {
  17149. // Clean up existing event listeners and reinitialize
  17150. this.input.destroy();
  17151. this.input.target = options.inputTarget;
  17152. this.input.init();
  17153. }
  17154. return this;
  17155. },
  17156. /**
  17157. * stop recognizing for this session.
  17158. * This session will be discarded, when a new [input]start event is fired.
  17159. * When forced, the recognizer cycle is stopped immediately.
  17160. * @param {Boolean} [force]
  17161. */
  17162. stop: function (force) {
  17163. this.session.stopped = force ? FORCED_STOP : STOP;
  17164. },
  17165. /**
  17166. * run the recognizers!
  17167. * called by the inputHandler function on every movement of the pointers (touches)
  17168. * it walks through all the recognizers and tries to detect the gesture that is being made
  17169. * @param {Object} inputData
  17170. */
  17171. recognize: function (inputData) {
  17172. var session = this.session;
  17173. if (session.stopped) {
  17174. return;
  17175. } // run the touch-action polyfill
  17176. this.touchAction.preventDefaults(inputData);
  17177. var recognizer;
  17178. var recognizers = this.recognizers; // this holds the recognizer that is being recognized.
  17179. // so the recognizer's state needs to be BEGAN, CHANGED, ENDED or RECOGNIZED
  17180. // if no recognizer is detecting a thing, it is set to `null`
  17181. var curRecognizer = session.curRecognizer; // reset when the last recognizer is recognized
  17182. // or when we're in a new session
  17183. if (!curRecognizer || curRecognizer && curRecognizer.state & STATE_RECOGNIZED) {
  17184. curRecognizer = session.curRecognizer = null;
  17185. }
  17186. var i = 0;
  17187. while (i < recognizers.length) {
  17188. recognizer = recognizers[i]; // find out if we are allowed try to recognize the input for this one.
  17189. // 1. allow if the session is NOT forced stopped (see the .stop() method)
  17190. // 2. allow if we still haven't recognized a gesture in this session, or the this recognizer is the one
  17191. // that is being recognized.
  17192. // 3. allow if the recognizer is allowed to run simultaneous with the current recognized recognizer.
  17193. // this can be setup with the `recognizeWith()` method on the recognizer.
  17194. if (session.stopped !== FORCED_STOP && ( // 1
  17195. !curRecognizer || recognizer == curRecognizer || // 2
  17196. recognizer.canRecognizeWith(curRecognizer))) {
  17197. // 3
  17198. recognizer.recognize(inputData);
  17199. } else {
  17200. recognizer.reset();
  17201. } // if the recognizer has been recognizing the input as a valid gesture, we want to store this one as the
  17202. // current active recognizer. but only if we don't already have an active recognizer
  17203. if (!curRecognizer && recognizer.state & (STATE_BEGAN | STATE_CHANGED | STATE_ENDED)) {
  17204. curRecognizer = session.curRecognizer = recognizer;
  17205. }
  17206. i++;
  17207. }
  17208. },
  17209. /**
  17210. * get a recognizer by its event name.
  17211. * @param {Recognizer|String} recognizer
  17212. * @returns {Recognizer|Null}
  17213. */
  17214. get: function (recognizer) {
  17215. if (recognizer instanceof Recognizer) {
  17216. return recognizer;
  17217. }
  17218. var recognizers = this.recognizers;
  17219. for (var i = 0; i < recognizers.length; i++) {
  17220. if (recognizers[i].options.event == recognizer) {
  17221. return recognizers[i];
  17222. }
  17223. }
  17224. return null;
  17225. },
  17226. /**
  17227. * add a recognizer to the manager
  17228. * existing recognizers with the same event name will be removed
  17229. * @param {Recognizer} recognizer
  17230. * @returns {Recognizer|Manager}
  17231. */
  17232. add: function (recognizer) {
  17233. if (invokeArrayArg(recognizer, 'add', this)) {
  17234. return this;
  17235. } // remove existing
  17236. var existing = this.get(recognizer.options.event);
  17237. if (existing) {
  17238. this.remove(existing);
  17239. }
  17240. this.recognizers.push(recognizer);
  17241. recognizer.manager = this;
  17242. this.touchAction.update();
  17243. return recognizer;
  17244. },
  17245. /**
  17246. * remove a recognizer by name or instance
  17247. * @param {Recognizer|String} recognizer
  17248. * @returns {Manager}
  17249. */
  17250. remove: function (recognizer) {
  17251. if (invokeArrayArg(recognizer, 'remove', this)) {
  17252. return this;
  17253. }
  17254. recognizer = this.get(recognizer); // let's make sure this recognizer exists
  17255. if (recognizer) {
  17256. var recognizers = this.recognizers;
  17257. var index = inArray(recognizers, recognizer);
  17258. if (index !== -1) {
  17259. recognizers.splice(index, 1);
  17260. this.touchAction.update();
  17261. }
  17262. }
  17263. return this;
  17264. },
  17265. /**
  17266. * bind event
  17267. * @param {String} events
  17268. * @param {Function} handler
  17269. * @returns {EventEmitter} this
  17270. */
  17271. on: function (events, handler) {
  17272. if (events === undefined$1) {
  17273. return;
  17274. }
  17275. if (handler === undefined$1) {
  17276. return;
  17277. }
  17278. var handlers = this.handlers;
  17279. each(splitStr(events), function (event) {
  17280. handlers[event] = handlers[event] || [];
  17281. handlers[event].push(handler);
  17282. });
  17283. return this;
  17284. },
  17285. /**
  17286. * unbind event, leave emit blank to remove all handlers
  17287. * @param {String} events
  17288. * @param {Function} [handler]
  17289. * @returns {EventEmitter} this
  17290. */
  17291. off: function (events, handler) {
  17292. if (events === undefined$1) {
  17293. return;
  17294. }
  17295. var handlers = this.handlers;
  17296. each(splitStr(events), function (event) {
  17297. if (!handler) {
  17298. delete handlers[event];
  17299. } else {
  17300. handlers[event] && handlers[event].splice(inArray(handlers[event], handler), 1);
  17301. }
  17302. });
  17303. return this;
  17304. },
  17305. /**
  17306. * emit event to the listeners
  17307. * @param {String} event
  17308. * @param {Object} data
  17309. */
  17310. emit: function (event, data) {
  17311. // we also want to trigger dom events
  17312. if (this.options.domEvents) {
  17313. triggerDomEvent(event, data);
  17314. } // no handlers, so skip it all
  17315. var handlers = this.handlers[event] && this.handlers[event].slice();
  17316. if (!handlers || !handlers.length) {
  17317. return;
  17318. }
  17319. data.type = event;
  17320. data.preventDefault = function () {
  17321. data.srcEvent.preventDefault();
  17322. };
  17323. var i = 0;
  17324. while (i < handlers.length) {
  17325. handlers[i](data);
  17326. i++;
  17327. }
  17328. },
  17329. /**
  17330. * destroy the manager and unbinds all events
  17331. * it doesn't unbind dom events, that is the user own responsibility
  17332. */
  17333. destroy: function () {
  17334. this.element && toggleCssProps(this, false);
  17335. this.handlers = {};
  17336. this.session = {};
  17337. this.input.destroy();
  17338. this.element = null;
  17339. }
  17340. };
  17341. /**
  17342. * add/remove the css properties as defined in manager.options.cssProps
  17343. * @param {Manager} manager
  17344. * @param {Boolean} add
  17345. */
  17346. function toggleCssProps(manager, add) {
  17347. var element = manager.element;
  17348. if (!element.style) {
  17349. return;
  17350. }
  17351. var prop;
  17352. each(manager.options.cssProps, function (value, name) {
  17353. prop = prefixed(element.style, name);
  17354. if (add) {
  17355. manager.oldCssProps[prop] = element.style[prop];
  17356. element.style[prop] = value;
  17357. } else {
  17358. element.style[prop] = manager.oldCssProps[prop] || '';
  17359. }
  17360. });
  17361. if (!add) {
  17362. manager.oldCssProps = {};
  17363. }
  17364. }
  17365. /**
  17366. * trigger dom event
  17367. * @param {String} event
  17368. * @param {Object} data
  17369. */
  17370. function triggerDomEvent(event, data) {
  17371. var gestureEvent = document.createEvent('Event');
  17372. gestureEvent.initEvent(event, true, true);
  17373. gestureEvent.gesture = data;
  17374. data.target.dispatchEvent(gestureEvent);
  17375. }
  17376. assign(Hammer, {
  17377. INPUT_START: INPUT_START,
  17378. INPUT_MOVE: INPUT_MOVE,
  17379. INPUT_END: INPUT_END,
  17380. INPUT_CANCEL: INPUT_CANCEL,
  17381. STATE_POSSIBLE: STATE_POSSIBLE,
  17382. STATE_BEGAN: STATE_BEGAN,
  17383. STATE_CHANGED: STATE_CHANGED,
  17384. STATE_ENDED: STATE_ENDED,
  17385. STATE_RECOGNIZED: STATE_RECOGNIZED,
  17386. STATE_CANCELLED: STATE_CANCELLED,
  17387. STATE_FAILED: STATE_FAILED,
  17388. DIRECTION_NONE: DIRECTION_NONE,
  17389. DIRECTION_LEFT: DIRECTION_LEFT,
  17390. DIRECTION_RIGHT: DIRECTION_RIGHT,
  17391. DIRECTION_UP: DIRECTION_UP,
  17392. DIRECTION_DOWN: DIRECTION_DOWN,
  17393. DIRECTION_HORIZONTAL: DIRECTION_HORIZONTAL,
  17394. DIRECTION_VERTICAL: DIRECTION_VERTICAL,
  17395. DIRECTION_ALL: DIRECTION_ALL,
  17396. Manager: Manager,
  17397. Input: Input,
  17398. TouchAction: TouchAction,
  17399. TouchInput: TouchInput,
  17400. MouseInput: MouseInput,
  17401. PointerEventInput: PointerEventInput,
  17402. TouchMouseInput: TouchMouseInput,
  17403. SingleTouchInput: SingleTouchInput,
  17404. Recognizer: Recognizer,
  17405. AttrRecognizer: AttrRecognizer,
  17406. Tap: TapRecognizer,
  17407. Pan: PanRecognizer,
  17408. Swipe: SwipeRecognizer,
  17409. Pinch: PinchRecognizer,
  17410. Rotate: RotateRecognizer,
  17411. Press: PressRecognizer,
  17412. on: addEventListeners,
  17413. off: removeEventListeners,
  17414. each: each,
  17415. merge: merge,
  17416. extend: extend,
  17417. assign: assign,
  17418. inherit: inherit,
  17419. bindFn: bindFn,
  17420. prefixed: prefixed
  17421. }); // this prevents errors when Hammer is loaded in the presence of an AMD
  17422. // style loader but by script tag, not by the loader.
  17423. var freeGlobal = typeof window !== 'undefined' ? window : typeof self !== 'undefined' ? self : {}; // jshint ignore:line
  17424. freeGlobal.Hammer = Hammer;
  17425. if (typeof undefined$1 === 'function' && undefined$1.amd) {
  17426. undefined$1(function () {
  17427. return Hammer;
  17428. });
  17429. } else if ( module.exports) {
  17430. module.exports = Hammer;
  17431. } else {
  17432. window[exportName] = Hammer;
  17433. }
  17434. })(window, document, 'Hammer');
  17435. });
  17436. Chart._Interactions = {};
  17437. Chart.registerInteraction = function (type, constructor) {
  17438. Chart._Interactions[type] = constructor;
  17439. };
  17440. Chart.getInteraction = function (type) {
  17441. return Chart._Interactions[type];
  17442. };
  17443. Chart.prototype.interaction = function (type, cfg) {
  17444. var interactions = this._interactions || {};
  17445. if (interactions[type]) {
  17446. // if reprated, destroy last
  17447. interactions[type].destroy();
  17448. }
  17449. var Ctor = Chart.getInteraction(type);
  17450. var interact = new Ctor(cfg, this);
  17451. interactions[type] = interact;
  17452. this._interactions = interactions;
  17453. return this;
  17454. };
  17455. Chart.prototype.clearInteraction = function (type) {
  17456. var interactions = this._interactions;
  17457. if (!interactions) return;
  17458. if (type) {
  17459. interactions[type] && interactions[type].destroy();
  17460. delete interactions[type];
  17461. } else {
  17462. each(interactions, function (interaction, key) {
  17463. interaction.destroy();
  17464. delete interactions[key];
  17465. });
  17466. }
  17467. return this;
  17468. };
  17469. var Hammer;
  17470. if (!isWx && !isMy) {
  17471. Hammer = hammer;
  17472. }
  17473. var TOUCH_EVENTS = ['touchstart', 'touchmove', 'touchend'];
  17474. var Interaction = /*#__PURE__*/function () {
  17475. var _proto = Interaction.prototype;
  17476. _proto.getDefaultCfg = function getDefaultCfg() {
  17477. return {
  17478. startEvent: TOUCH_EVENTS[0],
  17479. processEvent: TOUCH_EVENTS[1],
  17480. endEvent: TOUCH_EVENTS[2],
  17481. resetEvent: null
  17482. };
  17483. };
  17484. // override
  17485. _proto.start = function start() {} // override
  17486. ;
  17487. _proto.process = function process() {} // override
  17488. ;
  17489. _proto.end = function end() {} // override
  17490. ;
  17491. _proto.reset = function reset() {};
  17492. function Interaction(cfg, chart) {
  17493. var _this = this;
  17494. _defineProperty(this, "_start", function (ev) {
  17495. _this.preStart && _this.preStart(ev);
  17496. _this.start(ev);
  17497. _this.onStart && _this.onStart(ev);
  17498. });
  17499. _defineProperty(this, "_process", function (ev) {
  17500. _this.preProcess && _this.preProcess(ev);
  17501. _this.process(ev);
  17502. _this.onProcess && _this.onProcess(ev);
  17503. });
  17504. _defineProperty(this, "_end", function (ev) {
  17505. _this.preEnd && _this.preEnd(ev);
  17506. _this.end(ev);
  17507. _this.onEnd && _this.onEnd(ev);
  17508. });
  17509. _defineProperty(this, "_reset", function (ev) {
  17510. _this.preReset && _this.preReset(ev);
  17511. _this.reset(ev);
  17512. _this.onReset && _this.onReset(ev);
  17513. });
  17514. var defaultCfg = this.getDefaultCfg();
  17515. deepMix(this, defaultCfg, cfg);
  17516. this.chart = chart;
  17517. this.canvas = chart.get('canvas');
  17518. this.el = chart.get('canvas').get('el');
  17519. this._bindEvents();
  17520. }
  17521. _proto._bindEvents = function _bindEvents() {
  17522. this._clearEvents(); // clear events
  17523. var startEvent = this.startEvent,
  17524. processEvent = this.processEvent,
  17525. endEvent = this.endEvent,
  17526. resetEvent = this.resetEvent,
  17527. el = this.el;
  17528. if (Hammer) {
  17529. this.hammer = new Hammer(el);
  17530. }
  17531. this._bindEvent(startEvent, this._start);
  17532. this._bindEvent(processEvent, this._process);
  17533. this._bindEvent(endEvent, this._end);
  17534. this._bindEvent(resetEvent, this._reset);
  17535. };
  17536. _proto._clearEvents = function _clearEvents() {
  17537. var startEvent = this.startEvent,
  17538. processEvent = this.processEvent,
  17539. endEvent = this.endEvent,
  17540. resetEvent = this.resetEvent;
  17541. if (this.hammer) {
  17542. this.hammer.destroy();
  17543. this.hammer = null;
  17544. }
  17545. this._clearTouchEvent(startEvent, this._start);
  17546. this._clearTouchEvent(processEvent, this._process);
  17547. this._clearTouchEvent(endEvent, this._end);
  17548. this._clearTouchEvent(resetEvent, this._reset);
  17549. };
  17550. _proto._bindEvent = function _bindEvent(eventName, method) {
  17551. var el = this.el;
  17552. if (eventName) {
  17553. if (TOUCH_EVENTS.indexOf(eventName) !== -1) {
  17554. addEventListener(el, eventName, method);
  17555. } else if (this.hammer) {
  17556. this.hammer.on(eventName, method);
  17557. }
  17558. }
  17559. };
  17560. _proto._clearTouchEvent = function _clearTouchEvent(eventName, method) {
  17561. var el = this.el;
  17562. if (eventName && TOUCH_EVENTS.indexOf(eventName) !== -1) {
  17563. removeEventListener(el, eventName, method);
  17564. }
  17565. };
  17566. _proto.destroy = function destroy() {
  17567. this._clearEvents();
  17568. };
  17569. return Interaction;
  17570. }();
  17571. var PieSelect = /*#__PURE__*/function (_Interaction) {
  17572. _inheritsLoose(PieSelect, _Interaction);
  17573. var _proto = PieSelect.prototype;
  17574. _proto.getDefaultCfg = function getDefaultCfg() {
  17575. var defaultCfg = _Interaction.prototype.getDefaultCfg.call(this);
  17576. defaultCfg = mix({}, defaultCfg, {
  17577. startEvent: 'tap',
  17578. processEvent: null,
  17579. animate: false,
  17580. offset: 1,
  17581. appendRadius: 8,
  17582. style: {
  17583. fillOpacity: 0.5
  17584. },
  17585. cancelable: true,
  17586. defaultSelected: null // set the default selected shape
  17587. });
  17588. if (isWx || isMy) {
  17589. // 小程序
  17590. defaultCfg.startEvent = 'touchstart';
  17591. defaultCfg.endEvent = 'touchend';
  17592. }
  17593. return defaultCfg;
  17594. };
  17595. function PieSelect(cfg, chart) {
  17596. var _this;
  17597. _this = _Interaction.call(this, cfg, chart) || this;
  17598. var self = _assertThisInitialized(_this);
  17599. chart.registerPlugins({
  17600. clearInner: function clearInner() {
  17601. self.halo && self.halo.remove(true);
  17602. self.selected = false;
  17603. self.selectedShape = null;
  17604. self.lastShape = null;
  17605. self.halo = null;
  17606. self.defaultSelected = null;
  17607. }
  17608. });
  17609. var defaultSelected = self.defaultSelected;
  17610. if (isObject(defaultSelected)) {
  17611. var selectedShape = self._getSelectedShapeByData(defaultSelected);
  17612. selectedShape && self._selectedShape(selectedShape);
  17613. _this.canvas.draw();
  17614. }
  17615. return _this;
  17616. }
  17617. _proto._getSelectedShapeByData = function _getSelectedShapeByData(data) {
  17618. var selectedShape = null;
  17619. var chart = this.chart;
  17620. var geom = chart.get('geoms')[0];
  17621. var container = geom.get('container');
  17622. var children = container.get('children');
  17623. each(children, function (child) {
  17624. if (child.get('isShape') && child.get('className') === geom.get('type')) {
  17625. // get geometry's shape
  17626. var shapeData = child.get('origin')._origin;
  17627. if (isObjectValueEqual(shapeData, data)) {
  17628. selectedShape = child;
  17629. return false;
  17630. }
  17631. }
  17632. });
  17633. return selectedShape;
  17634. };
  17635. _proto._selectedShape = function _selectedShape(selectedShape) {
  17636. var offset = this.offset,
  17637. style = this.style,
  17638. appendRadius = this.appendRadius,
  17639. chart = this.chart;
  17640. this.lastShape = selectedShape;
  17641. var _selectedShape$_attrs = selectedShape._attrs.attrs,
  17642. x = _selectedShape$_attrs.x,
  17643. y = _selectedShape$_attrs.y,
  17644. startAngle = _selectedShape$_attrs.startAngle,
  17645. endAngle = _selectedShape$_attrs.endAngle,
  17646. r = _selectedShape$_attrs.r,
  17647. fill = _selectedShape$_attrs.fill;
  17648. var frontPlot = chart.get('frontPlot');
  17649. var halo = frontPlot.addShape('sector', {
  17650. attrs: mix({
  17651. x: x,
  17652. y: y,
  17653. r: r + offset + appendRadius,
  17654. r0: r + offset,
  17655. fill: fill,
  17656. startAngle: startAngle,
  17657. endAngle: endAngle
  17658. }, style)
  17659. });
  17660. this.halo = halo;
  17661. var animate = this.animate;
  17662. if (animate) {
  17663. if (animate === true) {
  17664. animate = {
  17665. duration: 300
  17666. };
  17667. }
  17668. halo.attr('r', r + offset);
  17669. halo.animate().to(mix({
  17670. attrs: {
  17671. r: r + offset + appendRadius
  17672. }
  17673. }, animate));
  17674. }
  17675. };
  17676. _proto.start = function start(ev) {
  17677. var chart = this.chart;
  17678. if (ev.type === 'tap') {
  17679. ev.clientX = ev.center.x;
  17680. ev.clientY = ev.center.y;
  17681. }
  17682. var _createEvent = createEvent(ev, chart),
  17683. x = _createEvent.x,
  17684. y = _createEvent.y;
  17685. var records = chart.getSnapRecords({
  17686. x: x,
  17687. y: y
  17688. });
  17689. if (!records.length) {
  17690. this.selected = false;
  17691. this.selectedShape = null;
  17692. return;
  17693. }
  17694. var data = records[0]._origin;
  17695. var selectedShape = this._getSelectedShapeByData(data);
  17696. var lastShape = this.lastShape;
  17697. this.selectedShape = selectedShape;
  17698. this.selected = true;
  17699. if (selectedShape === lastShape) {
  17700. if (!this.cancelable) {
  17701. return;
  17702. }
  17703. this.halo && this.halo.remove(true);
  17704. this.lastShape = null;
  17705. this.selected = false;
  17706. } else {
  17707. this.halo && this.halo.remove(true);
  17708. this._selectedShape(selectedShape);
  17709. }
  17710. this.canvas.draw();
  17711. };
  17712. _proto.end = function end(ev) {
  17713. var selectedShape = this.selectedShape;
  17714. if (selectedShape && !selectedShape.get('destroyed')) {
  17715. ev.data = selectedShape.get('origin')._origin;
  17716. ev.shapeInfo = selectedShape.get('origin');
  17717. ev.shape = selectedShape;
  17718. ev.selected = !!this.selected;
  17719. }
  17720. };
  17721. return PieSelect;
  17722. }(Interaction);
  17723. Chart.registerInteraction('pie-select', PieSelect);
  17724. var IntervalSelect = /*#__PURE__*/function (_Interaction) {
  17725. _inheritsLoose(IntervalSelect, _Interaction);
  17726. var _proto = IntervalSelect.prototype;
  17727. _proto.getDefaultCfg = function getDefaultCfg() {
  17728. var defaultCfg = _Interaction.prototype.getDefaultCfg.call(this);
  17729. defaultCfg = mix({}, defaultCfg, {
  17730. startEvent: 'tap',
  17731. processEvent: null,
  17732. selectAxis: true,
  17733. selectAxisStyle: {
  17734. fontWeight: 'bold'
  17735. },
  17736. mode: 'shape',
  17737. selectStyle: {
  17738. fillOpacity: 1
  17739. },
  17740. unSelectStyle: {
  17741. fillOpacity: 0.4
  17742. },
  17743. cancelable: true,
  17744. defaultSelected: null // set the default selected shape
  17745. });
  17746. if (isWx || isMy) {
  17747. // 小程序
  17748. defaultCfg.startEvent = 'touchstart';
  17749. defaultCfg.endEvent = 'touchend';
  17750. }
  17751. return defaultCfg;
  17752. };
  17753. function IntervalSelect(cfg, chart) {
  17754. var _this;
  17755. _this = _Interaction.call(this, cfg, chart) || this;
  17756. var defaultSelected = _this.defaultSelected;
  17757. if (isObject(defaultSelected)) {
  17758. var _this$_selectShapesBy = _this._selectShapesByData(defaultSelected),
  17759. selectedShape = _this$_selectShapesBy.selectedShape,
  17760. unSelectedShapes = _this$_selectShapesBy.unSelectedShapes;
  17761. selectedShape && _this._selectShapes(selectedShape, unSelectedShapes);
  17762. _this.selectedShape = selectedShape;
  17763. }
  17764. return _this;
  17765. }
  17766. _proto._getIntervalShapes = function _getIntervalShapes() {
  17767. var children = [];
  17768. var chart = this.chart;
  17769. var geoms = chart.get('geoms');
  17770. geoms.forEach(function (geom) {
  17771. if (geom.get('type') === 'interval') {
  17772. // only works for Interval geometry type
  17773. var container = geom.get('container');
  17774. children = children.concat(container.get('children'));
  17775. }
  17776. });
  17777. return children;
  17778. };
  17779. _proto._resetShape = function _resetShape(shape) {
  17780. var originAttrs = shape.get('_originAttrs');
  17781. if (originAttrs) {
  17782. shape._attrs.attrs = originAttrs;
  17783. shape.set('_originAttrs', null);
  17784. }
  17785. };
  17786. _proto._setEventData = function _setEventData(ev) {
  17787. var selectedShape = this.selectedShape;
  17788. if (selectedShape && !selectedShape.get('destroyed')) {
  17789. ev.data = selectedShape.get('origin')._origin;
  17790. ev.shapeInfo = selectedShape.get('origin');
  17791. ev.shape = selectedShape;
  17792. ev.selected = !!selectedShape.get('_selected');
  17793. }
  17794. };
  17795. _proto._selectShapesByData = function _selectShapesByData(data) {
  17796. var children = this._getIntervalShapes();
  17797. var selectedShape = null;
  17798. var unSelectedShapes = [];
  17799. each(children, function (child) {
  17800. if (child.get('isShape') && child.get('className') === 'interval') {
  17801. // get geometry's shape
  17802. var shapeData = child.get('origin')._origin;
  17803. if (isObjectValueEqual(shapeData, data)) {
  17804. selectedShape = child;
  17805. } else {
  17806. unSelectedShapes.push(child);
  17807. }
  17808. }
  17809. });
  17810. return {
  17811. selectedShape: selectedShape,
  17812. unSelectedShapes: unSelectedShapes
  17813. };
  17814. };
  17815. _proto._selectShapes = function _selectShapes(selectedShape, unSelectedShapes) {
  17816. var selectStyle = this.selectStyle,
  17817. unSelectStyle = this.unSelectStyle,
  17818. selectAxisStyle = this.selectAxisStyle,
  17819. chart = this.chart;
  17820. if (!selectedShape.get('_originAttrs')) {
  17821. var originAttrs = Object.assign({}, selectedShape.attr());
  17822. selectedShape.set('_originAttrs', originAttrs);
  17823. }
  17824. selectedShape.attr(selectStyle);
  17825. each(unSelectedShapes, function (child) {
  17826. if (!child.get('_originAttrs')) {
  17827. var _originAttrs = Object.assign({}, child.attr());
  17828. child.set('_originAttrs', _originAttrs);
  17829. } else {
  17830. child.attr(child.get('_originAttrs'));
  17831. }
  17832. child.set('_selected', false);
  17833. unSelectStyle && child.attr(unSelectStyle);
  17834. });
  17835. selectedShape.set('_selected', true);
  17836. if (this.selectAxis) {
  17837. if (this.selectedAxisShape) {
  17838. this._resetShape(this.selectedAxisShape);
  17839. }
  17840. var xScale = chart.getXScale();
  17841. var origin = selectedShape.get('origin')._origin;
  17842. var _chart$get = chart.get('axisController'),
  17843. frontPlot = _chart$get.frontPlot,
  17844. backPlot = _chart$get.backPlot;
  17845. var axisShape;
  17846. each(frontPlot.get('children').concat(backPlot.get('children')), function (s) {
  17847. if (s.get('value') === xScale.scale(origin[xScale.field])) {
  17848. axisShape = s;
  17849. return false;
  17850. }
  17851. });
  17852. this.selectedAxisShape = axisShape;
  17853. axisShape.set('_originAttrs', Object.assign({}, axisShape.attr()));
  17854. axisShape.attr(selectAxisStyle);
  17855. }
  17856. this.canvas.draw();
  17857. };
  17858. _proto.reset = function reset() {
  17859. var self = this;
  17860. if (!self.selectedShape) {
  17861. return;
  17862. }
  17863. var children = self._getIntervalShapes();
  17864. each(children, function (child) {
  17865. self._resetShape(child);
  17866. child.set('_selected', false);
  17867. });
  17868. if (self.selectedAxisShape) {
  17869. self._resetShape(self.selectedAxisShape);
  17870. }
  17871. self.canvas.draw();
  17872. self.selectedShape = null;
  17873. self.selectedAxisShape = null;
  17874. };
  17875. _proto.start = function start(ev) {
  17876. var chart = this.chart;
  17877. if (ev.type === 'tap') {
  17878. ev.clientX = ev.center.x;
  17879. ev.clientY = ev.center.y;
  17880. }
  17881. var _createEvent = createEvent(ev, chart),
  17882. x = _createEvent.x,
  17883. y = _createEvent.y;
  17884. var mode = this.mode;
  17885. var children = this._getIntervalShapes();
  17886. var selectedShape;
  17887. var unSelectedShapes = [];
  17888. if (mode === 'shape') {
  17889. var plot = chart.get('plotRange');
  17890. if (!isPointInPlot({
  17891. x: x,
  17892. y: y
  17893. }, plot)) {
  17894. this.reset();
  17895. return;
  17896. }
  17897. each(children, function (child) {
  17898. var box = child.getBBox();
  17899. if (x >= box.x && x <= box.x + box.width && y >= box.y && y <= box.height + box.y) {
  17900. // inbox
  17901. selectedShape = child;
  17902. } else {
  17903. unSelectedShapes.push(child);
  17904. }
  17905. });
  17906. } else if (mode === 'range') {
  17907. var records = chart.getSnapRecords({
  17908. x: x,
  17909. y: y
  17910. });
  17911. if (!records.length) {
  17912. this.reset();
  17913. return;
  17914. }
  17915. var data = records[0]._origin;
  17916. var result = this._selectShapesByData(data);
  17917. selectedShape = result.selectedShape;
  17918. unSelectedShapes = result.unSelectedShapes;
  17919. }
  17920. if (selectedShape) {
  17921. this.selectedShape = selectedShape;
  17922. if (selectedShape.get('_selected')) {
  17923. if (!this.cancelable) {
  17924. this._setEventData(ev);
  17925. return;
  17926. }
  17927. this.reset();
  17928. } else {
  17929. this._selectShapes(selectedShape, unSelectedShapes);
  17930. }
  17931. } else {
  17932. this.reset();
  17933. }
  17934. this._setEventData(ev);
  17935. };
  17936. _proto.end = function end(ev) {
  17937. this._setEventData(ev);
  17938. };
  17939. return IntervalSelect;
  17940. }(Interaction);
  17941. Chart.registerInteraction('interval-select', IntervalSelect);
  17942. /**
  17943. * filter the data out of scale' range
  17944. */
  17945. function beforeGeomInit(chart) {
  17946. chart.set('limitInPlot', true);
  17947. var data = chart.get('filteredData');
  17948. var colDefs = chart.get('colDefs');
  17949. if (!colDefs) return data;
  17950. var geoms = chart.get('geoms');
  17951. var isSpecialGeom = false; // TODO
  17952. each(geoms, function (geom) {
  17953. if (['area', 'line', 'path'].indexOf(geom.get('type')) !== -1) {
  17954. isSpecialGeom = true;
  17955. return false;
  17956. }
  17957. });
  17958. var fields = [];
  17959. each(colDefs, function (def, key) {
  17960. if (!isSpecialGeom && def && (def.values || def.min || def.max)) {
  17961. fields.push(key);
  17962. }
  17963. });
  17964. if (fields.length === 0) {
  17965. return data;
  17966. }
  17967. var geomData = [];
  17968. each(data, function (obj) {
  17969. var flag = true;
  17970. each(fields, function (field) {
  17971. var value = obj[field];
  17972. if (value) {
  17973. var colDef = colDefs[field];
  17974. if (colDef.type === 'timeCat') {
  17975. var values = colDef.values;
  17976. if (isNumber(values[0])) {
  17977. value = toTimeStamp(value);
  17978. }
  17979. }
  17980. if (colDef.values && colDef.values.indexOf(value) === -1 || colDef.min && value < colDef.min || colDef.max && value > colDef.max) {
  17981. flag = false;
  17982. }
  17983. }
  17984. });
  17985. if (flag) {
  17986. geomData.push(obj);
  17987. }
  17988. });
  17989. chart.set('filteredData', geomData);
  17990. }
  17991. var FilterPlugin = /*#__PURE__*/Object.freeze({
  17992. __proto__: null,
  17993. beforeGeomInit: beforeGeomInit
  17994. });
  17995. var TOUCH_EVENTS$1 = ['touchstart', 'touchmove', 'touchend', 'touchStart', 'touchMove', 'touchEnd'];
  17996. var DAY_TIMESTAMPS = 86400000;
  17997. function _handleMove(e) {
  17998. if (e.type === 'swipe' && e.deltaTime > 350) {
  17999. // 区分 pan 操作和 swipe 操作
  18000. return null;
  18001. }
  18002. var currentDeltaX = this.currentDeltaX,
  18003. currentDeltaY = this.currentDeltaY,
  18004. lastPoint = this.lastPoint;
  18005. var deltaX;
  18006. var deltaY;
  18007. if (TOUCH_EVENTS$1.indexOf(e.type) !== -1) {
  18008. // support touch and miniprogram
  18009. var currentPoint = e.touches[0];
  18010. deltaX = currentPoint.x - lastPoint.x;
  18011. deltaY = currentPoint.y - lastPoint.y;
  18012. this.lastPoint = currentPoint;
  18013. } else if (currentDeltaX !== null && currentDeltaY !== null) {
  18014. deltaX = e.deltaX - currentDeltaX;
  18015. deltaY = e.deltaY - currentDeltaY;
  18016. this.currentDeltaX = e.deltaX;
  18017. this.currentDeltaY = e.deltaY;
  18018. }
  18019. if (Math.abs(deltaX) > 0 || Math.abs(deltaY) > 0) {
  18020. var lastTimestamp = this._timestamp;
  18021. var now = +new Date();
  18022. if (now - lastTimestamp > 16) {
  18023. this._doMove(deltaX, deltaY);
  18024. this._timestamp = now;
  18025. }
  18026. }
  18027. }
  18028. function _doMove(deltaX, deltaY) {
  18029. var self = this;
  18030. var mode = self.mode,
  18031. chart = self.chart,
  18032. limitRange = self.limitRange;
  18033. var coord = chart.get('coord');
  18034. var start = coord.start,
  18035. end = coord.end;
  18036. var data = chart.get('data');
  18037. if (directionEnabled(mode, 'x') && deltaX !== 0) {
  18038. var xScale = chart.getXScale();
  18039. var xField = xScale.field;
  18040. if (!limitRange[xField]) {
  18041. limitRange[xField] = getLimitRange(data, xScale);
  18042. }
  18043. var coordWidth = end.x - start.x;
  18044. if (xScale.isCategory) {
  18045. self._handleCatScale(xScale, deltaX, coordWidth);
  18046. } else if (xScale.isLinear) {
  18047. self._handleLinearScale(xScale, deltaX, coordWidth, 'x');
  18048. }
  18049. self.xRange = getFieldRange(xScale, limitRange[xField], xScale.type);
  18050. }
  18051. if (directionEnabled(mode, 'y') && deltaY !== 0) {
  18052. var coordHeight = start.y - end.y;
  18053. var yScales = chart.getYScales();
  18054. each(yScales, function (yScale) {
  18055. var yField = yScale.field;
  18056. if (!limitRange[yField]) {
  18057. limitRange[yField] = getLimitRange(data, yScale);
  18058. }
  18059. yScale.isLinear && self._handleLinearScale(yScale, deltaY, coordHeight, 'y');
  18060. });
  18061. var scale = yScales[0];
  18062. self.yRange = getFieldRange(scale, limitRange[scale.field], scale.type);
  18063. }
  18064. chart.repaint();
  18065. }
  18066. function _handleLinearScale(scale, delta, range, flag) {
  18067. var field = scale.field,
  18068. min = scale.min,
  18069. max = scale.max;
  18070. var limitRange = this.limitRange;
  18071. if (min === limitRange[field].min && max === limitRange[field].max) return;
  18072. var ratio = delta / range;
  18073. var panValue = ratio * (max - min);
  18074. var newMax = flag === 'x' ? max - panValue : max + panValue;
  18075. var newMin = flag === 'x' ? min - panValue : min + panValue;
  18076. if (limitRange[field] && !isNil(limitRange[field].min) && newMin <= limitRange[field].min) {
  18077. newMin = limitRange[field].min;
  18078. newMax = max - min + newMin;
  18079. }
  18080. if (limitRange[field] && !isNil(limitRange[field].max) && newMax >= limitRange[field].max) {
  18081. newMax = limitRange[field].max;
  18082. newMin = newMax - (max - min);
  18083. }
  18084. this.updateLinearScale(field, newMin, newMax);
  18085. }
  18086. function _handleCatScale(scale, delta, range) {
  18087. var type = scale.type,
  18088. field = scale.field,
  18089. values = scale.values,
  18090. ticks = scale.ticks,
  18091. tickCount = scale.tickCount;
  18092. var duplicateRemovalValues = uniq(values);
  18093. var originValues = this.limitRange[field];
  18094. var lastValueIndex = originValues.length - 1;
  18095. var currentLength = duplicateRemovalValues.length;
  18096. var speed = this.speed || 1;
  18097. var step = range / (currentLength * speed);
  18098. var firstIndex = originValues.indexOf(duplicateRemovalValues[0]);
  18099. var lastIndex = originValues.indexOf(duplicateRemovalValues[currentLength - 1]);
  18100. var minIndex = firstIndex;
  18101. var maxIndex = lastIndex;
  18102. var ratio = Math.abs(delta / range);
  18103. var panStep = this.step || Math.max(1, parseInt(ratio * currentLength));
  18104. this._panCumulativeDelta += delta;
  18105. minIndex = this._panCumulativeDelta > step ? Math.max(0, minIndex - panStep) : this._panCumulativeDelta < -step ? Math.min(lastValueIndex - currentLength + 1, minIndex + panStep) : minIndex;
  18106. maxIndex = Math.min(lastValueIndex, minIndex + currentLength - 1);
  18107. if (minIndex === firstIndex && maxIndex === lastIndex) {
  18108. return null;
  18109. }
  18110. var newValues = originValues.slice(minIndex, maxIndex + 1);
  18111. var newTicks = null;
  18112. if (type === 'timeCat') {
  18113. var tickGap = ticks.length > 2 ? ticks[1] - ticks[0] : DAY_TIMESTAMPS;
  18114. if (this._panCumulativeDelta > step) {
  18115. for (var i = ticks[0] - tickGap; i >= newValues[0]; i -= tickGap) {
  18116. ticks.unshift(i);
  18117. }
  18118. } else if (this._panCumulativeDelta < -step) {
  18119. for (var _i = ticks[ticks.length - 1] + tickGap; _i <= newValues[newValues.length - 1]; _i += tickGap) {
  18120. ticks.push(_i);
  18121. }
  18122. }
  18123. newTicks = ticks;
  18124. } else if (type === 'cat') {
  18125. var catTicks = getTickMethod('cat');
  18126. newTicks = catTicks({
  18127. tickCount: tickCount,
  18128. values: newValues
  18129. });
  18130. } else {
  18131. // 保留之前的ticks
  18132. newTicks = ticks;
  18133. }
  18134. this.updateCatScale(field, newValues, newTicks, originValues, minIndex, maxIndex);
  18135. this._panCumulativeDelta = minIndex !== firstIndex ? 0 : this._panCumulativeDelta;
  18136. }
  18137. var MoveMixin = {
  18138. _handleMove: _handleMove,
  18139. _doMove: _doMove,
  18140. _handleLinearScale: _handleLinearScale,
  18141. _handleCatScale: _handleCatScale
  18142. };
  18143. function updateLinearScale(field, min, max) {
  18144. var chart = this.chart;
  18145. var scale = getScale(chart, field); // const colDef = Helper.getColDef(chart, field);
  18146. // chart.scale(field, Util.mix({}, colDef, {
  18147. // min,
  18148. // max,
  18149. // nice: false
  18150. // }));
  18151. scale.change({
  18152. min: min,
  18153. max: max,
  18154. nice: false
  18155. });
  18156. }
  18157. function updateCatScale(field, newValues, ticks, values, minIndex, maxIndex) {
  18158. var chart = this.chart; // const colDef = Helper.getColDef(chart, field);
  18159. var scale = getScale(chart, field);
  18160. scale.change({
  18161. values: newValues,
  18162. ticks: ticks,
  18163. scale: function scale(value) {
  18164. if (this.type === 'timeCat') {
  18165. value = toTimeStamp(value);
  18166. }
  18167. var rangeMin = this.rangeMin();
  18168. var rangeMax = this.rangeMax();
  18169. var range = rangeMax - rangeMin;
  18170. var min;
  18171. var max;
  18172. var percent;
  18173. var currentIndex = values.indexOf(value); // 在完整数据集中的索引值
  18174. if (currentIndex >= 0 && currentIndex < minIndex) {
  18175. // 不在范围内,左侧数据
  18176. max = rangeMin > 0 ? -0.1 : rangeMin - 0.1;
  18177. min = max - range;
  18178. percent = currentIndex / minIndex;
  18179. } else if (currentIndex >= 0 && currentIndex > maxIndex) {
  18180. // 不在范围内,右侧数据
  18181. min = rangeMax < 1 ? 1.1 : rangeMax + 0.1;
  18182. max = min + range;
  18183. percent = (currentIndex - maxIndex - 1) / (values.length - 1 - maxIndex);
  18184. } else {
  18185. // 数值在当前 this.values 范围内
  18186. var index = this.translate(value);
  18187. if (this.values.length === 1) {
  18188. percent = index;
  18189. } else {
  18190. percent = index / (this.values.length - 1);
  18191. }
  18192. min = rangeMin;
  18193. max = rangeMax;
  18194. }
  18195. return min + percent * (max - min);
  18196. },
  18197. getTicks: function getTicks() {
  18198. var self = this;
  18199. var ticks = this.ticks;
  18200. var rst = [];
  18201. each(ticks, function (tick) {
  18202. var obj;
  18203. if (isObject(tick)) {
  18204. obj = tick;
  18205. } else {
  18206. var value = self.scale(tick);
  18207. value = value >= 0 && value <= 1 ? value : NaN;
  18208. obj = {
  18209. text: isString(tick) ? tick : self.getText(tick),
  18210. value: value,
  18211. tickValue: tick // 用于坐标轴上文本动画时确定前后帧的对应关系
  18212. };
  18213. }
  18214. rst.push(obj);
  18215. });
  18216. return rst;
  18217. }
  18218. });
  18219. }
  18220. var UpdateScaleMixin = {
  18221. updateLinearScale: updateLinearScale,
  18222. updateCatScale: updateCatScale
  18223. };
  18224. var Swipe = /*#__PURE__*/function (_Interaction) {
  18225. _inheritsLoose(Swipe, _Interaction);
  18226. var _proto = Swipe.prototype;
  18227. _proto.getDefaultCfg = function getDefaultCfg() {
  18228. var defaultCfg = _Interaction.prototype.getDefaultCfg.call(this);
  18229. defaultCfg = mix({}, defaultCfg, {
  18230. startEvent: 'touchstart',
  18231. processEvent: 'swipe',
  18232. endEvent: 'touchend',
  18233. currentDeltaX: null,
  18234. threshold: 10,
  18235. // Minimal distance required before recognizing.
  18236. velocity: 0.3,
  18237. // Minimal velocity required before recognizing, unit is in px per ms.
  18238. limitRange: {},
  18239. _timestamp: 0,
  18240. _panCumulativeDelta: 0,
  18241. speed: 5
  18242. });
  18243. return defaultCfg;
  18244. };
  18245. function Swipe(cfg, chart) {
  18246. var _this;
  18247. _this = _Interaction.call(this, cfg, chart) || this;
  18248. var self = _assertThisInitialized(_this);
  18249. var hammer = self.hammer,
  18250. threshold = self.threshold,
  18251. velocity = self.velocity;
  18252. if (hammer) {
  18253. hammer.get('swipe').set({
  18254. direction: 6,
  18255. // only support horizontal
  18256. threshold: threshold,
  18257. velocity: velocity
  18258. });
  18259. }
  18260. chart.registerPlugins([FilterPlugin, {
  18261. changeData: function changeData() {
  18262. self.limitRange = {};
  18263. },
  18264. clear: function clear() {
  18265. self.limitRange = {};
  18266. }
  18267. }]);
  18268. self.mode = 'x';
  18269. mix(self, UpdateScaleMixin, MoveMixin);
  18270. return _this;
  18271. }
  18272. _proto.process = function process(e) {
  18273. this.currentDeltaX = 0;
  18274. this._handleMove(e);
  18275. };
  18276. _proto.end = function end() {
  18277. this.currentDeltaX = null;
  18278. this._panCumulativeDelta = 0;
  18279. };
  18280. return Swipe;
  18281. }(Interaction);
  18282. Chart.registerInteraction('swipe', Swipe);
  18283. var Pan = /*#__PURE__*/function (_Interaction) {
  18284. _inheritsLoose(Pan, _Interaction);
  18285. var _proto = Pan.prototype;
  18286. _proto.getDefaultCfg = function getDefaultCfg() {
  18287. var defaultCfg = _Interaction.prototype.getDefaultCfg.call(this);
  18288. defaultCfg = mix({}, defaultCfg, {
  18289. startEvent: 'panstart',
  18290. processEvent: 'panmove',
  18291. endEvent: 'panend',
  18292. resetEvent: 'touchend',
  18293. mode: 'x',
  18294. panThreshold: 10,
  18295. // Minimal pan distance required before recognizing
  18296. pressThreshold: 9,
  18297. // Minimal movement that is allowed while pressing
  18298. pressTime: 251,
  18299. // Minimal press time in ms
  18300. currentDeltaX: null,
  18301. currentDeltaY: null,
  18302. limitRange: {},
  18303. _timestamp: 0,
  18304. lastPoint: null,
  18305. _panCumulativeDelta: 0,
  18306. speed: 5
  18307. });
  18308. if (isWx || isMy) {
  18309. // 小程序
  18310. defaultCfg.startEvent = 'touchstart';
  18311. defaultCfg.processEvent = 'touchmove';
  18312. defaultCfg.endEvent = 'touchend';
  18313. }
  18314. return defaultCfg;
  18315. };
  18316. function Pan(cfg, chart) {
  18317. var _this;
  18318. _this = _Interaction.call(this, cfg, chart) || this;
  18319. var self = _assertThisInitialized(_this);
  18320. var hammer = self.hammer,
  18321. panThreshold = self.panThreshold;
  18322. chart.set('limitInPlot', true);
  18323. if (hammer) {
  18324. hammer.get('pan').set({
  18325. threshold: panThreshold
  18326. }); // 为了兼容hammer的pan 和 tooltips里的press, 后面去hammerjs的时候需要去掉
  18327. chart.get('canvas').on('pan', function () {});
  18328. } // chart.registerPlugins([ FilterPlugin, {
  18329. // changeData() {
  18330. // self.limitRange = {};
  18331. // },
  18332. // clear() {
  18333. // self.limitRange = {};
  18334. // }
  18335. // }]);
  18336. mix(_assertThisInitialized(_this), UpdateScaleMixin, MoveMixin);
  18337. return _this;
  18338. }
  18339. _proto.start = function start(e) {
  18340. if (this.pressed) return;
  18341. this.currentDeltaX = 0;
  18342. this.currentDeltaY = 0;
  18343. if (e.type === 'touchstart' || e.type === 'touchStart') {
  18344. this.lastPoint = e.touches[0];
  18345. }
  18346. this._handleMove(e);
  18347. };
  18348. _proto.process = function process(e) {
  18349. if (this.pressed) return;
  18350. this._handleMove(e);
  18351. };
  18352. _proto.end = function end() {
  18353. if (this.pressed) return;
  18354. this.currentDeltaX = null;
  18355. this.currentDeltaY = null;
  18356. this.lastPoint = null;
  18357. this._panCumulativeDelta = 0;
  18358. };
  18359. return Pan;
  18360. }(Interaction);
  18361. Chart.registerInteraction('pan', Pan);
  18362. var Pinch = /*#__PURE__*/function (_Interaction) {
  18363. _inheritsLoose(Pinch, _Interaction);
  18364. var _proto = Pinch.prototype;
  18365. _proto.getDefaultCfg = function getDefaultCfg() {
  18366. var defaultCfg = _Interaction.prototype.getDefaultCfg.call(this);
  18367. return mix({}, defaultCfg, {
  18368. startEvent: 'pinchstart',
  18369. processEvent: 'pinch',
  18370. endEvent: 'pinchend',
  18371. resetEvent: 'touchend',
  18372. pressThreshold: 9,
  18373. // Minimal movement that is allowed while pressing
  18374. pressTime: 251,
  18375. // Minimal press time in ms
  18376. mode: 'x',
  18377. currentPinchScaling: null,
  18378. originValues: null,
  18379. minScale: null,
  18380. maxScale: null,
  18381. limitRange: {},
  18382. sensitivity: 1,
  18383. _pinchCumulativeDelta: 0,
  18384. _timestamp: 0
  18385. });
  18386. };
  18387. function Pinch(cfg, chart) {
  18388. var _this;
  18389. _this = _Interaction.call(this, cfg, chart) || this;
  18390. var self = _assertThisInitialized(_this);
  18391. var hammer = self.hammer;
  18392. hammer.get('pinch').set({
  18393. // open pinch recognizer
  18394. enable: true
  18395. });
  18396. chart.registerPlugins([FilterPlugin, {
  18397. changeData: function changeData() {
  18398. self.limitRange = {};
  18399. self.originTicks = null;
  18400. },
  18401. clear: function clear() {
  18402. self.limitRange = {};
  18403. self.originTicks = null;
  18404. }
  18405. }]);
  18406. mix(self, UpdateScaleMixin);
  18407. return _this;
  18408. }
  18409. _proto.start = function start() {
  18410. if (this.pressed) return;
  18411. this.currentPinchScaling = 1;
  18412. };
  18413. _proto.process = function process(e) {
  18414. if (this.pressed) return;
  18415. this._handlePinch(e);
  18416. };
  18417. _proto.end = function end(e) {
  18418. if (this.pressed) return;
  18419. this._handlePinch(e);
  18420. this.currentPinchScaling = null; // reset
  18421. this.pinchCumulativeDelta = 0;
  18422. };
  18423. _proto._handlePinch = function _handlePinch(e) {
  18424. var currentPinchScaling = this.currentPinchScaling;
  18425. var diff = 1 / currentPinchScaling * e.scale;
  18426. var rect = e.target.getBoundingClientRect();
  18427. var offsetX = e.center.x - rect.left;
  18428. var offsetY = e.center.y - rect.top;
  18429. var center = {
  18430. x: offsetX,
  18431. y: offsetY
  18432. }; // fingers position difference
  18433. var x = Math.abs(e.pointers[0].clientX - e.pointers[1].clientX);
  18434. var y = Math.abs(e.pointers[0].clientY - e.pointers[1].clientY); // diagonal fingers will change both (xy) axes
  18435. var p = x / y;
  18436. var xy;
  18437. if (p > 0.3 && p < 1.7) {
  18438. xy = 'xy';
  18439. } else if (x > y) {
  18440. xy = 'x';
  18441. } else {
  18442. xy = 'y';
  18443. }
  18444. var lastTimestamp = this._timestamp;
  18445. var now = +new Date();
  18446. if (now - lastTimestamp > 16) {
  18447. this._doZoom(diff, center, xy);
  18448. this._timestamp = now;
  18449. } // Keep track of overall scale
  18450. this.currentPinchScaling = e.scale;
  18451. };
  18452. _proto._doZoom = function _doZoom(diff, center, whichAxes) {
  18453. var self = this;
  18454. var mode = self.mode,
  18455. chart = self.chart,
  18456. limitRange = self.limitRange; // Which axe should be modified when figers were used.
  18457. var _whichAxes;
  18458. if (mode === 'xy' && whichAxes !== undefined) {
  18459. // based on fingers positions
  18460. _whichAxes = whichAxes;
  18461. } else {
  18462. _whichAxes = 'xy';
  18463. }
  18464. var data = chart.get('data');
  18465. if (directionEnabled(mode, 'x') && directionEnabled(_whichAxes, 'x')) {
  18466. // x
  18467. var xScale = chart.getXScale();
  18468. var xField = xScale.field;
  18469. if (!limitRange[xField]) {
  18470. limitRange[xField] = getLimitRange(data, xScale);
  18471. }
  18472. if (xScale.isCategory) {
  18473. // 横轴为分类类型
  18474. self._zoomCatScale(xScale, diff, center);
  18475. } else if (xScale.isLinear) {
  18476. self._zoomLinearScale(xScale, diff, center, 'x');
  18477. }
  18478. this.xRange = getFieldRange(xScale, limitRange[xField], xScale.type);
  18479. }
  18480. if (directionEnabled(mode, 'y') && directionEnabled(_whichAxes, 'y')) {
  18481. // y
  18482. var yScales = chart.getYScales();
  18483. each(yScales, function (yScale) {
  18484. var yField = yScale.field;
  18485. if (!limitRange[yField]) {
  18486. limitRange[yField] = getLimitRange(data, yScale);
  18487. }
  18488. yScale.isLinear && self._zoomLinearScale(yScale, diff, center, 'y');
  18489. });
  18490. var scale = yScales[0];
  18491. this.yRange = getFieldRange(scale, limitRange[scale.field], scale.type);
  18492. }
  18493. chart.repaint();
  18494. };
  18495. _proto._zoomLinearScale = function _zoomLinearScale(scale, zoom, center, flag) {
  18496. var chart = this.chart;
  18497. var min = scale.min,
  18498. max = scale.max,
  18499. field = scale.field;
  18500. var valueRange = max - min;
  18501. var limitRange = this.limitRange;
  18502. var originRange = limitRange[field].max - limitRange[field].min;
  18503. var coord = chart.get('coord');
  18504. var newDiff = valueRange * (zoom - 1);
  18505. if (this.minScale && zoom < 1) {
  18506. // zoom in
  18507. var maxRange = originRange / this.minScale;
  18508. newDiff = Math.max(valueRange - maxRange, newDiff);
  18509. }
  18510. if (this.maxScale && zoom >= 1) {
  18511. // zoom out
  18512. var minRange = originRange / this.maxScale;
  18513. newDiff = Math.min(valueRange - minRange, newDiff);
  18514. }
  18515. var offsetPoint = coord.invertPoint(center);
  18516. var percent = flag === 'x' ? offsetPoint.x : offsetPoint.y;
  18517. var minDelta = newDiff * percent;
  18518. var maxDelta = newDiff * (1 - percent);
  18519. var newMax = max - maxDelta;
  18520. var newMin = min + minDelta;
  18521. this.updateLinearScale(field, newMin, newMax);
  18522. } // 针对分类类型
  18523. ;
  18524. _proto._zoomCatScale = function _zoomCatScale(scale, zoom, center) {
  18525. var pinchCumulativeDelta = this._pinchCumulativeDelta;
  18526. var sensitivity = this.sensitivity;
  18527. pinchCumulativeDelta = zoom > 1 ? pinchCumulativeDelta + 1 : pinchCumulativeDelta - 1;
  18528. this._pinchCumulativeDelta = pinchCumulativeDelta;
  18529. var field = scale.field,
  18530. values = scale.values;
  18531. var chart = this.chart;
  18532. var coord = chart.get('coord');
  18533. if (!this.originTicks) {
  18534. this.originTicks = scale.ticks;
  18535. }
  18536. var originValues = this.limitRange[field];
  18537. var originValuesLen = originValues.length;
  18538. var minScale = this.minScale || 1;
  18539. var maxScale = this.maxScale || 5;
  18540. var minCount = parseInt(originValuesLen / maxScale);
  18541. var maxCount = parseInt(originValuesLen / minScale);
  18542. var currentLen = values.length;
  18543. if (pinchCumulativeDelta > 0 && currentLen <= minCount) {
  18544. return null;
  18545. }
  18546. if (pinchCumulativeDelta < 0 && currentLen >= maxCount) {
  18547. return null;
  18548. }
  18549. var lastLabelIndex = originValuesLen - 1;
  18550. var firstValue = values[0];
  18551. var lastValue = values[currentLen - 1];
  18552. var minIndex = originValues.indexOf(firstValue);
  18553. var maxIndex = originValues.indexOf(lastValue);
  18554. var chartCenter = (coord.start.x + coord.end.x) / 2;
  18555. var centerPointer = center.x;
  18556. if (Math.abs(pinchCumulativeDelta) > sensitivity) {
  18557. var deltaCount = Math.max(1, parseInt(currentLen * Math.abs(zoom - 1)));
  18558. if (pinchCumulativeDelta < 0) {
  18559. if (centerPointer >= chartCenter) {
  18560. if (minIndex <= 0) {
  18561. maxIndex = Math.min(lastLabelIndex, maxIndex + deltaCount);
  18562. } else {
  18563. minIndex = Math.max(0, minIndex - deltaCount);
  18564. }
  18565. } else if (centerPointer < chartCenter) {
  18566. if (maxIndex >= lastLabelIndex) {
  18567. minIndex = Math.max(0, minIndex - deltaCount);
  18568. } else {
  18569. maxIndex = Math.min(lastLabelIndex, maxIndex + deltaCount);
  18570. }
  18571. }
  18572. this._pinchCumulativeDelta = 0;
  18573. } else if (pinchCumulativeDelta > 0) {
  18574. if (centerPointer >= chartCenter) {
  18575. minIndex = minIndex < maxIndex ? minIndex = Math.min(maxIndex, minIndex + deltaCount) : minIndex;
  18576. } else if (centerPointer < chartCenter) {
  18577. maxIndex = maxIndex > minIndex ? maxIndex = Math.max(minIndex, maxIndex - deltaCount) : maxIndex;
  18578. }
  18579. this._pinchCumulativeDelta = 0;
  18580. }
  18581. var newValues = originValues.slice(minIndex, maxIndex + 1);
  18582. this.updateCatScale(field, newValues, this.originTicks, originValues, minIndex, maxIndex);
  18583. }
  18584. };
  18585. return Pinch;
  18586. }(Interaction);
  18587. Chart.registerInteraction('pinch', Pinch);
  18588. /**
  18589. * all
  18590. */
  18591. Chart.plugins.register([Tooltip$1, Legend, Guide, Animation, ScrollBar, PieLabel, intervalLabel$1]);
  18592. var indexAll = {
  18593. Global: Global,
  18594. Chart: Chart,
  18595. Shape: Shape$1,
  18596. G: G,
  18597. Util: Util,
  18598. Helper: Helper,
  18599. track: track,
  18600. Interaction: Interaction,
  18601. Animate: Animate
  18602. };
  18603. exports.Animate = Animate;
  18604. exports.Chart = Chart;
  18605. exports.G = G;
  18606. exports.Global = Global;
  18607. exports.Helper = Helper;
  18608. exports.Interaction = Interaction;
  18609. exports.Shape = Shape$1;
  18610. exports.Util = Util;
  18611. exports.default = indexAll;
  18612. exports.track = track;
  18613. Object.defineProperty(exports, '__esModule', { value: true });
  18614. })));