mapv.js 179 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622
  1. /*!
  2. * Copyright (c) 2016, Baidu, Inc. All rights reserved.
  3. * mapv.(http://mapv.baidu.com)
  4. * github: https://github.com/huiyan-fe/mapv
  5. * license: BSD 3-clause "New" or "Revised"
  6. */
  7. (function (global, factory) {
  8. typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
  9. typeof define === 'function' && define.amd ? define(['exports'], factory) :
  10. (factory((global.mapv = global.mapv || {})));
  11. }(this, (function (exports) { 'use strict';
  12. var version = "2.0.14";
  13. /**
  14. * @author kyle / http://nikai.us/
  15. */
  16. var clear = function (context) {
  17. context && context.clearRect && context.clearRect(0, 0, context.canvas.width, context.canvas.height);
  18. //context.canvas.width = context.canvas.width;
  19. //context.canvas.height = context.canvas.height;
  20. };
  21. /**
  22. * @author kyle / http://nikai.us/
  23. */
  24. var resolutionScale$1 = function (context) {
  25. var devicePixelRatio = window.devicePixelRatio || 1;
  26. context.canvas.width = context.canvas.width * devicePixelRatio;
  27. context.canvas.height = context.canvas.height * devicePixelRatio;
  28. context.canvas.style.width = context.canvas.width / devicePixelRatio + 'px';
  29. context.canvas.style.height = context.canvas.height / devicePixelRatio + 'px';
  30. context.scale(devicePixelRatio, devicePixelRatio);
  31. };
  32. function Event() {
  33. this._subscribers = {}; // event subscribers
  34. }
  35. /**
  36. * Subscribe to an event, add an event listener
  37. * @param {String} event Event name. Available events: 'put', 'update',
  38. * 'remove'
  39. * @param {function} callback Callback method. Called with three parameters:
  40. * {String} event
  41. * {Object | null} params
  42. * {String | Number} senderId
  43. */
  44. Event.prototype.on = function (event, callback) {
  45. var subscribers = this._subscribers[event];
  46. if (!subscribers) {
  47. subscribers = [];
  48. this._subscribers[event] = subscribers;
  49. }
  50. subscribers.push({
  51. callback: callback
  52. });
  53. };
  54. /**
  55. * Unsubscribe from an event, remove an event listener
  56. * @param {String} event
  57. * @param {function} callback
  58. */
  59. Event.prototype.off = function (event, callback) {
  60. var subscribers = this._subscribers[event];
  61. if (subscribers) {
  62. //this._subscribers[event] = subscribers.filter(listener => listener.callback != callback);
  63. for (var i = 0; i < subscribers.length; i++) {
  64. if (subscribers[i].callback == callback) {
  65. subscribers.splice(i, 1);
  66. i--;
  67. }
  68. }
  69. }
  70. };
  71. /**
  72. * Trigger an event
  73. * @param {String} event
  74. * @param {Object | null} params
  75. * @param {String} [senderId] Optional id of the sender.
  76. * @private
  77. */
  78. Event.prototype._trigger = function (event, params, senderId) {
  79. if (event == '*') {
  80. throw new Error('Cannot trigger event *');
  81. }
  82. var subscribers = [];
  83. if (event in this._subscribers) {
  84. subscribers = subscribers.concat(this._subscribers[event]);
  85. }
  86. if ('*' in this._subscribers) {
  87. subscribers = subscribers.concat(this._subscribers['*']);
  88. }
  89. for (var i = 0, len = subscribers.length; i < len; i++) {
  90. var subscriber = subscribers[i];
  91. if (subscriber.callback) {
  92. subscriber.callback(event, params, senderId || null);
  93. }
  94. }
  95. };
  96. var classCallCheck = function (instance, Constructor) {
  97. if (!(instance instanceof Constructor)) {
  98. throw new TypeError("Cannot call a class as a function");
  99. }
  100. };
  101. var createClass = function () {
  102. function defineProperties(target, props) {
  103. for (var i = 0; i < props.length; i++) {
  104. var descriptor = props[i];
  105. descriptor.enumerable = descriptor.enumerable || false;
  106. descriptor.configurable = true;
  107. if ("value" in descriptor) descriptor.writable = true;
  108. Object.defineProperty(target, descriptor.key, descriptor);
  109. }
  110. }
  111. return function (Constructor, protoProps, staticProps) {
  112. if (protoProps) defineProperties(Constructor.prototype, protoProps);
  113. if (staticProps) defineProperties(Constructor, staticProps);
  114. return Constructor;
  115. };
  116. }();
  117. var get = function get(object, property, receiver) {
  118. if (object === null) object = Function.prototype;
  119. var desc = Object.getOwnPropertyDescriptor(object, property);
  120. if (desc === undefined) {
  121. var parent = Object.getPrototypeOf(object);
  122. if (parent === null) {
  123. return undefined;
  124. } else {
  125. return get(parent, property, receiver);
  126. }
  127. } else if ("value" in desc) {
  128. return desc.value;
  129. } else {
  130. var getter = desc.get;
  131. if (getter === undefined) {
  132. return undefined;
  133. }
  134. return getter.call(receiver);
  135. }
  136. };
  137. var inherits = function (subClass, superClass) {
  138. if (typeof superClass !== "function" && superClass !== null) {
  139. throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);
  140. }
  141. subClass.prototype = Object.create(superClass && superClass.prototype, {
  142. constructor: {
  143. value: subClass,
  144. enumerable: false,
  145. writable: true,
  146. configurable: true
  147. }
  148. });
  149. if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
  150. };
  151. var possibleConstructorReturn = function (self, call) {
  152. if (!self) {
  153. throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
  154. }
  155. return call && (typeof call === "object" || typeof call === "function") ? call : self;
  156. };
  157. /**
  158. * @author kyle / http://nikai.us/
  159. */
  160. /**
  161. * DataSet
  162. *
  163. * A data set can:
  164. * - add/remove/update data
  165. * - gives triggers upon changes in the data
  166. * - can import/export data in various data formats
  167. * @param {Array} [data] Optional array with initial data
  168. * the field geometry is like geojson, it can be:
  169. * {
  170. * "type": "Point",
  171. * "coordinates": [125.6, 10.1]
  172. * }
  173. * {
  174. * "type": "LineString",
  175. * "coordinates": [
  176. * [102.0, 0.0], [103.0, 1.0], [104.0, 0.0], [105.0, 1.0]
  177. * ]
  178. * }
  179. * {
  180. * "type": "Polygon",
  181. * "coordinates": [
  182. * [ [100.0, 0.0], [101.0, 0.0], [101.0, 1.0],
  183. * [100.0, 1.0], [100.0, 0.0] ]
  184. * ]
  185. * }
  186. * @param {Object} [options] Available options:
  187. *
  188. */
  189. function DataSet(data, options) {
  190. Event.bind(this)();
  191. this._options = options || {};
  192. this._data = []; // map with data indexed by id
  193. // add initial data when provided
  194. if (data) {
  195. this.add(data);
  196. }
  197. }
  198. DataSet.prototype = Event.prototype;
  199. /**
  200. * Add data.
  201. */
  202. DataSet.prototype.add = function (data, senderId) {
  203. if (Array.isArray(data)) {
  204. // Array
  205. for (var i = 0, len = data.length; i < len; i++) {
  206. if (data[i].time && data[i].time.length == 14 && data[i].time.substr(0, 2) == '20') {
  207. var time = data[i].time;
  208. data[i].time = new Date(time.substr(0, 4) + '-' + time.substr(4, 2) + '-' + time.substr(6, 2) + ' ' + time.substr(8, 2) + ':' + time.substr(10, 2) + ':' + time.substr(12, 2)).getTime();
  209. }
  210. this._data.push(data[i]);
  211. }
  212. } else if (data instanceof Object) {
  213. // Single item
  214. this._data.push(data);
  215. } else {
  216. throw new Error('Unknown dataType');
  217. }
  218. };
  219. /**
  220. * get data.
  221. */
  222. DataSet.prototype.get = function (args) {
  223. args = args || {};
  224. //console.time('copy data time')
  225. var start = new Date();
  226. // TODO: 不修改原始数据,在数据上挂载新的名称,每次修改数据直接修改新名称下的数据,可以省去deepCopy
  227. // var data = deepCopy(this._data);
  228. var data = this._data;
  229. // console.timeEnd('copy data time')
  230. // console.time('transferCoordinate time')
  231. var start = new Date();
  232. if (args.filter) {
  233. var newData = [];
  234. for (var i = 0; i < data.length; i++) {
  235. if (args.filter(data[i])) {
  236. newData.push(data[i]);
  237. }
  238. }
  239. data = newData;
  240. }
  241. if (args.transferCoordinate) {
  242. data = this.transferCoordinate(data, args.transferCoordinate, args.fromColumn, args.toColumn);
  243. }
  244. // console.timeEnd('transferCoordinate time')
  245. return data;
  246. };
  247. /**
  248. * set data.
  249. */
  250. DataSet.prototype.set = function (data) {
  251. this._set(data);
  252. this._trigger('change');
  253. };
  254. /**
  255. * set data.
  256. */
  257. DataSet.prototype._set = function (data) {
  258. this.clear();
  259. this.add(data);
  260. };
  261. /**
  262. * clear data.
  263. */
  264. DataSet.prototype.clear = function (args) {
  265. this._data = []; // map with data indexed by id
  266. };
  267. /**
  268. * remove data.
  269. */
  270. DataSet.prototype.remove = function (args) {};
  271. /**
  272. * update data.
  273. */
  274. DataSet.prototype.update = function (cbk, condition) {
  275. var data = this._data;
  276. var item = null;
  277. for (var i = 0; i < data.length; i++) {
  278. if (condition) {
  279. var flag = true;
  280. for (var key in condition) {
  281. if (data[i][key] != condition[key]) {
  282. flag = false;
  283. }
  284. }
  285. if (flag) {
  286. cbk && cbk(data[i]);
  287. }
  288. } else {
  289. cbk && cbk(data[i]);
  290. }
  291. }
  292. this._trigger('change');
  293. };
  294. /**
  295. * transfer coordinate.
  296. */
  297. DataSet.prototype.transferCoordinate = function (data, transferFn, fromColumn, toColumnName) {
  298. toColumnName = toColumnName || '_coordinates';
  299. fromColumn = fromColumn || 'coordinates';
  300. for (var i = 0; i < data.length; i++) {
  301. var geometry = data[i].geometry;
  302. var coordinates = geometry[fromColumn];
  303. switch (geometry.type) {
  304. case 'Point':
  305. geometry[toColumnName] = transferFn(coordinates);
  306. break;
  307. case 'LineString':
  308. var newCoordinates = [];
  309. for (var j = 0; j < coordinates.length; j++) {
  310. newCoordinates.push(transferFn(coordinates[j]));
  311. }
  312. geometry[toColumnName] = newCoordinates;
  313. break;
  314. case 'Polygon':
  315. var newCoordinates = getPolygon(coordinates);
  316. geometry[toColumnName] = newCoordinates;
  317. break;
  318. case 'MultiPolygon':
  319. var newCoordinates = [];
  320. for (var c = 0; c < coordinates.length; c++) {
  321. var polygon = coordinates[c];
  322. var polygon = getPolygon(polygon);
  323. newCoordinates.push(polygon);
  324. }
  325. geometry[toColumnName] = newCoordinates;
  326. break;
  327. }
  328. }
  329. function getPolygon(coordinates) {
  330. var newCoordinates = [];
  331. for (var c = 0; c < coordinates.length; c++) {
  332. var coordinate = coordinates[c];
  333. var newcoordinate = [];
  334. for (var j = 0; j < coordinate.length; j++) {
  335. newcoordinate.push(transferFn(coordinate[j]));
  336. }
  337. newCoordinates.push(newcoordinate);
  338. }
  339. return newCoordinates;
  340. }
  341. return data;
  342. };
  343. DataSet.prototype.initGeometry = function (transferFn) {
  344. if (transferFn) {
  345. this._data.forEach(function (item) {
  346. item.geometry = transferFn(item);
  347. });
  348. } else {
  349. this._data.forEach(function (item) {
  350. if (!item.geometry && item.lng && item.lat) {
  351. item.geometry = {
  352. type: 'Point',
  353. coordinates: [item.lng, item.lat]
  354. };
  355. }
  356. });
  357. }
  358. };
  359. /**
  360. * 获取当前列的最大值
  361. */
  362. DataSet.prototype.getMax = function (columnName) {
  363. var data = this._data;
  364. if (!data || data.length <= 0) {
  365. return;
  366. }
  367. var max = parseFloat(data[0][columnName]);
  368. for (var i = 1; i < data.length; i++) {
  369. var value = parseFloat(data[i][columnName]);
  370. if (value > max) {
  371. max = value;
  372. }
  373. }
  374. return max;
  375. };
  376. /**
  377. * 获取当前列的总和
  378. */
  379. DataSet.prototype.getSum = function (columnName) {
  380. var data = this._data;
  381. if (!data || data.length <= 0) {
  382. return;
  383. }
  384. var sum = 0;
  385. for (var i = 0; i < data.length; i++) {
  386. if (data[i][columnName]) {
  387. sum += parseFloat(data[i][columnName]);
  388. }
  389. }
  390. return sum;
  391. };
  392. /**
  393. * 获取当前列的最小值
  394. */
  395. DataSet.prototype.getMin = function (columnName) {
  396. var data = this._data;
  397. if (!data || data.length <= 0) {
  398. return;
  399. }
  400. var min = parseFloat(data[0][columnName]);
  401. for (var i = 1; i < data.length; i++) {
  402. var value = parseFloat(data[i][columnName]);
  403. if (value < min) {
  404. min = value;
  405. }
  406. }
  407. return min;
  408. };
  409. /**
  410. * @author kyle / http://nikai.us/
  411. */
  412. var pathSimple = {
  413. drawDataSet: function drawDataSet(context, dataSet, options) {
  414. var data = dataSet instanceof DataSet ? dataSet.get() : dataSet;
  415. for (var i = 0, len = data.length; i < len; i++) {
  416. var item = data[i];
  417. this.draw(context, item, options);
  418. }
  419. },
  420. draw: function draw(context, data, options) {
  421. var type = data.geometry.type;
  422. var coordinates = data.geometry._coordinates || data.geometry.coordinates;
  423. var symbol = options.symbol || 'circle';
  424. switch (type) {
  425. case 'Point':
  426. var size = data._size || data.size || options._size || options.size || 5;
  427. if (options.symbol === 'rect') {
  428. context.rect(coordinates[0] - size / 2, coordinates[1] - size / 2, size, size);
  429. } else {
  430. if (options.bigData === 'Point') {
  431. context.moveTo(coordinates[0], coordinates[1]);
  432. }
  433. context.arc(coordinates[0], coordinates[1], size, 0, Math.PI * 2);
  434. }
  435. break;
  436. case 'LineString':
  437. for (var j = 0; j < coordinates.length; j++) {
  438. var x = coordinates[j][0];
  439. var y = coordinates[j][1];
  440. if (j == 0) {
  441. context.moveTo(x, y);
  442. } else {
  443. context.lineTo(x, y);
  444. }
  445. }
  446. break;
  447. case 'Polygon':
  448. this.drawPolygon(context, coordinates);
  449. break;
  450. case 'MultiPolygon':
  451. for (var i = 0; i < coordinates.length; i++) {
  452. var polygon = coordinates[i];
  453. this.drawPolygon(context, polygon);
  454. }
  455. context.closePath();
  456. break;
  457. default:
  458. console.log('type' + type + 'is not support now!');
  459. break;
  460. }
  461. },
  462. drawPolygon: function drawPolygon(context, coordinates) {
  463. for (var i = 0; i < coordinates.length; i++) {
  464. var coordinate = coordinates[i];
  465. context.moveTo(coordinate[0][0], coordinate[0][1]);
  466. for (var j = 1; j < coordinate.length; j++) {
  467. context.lineTo(coordinate[j][0], coordinate[j][1]);
  468. }
  469. context.lineTo(coordinate[0][0], coordinate[0][1]);
  470. }
  471. }
  472. };
  473. /**
  474. * @author kyle / http://nikai.us/
  475. */
  476. var drawSimple = {
  477. draw: function draw(context, dataSet, options) {
  478. var data = dataSet instanceof DataSet ? dataSet.get() : dataSet;
  479. // console.log('xxxx',options)
  480. context.save();
  481. for (var key in options) {
  482. context[key] = options[key];
  483. }
  484. // console.log(data);
  485. if (options.bigData) {
  486. context.save();
  487. context.beginPath();
  488. for (var i = 0, len = data.length; i < len; i++) {
  489. var item = data[i];
  490. pathSimple.draw(context, item, options);
  491. }
  492. var type = options.bigData;
  493. if (type == 'Point' || type == 'Polygon' || type == 'MultiPolygon') {
  494. context.fill();
  495. if ((item.strokeStyle || options.strokeStyle) && options.lineWidth) {
  496. context.stroke();
  497. }
  498. } else if (type == 'LineString') {
  499. context.stroke();
  500. }
  501. context.restore();
  502. } else {
  503. for (var i = 0, len = data.length; i < len; i++) {
  504. var item = data[i];
  505. context.save();
  506. if (item.fillStyle || item._fillStyle) {
  507. context.fillStyle = item.fillStyle || item._fillStyle;
  508. }
  509. if (item.strokeStyle || item._strokeStyle) {
  510. context.strokeStyle = item.strokeStyle || item._strokeStyle;
  511. }
  512. var type = item.geometry.type;
  513. context.beginPath();
  514. pathSimple.draw(context, item, options);
  515. if (type == 'Point' || type == 'Polygon' || type == 'MultiPolygon') {
  516. context.fill();
  517. if ((item.strokeStyle || options.strokeStyle) && options.lineWidth) {
  518. context.stroke();
  519. }
  520. } else if (type == 'LineString') {
  521. context.stroke();
  522. }
  523. context.restore();
  524. }
  525. }
  526. context.restore();
  527. }
  528. };
  529. function Canvas(width, height) {
  530. var canvas;
  531. if (typeof document === 'undefined') {
  532. // var Canvas = require('canvas');
  533. // canvas = new Canvas(width, height);
  534. } else {
  535. var canvas = document.createElement('canvas');
  536. if (width) {
  537. canvas.width = width;
  538. }
  539. if (height) {
  540. canvas.height = height;
  541. }
  542. }
  543. return canvas;
  544. }
  545. /**
  546. * @author kyle / http://nikai.us/
  547. */
  548. /**
  549. * Category
  550. * @param {Object} [options] Available options:
  551. * {Object} gradient: { 0.25: "rgb(0,0,255)", 0.55: "rgb(0,255,0)", 0.85: "yellow", 1.0: "rgb(255,0,0)"}
  552. */
  553. function Intensity(options) {
  554. options = options || {};
  555. this.gradient = options.gradient || {
  556. 0.25: "rgba(0, 0, 255, 1)",
  557. 0.55: "rgba(0, 255, 0, 1)",
  558. 0.85: "rgba(255, 255, 0, 1)",
  559. 1.0: "rgba(255, 0, 0, 1)"
  560. };
  561. this.maxSize = options.maxSize || 35;
  562. this.minSize = options.minSize || 0;
  563. this.max = options.max || 100;
  564. this.min = options.min || 0;
  565. this.initPalette();
  566. }
  567. Intensity.prototype.setMax = function (value) {
  568. this.max = value || 100;
  569. };
  570. Intensity.prototype.setMin = function (value) {
  571. this.min = value || 0;
  572. };
  573. Intensity.prototype.setMaxSize = function (maxSize) {
  574. this.maxSize = maxSize || 35;
  575. };
  576. Intensity.prototype.setMinSize = function (minSize) {
  577. this.minSize = minSize || 0;
  578. };
  579. Intensity.prototype.initPalette = function () {
  580. var gradient = this.gradient;
  581. var canvas = new Canvas(256, 1);
  582. var paletteCtx = this.paletteCtx = canvas.getContext('2d');
  583. var lineGradient = paletteCtx.createLinearGradient(0, 0, 256, 1);
  584. for (var key in gradient) {
  585. lineGradient.addColorStop(parseFloat(key), gradient[key]);
  586. }
  587. paletteCtx.fillStyle = lineGradient;
  588. paletteCtx.fillRect(0, 0, 256, 1);
  589. };
  590. Intensity.prototype.getColor = function (value) {
  591. var imageData = this.getImageData(value);
  592. return "rgba(" + imageData[0] + ", " + imageData[1] + ", " + imageData[2] + ", " + imageData[3] / 256 + ")";
  593. };
  594. Intensity.prototype.getImageData = function (value) {
  595. var imageData = this.paletteCtx.getImageData(0, 0, 256, 1).data;
  596. if (value === undefined) {
  597. return imageData;
  598. }
  599. var max = this.max;
  600. var min = this.min;
  601. if (value > max) {
  602. value = max;
  603. }
  604. if (value < min) {
  605. value = min;
  606. }
  607. var index = Math.floor((value - min) / (max - min) * (256 - 1)) * 4;
  608. return [imageData[index], imageData[index + 1], imageData[index + 2], imageData[index + 3]];
  609. };
  610. /**
  611. * @param Number value
  612. * @param Number max of value
  613. * @param Number max of size
  614. * @param Object other options
  615. */
  616. Intensity.prototype.getSize = function (value) {
  617. var size = 0;
  618. var max = this.max;
  619. var min = this.min;
  620. var maxSize = this.maxSize;
  621. var minSize = this.minSize;
  622. if (value > max) {
  623. value = max;
  624. }
  625. if (value < min) {
  626. value = min;
  627. }
  628. size = minSize + (value - min) / (max - min) * (maxSize - minSize);
  629. return size;
  630. };
  631. Intensity.prototype.getLegend = function (options) {
  632. var gradient = this.gradient;
  633. var width = options.width || 20;
  634. var height = options.height || 180;
  635. var canvas = new Canvas(width, height);
  636. var paletteCtx = canvas.getContext('2d');
  637. var lineGradient = paletteCtx.createLinearGradient(0, height, 0, 0);
  638. for (var key in gradient) {
  639. lineGradient.addColorStop(parseFloat(key), gradient[key]);
  640. }
  641. paletteCtx.fillStyle = lineGradient;
  642. paletteCtx.fillRect(0, 0, width, height);
  643. return canvas;
  644. };
  645. var global$1 = typeof window === 'undefined' ? {} : window;
  646. var devicePixelRatio = global$1.devicePixelRatio || 1;
  647. /**
  648. * @author kyle / http://nikai.us/
  649. */
  650. function createCircle(size) {
  651. var shadowBlur = size / 2;
  652. var r2 = size + shadowBlur;
  653. var offsetDistance = 10000;
  654. var circle = new Canvas(r2 * 2, r2 * 2);
  655. var context = circle.getContext('2d');
  656. context.shadowBlur = shadowBlur;
  657. context.shadowColor = 'black';
  658. context.shadowOffsetX = context.shadowOffsetY = offsetDistance;
  659. context.beginPath();
  660. context.arc(r2 - offsetDistance, r2 - offsetDistance, size, 0, Math.PI * 2, true);
  661. context.closePath();
  662. context.fill();
  663. return circle;
  664. }
  665. function colorize(pixels, gradient, options) {
  666. var maxOpacity = options.maxOpacity || 0.8;
  667. for (var i = 3, len = pixels.length, j; i < len; i += 4) {
  668. j = pixels[i] * 4; // get gradient color from opacity value
  669. if (pixels[i] / 256 > maxOpacity) {
  670. pixels[i] = 256 * maxOpacity;
  671. }
  672. pixels[i - 3] = gradient[j];
  673. pixels[i - 2] = gradient[j + 1];
  674. pixels[i - 1] = gradient[j + 2];
  675. }
  676. }
  677. function drawGray(context, dataSet, options) {
  678. var max = options.max || 100;
  679. var min = options.min || 0;
  680. // console.log(max)
  681. var size = options._size;
  682. if (size == undefined) {
  683. size = options.size;
  684. if (size == undefined) {
  685. size = 13;
  686. }
  687. }
  688. var intensity = new Intensity({
  689. gradient: options.gradient,
  690. max: max,
  691. min: min
  692. });
  693. var circle = createCircle(size);
  694. var circleHalfWidth = circle.width / 2;
  695. var circleHalfHeight = circle.height / 2;
  696. var data = dataSet;
  697. var dataOrderByAlpha = {};
  698. data.forEach(function (item, index) {
  699. var count = item.count === undefined ? 1 : item.count;
  700. var alpha = Math.min(1, count / max).toFixed(2);
  701. dataOrderByAlpha[alpha] = dataOrderByAlpha[alpha] || [];
  702. dataOrderByAlpha[alpha].push(item);
  703. });
  704. for (var i in dataOrderByAlpha) {
  705. if (isNaN(i)) continue;
  706. var _data = dataOrderByAlpha[i];
  707. context.beginPath();
  708. if (!options.withoutAlpha) {
  709. context.globalAlpha = i;
  710. }
  711. context.strokeStyle = intensity.getColor(i * max);
  712. _data.forEach(function (item, index) {
  713. if (!item.geometry) {
  714. return;
  715. }
  716. var coordinates = item.geometry._coordinates || item.geometry.coordinates;
  717. var type = item.geometry.type;
  718. if (type === 'Point') {
  719. var count = item.count === undefined ? 1 : item.count;
  720. context.globalAlpha = count / max;
  721. context.drawImage(circle, coordinates[0] - circleHalfWidth, coordinates[1] - circleHalfHeight);
  722. } else if (type === 'LineString') {
  723. var count = item.count === undefined ? 1 : item.count;
  724. context.globalAlpha = count / max;
  725. context.beginPath();
  726. pathSimple.draw(context, item, options);
  727. context.stroke();
  728. } else if (type === 'Polygon') {}
  729. });
  730. }
  731. }
  732. function draw(context, dataSet, options) {
  733. var strength = options.strength || 0.3;
  734. context.strokeStyle = 'rgba(0,0,0,' + strength + ')';
  735. var shadowCanvas = new Canvas(context.canvas.width, context.canvas.height);
  736. var shadowContext = shadowCanvas.getContext('2d');
  737. shadowContext.scale(devicePixelRatio, devicePixelRatio);
  738. options = options || {};
  739. var data = dataSet instanceof DataSet ? dataSet.get() : dataSet;
  740. context.save();
  741. var intensity = new Intensity({
  742. gradient: options.gradient
  743. });
  744. //console.time('drawGray')
  745. drawGray(shadowContext, data, options);
  746. //console.timeEnd('drawGray');
  747. // return false;
  748. if (!options.absolute) {
  749. //console.time('changeColor');
  750. var colored = shadowContext.getImageData(0, 0, context.canvas.width, context.canvas.height);
  751. colorize(colored.data, intensity.getImageData(), options);
  752. //console.timeEnd('changeColor');
  753. context.putImageData(colored, 0, 0);
  754. context.restore();
  755. }
  756. intensity = null;
  757. shadowCanvas = null;
  758. }
  759. var drawHeatmap = {
  760. draw: draw
  761. };
  762. /**
  763. * @author kyle / http://nikai.us/
  764. */
  765. var drawGrid = {
  766. draw: function draw(context, dataSet, options) {
  767. context.save();
  768. var data = dataSet instanceof DataSet ? dataSet.get() : dataSet;
  769. var grids = {};
  770. var size = options._size || options.size || 50;
  771. var offset = options.offset || {
  772. x: 0,
  773. y: 0
  774. };
  775. for (var i = 0; i < data.length; i++) {
  776. var coordinates = data[i].geometry._coordinates || data[i].geometry.coordinates;
  777. var gridKey = Math.floor((coordinates[0] - offset.x) / size) + "," + Math.floor((coordinates[1] - offset.y) / size);
  778. if (!grids[gridKey]) {
  779. grids[gridKey] = 0;
  780. }
  781. grids[gridKey] += ~~(data[i].count || 1);
  782. }
  783. var intensity = new Intensity({
  784. max: options.max || 100,
  785. gradient: options.gradient
  786. });
  787. for (var gridKey in grids) {
  788. gridKey = gridKey.split(",");
  789. context.beginPath();
  790. context.rect(gridKey[0] * size + .5 + offset.x, gridKey[1] * size + .5 + offset.y, size, size);
  791. context.fillStyle = intensity.getColor(grids[gridKey]);
  792. context.fill();
  793. if (options.strokeStyle && options.lineWidth) {
  794. context.stroke();
  795. }
  796. }
  797. if (options.label && options.label.show !== false) {
  798. context.fillStyle = options.label.fillStyle || 'white';
  799. if (options.label.font) {
  800. context.font = options.label.font;
  801. }
  802. if (options.label.shadowColor) {
  803. context.shadowColor = options.label.shadowColor;
  804. }
  805. if (options.label.shadowBlur) {
  806. context.shadowBlur = options.label.shadowBlur;
  807. }
  808. for (var gridKey in grids) {
  809. gridKey = gridKey.split(",");
  810. var text = grids[gridKey];
  811. var textWidth = context.measureText(text).width;
  812. context.fillText(text, gridKey[0] * size + .5 + offset.x + size / 2 - textWidth / 2, gridKey[1] * size + .5 + offset.y + size / 2 + 5);
  813. }
  814. }
  815. context.restore();
  816. }
  817. };
  818. /**
  819. * @author kyle / http://nikai.us/
  820. */
  821. function hex_corner(center, size, i) {
  822. var angle_deg = 60 * i + 30;
  823. var angle_rad = Math.PI / 180 * angle_deg;
  824. return [center.x + size * Math.cos(angle_rad), center.y + size * Math.sin(angle_rad)];
  825. }
  826. var drawHoneycomb = {
  827. draw: function draw(context, dataSet, options) {
  828. context.save();
  829. var data = dataSet instanceof DataSet ? dataSet.get() : dataSet;
  830. for (var key in options) {
  831. context[key] = options[key];
  832. }
  833. var grids = {};
  834. var offset = options.offset || {
  835. x: 10,
  836. y: 10
  837. };
  838. //
  839. var r = options._size || options.size || 40;
  840. r = r / 2 / Math.sin(Math.PI / 3);
  841. var dx = r * 2 * Math.sin(Math.PI / 3);
  842. var dy = r * 1.5;
  843. var binsById = {};
  844. for (var i = 0; i < data.length; i++) {
  845. var coordinates = data[i].geometry._coordinates || data[i].geometry.coordinates;
  846. var py = (coordinates[1] - offset.y) / dy,
  847. pj = Math.round(py),
  848. px = (coordinates[0] - offset.x) / dx - (pj & 1 ? .5 : 0),
  849. pi = Math.round(px),
  850. py1 = py - pj;
  851. if (Math.abs(py1) * 3 > 1) {
  852. var px1 = px - pi,
  853. pi2 = pi + (px < pi ? -1 : 1) / 2,
  854. pj2 = pj + (py < pj ? -1 : 1),
  855. px2 = px - pi2,
  856. py2 = py - pj2;
  857. if (px1 * px1 + py1 * py1 > px2 * px2 + py2 * py2) pi = pi2 + (pj & 1 ? 1 : -1) / 2, pj = pj2;
  858. }
  859. var id = pi + "-" + pj,
  860. bin = binsById[id];
  861. if (bin) {
  862. bin.push(data[i]);
  863. } else {
  864. bin = binsById[id] = [data[i]];
  865. bin.i = pi;
  866. bin.j = pj;
  867. bin.x = (pi + (pj & 1 ? 1 / 2 : 0)) * dx;
  868. bin.y = pj * dy;
  869. }
  870. }
  871. var intensity = new Intensity({
  872. max: options.max || 100,
  873. maxSize: r,
  874. gradient: options.gradient
  875. });
  876. for (var key in binsById) {
  877. var item = binsById[key];
  878. context.beginPath();
  879. for (var j = 0; j < 6; j++) {
  880. var radius = r;
  881. var result = hex_corner({
  882. x: item.x + offset.x,
  883. y: item.y + offset.y
  884. }, radius, j);
  885. context.lineTo(result[0], result[1]);
  886. }
  887. context.closePath();
  888. var count = 0;
  889. for (var i = 0; i < item.length; i++) {
  890. count += item[i].count || 1;
  891. }
  892. item.count = count;
  893. context.fillStyle = intensity.getColor(count);
  894. context.fill();
  895. if (options.strokeStyle && options.lineWidth) {
  896. context.stroke();
  897. }
  898. }
  899. if (options.label && options.label.show !== false) {
  900. context.fillStyle = options.label.fillStyle || 'white';
  901. if (options.label.font) {
  902. context.font = options.label.font;
  903. }
  904. if (options.label.shadowColor) {
  905. context.shadowColor = options.label.shadowColor;
  906. }
  907. if (options.label.shadowBlur) {
  908. context.shadowBlur = options.label.shadowBlur;
  909. }
  910. for (var key in binsById) {
  911. var item = binsById[key];
  912. var text = item.count;
  913. if (text < 0) {
  914. text = text.toFixed(2);
  915. } else {
  916. text = ~~text;
  917. }
  918. var textWidth = context.measureText(text).width;
  919. context.fillText(text, item.x + offset.x - textWidth / 2, item.y + offset.y + 5);
  920. }
  921. }
  922. context.restore();
  923. }
  924. };
  925. function createShader(gl, src, type) {
  926. var shader = gl.createShader(type);
  927. gl.shaderSource(shader, src);
  928. gl.compileShader(shader);
  929. return shader;
  930. }
  931. function initShaders(gl, vs_source, fs_source) {
  932. var vertexShader = createShader(gl, vs_source, gl.VERTEX_SHADER);
  933. var fragmentShader = createShader(gl, fs_source, gl.FRAGMENT_SHADER);
  934. var glProgram = gl.createProgram();
  935. gl.attachShader(glProgram, vertexShader);
  936. gl.attachShader(glProgram, fragmentShader);
  937. gl.linkProgram(glProgram);
  938. gl.useProgram(glProgram);
  939. return glProgram;
  940. }
  941. function getColorData(color) {
  942. var tmpCanvas = document.createElement('canvas');
  943. var tmpCtx = tmpCanvas.getContext('2d');
  944. tmpCanvas.width = 1;
  945. tmpCanvas.height = 1;
  946. tmpCtx.fillStyle = color;
  947. tmpCtx.fillRect(0, 0, 1, 1);
  948. return tmpCtx.getImageData(0, 0, 1, 1).data;
  949. }
  950. var vs_s = ['attribute vec4 a_Position;', 'void main() {', 'gl_Position = a_Position;', 'gl_PointSize = 30.0;', '}'].join('');
  951. var fs_s = ['precision mediump float;', 'uniform vec4 u_FragColor;', 'void main() {', 'gl_FragColor = u_FragColor;', '}'].join('');
  952. function draw$1(gl, data, options) {
  953. if (!data) {
  954. return;
  955. }
  956. var program = initShaders(gl, vs_s, fs_s);
  957. gl.enable(gl.BLEND);
  958. gl.blendFunc(gl.SRC_ALPHA, gl.ONE);
  959. //gl.clearColor(0.0, 0.0, 1.0, 1.0);
  960. gl.clear(gl.COLOR_BUFFER_BIT);
  961. var halfCanvasWidth = gl.canvas.width / 2;
  962. var halfCanvasHeight = gl.canvas.height / 2;
  963. // Create a buffer object
  964. var vertexBuffer = gl.createBuffer();
  965. // Bind the buffer object to target
  966. gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
  967. var a_Position = gl.getAttribLocation(program, 'a_Position');
  968. // Assign the buffer object to a_Position variable
  969. gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, 0, 0);
  970. // Enable the assignment to a_Position variable
  971. gl.enableVertexAttribArray(a_Position);
  972. var uFragColor = gl.getUniformLocation(program, 'u_FragColor');
  973. var colored = getColorData(options.strokeStyle || 'red');
  974. gl.uniform4f(uFragColor, colored[0] / 255, colored[1] / 255, colored[2] / 255, colored[3] / 255);
  975. gl.lineWidth(options.lineWidth || 1);
  976. for (var i = 0, len = data.length; i < len; i++) {
  977. var _geometry = data[i].geometry._coordinates;
  978. var verticesData = [];
  979. for (var j = 0; j < _geometry.length; j++) {
  980. var item = _geometry[j];
  981. var x = (item[0] - halfCanvasWidth) / halfCanvasWidth;
  982. var y = (halfCanvasHeight - item[1]) / halfCanvasHeight;
  983. verticesData.push(x, y);
  984. }
  985. var vertices = new Float32Array(verticesData);
  986. // Write date into the buffer object
  987. gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
  988. gl.drawArrays(gl.LINE_STRIP, 0, _geometry.length);
  989. }
  990. }
  991. var line = {
  992. draw: draw$1
  993. };
  994. var vs_s$1 = ['attribute vec4 a_Position;', 'attribute float a_PointSize;', 'void main() {', 'gl_Position = a_Position;', 'gl_PointSize = a_PointSize;', '}'].join('');
  995. var fs_s$1 = ['precision mediump float;', 'uniform vec4 u_FragColor;', 'void main() {', 'gl_FragColor = u_FragColor;', '}'].join('');
  996. function draw$2(gl, data, options) {
  997. if (!data) {
  998. return;
  999. }
  1000. var program = initShaders(gl, vs_s$1, fs_s$1);
  1001. var a_Position = gl.getAttribLocation(program, 'a_Position');
  1002. var a_PointSize = gl.getAttribLocation(program, 'a_PointSize');
  1003. var uFragColor = gl.getUniformLocation(program, 'u_FragColor');
  1004. //gl.clearColor(0.0, 0.0, 1.0, 1.0);
  1005. gl.clear(gl.COLOR_BUFFER_BIT);
  1006. var halfCanvasWidth = gl.canvas.width / 2;
  1007. var halfCanvasHeight = gl.canvas.height / 2;
  1008. var verticesData = [];
  1009. var count = 0;
  1010. for (var i = 0; i < data.length; i++) {
  1011. var item = data[i].geometry._coordinates;
  1012. var x = (item[0] - halfCanvasWidth) / halfCanvasWidth;
  1013. var y = (halfCanvasHeight - item[1]) / halfCanvasHeight;
  1014. if (x < -1 || x > 1 || y < -1 || y > 1) {
  1015. continue;
  1016. }
  1017. verticesData.push(x, y);
  1018. count++;
  1019. }
  1020. var vertices = new Float32Array(verticesData);
  1021. var n = count; // The number of vertices
  1022. // Create a buffer object
  1023. var vertexBuffer = gl.createBuffer();
  1024. // Bind the buffer object to target
  1025. gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
  1026. // Write date into the buffer object
  1027. gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
  1028. // Assign the buffer object to a_Position variable
  1029. gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, 0, 0);
  1030. // Enable the assignment to a_Position variable
  1031. gl.enableVertexAttribArray(a_Position);
  1032. gl.vertexAttrib1f(a_PointSize, options._size);
  1033. var colored = getColorData(options.fillStyle || 'red');
  1034. gl.uniform4f(uFragColor, colored[0] / 255, colored[1] / 255, colored[2] / 255, colored[3] / 255);
  1035. gl.drawArrays(gl.POINTS, 0, n);
  1036. }
  1037. var point = {
  1038. draw: draw$2
  1039. };
  1040. function earcut(data, holeIndices, dim) {
  1041. dim = dim || 2;
  1042. var hasHoles = holeIndices && holeIndices.length,
  1043. outerLen = hasHoles ? holeIndices[0] * dim : data.length,
  1044. outerNode = linkedList(data, 0, outerLen, dim, true),
  1045. triangles = [];
  1046. if (!outerNode) return triangles;
  1047. var minX, minY, maxX, maxY, x, y, size;
  1048. if (hasHoles) outerNode = eliminateHoles(data, holeIndices, outerNode, dim);
  1049. // if the shape is not too simple, we'll use z-order curve hash later; calculate polygon bbox
  1050. if (data.length > 80 * dim) {
  1051. minX = maxX = data[0];
  1052. minY = maxY = data[1];
  1053. for (var i = dim; i < outerLen; i += dim) {
  1054. x = data[i];
  1055. y = data[i + 1];
  1056. if (x < minX) minX = x;
  1057. if (y < minY) minY = y;
  1058. if (x > maxX) maxX = x;
  1059. if (y > maxY) maxY = y;
  1060. }
  1061. // minX, minY and size are later used to transform coords into integers for z-order calculation
  1062. size = Math.max(maxX - minX, maxY - minY);
  1063. }
  1064. earcutLinked(outerNode, triangles, dim, minX, minY, size);
  1065. return triangles;
  1066. }
  1067. // create a circular doubly linked list from polygon points in the specified winding order
  1068. function linkedList(data, start, end, dim, clockwise) {
  1069. var i, last;
  1070. if (clockwise === signedArea(data, start, end, dim) > 0) {
  1071. for (i = start; i < end; i += dim) {
  1072. last = insertNode(i, data[i], data[i + 1], last);
  1073. }
  1074. } else {
  1075. for (i = end - dim; i >= start; i -= dim) {
  1076. last = insertNode(i, data[i], data[i + 1], last);
  1077. }
  1078. }
  1079. if (last && equals(last, last.next)) {
  1080. removeNode(last);
  1081. last = last.next;
  1082. }
  1083. return last;
  1084. }
  1085. // eliminate colinear or duplicate points
  1086. function filterPoints(start, end) {
  1087. if (!start) return start;
  1088. if (!end) end = start;
  1089. var p = start,
  1090. again;
  1091. do {
  1092. again = false;
  1093. if (!p.steiner && (equals(p, p.next) || area(p.prev, p, p.next) === 0)) {
  1094. removeNode(p);
  1095. p = end = p.prev;
  1096. if (p === p.next) return null;
  1097. again = true;
  1098. } else {
  1099. p = p.next;
  1100. }
  1101. } while (again || p !== end);
  1102. return end;
  1103. }
  1104. // main ear slicing loop which triangulates a polygon (given as a linked list)
  1105. function earcutLinked(ear, triangles, dim, minX, minY, size, pass) {
  1106. if (!ear) return;
  1107. // interlink polygon nodes in z-order
  1108. if (!pass && size) indexCurve(ear, minX, minY, size);
  1109. var stop = ear,
  1110. prev,
  1111. next;
  1112. // iterate through ears, slicing them one by one
  1113. while (ear.prev !== ear.next) {
  1114. prev = ear.prev;
  1115. next = ear.next;
  1116. if (size ? isEarHashed(ear, minX, minY, size) : isEar(ear)) {
  1117. // cut off the triangle
  1118. triangles.push(prev.i / dim);
  1119. triangles.push(ear.i / dim);
  1120. triangles.push(next.i / dim);
  1121. removeNode(ear);
  1122. // skipping the next vertice leads to less sliver triangles
  1123. ear = next.next;
  1124. stop = next.next;
  1125. continue;
  1126. }
  1127. ear = next;
  1128. // if we looped through the whole remaining polygon and can't find any more ears
  1129. if (ear === stop) {
  1130. // try filtering points and slicing again
  1131. if (!pass) {
  1132. earcutLinked(filterPoints(ear), triangles, dim, minX, minY, size, 1);
  1133. // if this didn't work, try curing all small self-intersections locally
  1134. } else if (pass === 1) {
  1135. ear = cureLocalIntersections(ear, triangles, dim);
  1136. earcutLinked(ear, triangles, dim, minX, minY, size, 2);
  1137. // as a last resort, try splitting the remaining polygon into two
  1138. } else if (pass === 2) {
  1139. splitEarcut(ear, triangles, dim, minX, minY, size);
  1140. }
  1141. break;
  1142. }
  1143. }
  1144. }
  1145. // check whether a polygon node forms a valid ear with adjacent nodes
  1146. function isEar(ear) {
  1147. var a = ear.prev,
  1148. b = ear,
  1149. c = ear.next;
  1150. if (area(a, b, c) >= 0) return false; // reflex, can't be an ear
  1151. // now make sure we don't have other points inside the potential ear
  1152. var p = ear.next.next;
  1153. while (p !== ear.prev) {
  1154. if (pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) && area(p.prev, p, p.next) >= 0) return false;
  1155. p = p.next;
  1156. }
  1157. return true;
  1158. }
  1159. function isEarHashed(ear, minX, minY, size) {
  1160. var a = ear.prev,
  1161. b = ear,
  1162. c = ear.next;
  1163. if (area(a, b, c) >= 0) return false; // reflex, can't be an ear
  1164. // triangle bbox; min & max are calculated like this for speed
  1165. var minTX = a.x < b.x ? a.x < c.x ? a.x : c.x : b.x < c.x ? b.x : c.x,
  1166. minTY = a.y < b.y ? a.y < c.y ? a.y : c.y : b.y < c.y ? b.y : c.y,
  1167. maxTX = a.x > b.x ? a.x > c.x ? a.x : c.x : b.x > c.x ? b.x : c.x,
  1168. maxTY = a.y > b.y ? a.y > c.y ? a.y : c.y : b.y > c.y ? b.y : c.y;
  1169. // z-order range for the current triangle bbox;
  1170. var minZ = zOrder(minTX, minTY, minX, minY, size),
  1171. maxZ = zOrder(maxTX, maxTY, minX, minY, size);
  1172. // first look for points inside the triangle in increasing z-order
  1173. var p = ear.nextZ;
  1174. while (p && p.z <= maxZ) {
  1175. if (p !== ear.prev && p !== ear.next && pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) && area(p.prev, p, p.next) >= 0) return false;
  1176. p = p.nextZ;
  1177. }
  1178. // then look for points in decreasing z-order
  1179. p = ear.prevZ;
  1180. while (p && p.z >= minZ) {
  1181. if (p !== ear.prev && p !== ear.next && pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) && area(p.prev, p, p.next) >= 0) return false;
  1182. p = p.prevZ;
  1183. }
  1184. return true;
  1185. }
  1186. // go through all polygon nodes and cure small local self-intersections
  1187. function cureLocalIntersections(start, triangles, dim) {
  1188. var p = start;
  1189. do {
  1190. var a = p.prev,
  1191. b = p.next.next;
  1192. if (!equals(a, b) && intersects(a, p, p.next, b) && locallyInside(a, b) && locallyInside(b, a)) {
  1193. triangles.push(a.i / dim);
  1194. triangles.push(p.i / dim);
  1195. triangles.push(b.i / dim);
  1196. // remove two nodes involved
  1197. removeNode(p);
  1198. removeNode(p.next);
  1199. p = start = b;
  1200. }
  1201. p = p.next;
  1202. } while (p !== start);
  1203. return p;
  1204. }
  1205. // try splitting polygon into two and triangulate them independently
  1206. function splitEarcut(start, triangles, dim, minX, minY, size) {
  1207. // look for a valid diagonal that divides the polygon into two
  1208. var a = start;
  1209. do {
  1210. var b = a.next.next;
  1211. while (b !== a.prev) {
  1212. if (a.i !== b.i && isValidDiagonal(a, b)) {
  1213. // split the polygon in two by the diagonal
  1214. var c = splitPolygon(a, b);
  1215. // filter colinear points around the cuts
  1216. a = filterPoints(a, a.next);
  1217. c = filterPoints(c, c.next);
  1218. // run earcut on each half
  1219. earcutLinked(a, triangles, dim, minX, minY, size);
  1220. earcutLinked(c, triangles, dim, minX, minY, size);
  1221. return;
  1222. }
  1223. b = b.next;
  1224. }
  1225. a = a.next;
  1226. } while (a !== start);
  1227. }
  1228. // link every hole into the outer loop, producing a single-ring polygon without holes
  1229. function eliminateHoles(data, holeIndices, outerNode, dim) {
  1230. var queue = [],
  1231. i,
  1232. len,
  1233. start,
  1234. end,
  1235. list;
  1236. for (i = 0, len = holeIndices.length; i < len; i++) {
  1237. start = holeIndices[i] * dim;
  1238. end = i < len - 1 ? holeIndices[i + 1] * dim : data.length;
  1239. list = linkedList(data, start, end, dim, false);
  1240. if (list === list.next) list.steiner = true;
  1241. queue.push(getLeftmost(list));
  1242. }
  1243. queue.sort(compareX);
  1244. // process holes from left to right
  1245. for (i = 0; i < queue.length; i++) {
  1246. eliminateHole(queue[i], outerNode);
  1247. outerNode = filterPoints(outerNode, outerNode.next);
  1248. }
  1249. return outerNode;
  1250. }
  1251. function compareX(a, b) {
  1252. return a.x - b.x;
  1253. }
  1254. // find a bridge between vertices that connects hole with an outer ring and and link it
  1255. function eliminateHole(hole, outerNode) {
  1256. outerNode = findHoleBridge(hole, outerNode);
  1257. if (outerNode) {
  1258. var b = splitPolygon(outerNode, hole);
  1259. filterPoints(b, b.next);
  1260. }
  1261. }
  1262. // David Eberly's algorithm for finding a bridge between hole and outer polygon
  1263. function findHoleBridge(hole, outerNode) {
  1264. var p = outerNode,
  1265. hx = hole.x,
  1266. hy = hole.y,
  1267. qx = -Infinity,
  1268. m;
  1269. // find a segment intersected by a ray from the hole's leftmost point to the left;
  1270. // segment's endpoint with lesser x will be potential connection point
  1271. do {
  1272. if (hy <= p.y && hy >= p.next.y) {
  1273. var x = p.x + (hy - p.y) * (p.next.x - p.x) / (p.next.y - p.y);
  1274. if (x <= hx && x > qx) {
  1275. qx = x;
  1276. if (x === hx) {
  1277. if (hy === p.y) return p;
  1278. if (hy === p.next.y) return p.next;
  1279. }
  1280. m = p.x < p.next.x ? p : p.next;
  1281. }
  1282. }
  1283. p = p.next;
  1284. } while (p !== outerNode);
  1285. if (!m) return null;
  1286. if (hx === qx) return m.prev; // hole touches outer segment; pick lower endpoint
  1287. // look for points inside the triangle of hole point, segment intersection and endpoint;
  1288. // if there are no points found, we have a valid connection;
  1289. // otherwise choose the point of the minimum angle with the ray as connection point
  1290. var stop = m,
  1291. mx = m.x,
  1292. my = m.y,
  1293. tanMin = Infinity,
  1294. tan;
  1295. p = m.next;
  1296. while (p !== stop) {
  1297. if (hx >= p.x && p.x >= mx && pointInTriangle(hy < my ? hx : qx, hy, mx, my, hy < my ? qx : hx, hy, p.x, p.y)) {
  1298. tan = Math.abs(hy - p.y) / (hx - p.x); // tangential
  1299. if ((tan < tanMin || tan === tanMin && p.x > m.x) && locallyInside(p, hole)) {
  1300. m = p;
  1301. tanMin = tan;
  1302. }
  1303. }
  1304. p = p.next;
  1305. }
  1306. return m;
  1307. }
  1308. // interlink polygon nodes in z-order
  1309. function indexCurve(start, minX, minY, size) {
  1310. var p = start;
  1311. do {
  1312. if (p.z === null) p.z = zOrder(p.x, p.y, minX, minY, size);
  1313. p.prevZ = p.prev;
  1314. p.nextZ = p.next;
  1315. p = p.next;
  1316. } while (p !== start);
  1317. p.prevZ.nextZ = null;
  1318. p.prevZ = null;
  1319. sortLinked(p);
  1320. }
  1321. // Simon Tatham's linked list merge sort algorithm
  1322. // http://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.html
  1323. function sortLinked(list) {
  1324. var i,
  1325. p,
  1326. q,
  1327. e,
  1328. tail,
  1329. numMerges,
  1330. pSize,
  1331. qSize,
  1332. inSize = 1;
  1333. do {
  1334. p = list;
  1335. list = null;
  1336. tail = null;
  1337. numMerges = 0;
  1338. while (p) {
  1339. numMerges++;
  1340. q = p;
  1341. pSize = 0;
  1342. for (i = 0; i < inSize; i++) {
  1343. pSize++;
  1344. q = q.nextZ;
  1345. if (!q) break;
  1346. }
  1347. qSize = inSize;
  1348. while (pSize > 0 || qSize > 0 && q) {
  1349. if (pSize === 0) {
  1350. e = q;
  1351. q = q.nextZ;
  1352. qSize--;
  1353. } else if (qSize === 0 || !q) {
  1354. e = p;
  1355. p = p.nextZ;
  1356. pSize--;
  1357. } else if (p.z <= q.z) {
  1358. e = p;
  1359. p = p.nextZ;
  1360. pSize--;
  1361. } else {
  1362. e = q;
  1363. q = q.nextZ;
  1364. qSize--;
  1365. }
  1366. if (tail) tail.nextZ = e;else list = e;
  1367. e.prevZ = tail;
  1368. tail = e;
  1369. }
  1370. p = q;
  1371. }
  1372. tail.nextZ = null;
  1373. inSize *= 2;
  1374. } while (numMerges > 1);
  1375. return list;
  1376. }
  1377. // z-order of a point given coords and size of the data bounding box
  1378. function zOrder(x, y, minX, minY, size) {
  1379. // coords are transformed into non-negative 15-bit integer range
  1380. x = 32767 * (x - minX) / size;
  1381. y = 32767 * (y - minY) / size;
  1382. x = (x | x << 8) & 0x00FF00FF;
  1383. x = (x | x << 4) & 0x0F0F0F0F;
  1384. x = (x | x << 2) & 0x33333333;
  1385. x = (x | x << 1) & 0x55555555;
  1386. y = (y | y << 8) & 0x00FF00FF;
  1387. y = (y | y << 4) & 0x0F0F0F0F;
  1388. y = (y | y << 2) & 0x33333333;
  1389. y = (y | y << 1) & 0x55555555;
  1390. return x | y << 1;
  1391. }
  1392. // find the leftmost node of a polygon ring
  1393. function getLeftmost(start) {
  1394. var p = start,
  1395. leftmost = start;
  1396. do {
  1397. if (p.x < leftmost.x) leftmost = p;
  1398. p = p.next;
  1399. } while (p !== start);
  1400. return leftmost;
  1401. }
  1402. // check if a point lies within a convex triangle
  1403. function pointInTriangle(ax, ay, bx, by, cx, cy, px, py) {
  1404. return (cx - px) * (ay - py) - (ax - px) * (cy - py) >= 0 && (ax - px) * (by - py) - (bx - px) * (ay - py) >= 0 && (bx - px) * (cy - py) - (cx - px) * (by - py) >= 0;
  1405. }
  1406. // check if a diagonal between two polygon nodes is valid (lies in polygon interior)
  1407. function isValidDiagonal(a, b) {
  1408. return a.next.i !== b.i && a.prev.i !== b.i && !intersectsPolygon(a, b) && locallyInside(a, b) && locallyInside(b, a) && middleInside(a, b);
  1409. }
  1410. // signed area of a triangle
  1411. function area(p, q, r) {
  1412. return (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y);
  1413. }
  1414. // check if two points are equal
  1415. function equals(p1, p2) {
  1416. return p1.x === p2.x && p1.y === p2.y;
  1417. }
  1418. // check if two segments intersect
  1419. function intersects(p1, q1, p2, q2) {
  1420. if (equals(p1, q1) && equals(p2, q2) || equals(p1, q2) && equals(p2, q1)) return true;
  1421. return area(p1, q1, p2) > 0 !== area(p1, q1, q2) > 0 && area(p2, q2, p1) > 0 !== area(p2, q2, q1) > 0;
  1422. }
  1423. // check if a polygon diagonal intersects any polygon segments
  1424. function intersectsPolygon(a, b) {
  1425. var p = a;
  1426. do {
  1427. if (p.i !== a.i && p.next.i !== a.i && p.i !== b.i && p.next.i !== b.i && intersects(p, p.next, a, b)) return true;
  1428. p = p.next;
  1429. } while (p !== a);
  1430. return false;
  1431. }
  1432. // check if a polygon diagonal is locally inside the polygon
  1433. function locallyInside(a, b) {
  1434. return area(a.prev, a, a.next) < 0 ? area(a, b, a.next) >= 0 && area(a, a.prev, b) >= 0 : area(a, b, a.prev) < 0 || area(a, a.next, b) < 0;
  1435. }
  1436. // check if the middle point of a polygon diagonal is inside the polygon
  1437. function middleInside(a, b) {
  1438. var p = a,
  1439. inside = false,
  1440. px = (a.x + b.x) / 2,
  1441. py = (a.y + b.y) / 2;
  1442. do {
  1443. if (p.y > py !== p.next.y > py && px < (p.next.x - p.x) * (py - p.y) / (p.next.y - p.y) + p.x) inside = !inside;
  1444. p = p.next;
  1445. } while (p !== a);
  1446. return inside;
  1447. }
  1448. // link two polygon vertices with a bridge; if the vertices belong to the same ring, it splits polygon into two;
  1449. // if one belongs to the outer ring and another to a hole, it merges it into a single ring
  1450. function splitPolygon(a, b) {
  1451. var a2 = new Node(a.i, a.x, a.y),
  1452. b2 = new Node(b.i, b.x, b.y),
  1453. an = a.next,
  1454. bp = b.prev;
  1455. a.next = b;
  1456. b.prev = a;
  1457. a2.next = an;
  1458. an.prev = a2;
  1459. b2.next = a2;
  1460. a2.prev = b2;
  1461. bp.next = b2;
  1462. b2.prev = bp;
  1463. return b2;
  1464. }
  1465. // create a node and optionally link it with previous one (in a circular doubly linked list)
  1466. function insertNode(i, x, y, last) {
  1467. var p = new Node(i, x, y);
  1468. if (!last) {
  1469. p.prev = p;
  1470. p.next = p;
  1471. } else {
  1472. p.next = last.next;
  1473. p.prev = last;
  1474. last.next.prev = p;
  1475. last.next = p;
  1476. }
  1477. return p;
  1478. }
  1479. function removeNode(p) {
  1480. p.next.prev = p.prev;
  1481. p.prev.next = p.next;
  1482. if (p.prevZ) p.prevZ.nextZ = p.nextZ;
  1483. if (p.nextZ) p.nextZ.prevZ = p.prevZ;
  1484. }
  1485. function Node(i, x, y) {
  1486. // vertice index in coordinates array
  1487. this.i = i;
  1488. // vertex coordinates
  1489. this.x = x;
  1490. this.y = y;
  1491. // previous and next vertice nodes in a polygon ring
  1492. this.prev = null;
  1493. this.next = null;
  1494. // z-order curve value
  1495. this.z = null;
  1496. // previous and next nodes in z-order
  1497. this.prevZ = null;
  1498. this.nextZ = null;
  1499. // indicates whether this is a steiner point
  1500. this.steiner = false;
  1501. }
  1502. // return a percentage difference between the polygon area and its triangulation area;
  1503. // used to verify correctness of triangulation
  1504. earcut.deviation = function (data, holeIndices, dim, triangles) {
  1505. var hasHoles = holeIndices && holeIndices.length;
  1506. var outerLen = hasHoles ? holeIndices[0] * dim : data.length;
  1507. var polygonArea = Math.abs(signedArea(data, 0, outerLen, dim));
  1508. if (hasHoles) {
  1509. for (var i = 0, len = holeIndices.length; i < len; i++) {
  1510. var start = holeIndices[i] * dim;
  1511. var end = i < len - 1 ? holeIndices[i + 1] * dim : data.length;
  1512. polygonArea -= Math.abs(signedArea(data, start, end, dim));
  1513. }
  1514. }
  1515. var trianglesArea = 0;
  1516. for (i = 0; i < triangles.length; i += 3) {
  1517. var a = triangles[i] * dim;
  1518. var b = triangles[i + 1] * dim;
  1519. var c = triangles[i + 2] * dim;
  1520. trianglesArea += Math.abs((data[a] - data[c]) * (data[b + 1] - data[a + 1]) - (data[a] - data[b]) * (data[c + 1] - data[a + 1]));
  1521. }
  1522. return polygonArea === 0 && trianglesArea === 0 ? 0 : Math.abs((trianglesArea - polygonArea) / polygonArea);
  1523. };
  1524. function signedArea(data, start, end, dim) {
  1525. var sum = 0;
  1526. for (var i = start, j = end - dim; i < end; i += dim) {
  1527. sum += (data[j] - data[i]) * (data[i + 1] + data[j + 1]);
  1528. j = i;
  1529. }
  1530. return sum;
  1531. }
  1532. // turn a polygon in a multi-dimensional array form (e.g. as in GeoJSON) into a form Earcut accepts
  1533. earcut.flatten = function (data) {
  1534. var dim = data[0][0].length,
  1535. result = { vertices: [], holes: [], dimensions: dim },
  1536. holeIndex = 0;
  1537. for (var i = 0; i < data.length; i++) {
  1538. for (var j = 0; j < data[i].length; j++) {
  1539. for (var d = 0; d < dim; d++) {
  1540. result.vertices.push(data[i][j][d]);
  1541. }
  1542. }
  1543. if (i > 0) {
  1544. holeIndex += data[i - 1].length;
  1545. result.holes.push(holeIndex);
  1546. }
  1547. }
  1548. return result;
  1549. };
  1550. var vs_s$2 = ['attribute vec4 a_Position;', 'void main() {', 'gl_Position = a_Position;', 'gl_PointSize = 30.0;', '}'].join('');
  1551. var fs_s$2 = ['precision mediump float;', 'uniform vec4 u_FragColor;', 'void main() {', 'gl_FragColor = u_FragColor;', '}'].join('');
  1552. function draw$3(gl, data, options) {
  1553. if (!data) {
  1554. return;
  1555. }
  1556. // gl.clearColor(0.0, 0.0, 0.0, 1.0);
  1557. gl.clear(gl.COLOR_BUFFER_BIT);
  1558. gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);
  1559. var program = initShaders(gl, vs_s$2, fs_s$2);
  1560. gl.enable(gl.BLEND);
  1561. gl.blendFunc(gl.SRC_ALPHA, gl.ONE);
  1562. var halfCanvasWidth = gl.canvas.width / 2;
  1563. var halfCanvasHeight = gl.canvas.height / 2;
  1564. // Bind the buffer object to target
  1565. gl.bindBuffer(gl.ARRAY_BUFFER, gl.createBuffer());
  1566. gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, gl.createBuffer());
  1567. var a_Position = gl.getAttribLocation(program, 'a_Position');
  1568. // Assign the buffer object to a_Position variable
  1569. gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, 0, 0);
  1570. // Enable the assignment to a_Position variable
  1571. gl.enableVertexAttribArray(a_Position);
  1572. var uFragColor = gl.getUniformLocation(program, 'u_FragColor');
  1573. var colored = getColorData(options.fillStyle || 'red');
  1574. gl.uniform4f(uFragColor, colored[0] / 255, colored[1] / 255, colored[2] / 255, colored[3] / 255);
  1575. gl.lineWidth(options.lineWidth || 1);
  1576. var verticesArr = [];
  1577. var trianglesArr = [];
  1578. var maxSize = 65536;
  1579. var indexOffset = 0;
  1580. for (var i = 0, len = data.length; i < len; i++) {
  1581. var flatten = earcut.flatten(data[i].geometry._coordinates || data[i].geometry.coordinates);
  1582. var vertices = flatten.vertices;
  1583. indexOffset = verticesArr.length / 2;
  1584. for (var j = 0; j < vertices.length; j += 2) {
  1585. vertices[j] = (vertices[j] - halfCanvasWidth) / halfCanvasWidth;
  1586. vertices[j + 1] = (halfCanvasHeight - vertices[j + 1]) / halfCanvasHeight;
  1587. }
  1588. if ((verticesArr.length + vertices.length) / 2 > maxSize) {
  1589. gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(verticesArr), gl.STATIC_DRAW);
  1590. gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(trianglesArr), gl.STATIC_DRAW);
  1591. gl.drawElements(gl.TRIANGLES, trianglesArr.length, gl.UNSIGNED_SHORT, 0);
  1592. verticesArr.length = 0;
  1593. trianglesArr.length = 0;
  1594. indexOffset = 0;
  1595. }
  1596. for (var j = 0; j < vertices.length; j++) {
  1597. verticesArr.push(vertices[j]);
  1598. }
  1599. var triangles = earcut(vertices, flatten.holes, flatten.dimensions);
  1600. for (var j = 0; j < triangles.length; j++) {
  1601. trianglesArr.push(triangles[j] + indexOffset);
  1602. }
  1603. }
  1604. gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(verticesArr), gl.STATIC_DRAW);
  1605. gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(trianglesArr), gl.STATIC_DRAW);
  1606. gl.drawElements(gl.TRIANGLES, trianglesArr.length, gl.UNSIGNED_SHORT, 0);
  1607. gl.bindBuffer(gl.ARRAY_BUFFER, null);
  1608. gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
  1609. }
  1610. var polygon = {
  1611. draw: draw$3
  1612. };
  1613. /**
  1614. * @author kyle / http://nikai.us/
  1615. */
  1616. var webglDrawSimple = {
  1617. draw: function draw(gl, dataSet, options) {
  1618. var data = dataSet instanceof DataSet ? dataSet.get() : dataSet;
  1619. if (data.length > 0) {
  1620. if (data[0].geometry.type == "LineString") {
  1621. line.draw(gl, data, options);
  1622. } else if (data[0].geometry.type == "Polygon" || data[0].geometry.type == "MultiPolygon") {
  1623. polygon.draw(gl, data, options);
  1624. } else {
  1625. point.draw(gl, data, options);
  1626. }
  1627. }
  1628. }
  1629. };
  1630. /**
  1631. * get the center by the city name
  1632. * @author kyle / http://nikai.us/
  1633. */
  1634. var citycenter = { municipalities: [{ n: "北京", g: "116.395645,39.929986|12" }, { n: "上海", g: "121.487899,31.249162|12" }, { n: "天津", g: "117.210813,39.14393|12" }, { n: "重庆", g: "106.530635,29.544606|12" }], provinces: [{ n: "安徽", g: "117.216005,31.859252|8", cities: [{ n: "合肥", g: "117.282699,31.866942|12" }, { n: "安庆", g: "117.058739,30.537898|13" }, { n: "蚌埠", g: "117.35708,32.929499|13" }, { n: "亳州", g: "115.787928,33.871211|13" }, { n: "巢湖", g: "117.88049,31.608733|13" }, { n: "池州", g: "117.494477,30.660019|14" }, { n: "滁州", g: "118.32457,32.317351|13" }, { n: "阜阳", g: "115.820932,32.901211|13" }, { n: "淮北", g: "116.791447,33.960023|13" }, { n: "淮南", g: "117.018639,32.642812|13" }, { n: "黄山", g: "118.29357,29.734435|13" }, { n: "六安", g: "116.505253,31.755558|13" }, { n: "马鞍山", g: "118.515882,31.688528|13" }, { n: "宿州", g: "116.988692,33.636772|13" }, { n: "铜陵", g: "117.819429,30.94093|14" }, { n: "芜湖", g: "118.384108,31.36602|12" }, { n: "宣城", g: "118.752096,30.951642|13" }] }, { n: "福建", g: "117.984943,26.050118|8", cities: [{ n: "福州", g: "119.330221,26.047125|12" }, { n: "龙岩", g: "117.017997,25.078685|13" }, { n: "南平", g: "118.181883,26.643626|13" }, { n: "宁德", g: "119.542082,26.656527|14" }, { n: "莆田", g: "119.077731,25.44845|13" }, { n: "泉州", g: "118.600362,24.901652|12" }, { n: "三明", g: "117.642194,26.270835|14" }, { n: "厦门", g: "118.103886,24.489231|12" }, { n: "漳州", g: "117.676205,24.517065|12" }] }, { n: "甘肃", g: "102.457625,38.103267|6", cities: [{ n: "兰州", g: "103.823305,36.064226|12" }, { n: "白银", g: "104.171241,36.546682|13" }, { n: "定西", g: "104.626638,35.586056|13" }, { n: "甘南州", g: "102.917442,34.992211|14" }, { n: "嘉峪关", g: "98.281635,39.802397|13" }, { n: "金昌", g: "102.208126,38.516072|13" }, { n: "酒泉", g: "98.508415,39.741474|13" }, { n: "临夏州", g: "103.215249,35.598514|13" }, { n: "陇南", g: "104.934573,33.39448|14" }, { n: "平凉", g: "106.688911,35.55011|13" }, { n: "庆阳", g: "107.644227,35.726801|13" }, { n: "天水", g: "105.736932,34.584319|13" }, { n: "武威", g: "102.640147,37.933172|13" }, { n: "张掖", g: "100.459892,38.93932|13" }] }, { n: "广东", g: "113.394818,23.408004|8", cities: [{ n: "广州", g: "113.30765,23.120049|12" }, { n: "潮州", g: "116.630076,23.661812|13" }, { n: "东莞", g: "113.763434,23.043024|12" }, { n: "佛山", g: "113.134026,23.035095|13" }, { n: "河源", g: "114.713721,23.757251|12" }, { n: "惠州", g: "114.410658,23.11354|12" }, { n: "江门", g: "113.078125,22.575117|13" }, { n: "揭阳", g: "116.379501,23.547999|13" }, { n: "茂名", g: "110.931245,21.668226|13" }, { n: "梅州", g: "116.126403,24.304571|13" }, { n: "清远", g: "113.040773,23.698469|13" }, { n: "汕头", g: "116.72865,23.383908|13" }, { n: "汕尾", g: "115.372924,22.778731|14" }, { n: "韶关", g: "113.594461,24.80296|13" }, { n: "深圳", g: "114.025974,22.546054|12" }, { n: "阳江", g: "111.97701,21.871517|14" }, { n: "云浮", g: "112.050946,22.937976|13" }, { n: "湛江", g: "110.365067,21.257463|13" }, { n: "肇庆", g: "112.479653,23.078663|13" }, { n: "中山", g: "113.42206,22.545178|12" }, { n: "珠海", g: "113.562447,22.256915|13" }] }, { n: "广西", g: "108.924274,23.552255|7", cities: [{ n: "南宁", g: "108.297234,22.806493|12" }, { n: "百色", g: "106.631821,23.901512|13" }, { n: "北海", g: "109.122628,21.472718|13" }, { n: "崇左", g: "107.357322,22.415455|14" }, { n: "防城港", g: "108.351791,21.617398|15" }, { n: "桂林", g: "110.26092,25.262901|12" }, { n: "贵港", g: "109.613708,23.103373|13" }, { n: "河池", g: "108.069948,24.699521|14" }, { n: "贺州", g: "111.552594,24.411054|14" }, { n: "来宾", g: "109.231817,23.741166|14" }, { n: "柳州", g: "109.422402,24.329053|12" }, { n: "钦州", g: "108.638798,21.97335|13" }, { n: "梧州", g: "111.305472,23.485395|13" }, { n: "玉林", g: "110.151676,22.643974|14" }] }, { n: "贵州", g: "106.734996,26.902826|8", cities: [{ n: "贵阳", g: "106.709177,26.629907|12" }, { n: "安顺", g: "105.92827,26.228595|13" }, { n: "毕节地区", g: "105.300492,27.302612|14" }, { n: "六盘水", g: "104.852087,26.591866|13" }, { n: "铜仁地区", g: "109.196161,27.726271|14" }, { n: "遵义", g: "106.93126,27.699961|13" }, { n: "黔西南州", g: "104.900558,25.095148|11" }, { n: "黔东南州", g: "107.985353,26.583992|11" }, { n: "黔南州", g: "107.523205,26.264536|11" }] }, { n: "海南", g: "109.733755,19.180501|9", cities: [{ n: "海口", g: "110.330802,20.022071|13" }, { n: "白沙", g: "109.358586,19.216056|12" }, { n: "保亭", g: "109.656113,18.597592|12" }, { n: "昌江", g: "109.0113,19.222483|12" }, { n: "儋州", g: "109.413973,19.571153|13" }, { n: "澄迈", g: "109.996736,19.693135|13" }, { n: "东方", g: "108.85101,18.998161|13" }, { n: "定安", g: "110.32009,19.490991|13" }, { n: "琼海", g: "110.414359,19.21483|13" }, { n: "琼中", g: "109.861849,19.039771|12" }, { n: "乐东", g: "109.062698,18.658614|12" }, { n: "临高", g: "109.724101,19.805922|13" }, { n: "陵水", g: "109.948661,18.575985|12" }, { n: "三亚", g: "109.522771,18.257776|12" }, { n: "屯昌", g: "110.063364,19.347749|13" }, { n: "万宁", g: "110.292505,18.839886|13" }, { n: "文昌", g: "110.780909,19.750947|13" }, { n: "五指山", g: "109.51775,18.831306|13" }] }, { n: "河北", g: "115.661434,38.61384|7", cities: [{ n: "石家庄", g: "114.522082,38.048958|12" }, { n: "保定", g: "115.49481,38.886565|13" }, { n: "沧州", g: "116.863806,38.297615|13" }, { n: "承德", g: "117.933822,40.992521|14" }, { n: "邯郸", g: "114.482694,36.609308|13" }, { n: "衡水", g: "115.686229,37.746929|13" }, { n: "廊坊", g: "116.703602,39.518611|13" }, { n: "秦皇岛", g: "119.604368,39.945462|12" }, { n: "唐山", g: "118.183451,39.650531|13" }, { n: "邢台", g: "114.520487,37.069531|13" }, { n: "张家口", g: "114.893782,40.811188|13" }] }, { n: "河南", g: "113.486804,34.157184|7", cities: [{ n: "郑州", g: "113.649644,34.75661|12" }, { n: "安阳", g: "114.351807,36.110267|12" }, { n: "鹤壁", g: "114.29777,35.755426|13" }, { n: "焦作", g: "113.211836,35.234608|13" }, { n: "开封", g: "114.351642,34.801854|13" }, { n: "洛阳", g: "112.447525,34.657368|12" }, { n: "漯河", g: "114.046061,33.576279|13" }, { n: "南阳", g: "112.542842,33.01142|13" }, { n: "平顶山", g: "113.300849,33.745301|13" }, { n: "濮阳", g: "115.026627,35.753298|12" }, { n: "三门峡", g: "111.181262,34.78332|13" }, { n: "商丘", g: "115.641886,34.438589|13" }, { n: "新乡", g: "113.91269,35.307258|13" }, { n: "信阳", g: "114.085491,32.128582|13" }, { n: "许昌", g: "113.835312,34.02674|13" }, { n: "周口", g: "114.654102,33.623741|13" }, { n: "驻马店", g: "114.049154,32.983158|13" }] }, { n: "黑龙江", g: "128.047414,47.356592|6", cities: [{ n: "哈尔滨", g: "126.657717,45.773225|12" }, { n: "大庆", g: "125.02184,46.596709|12" }, { n: "大兴安岭地区", g: "124.196104,51.991789|10" }, { n: "鹤岗", g: "130.292472,47.338666|13" }, { n: "黑河", g: "127.50083,50.25069|14" }, { n: "鸡西", g: "130.941767,45.32154|13" }, { n: "佳木斯", g: "130.284735,46.81378|12" }, { n: "牡丹江", g: "129.608035,44.588521|13" }, { n: "七台河", g: "131.019048,45.775005|14" }, { n: "齐齐哈尔", g: "123.987289,47.3477|13" }, { n: "双鸭山", g: "131.171402,46.655102|13" }, { n: "绥化", g: "126.989095,46.646064|13" }, { n: "伊春", g: "128.910766,47.734685|14" }] }, { n: "湖北", g: "112.410562,31.209316|8", cities: [{ n: "武汉", g: "114.3162,30.581084|12" }, { n: "鄂州", g: "114.895594,30.384439|14" }, { n: "恩施", g: "109.517433,30.308978|14" }, { n: "黄冈", g: "114.906618,30.446109|14" }, { n: "黄石", g: "115.050683,30.216127|13" }, { n: "荆门", g: "112.21733,31.042611|13" }, { n: "荆州", g: "112.241866,30.332591|12" }, { n: "潜江", g: "112.768768,30.343116|13" }, { n: "神农架林区", g: "110.487231,31.595768|13" }, { n: "十堰", g: "110.801229,32.636994|13" }, { n: "随州", g: "113.379358,31.717858|13" }, { n: "天门", g: "113.12623,30.649047|13" }, { n: "仙桃", g: "113.387448,30.293966|13" }, { n: "咸宁", g: "114.300061,29.880657|13" }, { n: "襄阳", g: "112.176326,32.094934|12" }, { n: "孝感", g: "113.935734,30.927955|13" }, { n: "宜昌", g: "111.310981,30.732758|13" }] }, { n: "湖南", g: "111.720664,27.695864|7", cities: [{ n: "长沙", g: "112.979353,28.213478|12" }, { n: "常德", g: "111.653718,29.012149|12" }, { n: "郴州", g: "113.037704,25.782264|13" }, { n: "衡阳", g: "112.583819,26.898164|13" }, { n: "怀化", g: "109.986959,27.557483|13" }, { n: "娄底", g: "111.996396,27.741073|13" }, { n: "邵阳", g: "111.461525,27.236811|13" }, { n: "湘潭", g: "112.935556,27.835095|13" }, { n: "湘西州", g: "109.745746,28.317951|14" }, { n: "益阳", g: "112.366547,28.588088|13" }, { n: "永州", g: "111.614648,26.435972|13" }, { n: "岳阳", g: "113.146196,29.378007|13" }, { n: "张家界", g: "110.48162,29.124889|13" }, { n: "株洲", g: "113.131695,27.827433|13" }] }, { n: "江苏", g: "119.368489,33.013797|8", cities: [{ n: "南京", g: "118.778074,32.057236|12" }, { n: "常州", g: "119.981861,31.771397|12" }, { n: "淮安", g: "119.030186,33.606513|12" }, { n: "连云港", g: "119.173872,34.601549|12" }, { n: "南通", g: "120.873801,32.014665|12" }, { n: "苏州", g: "120.619907,31.317987|12" }, { n: "宿迁", g: "118.296893,33.95205|13" }, { n: "泰州", g: "119.919606,32.476053|13" }, { n: "无锡", g: "120.305456,31.570037|12" }, { n: "徐州", g: "117.188107,34.271553|12" }, { n: "盐城", g: "120.148872,33.379862|12" }, { n: "扬州", g: "119.427778,32.408505|13" }, { n: "镇江", g: "119.455835,32.204409|13" }] }, { n: "江西", g: "115.676082,27.757258|7", cities: [{ n: "南昌", g: "115.893528,28.689578|12" }, { n: "抚州", g: "116.360919,27.954545|13" }, { n: "赣州", g: "114.935909,25.845296|13" }, { n: "吉安", g: "114.992039,27.113848|13" }, { n: "景德镇", g: "117.186523,29.303563|12" }, { n: "九江", g: "115.999848,29.71964|13" }, { n: "萍乡", g: "113.859917,27.639544|13" }, { n: "上饶", g: "117.955464,28.457623|13" }, { n: "新余", g: "114.947117,27.822322|13" }, { n: "宜春", g: "114.400039,27.81113|13" }, { n: "鹰潭", g: "117.03545,28.24131|13" }] }, { n: "吉林", g: "126.262876,43.678846|7", cities: [{ n: "长春", g: "125.313642,43.898338|12" }, { n: "白城", g: "122.840777,45.621086|13" }, { n: "白山", g: "126.435798,41.945859|13" }, { n: "吉林市", g: "126.564544,43.871988|12" }, { n: "辽源", g: "125.133686,42.923303|13" }, { n: "四平", g: "124.391382,43.175525|12" }, { n: "松原", g: "124.832995,45.136049|13" }, { n: "通化", g: "125.94265,41.736397|13" }, { n: "延边", g: "129.485902,42.896414|13" }] }, { n: "辽宁", g: "122.753592,41.6216|8", cities: [{ n: "沈阳", g: "123.432791,41.808645|12" }, { n: "鞍山", g: "123.007763,41.118744|13" }, { n: "本溪", g: "123.778062,41.325838|12" }, { n: "朝阳", g: "120.446163,41.571828|13" }, { n: "大连", g: "121.593478,38.94871|12" }, { n: "丹东", g: "124.338543,40.129023|12" }, { n: "抚顺", g: "123.92982,41.877304|12" }, { n: "阜新", g: "121.660822,42.01925|14" }, { n: "葫芦岛", g: "120.860758,40.74303|13" }, { n: "锦州", g: "121.147749,41.130879|13" }, { n: "辽阳", g: "123.172451,41.273339|14" }, { n: "盘锦", g: "122.073228,41.141248|13" }, { n: "铁岭", g: "123.85485,42.299757|13" }, { n: "营口", g: "122.233391,40.668651|13" }] }, { n: "内蒙古", g: "114.415868,43.468238|5", cities: [{ n: "呼和浩特", g: "111.660351,40.828319|12" }, { n: "阿拉善盟", g: "105.695683,38.843075|14" }, { n: "包头", g: "109.846239,40.647119|12" }, { n: "巴彦淖尔", g: "107.423807,40.76918|12" }, { n: "赤峰", g: "118.930761,42.297112|12" }, { n: "鄂尔多斯", g: "109.993706,39.81649|12" }, { n: "呼伦贝尔", g: "119.760822,49.201636|12" }, { n: "通辽", g: "122.260363,43.633756|12" }, { n: "乌海", g: "106.831999,39.683177|13" }, { n: "乌兰察布", g: "113.112846,41.022363|12" }, { n: "锡林郭勒盟", g: "116.02734,43.939705|11" }, { n: "兴安盟", g: "122.048167,46.083757|11" }] }, { n: "宁夏", g: "106.155481,37.321323|8", cities: [{ n: "银川", g: "106.206479,38.502621|12" }, { n: "固原", g: "106.285268,36.021523|13" }, { n: "石嘴山", g: "106.379337,39.020223|13" }, { n: "吴忠", g: "106.208254,37.993561|14" }, { n: "中卫", g: "105.196754,37.521124|14" }] }, { n: "青海", g: "96.202544,35.499761|7", cities: [{ n: "西宁", g: "101.767921,36.640739|12" }, { n: "果洛州", g: "100.223723,34.480485|11" }, { n: "海东地区", g: "102.085207,36.51761|11" }, { n: "海北州", g: "100.879802,36.960654|11" }, { n: "海南州", g: "100.624066,36.284364|11" }, { n: "海西州", g: "97.342625,37.373799|11" }, { n: "黄南州", g: "102.0076,35.522852|11" }, { n: "玉树州", g: "97.013316,33.00624|14" }] }, { n: "山东", g: "118.527663,36.09929|8", cities: [{ n: "济南", g: "117.024967,36.682785|12" }, { n: "滨州", g: "117.968292,37.405314|12" }, { n: "东营", g: "118.583926,37.487121|12" }, { n: "德州", g: "116.328161,37.460826|12" }, { n: "菏泽", g: "115.46336,35.26244|13" }, { n: "济宁", g: "116.600798,35.402122|13" }, { n: "莱芜", g: "117.684667,36.233654|13" }, { n: "聊城", g: "115.986869,36.455829|12" }, { n: "临沂", g: "118.340768,35.072409|12" }, { n: "青岛", g: "120.384428,36.105215|12" }, { n: "日照", g: "119.50718,35.420225|12" }, { n: "泰安", g: "117.089415,36.188078|13" }, { n: "威海", g: "122.093958,37.528787|13" }, { n: "潍坊", g: "119.142634,36.716115|12" }, { n: "烟台", g: "121.309555,37.536562|12" }, { n: "枣庄", g: "117.279305,34.807883|13" }, { n: "淄博", g: "118.059134,36.804685|12" }] }, { n: "山西", g: "112.515496,37.866566|7", cities: [{ n: "太原", g: "112.550864,37.890277|12" }, { n: "长治", g: "113.120292,36.201664|12" }, { n: "大同", g: "113.290509,40.113744|12" }, { n: "晋城", g: "112.867333,35.499834|13" }, { n: "晋中", g: "112.738514,37.693362|13" }, { n: "临汾", g: "111.538788,36.099745|13" }, { n: "吕梁", g: "111.143157,37.527316|14" }, { n: "朔州", g: "112.479928,39.337672|13" }, { n: "忻州", g: "112.727939,38.461031|12" }, { n: "阳泉", g: "113.569238,37.869529|13" }, { n: "运城", g: "111.006854,35.038859|13" }] }, { n: "陕西", g: "109.503789,35.860026|7", cities: [{ n: "西安", g: "108.953098,34.2778|12" }, { n: "安康", g: "109.038045,32.70437|13" }, { n: "宝鸡", g: "107.170645,34.364081|12" }, { n: "汉中", g: "107.045478,33.081569|13" }, { n: "商洛", g: "109.934208,33.873907|13" }, { n: "铜川", g: "108.968067,34.908368|13" }, { n: "渭南", g: "109.483933,34.502358|13" }, { n: "咸阳", g: "108.707509,34.345373|13" }, { n: "延安", g: "109.50051,36.60332|13" }, { n: "榆林", g: "109.745926,38.279439|12" }] }, { n: "四川", g: "102.89916,30.367481|7", cities: [{ n: "成都", g: "104.067923,30.679943|12" }, { n: "阿坝州", g: "102.228565,31.905763|15" }, { n: "巴中", g: "106.757916,31.869189|14" }, { n: "达州", g: "107.494973,31.214199|14" }, { n: "德阳", g: "104.402398,31.13114|13" }, { n: "甘孜州", g: "101.969232,30.055144|15" }, { n: "广安", g: "106.63572,30.463984|13" }, { n: "广元", g: "105.819687,32.44104|13" }, { n: "乐山", g: "103.760824,29.600958|13" }, { n: "凉山州", g: "102.259591,27.892393|14" }, { n: "泸州", g: "105.44397,28.89593|14" }, { n: "南充", g: "106.105554,30.800965|13" }, { n: "眉山", g: "103.84143,30.061115|13" }, { n: "绵阳", g: "104.705519,31.504701|12" }, { n: "内江", g: "105.073056,29.599462|13" }, { n: "攀枝花", g: "101.722423,26.587571|14" }, { n: "遂宁", g: "105.564888,30.557491|12" }, { n: "雅安", g: "103.009356,29.999716|13" }, { n: "宜宾", g: "104.633019,28.769675|13" }, { n: "资阳", g: "104.63593,30.132191|13" }, { n: "自贡", g: "104.776071,29.359157|13" }] }, { n: "西藏", g: "89.137982,31.367315|6", cities: [{ n: "拉萨", g: "91.111891,29.662557|13" }, { n: "阿里地区", g: "81.107669,30.404557|11" }, { n: "昌都地区", g: "97.185582,31.140576|15" }, { n: "林芝地区", g: "94.349985,29.666941|11" }, { n: "那曲地区", g: "92.067018,31.48068|14" }, { n: "日喀则地区", g: "88.891486,29.269023|14" }, { n: "山南地区", g: "91.750644,29.229027|11" }] }, { n: "新疆", g: "85.614899,42.127001|6", cities: [{ n: "乌鲁木齐", g: "87.564988,43.84038|12" }, { n: "阿拉尔", g: "81.291737,40.61568|13" }, { n: "阿克苏地区", g: "80.269846,41.171731|12" }, { n: "阿勒泰地区", g: "88.137915,47.839744|13" }, { n: "巴音郭楞", g: "86.121688,41.771362|12" }, { n: "博尔塔拉州", g: "82.052436,44.913651|11" }, { n: "昌吉州", g: "87.296038,44.007058|13" }, { n: "哈密地区", g: "93.528355,42.858596|13" }, { n: "和田地区", g: "79.930239,37.116774|13" }, { n: "喀什地区", g: "75.992973,39.470627|12" }, { n: "克拉玛依", g: "84.88118,45.594331|13" }, { n: "克孜勒苏州", g: "76.137564,39.750346|11" }, { n: "石河子", g: "86.041865,44.308259|13" }, { n: "塔城地区", g: "82.974881,46.758684|12" }, { n: "图木舒克", g: "79.198155,39.889223|13" }, { n: "吐鲁番地区", g: "89.181595,42.96047|13" }, { n: "五家渠", g: "87.565449,44.368899|13" }, { n: "伊犁州", g: "81.297854,43.922248|11" }] }, { n: "云南", g: "101.592952,24.864213|7", cities: [{ n: "昆明", g: "102.714601,25.049153|12" }, { n: "保山", g: "99.177996,25.120489|13" }, { n: "楚雄州", g: "101.529382,25.066356|13" }, { n: "大理州", g: "100.223675,25.5969|14" }, { n: "德宏州", g: "98.589434,24.44124|14" }, { n: "迪庆州", g: "99.713682,27.831029|14" }, { n: "红河州", g: "103.384065,23.367718|11" }, { n: "丽江", g: "100.229628,26.875351|13" }, { n: "临沧", g: "100.092613,23.887806|14" }, { n: "怒江州", g: "98.859932,25.860677|14" }, { n: "普洱", g: "100.980058,22.788778|14" }, { n: "曲靖", g: "103.782539,25.520758|12" }, { n: "昭通", g: "103.725021,27.340633|13" }, { n: "文山", g: "104.089112,23.401781|14" }, { n: "西双版纳", g: "100.803038,22.009433|13" }, { n: "玉溪", g: "102.545068,24.370447|13" }] }, { n: "浙江", g: "119.957202,29.159494|8", cities: [{ n: "杭州", g: "120.219375,30.259244|12" }, { n: "湖州", g: "120.137243,30.877925|12" }, { n: "嘉兴", g: "120.760428,30.773992|13" }, { n: "金华", g: "119.652576,29.102899|12" }, { n: "丽水", g: "119.929576,28.4563|13" }, { n: "宁波", g: "121.579006,29.885259|12" }, { n: "衢州", g: "118.875842,28.95691|12" }, { n: "绍兴", g: "120.592467,30.002365|13" }, { n: "台州", g: "121.440613,28.668283|13" }, { n: "温州", g: "120.690635,28.002838|12" }, { n: "舟山", g: "122.169872,30.03601|13" }] }], other: [{ n: "香港", g: "114.186124,22.293586|11" }, { n: "澳门", g: "113.557519,22.204118|13" }, { n: "台湾", g: "120.961454,23.80406|8" }] };
  1635. function getCenter(g) {
  1636. var item = g.split("|");
  1637. item[0] = item[0].split(",");
  1638. return {
  1639. lng: parseFloat(item[0][0]),
  1640. lat: parseFloat(item[0][1])
  1641. };
  1642. }
  1643. var cityCenter = {
  1644. getProvinceNameByCityName: function getProvinceNameByCityName(name) {
  1645. var provinces = citycenter.provinces;
  1646. for (var i = 0; i < provinces.length; i++) {
  1647. var provinceName = provinces[i].n;
  1648. var cities = provinces[i].cities;
  1649. for (var j = 0; j < cities.length; j++) {
  1650. if (cities[j].n == name) {
  1651. return provinceName;
  1652. }
  1653. }
  1654. }
  1655. return null;
  1656. },
  1657. getCenterByCityName: function getCenterByCityName(name) {
  1658. for (var i = 0; i < citycenter.municipalities.length; i++) {
  1659. if (citycenter.municipalities[i].n == name) {
  1660. return getCenter(citycenter.municipalities[i].g);
  1661. }
  1662. }
  1663. for (var i = 0; i < citycenter.other.length; i++) {
  1664. if (citycenter.other[i].n == name) {
  1665. return getCenter(citycenter.other[i].g);
  1666. }
  1667. }
  1668. var provinces = citycenter.provinces;
  1669. for (var i = 0; i < provinces.length; i++) {
  1670. if (provinces[i].n == name) {
  1671. return getCenter(provinces[i].g);
  1672. }
  1673. var cities = provinces[i].cities;
  1674. for (var j = 0; j < cities.length; j++) {
  1675. if (cities[j].n == name) {
  1676. return getCenter(cities[j].g);
  1677. }
  1678. }
  1679. }
  1680. return null;
  1681. }
  1682. };
  1683. /**
  1684. * 根据弧线的坐标节点数组
  1685. */
  1686. function getCurvePoints(points) {
  1687. var curvePoints = [];
  1688. for (var i = 0; i < points.length - 1; i++) {
  1689. var p = getCurveByTwoPoints(points[i], points[i + 1]);
  1690. if (p && p.length > 0) {
  1691. curvePoints = curvePoints.concat(p);
  1692. }
  1693. }
  1694. return curvePoints;
  1695. }
  1696. /**
  1697. * 根据两点获取曲线坐标点数组
  1698. * @param Point 起点
  1699. * @param Point 终点
  1700. */
  1701. function getCurveByTwoPoints(obj1, obj2) {
  1702. if (!obj1 || !obj2) {
  1703. return null;
  1704. }
  1705. var B1 = function B1(x) {
  1706. return 1 - 2 * x + x * x;
  1707. };
  1708. var B2 = function B2(x) {
  1709. return 2 * x - 2 * x * x;
  1710. };
  1711. var B3 = function B3(x) {
  1712. return x * x;
  1713. };
  1714. var curveCoordinates = [];
  1715. var count = 40; // 曲线是由一些小的线段组成的,这个表示这个曲线所有到的折线的个数
  1716. var isFuture = false;
  1717. var t, h, h2, lat3, lng3, j, t2;
  1718. var LnArray = [];
  1719. var i = 0;
  1720. var inc = 0;
  1721. if (typeof obj2 == "undefined") {
  1722. if (typeof curveCoordinates != "undefined") {
  1723. curveCoordinates = [];
  1724. }
  1725. return;
  1726. }
  1727. var lat1 = parseFloat(obj1.lat);
  1728. var lat2 = parseFloat(obj2.lat);
  1729. var lng1 = parseFloat(obj1.lng);
  1730. var lng2 = parseFloat(obj2.lng);
  1731. // 计算曲线角度的方法
  1732. if (lng2 > lng1) {
  1733. if (parseFloat(lng2 - lng1) > 180) {
  1734. if (lng1 < 0) {
  1735. lng1 = parseFloat(180 + 180 + lng1);
  1736. }
  1737. }
  1738. }
  1739. if (lng1 > lng2) {
  1740. if (parseFloat(lng1 - lng2) > 180) {
  1741. if (lng2 < 0) {
  1742. lng2 = parseFloat(180 + 180 + lng2);
  1743. }
  1744. }
  1745. }
  1746. j = 0;
  1747. t2 = 0;
  1748. if (lat2 == lat1) {
  1749. t = 0;
  1750. h = lng1 - lng2;
  1751. } else if (lng2 == lng1) {
  1752. t = Math.PI / 2;
  1753. h = lat1 - lat2;
  1754. } else {
  1755. t = Math.atan((lat2 - lat1) / (lng2 - lng1));
  1756. h = (lat2 - lat1) / Math.sin(t);
  1757. }
  1758. if (t2 == 0) {
  1759. t2 = t + Math.PI / 5;
  1760. }
  1761. h2 = h / 2;
  1762. lng3 = h2 * Math.cos(t2) + lng1;
  1763. lat3 = h2 * Math.sin(t2) + lat1;
  1764. for (i = 0; i < count + 1; i++) {
  1765. curveCoordinates.push([lng1 * B1(inc) + lng3 * B2(inc) + lng2 * B3(inc), lat1 * B1(inc) + lat3 * B2(inc) + lat2 * B3(inc)]);
  1766. inc = inc + 1 / count;
  1767. }
  1768. return curveCoordinates;
  1769. }
  1770. var curve = {
  1771. getPoints: getCurvePoints
  1772. };
  1773. /*
  1774. FDEB algorithm implementation [www.win.tue.nl/~dholten/papers/forcebundles_eurovis.pdf].
  1775. Author: (github.com/upphiminn)
  1776. 2013
  1777. */
  1778. var ForceEdgeBundling = function ForceEdgeBundling() {
  1779. var data_nodes = {},
  1780. // {'nodeid':{'x':,'y':},..}
  1781. data_edges = [],
  1782. // [{'source':'nodeid1', 'target':'nodeid2'},..]
  1783. compatibility_list_for_edge = [],
  1784. subdivision_points_for_edge = [],
  1785. K = 0.1,
  1786. // global bundling constant controling edge stiffness
  1787. S_initial = 0.1,
  1788. // init. distance to move points
  1789. P_initial = 1,
  1790. // init. subdivision number
  1791. P_rate = 2,
  1792. // subdivision rate increase
  1793. C = 6,
  1794. // number of cycles to perform
  1795. I_initial = 70,
  1796. // init. number of iterations for cycle
  1797. I_rate = 0.6666667,
  1798. // rate at which iteration number decreases i.e. 2/3
  1799. compatibility_threshold = 0.6,
  1800. invers_quadratic_mode = false,
  1801. eps = 1e-8;
  1802. /*** Geometry Helper Methods ***/
  1803. function vector_dot_product(p, q) {
  1804. return p.x * q.x + p.y * q.y;
  1805. }
  1806. function edge_as_vector(P) {
  1807. return { 'x': data_nodes[P.target].x - data_nodes[P.source].x,
  1808. 'y': data_nodes[P.target].y - data_nodes[P.source].y };
  1809. }
  1810. function edge_length(e) {
  1811. return Math.sqrt(Math.pow(data_nodes[e.source].x - data_nodes[e.target].x, 2) + Math.pow(data_nodes[e.source].y - data_nodes[e.target].y, 2));
  1812. }
  1813. function custom_edge_length(e) {
  1814. return Math.sqrt(Math.pow(e.source.x - e.target.x, 2) + Math.pow(e.source.y - e.target.y, 2));
  1815. }
  1816. function edge_midpoint(e) {
  1817. var middle_x = (data_nodes[e.source].x + data_nodes[e.target].x) / 2.0;
  1818. var middle_y = (data_nodes[e.source].y + data_nodes[e.target].y) / 2.0;
  1819. return { 'x': middle_x, 'y': middle_y };
  1820. }
  1821. function compute_divided_edge_length(e_idx) {
  1822. var length = 0;
  1823. for (var i = 1; i < subdivision_points_for_edge[e_idx].length; i++) {
  1824. var segment_length = euclidean_distance(subdivision_points_for_edge[e_idx][i], subdivision_points_for_edge[e_idx][i - 1]);
  1825. length += segment_length;
  1826. }
  1827. return length;
  1828. }
  1829. function euclidean_distance(p, q) {
  1830. return Math.sqrt(Math.pow(p.x - q.x, 2) + Math.pow(p.y - q.y, 2));
  1831. }
  1832. function project_point_on_line(p, Q) {
  1833. var L = Math.sqrt((Q.target.x - Q.source.x) * (Q.target.x - Q.source.x) + (Q.target.y - Q.source.y) * (Q.target.y - Q.source.y));
  1834. var r = ((Q.source.y - p.y) * (Q.source.y - Q.target.y) - (Q.source.x - p.x) * (Q.target.x - Q.source.x)) / (L * L);
  1835. return { 'x': Q.source.x + r * (Q.target.x - Q.source.x), 'y': Q.source.y + r * (Q.target.y - Q.source.y) };
  1836. }
  1837. /*** ********************** ***/
  1838. /*** Initialization Methods ***/
  1839. function initialize_edge_subdivisions() {
  1840. for (var i = 0; i < data_edges.length; i++) {
  1841. if (P_initial == 1) subdivision_points_for_edge[i] = []; //0 subdivisions
  1842. else {
  1843. subdivision_points_for_edge[i] = [];
  1844. subdivision_points_for_edge[i].push(data_nodes[data_edges[i].source]);
  1845. subdivision_points_for_edge[i].push(data_nodes[data_edges[i].target]);
  1846. }
  1847. }
  1848. }
  1849. function initialize_compatibility_lists() {
  1850. for (var i = 0; i < data_edges.length; i++) {
  1851. compatibility_list_for_edge[i] = [];
  1852. } //0 compatible edges.
  1853. }
  1854. function filter_self_loops(edgelist) {
  1855. var filtered_edge_list = [];
  1856. for (var e = 0; e < edgelist.length; e++) {
  1857. if (data_nodes[edgelist[e].source].x != data_nodes[edgelist[e].target].x && data_nodes[edgelist[e].source].y != data_nodes[edgelist[e].target].y) {
  1858. //or smaller than eps
  1859. filtered_edge_list.push(edgelist[e]);
  1860. }
  1861. }
  1862. return filtered_edge_list;
  1863. }
  1864. /*** ********************** ***/
  1865. /*** Force Calculation Methods ***/
  1866. function apply_spring_force(e_idx, i, kP) {
  1867. var prev = subdivision_points_for_edge[e_idx][i - 1];
  1868. var next = subdivision_points_for_edge[e_idx][i + 1];
  1869. var crnt = subdivision_points_for_edge[e_idx][i];
  1870. var x = prev.x - crnt.x + next.x - crnt.x;
  1871. var y = prev.y - crnt.y + next.y - crnt.y;
  1872. x *= kP;
  1873. y *= kP;
  1874. return { 'x': x, 'y': y };
  1875. }
  1876. function apply_electrostatic_force(e_idx, i, S) {
  1877. var sum_of_forces = { 'x': 0, 'y': 0 };
  1878. var compatible_edges_list = compatibility_list_for_edge[e_idx];
  1879. for (var oe = 0; oe < compatible_edges_list.length; oe++) {
  1880. var force = { 'x': subdivision_points_for_edge[compatible_edges_list[oe]][i].x - subdivision_points_for_edge[e_idx][i].x,
  1881. 'y': subdivision_points_for_edge[compatible_edges_list[oe]][i].y - subdivision_points_for_edge[e_idx][i].y };
  1882. if (Math.abs(force.x) > eps || Math.abs(force.y) > eps) {
  1883. var diff = 1 / Math.pow(custom_edge_length({ 'source': subdivision_points_for_edge[compatible_edges_list[oe]][i],
  1884. 'target': subdivision_points_for_edge[e_idx][i] }), 1);
  1885. sum_of_forces.x += force.x * diff;
  1886. sum_of_forces.y += force.y * diff;
  1887. }
  1888. }
  1889. return sum_of_forces;
  1890. }
  1891. function apply_resulting_forces_on_subdivision_points(e_idx, P, S) {
  1892. var kP = K / (edge_length(data_edges[e_idx]) * (P + 1)); // kP=K/|P|(number of segments), where |P| is the initial length of edge P.
  1893. // (length * (num of sub division pts - 1))
  1894. var resulting_forces_for_subdivision_points = [{ 'x': 0, 'y': 0 }];
  1895. for (var i = 1; i < P + 1; i++) {
  1896. // exclude initial end points of the edge 0 and P+1
  1897. var resulting_force = { 'x': 0, 'y': 0 };
  1898. var spring_force = apply_spring_force(e_idx, i, kP);
  1899. var electrostatic_force = apply_electrostatic_force(e_idx, i, S);
  1900. resulting_force.x = S * (spring_force.x + electrostatic_force.x);
  1901. resulting_force.y = S * (spring_force.y + electrostatic_force.y);
  1902. resulting_forces_for_subdivision_points.push(resulting_force);
  1903. }
  1904. resulting_forces_for_subdivision_points.push({ 'x': 0, 'y': 0 });
  1905. return resulting_forces_for_subdivision_points;
  1906. }
  1907. /*** ********************** ***/
  1908. /*** Edge Division Calculation Methods ***/
  1909. function update_edge_divisions(P) {
  1910. for (var e_idx = 0; e_idx < data_edges.length; e_idx++) {
  1911. if (P == 1) {
  1912. subdivision_points_for_edge[e_idx].push(data_nodes[data_edges[e_idx].source]); // source
  1913. subdivision_points_for_edge[e_idx].push(edge_midpoint(data_edges[e_idx])); // mid point
  1914. subdivision_points_for_edge[e_idx].push(data_nodes[data_edges[e_idx].target]); // target
  1915. } else {
  1916. var divided_edge_length = compute_divided_edge_length(e_idx);
  1917. var segment_length = divided_edge_length / (P + 1);
  1918. var current_segment_length = segment_length;
  1919. var new_subdivision_points = [];
  1920. new_subdivision_points.push(data_nodes[data_edges[e_idx].source]); //source
  1921. for (var i = 1; i < subdivision_points_for_edge[e_idx].length; i++) {
  1922. var old_segment_length = euclidean_distance(subdivision_points_for_edge[e_idx][i], subdivision_points_for_edge[e_idx][i - 1]);
  1923. while (old_segment_length > current_segment_length) {
  1924. var percent_position = current_segment_length / old_segment_length;
  1925. var new_subdivision_point_x = subdivision_points_for_edge[e_idx][i - 1].x;
  1926. var new_subdivision_point_y = subdivision_points_for_edge[e_idx][i - 1].y;
  1927. new_subdivision_point_x += percent_position * (subdivision_points_for_edge[e_idx][i].x - subdivision_points_for_edge[e_idx][i - 1].x);
  1928. new_subdivision_point_y += percent_position * (subdivision_points_for_edge[e_idx][i].y - subdivision_points_for_edge[e_idx][i - 1].y);
  1929. new_subdivision_points.push({ 'x': new_subdivision_point_x,
  1930. 'y': new_subdivision_point_y });
  1931. old_segment_length -= current_segment_length;
  1932. current_segment_length = segment_length;
  1933. }
  1934. current_segment_length -= old_segment_length;
  1935. }
  1936. new_subdivision_points.push(data_nodes[data_edges[e_idx].target]); //target
  1937. subdivision_points_for_edge[e_idx] = new_subdivision_points;
  1938. }
  1939. }
  1940. }
  1941. /*** ********************** ***/
  1942. /*** Edge compatibility measures ***/
  1943. function angle_compatibility(P, Q) {
  1944. var result = Math.abs(vector_dot_product(edge_as_vector(P), edge_as_vector(Q)) / (edge_length(P) * edge_length(Q)));
  1945. return result;
  1946. }
  1947. function scale_compatibility(P, Q) {
  1948. var lavg = (edge_length(P) + edge_length(Q)) / 2.0;
  1949. var result = 2.0 / (lavg / Math.min(edge_length(P), edge_length(Q)) + Math.max(edge_length(P), edge_length(Q)) / lavg);
  1950. return result;
  1951. }
  1952. function position_compatibility(P, Q) {
  1953. var lavg = (edge_length(P) + edge_length(Q)) / 2.0;
  1954. var midP = { 'x': (data_nodes[P.source].x + data_nodes[P.target].x) / 2.0,
  1955. 'y': (data_nodes[P.source].y + data_nodes[P.target].y) / 2.0 };
  1956. var midQ = { 'x': (data_nodes[Q.source].x + data_nodes[Q.target].x) / 2.0,
  1957. 'y': (data_nodes[Q.source].y + data_nodes[Q.target].y) / 2.0 };
  1958. var result = lavg / (lavg + euclidean_distance(midP, midQ));
  1959. return result;
  1960. }
  1961. function edge_visibility(P, Q) {
  1962. var I0 = project_point_on_line(data_nodes[Q.source], { 'source': data_nodes[P.source],
  1963. 'target': data_nodes[P.target] });
  1964. var I1 = project_point_on_line(data_nodes[Q.target], { 'source': data_nodes[P.source],
  1965. 'target': data_nodes[P.target] }); //send acutal edge points positions
  1966. var midI = { 'x': (I0.x + I1.x) / 2.0,
  1967. 'y': (I0.y + I1.y) / 2.0 };
  1968. var midP = { 'x': (data_nodes[P.source].x + data_nodes[P.target].x) / 2.0,
  1969. 'y': (data_nodes[P.source].y + data_nodes[P.target].y) / 2.0 };
  1970. var result = Math.max(0, 1 - 2 * euclidean_distance(midP, midI) / euclidean_distance(I0, I1));
  1971. return result;
  1972. }
  1973. function visibility_compatibility(P, Q) {
  1974. return Math.min(edge_visibility(P, Q), edge_visibility(Q, P));
  1975. }
  1976. function compatibility_score(P, Q) {
  1977. var result = angle_compatibility(P, Q) * scale_compatibility(P, Q) * position_compatibility(P, Q) * visibility_compatibility(P, Q);
  1978. return result;
  1979. }
  1980. function are_compatible(P, Q) {
  1981. // console.log('compatibility ' + P.source +' - '+ P.target + ' and ' + Q.source +' '+ Q.target);
  1982. return compatibility_score(P, Q) >= compatibility_threshold;
  1983. }
  1984. function compute_compatibility_lists() {
  1985. for (var e = 0; e < data_edges.length - 1; e++) {
  1986. for (var oe = e + 1; oe < data_edges.length; oe++) {
  1987. // don't want any duplicates
  1988. if (e == oe) continue;else {
  1989. if (are_compatible(data_edges[e], data_edges[oe])) {
  1990. compatibility_list_for_edge[e].push(oe);
  1991. compatibility_list_for_edge[oe].push(e);
  1992. }
  1993. }
  1994. }
  1995. }
  1996. }
  1997. /*** ************************ ***/
  1998. /*** Main Bundling Loop Methods ***/
  1999. var forcebundle = function forcebundle() {
  2000. var S = S_initial;
  2001. var I = I_initial;
  2002. var P = P_initial;
  2003. initialize_edge_subdivisions();
  2004. initialize_compatibility_lists();
  2005. update_edge_divisions(P);
  2006. compute_compatibility_lists();
  2007. for (var cycle = 0; cycle < C; cycle++) {
  2008. for (var iteration = 0; iteration < I; iteration++) {
  2009. var forces = [];
  2010. for (var edge = 0; edge < data_edges.length; edge++) {
  2011. forces[edge] = apply_resulting_forces_on_subdivision_points(edge, P, S);
  2012. }
  2013. for (var e = 0; e < data_edges.length; e++) {
  2014. for (var i = 0; i < P + 1; i++) {
  2015. subdivision_points_for_edge[e][i].x += forces[e][i].x;
  2016. subdivision_points_for_edge[e][i].y += forces[e][i].y;
  2017. }
  2018. }
  2019. }
  2020. //prepare for next cycle
  2021. S = S / 2;
  2022. P = P * 2;
  2023. I = I_rate * I;
  2024. update_edge_divisions(P);
  2025. // console.log('C' + cycle);
  2026. // console.log('P' + P);
  2027. // console.log('S' + S);
  2028. }
  2029. return subdivision_points_for_edge;
  2030. };
  2031. /*** ************************ ***/
  2032. /*** Getters/Setters Methods ***/
  2033. forcebundle.nodes = function (nl) {
  2034. if (arguments.length == 0) {
  2035. return data_nodes;
  2036. } else {
  2037. data_nodes = nl;
  2038. }
  2039. return forcebundle;
  2040. };
  2041. forcebundle.edges = function (ll) {
  2042. if (arguments.length == 0) {
  2043. return data_edges;
  2044. } else {
  2045. data_edges = filter_self_loops(ll); //remove edges to from to the same point
  2046. }
  2047. return forcebundle;
  2048. };
  2049. forcebundle.bundling_stiffness = function (k) {
  2050. if (arguments.length == 0) {
  2051. return K;
  2052. } else {
  2053. K = k;
  2054. }
  2055. return forcebundle;
  2056. };
  2057. forcebundle.step_size = function (step) {
  2058. if (arguments.length == 0) {
  2059. return S_initial;
  2060. } else {
  2061. S_initial = step;
  2062. }
  2063. return forcebundle;
  2064. };
  2065. forcebundle.cycles = function (c) {
  2066. if (arguments.length == 0) {
  2067. return C;
  2068. } else {
  2069. C = c;
  2070. }
  2071. return forcebundle;
  2072. };
  2073. forcebundle.iterations = function (i) {
  2074. if (arguments.length == 0) {
  2075. return I_initial;
  2076. } else {
  2077. I_initial = i;
  2078. }
  2079. return forcebundle;
  2080. };
  2081. forcebundle.iterations_rate = function (i) {
  2082. if (arguments.length == 0) {
  2083. return I_rate;
  2084. } else {
  2085. I_rate = i;
  2086. }
  2087. return forcebundle;
  2088. };
  2089. forcebundle.subdivision_points_seed = function (p) {
  2090. if (arguments.length == 0) {
  2091. return P;
  2092. } else {
  2093. P = p;
  2094. }
  2095. return forcebundle;
  2096. };
  2097. forcebundle.subdivision_rate = function (r) {
  2098. if (arguments.length == 0) {
  2099. return P_rate;
  2100. } else {
  2101. P_rate = r;
  2102. }
  2103. return forcebundle;
  2104. };
  2105. forcebundle.compatbility_threshold = function (t) {
  2106. if (arguments.length == 0) {
  2107. return compatbility_threshold;
  2108. } else {
  2109. compatibility_threshold = t;
  2110. }
  2111. return forcebundle;
  2112. };
  2113. /*** ************************ ***/
  2114. return forcebundle;
  2115. };
  2116. /**
  2117. * @author kyle / http://nikai.us/
  2118. */
  2119. /**
  2120. * Category
  2121. * @param {Object} splitList:
  2122. * {
  2123. * other: 1,
  2124. * 1: 2,
  2125. * 2: 3,
  2126. * 3: 4,
  2127. * 4: 5,
  2128. * 5: 6,
  2129. * 6: 7
  2130. * }
  2131. */
  2132. function Category(splitList) {
  2133. this.splitList = splitList || {
  2134. other: 1
  2135. };
  2136. }
  2137. Category.prototype.get = function (count) {
  2138. var splitList = this.splitList;
  2139. var value = splitList['other'];
  2140. for (var i in splitList) {
  2141. if (count == i) {
  2142. value = splitList[i];
  2143. break;
  2144. }
  2145. }
  2146. return value;
  2147. };
  2148. /**
  2149. * 根据DataSet自动生成对应的splitList
  2150. */
  2151. Category.prototype.generateByDataSet = function (dataSet) {
  2152. var colors = ['rgba(255, 255, 0, 0.8)', 'rgba(253, 98, 104, 0.8)', 'rgba(255, 146, 149, 0.8)', 'rgba(255, 241, 193, 0.8)', 'rgba(110, 176, 253, 0.8)', 'rgba(52, 139, 251, 0.8)', 'rgba(17, 102, 252, 0.8)'];
  2153. var data = dataSet.get();
  2154. this.splitList = {};
  2155. var count = 0;
  2156. for (var i = 0; i < data.length; i++) {
  2157. if (this.splitList[data[i].count] === undefined) {
  2158. this.splitList[data[i].count] = colors[count];
  2159. count++;
  2160. }
  2161. if (count >= colors.length - 1) {
  2162. break;
  2163. }
  2164. }
  2165. this.splitList['other'] = colors[colors.length - 1];
  2166. };
  2167. Category.prototype.getLegend = function (options) {
  2168. var splitList = this.splitList;
  2169. var container = document.createElement('div');
  2170. container.style.cssText = "background:#fff; padding: 5px; border: 1px solid #ccc;";
  2171. var html = '';
  2172. for (var key in splitList) {
  2173. html += '<div style="line-height: 19px;"><span style="vertical-align: -2px; display: inline-block; width: 30px;height: 19px;background:' + splitList[key] + ';"></span><span style="margin-left: 3px;">' + key + '<span></div>';
  2174. }
  2175. container.innerHTML = html;
  2176. return container;
  2177. };
  2178. /**
  2179. * @author kyle / http://nikai.us/
  2180. */
  2181. /**
  2182. * Choropleth
  2183. * @param {Object} splitList:
  2184. * [
  2185. * {
  2186. * start: 0,
  2187. * end: 2,
  2188. * value: randomColor()
  2189. * },{
  2190. * start: 2,
  2191. * end: 4,
  2192. * value: randomColor()
  2193. * },{
  2194. * start: 4,
  2195. * value: randomColor()
  2196. * }
  2197. * ];
  2198. *
  2199. */
  2200. function Choropleth(splitList) {
  2201. this.splitList = splitList || [{
  2202. start: 0,
  2203. value: 'red'
  2204. }];
  2205. }
  2206. Choropleth.prototype.get = function (count) {
  2207. var splitList = this.splitList;
  2208. var value = false;
  2209. for (var i = 0; i < splitList.length; i++) {
  2210. if ((splitList[i].start === undefined || splitList[i].start !== undefined && count >= splitList[i].start) && (splitList[i].end === undefined || splitList[i].end !== undefined && count < splitList[i].end)) {
  2211. value = splitList[i].value;
  2212. break;
  2213. }
  2214. }
  2215. return value;
  2216. };
  2217. /**
  2218. * 根据DataSet自动生成对应的splitList
  2219. */
  2220. Choropleth.prototype.generateByDataSet = function (dataSet) {
  2221. var min = dataSet.getMin('count');
  2222. var max = dataSet.getMax('count');
  2223. this.generateByMinMax(min, max);
  2224. };
  2225. /**
  2226. * 根据DataSet自动生成对应的splitList
  2227. */
  2228. Choropleth.prototype.generateByMinMax = function (min, max) {
  2229. var colors = ['rgba(255, 255, 0, 0.8)', 'rgba(253, 98, 104, 0.8)', 'rgba(255, 146, 149, 0.8)', 'rgba(255, 241, 193, 0.8)', 'rgba(110, 176, 253, 0.8)', 'rgba(52, 139, 251, 0.8)', 'rgba(17, 102, 252, 0.8)'];
  2230. var splitNum = (max - min) / 7;
  2231. var index = min;
  2232. this.splitList = [];
  2233. var count = 0;
  2234. while (index < max) {
  2235. this.splitList.push({
  2236. start: index,
  2237. end: index + splitNum,
  2238. value: colors[count]
  2239. });
  2240. count++;
  2241. index += splitNum;
  2242. }
  2243. };
  2244. Choropleth.prototype.getLegend = function (options) {
  2245. var splitList = this.splitList;
  2246. };
  2247. /**
  2248. * @author Mofei<http://www.zhuwenlong.com>
  2249. */
  2250. var MapHelper = function () {
  2251. function MapHelper(id, type, opt) {
  2252. classCallCheck(this, MapHelper);
  2253. if (!id || !type) {
  2254. console.warn('id 和 type 为必填项');
  2255. return false;
  2256. }
  2257. if (type == 'baidu') {
  2258. if (!BMap) {
  2259. console.warn('请先引入百度地图JS API');
  2260. return false;
  2261. }
  2262. } else {
  2263. console.warn('暂不支持你的地图类型');
  2264. }
  2265. this.type = type;
  2266. var center = opt && opt.center ? opt.center : [106.962497, 38.208726];
  2267. var zoom = opt && opt.zoom ? opt.zoom : 5;
  2268. var map = this.map = new BMap.Map(id, {
  2269. enableMapClick: false
  2270. });
  2271. map.centerAndZoom(new BMap.Point(center[0], center[1]), zoom);
  2272. map.enableScrollWheelZoom(true);
  2273. map.setMapStyle({
  2274. style: 'light'
  2275. });
  2276. }
  2277. createClass(MapHelper, [{
  2278. key: 'addLayer',
  2279. value: function addLayer(datas, options) {
  2280. if (this.type == 'baidu') {
  2281. return new mapv.baiduMapLayer(this.map, dataSet, options);
  2282. }
  2283. }
  2284. }, {
  2285. key: 'getMap',
  2286. value: function getMap() {
  2287. return this.map;
  2288. }
  2289. }]);
  2290. return MapHelper;
  2291. }();
  2292. /**
  2293. * 一直覆盖在当前地图视野的Canvas对象
  2294. *
  2295. * @author nikai (@胖嘟嘟的骨头, nikai@baidu.com)
  2296. *
  2297. * @param
  2298. * {
  2299. * map 地图实例对象
  2300. * }
  2301. */
  2302. function CanvasLayer(options) {
  2303. this.options = options || {};
  2304. this.paneName = this.options.paneName || 'mapPane';
  2305. this.context = this.options.context || '2d';
  2306. this.zIndex = this.options.zIndex || 0;
  2307. this.mixBlendMode = this.options.mixBlendMode || null;
  2308. this.enableMassClear = this.options.enableMassClear;
  2309. this._map = options.map;
  2310. this._lastDrawTime = null;
  2311. this.show();
  2312. }
  2313. var global$3 = typeof window === 'undefined' ? {} : window;
  2314. if (global$3.BMap) {
  2315. CanvasLayer.prototype = new BMap.Overlay();
  2316. CanvasLayer.prototype.initialize = function (map) {
  2317. this._map = map;
  2318. var canvas = this.canvas = document.createElement("canvas");
  2319. canvas.style.cssText = "position:absolute;" + "left:0;" + "top:0;" + "z-index:" + this.zIndex + ";user-select:none;";
  2320. canvas.style.mixBlendMode = this.mixBlendMode;
  2321. this.adjustSize();
  2322. map.getPanes()[this.paneName].appendChild(canvas);
  2323. var that = this;
  2324. map.addEventListener('resize', function () {
  2325. that.adjustSize();
  2326. that._draw();
  2327. });
  2328. return this.canvas;
  2329. };
  2330. CanvasLayer.prototype.adjustSize = function () {
  2331. var size = this._map.getSize();
  2332. var canvas = this.canvas;
  2333. var devicePixelRatio = this.devicePixelRatio = global$3.devicePixelRatio || 1;
  2334. canvas.width = size.width * devicePixelRatio;
  2335. canvas.height = size.height * devicePixelRatio;
  2336. if (this.context == '2d') {
  2337. canvas.getContext(this.context).scale(devicePixelRatio, devicePixelRatio);
  2338. }
  2339. canvas.style.width = size.width + "px";
  2340. canvas.style.height = size.height + "px";
  2341. };
  2342. CanvasLayer.prototype.draw = function () {
  2343. var self = this;
  2344. clearTimeout(self.timeoutID);
  2345. self.timeoutID = setTimeout(function () {
  2346. self._draw();
  2347. }, 15);
  2348. };
  2349. CanvasLayer.prototype._draw = function () {
  2350. var map = this._map;
  2351. var size = map.getSize();
  2352. var center = map.getCenter();
  2353. if (center) {
  2354. var pixel = map.pointToOverlayPixel(center);
  2355. this.canvas.style.left = pixel.x - size.width / 2 + 'px';
  2356. this.canvas.style.top = pixel.y - size.height / 2 + 'px';
  2357. this.dispatchEvent('draw');
  2358. this.options.update && this.options.update.call(this);
  2359. }
  2360. };
  2361. CanvasLayer.prototype.getContainer = function () {
  2362. return this.canvas;
  2363. };
  2364. CanvasLayer.prototype.show = function () {
  2365. if (!this.canvas) {
  2366. this._map.addOverlay(this);
  2367. }
  2368. this.canvas.style.display = "block";
  2369. };
  2370. CanvasLayer.prototype.hide = function () {
  2371. this.canvas.style.display = "none";
  2372. //this._map.removeOverlay(this);
  2373. };
  2374. CanvasLayer.prototype.setZIndex = function (zIndex) {
  2375. this.canvas.style.zIndex = zIndex;
  2376. };
  2377. CanvasLayer.prototype.getZIndex = function () {
  2378. return this.zIndex;
  2379. };
  2380. }
  2381. /**
  2382. * Tween.js - Licensed under the MIT license
  2383. * https://github.com/tweenjs/tween.js
  2384. * ----------------------------------------------
  2385. *
  2386. * See https://github.com/tweenjs/tween.js/graphs/contributors for the full list of contributors.
  2387. * Thank you all, you're awesome!
  2388. */
  2389. var TWEEN = TWEEN || function () {
  2390. var _tweens = [];
  2391. return {
  2392. getAll: function getAll() {
  2393. return _tweens;
  2394. },
  2395. removeAll: function removeAll() {
  2396. _tweens = [];
  2397. },
  2398. add: function add(tween) {
  2399. _tweens.push(tween);
  2400. },
  2401. remove: function remove(tween) {
  2402. var i = _tweens.indexOf(tween);
  2403. if (i !== -1) {
  2404. _tweens.splice(i, 1);
  2405. }
  2406. },
  2407. update: function update(time, preserve) {
  2408. if (_tweens.length === 0) {
  2409. return false;
  2410. }
  2411. var i = 0;
  2412. time = time !== undefined ? time : TWEEN.now();
  2413. while (i < _tweens.length) {
  2414. if (_tweens[i].update(time) || preserve) {
  2415. i++;
  2416. } else {
  2417. _tweens.splice(i, 1);
  2418. }
  2419. }
  2420. return true;
  2421. }
  2422. };
  2423. }();
  2424. // Include a performance.now polyfill.
  2425. // In node.js, use process.hrtime.
  2426. if (typeof window === 'undefined' && typeof process !== 'undefined') {
  2427. TWEEN.now = function () {
  2428. var time = process.hrtime();
  2429. // Convert [seconds, nanoseconds] to milliseconds.
  2430. return time[0] * 1000 + time[1] / 1000000;
  2431. };
  2432. }
  2433. // In a browser, use window.performance.now if it is available.
  2434. else if (typeof window !== 'undefined' && window.performance !== undefined && window.performance.now !== undefined) {
  2435. // This must be bound, because directly assigning this function
  2436. // leads to an invocation exception in Chrome.
  2437. TWEEN.now = window.performance.now.bind(window.performance);
  2438. }
  2439. // Use Date.now if it is available.
  2440. else if (Date.now !== undefined) {
  2441. TWEEN.now = Date.now;
  2442. }
  2443. // Otherwise, use 'new Date().getTime()'.
  2444. else {
  2445. TWEEN.now = function () {
  2446. return new Date().getTime();
  2447. };
  2448. }
  2449. TWEEN.Tween = function (object) {
  2450. var _object = object;
  2451. var _valuesStart = {};
  2452. var _valuesEnd = {};
  2453. var _valuesStartRepeat = {};
  2454. var _duration = 1000;
  2455. var _repeat = 0;
  2456. var _repeatDelayTime;
  2457. var _yoyo = false;
  2458. var _isPlaying = false;
  2459. var _reversed = false;
  2460. var _delayTime = 0;
  2461. var _startTime = null;
  2462. var _easingFunction = TWEEN.Easing.Linear.None;
  2463. var _interpolationFunction = TWEEN.Interpolation.Linear;
  2464. var _chainedTweens = [];
  2465. var _onStartCallback = null;
  2466. var _onStartCallbackFired = false;
  2467. var _onUpdateCallback = null;
  2468. var _onCompleteCallback = null;
  2469. var _onStopCallback = null;
  2470. this.to = function (properties, duration) {
  2471. _valuesEnd = properties;
  2472. if (duration !== undefined) {
  2473. _duration = duration;
  2474. }
  2475. return this;
  2476. };
  2477. this.start = function (time) {
  2478. TWEEN.add(this);
  2479. _isPlaying = true;
  2480. _onStartCallbackFired = false;
  2481. _startTime = time !== undefined ? time : TWEEN.now();
  2482. _startTime += _delayTime;
  2483. for (var property in _valuesEnd) {
  2484. // Check if an Array was provided as property value
  2485. if (_valuesEnd[property] instanceof Array) {
  2486. if (_valuesEnd[property].length === 0) {
  2487. continue;
  2488. }
  2489. // Create a local copy of the Array with the start value at the front
  2490. _valuesEnd[property] = [_object[property]].concat(_valuesEnd[property]);
  2491. }
  2492. // If `to()` specifies a property that doesn't exist in the source object,
  2493. // we should not set that property in the object
  2494. if (_object[property] === undefined) {
  2495. continue;
  2496. }
  2497. // Save the starting value.
  2498. _valuesStart[property] = _object[property];
  2499. if (_valuesStart[property] instanceof Array === false) {
  2500. _valuesStart[property] *= 1.0; // Ensures we're using numbers, not strings
  2501. }
  2502. _valuesStartRepeat[property] = _valuesStart[property] || 0;
  2503. }
  2504. return this;
  2505. };
  2506. this.stop = function () {
  2507. if (!_isPlaying) {
  2508. return this;
  2509. }
  2510. TWEEN.remove(this);
  2511. _isPlaying = false;
  2512. if (_onStopCallback !== null) {
  2513. _onStopCallback.call(_object, _object);
  2514. }
  2515. this.stopChainedTweens();
  2516. return this;
  2517. };
  2518. this.end = function () {
  2519. this.update(_startTime + _duration);
  2520. return this;
  2521. };
  2522. this.stopChainedTweens = function () {
  2523. for (var i = 0, numChainedTweens = _chainedTweens.length; i < numChainedTweens; i++) {
  2524. _chainedTweens[i].stop();
  2525. }
  2526. };
  2527. this.delay = function (amount) {
  2528. _delayTime = amount;
  2529. return this;
  2530. };
  2531. this.repeat = function (times) {
  2532. _repeat = times;
  2533. return this;
  2534. };
  2535. this.repeatDelay = function (amount) {
  2536. _repeatDelayTime = amount;
  2537. return this;
  2538. };
  2539. this.yoyo = function (yoyo) {
  2540. _yoyo = yoyo;
  2541. return this;
  2542. };
  2543. this.easing = function (easing) {
  2544. _easingFunction = easing;
  2545. return this;
  2546. };
  2547. this.interpolation = function (interpolation) {
  2548. _interpolationFunction = interpolation;
  2549. return this;
  2550. };
  2551. this.chain = function () {
  2552. _chainedTweens = arguments;
  2553. return this;
  2554. };
  2555. this.onStart = function (callback) {
  2556. _onStartCallback = callback;
  2557. return this;
  2558. };
  2559. this.onUpdate = function (callback) {
  2560. _onUpdateCallback = callback;
  2561. return this;
  2562. };
  2563. this.onComplete = function (callback) {
  2564. _onCompleteCallback = callback;
  2565. return this;
  2566. };
  2567. this.onStop = function (callback) {
  2568. _onStopCallback = callback;
  2569. return this;
  2570. };
  2571. this.update = function (time) {
  2572. var property;
  2573. var elapsed;
  2574. var value;
  2575. if (time < _startTime) {
  2576. return true;
  2577. }
  2578. if (_onStartCallbackFired === false) {
  2579. if (_onStartCallback !== null) {
  2580. _onStartCallback.call(_object, _object);
  2581. }
  2582. _onStartCallbackFired = true;
  2583. }
  2584. elapsed = (time - _startTime) / _duration;
  2585. elapsed = elapsed > 1 ? 1 : elapsed;
  2586. value = _easingFunction(elapsed);
  2587. for (property in _valuesEnd) {
  2588. // Don't update properties that do not exist in the source object
  2589. if (_valuesStart[property] === undefined) {
  2590. continue;
  2591. }
  2592. var start = _valuesStart[property] || 0;
  2593. var end = _valuesEnd[property];
  2594. if (end instanceof Array) {
  2595. _object[property] = _interpolationFunction(end, value);
  2596. } else {
  2597. // Parses relative end values with start as base (e.g.: +10, -3)
  2598. if (typeof end === 'string') {
  2599. if (end.charAt(0) === '+' || end.charAt(0) === '-') {
  2600. end = start + parseFloat(end);
  2601. } else {
  2602. end = parseFloat(end);
  2603. }
  2604. }
  2605. // Protect against non numeric properties.
  2606. if (typeof end === 'number') {
  2607. _object[property] = start + (end - start) * value;
  2608. }
  2609. }
  2610. }
  2611. if (_onUpdateCallback !== null) {
  2612. _onUpdateCallback.call(_object, value);
  2613. }
  2614. if (elapsed === 1) {
  2615. if (_repeat > 0) {
  2616. if (isFinite(_repeat)) {
  2617. _repeat--;
  2618. }
  2619. // Reassign starting values, restart by making startTime = now
  2620. for (property in _valuesStartRepeat) {
  2621. if (typeof _valuesEnd[property] === 'string') {
  2622. _valuesStartRepeat[property] = _valuesStartRepeat[property] + parseFloat(_valuesEnd[property]);
  2623. }
  2624. if (_yoyo) {
  2625. var tmp = _valuesStartRepeat[property];
  2626. _valuesStartRepeat[property] = _valuesEnd[property];
  2627. _valuesEnd[property] = tmp;
  2628. }
  2629. _valuesStart[property] = _valuesStartRepeat[property];
  2630. }
  2631. if (_yoyo) {
  2632. _reversed = !_reversed;
  2633. }
  2634. if (_repeatDelayTime !== undefined) {
  2635. _startTime = time + _repeatDelayTime;
  2636. } else {
  2637. _startTime = time + _delayTime;
  2638. }
  2639. return true;
  2640. } else {
  2641. if (_onCompleteCallback !== null) {
  2642. _onCompleteCallback.call(_object, _object);
  2643. }
  2644. for (var i = 0, numChainedTweens = _chainedTweens.length; i < numChainedTweens; i++) {
  2645. // Make the chained tweens start exactly at the time they should,
  2646. // even if the `update()` method was called way past the duration of the tween
  2647. _chainedTweens[i].start(_startTime + _duration);
  2648. }
  2649. return false;
  2650. }
  2651. }
  2652. return true;
  2653. };
  2654. };
  2655. TWEEN.Easing = {
  2656. Linear: {
  2657. None: function None(k) {
  2658. return k;
  2659. }
  2660. },
  2661. Quadratic: {
  2662. In: function In(k) {
  2663. return k * k;
  2664. },
  2665. Out: function Out(k) {
  2666. return k * (2 - k);
  2667. },
  2668. InOut: function InOut(k) {
  2669. if ((k *= 2) < 1) {
  2670. return 0.5 * k * k;
  2671. }
  2672. return -0.5 * (--k * (k - 2) - 1);
  2673. }
  2674. },
  2675. Cubic: {
  2676. In: function In(k) {
  2677. return k * k * k;
  2678. },
  2679. Out: function Out(k) {
  2680. return --k * k * k + 1;
  2681. },
  2682. InOut: function InOut(k) {
  2683. if ((k *= 2) < 1) {
  2684. return 0.5 * k * k * k;
  2685. }
  2686. return 0.5 * ((k -= 2) * k * k + 2);
  2687. }
  2688. },
  2689. Quartic: {
  2690. In: function In(k) {
  2691. return k * k * k * k;
  2692. },
  2693. Out: function Out(k) {
  2694. return 1 - --k * k * k * k;
  2695. },
  2696. InOut: function InOut(k) {
  2697. if ((k *= 2) < 1) {
  2698. return 0.5 * k * k * k * k;
  2699. }
  2700. return -0.5 * ((k -= 2) * k * k * k - 2);
  2701. }
  2702. },
  2703. Quintic: {
  2704. In: function In(k) {
  2705. return k * k * k * k * k;
  2706. },
  2707. Out: function Out(k) {
  2708. return --k * k * k * k * k + 1;
  2709. },
  2710. InOut: function InOut(k) {
  2711. if ((k *= 2) < 1) {
  2712. return 0.5 * k * k * k * k * k;
  2713. }
  2714. return 0.5 * ((k -= 2) * k * k * k * k + 2);
  2715. }
  2716. },
  2717. Sinusoidal: {
  2718. In: function In(k) {
  2719. return 1 - Math.cos(k * Math.PI / 2);
  2720. },
  2721. Out: function Out(k) {
  2722. return Math.sin(k * Math.PI / 2);
  2723. },
  2724. InOut: function InOut(k) {
  2725. return 0.5 * (1 - Math.cos(Math.PI * k));
  2726. }
  2727. },
  2728. Exponential: {
  2729. In: function In(k) {
  2730. return k === 0 ? 0 : Math.pow(1024, k - 1);
  2731. },
  2732. Out: function Out(k) {
  2733. return k === 1 ? 1 : 1 - Math.pow(2, -10 * k);
  2734. },
  2735. InOut: function InOut(k) {
  2736. if (k === 0) {
  2737. return 0;
  2738. }
  2739. if (k === 1) {
  2740. return 1;
  2741. }
  2742. if ((k *= 2) < 1) {
  2743. return 0.5 * Math.pow(1024, k - 1);
  2744. }
  2745. return 0.5 * (-Math.pow(2, -10 * (k - 1)) + 2);
  2746. }
  2747. },
  2748. Circular: {
  2749. In: function In(k) {
  2750. return 1 - Math.sqrt(1 - k * k);
  2751. },
  2752. Out: function Out(k) {
  2753. return Math.sqrt(1 - --k * k);
  2754. },
  2755. InOut: function InOut(k) {
  2756. if ((k *= 2) < 1) {
  2757. return -0.5 * (Math.sqrt(1 - k * k) - 1);
  2758. }
  2759. return 0.5 * (Math.sqrt(1 - (k -= 2) * k) + 1);
  2760. }
  2761. },
  2762. Elastic: {
  2763. In: function In(k) {
  2764. if (k === 0) {
  2765. return 0;
  2766. }
  2767. if (k === 1) {
  2768. return 1;
  2769. }
  2770. return -Math.pow(2, 10 * (k - 1)) * Math.sin((k - 1.1) * 5 * Math.PI);
  2771. },
  2772. Out: function Out(k) {
  2773. if (k === 0) {
  2774. return 0;
  2775. }
  2776. if (k === 1) {
  2777. return 1;
  2778. }
  2779. return Math.pow(2, -10 * k) * Math.sin((k - 0.1) * 5 * Math.PI) + 1;
  2780. },
  2781. InOut: function InOut(k) {
  2782. if (k === 0) {
  2783. return 0;
  2784. }
  2785. if (k === 1) {
  2786. return 1;
  2787. }
  2788. k *= 2;
  2789. if (k < 1) {
  2790. return -0.5 * Math.pow(2, 10 * (k - 1)) * Math.sin((k - 1.1) * 5 * Math.PI);
  2791. }
  2792. return 0.5 * Math.pow(2, -10 * (k - 1)) * Math.sin((k - 1.1) * 5 * Math.PI) + 1;
  2793. }
  2794. },
  2795. Back: {
  2796. In: function In(k) {
  2797. var s = 1.70158;
  2798. return k * k * ((s + 1) * k - s);
  2799. },
  2800. Out: function Out(k) {
  2801. var s = 1.70158;
  2802. return --k * k * ((s + 1) * k + s) + 1;
  2803. },
  2804. InOut: function InOut(k) {
  2805. var s = 1.70158 * 1.525;
  2806. if ((k *= 2) < 1) {
  2807. return 0.5 * (k * k * ((s + 1) * k - s));
  2808. }
  2809. return 0.5 * ((k -= 2) * k * ((s + 1) * k + s) + 2);
  2810. }
  2811. },
  2812. Bounce: {
  2813. In: function In(k) {
  2814. return 1 - TWEEN.Easing.Bounce.Out(1 - k);
  2815. },
  2816. Out: function Out(k) {
  2817. if (k < 1 / 2.75) {
  2818. return 7.5625 * k * k;
  2819. } else if (k < 2 / 2.75) {
  2820. return 7.5625 * (k -= 1.5 / 2.75) * k + 0.75;
  2821. } else if (k < 2.5 / 2.75) {
  2822. return 7.5625 * (k -= 2.25 / 2.75) * k + 0.9375;
  2823. } else {
  2824. return 7.5625 * (k -= 2.625 / 2.75) * k + 0.984375;
  2825. }
  2826. },
  2827. InOut: function InOut(k) {
  2828. if (k < 0.5) {
  2829. return TWEEN.Easing.Bounce.In(k * 2) * 0.5;
  2830. }
  2831. return TWEEN.Easing.Bounce.Out(k * 2 - 1) * 0.5 + 0.5;
  2832. }
  2833. }
  2834. };
  2835. TWEEN.Interpolation = {
  2836. Linear: function Linear(v, k) {
  2837. var m = v.length - 1;
  2838. var f = m * k;
  2839. var i = Math.floor(f);
  2840. var fn = TWEEN.Interpolation.Utils.Linear;
  2841. if (k < 0) {
  2842. return fn(v[0], v[1], f);
  2843. }
  2844. if (k > 1) {
  2845. return fn(v[m], v[m - 1], m - f);
  2846. }
  2847. return fn(v[i], v[i + 1 > m ? m : i + 1], f - i);
  2848. },
  2849. Bezier: function Bezier(v, k) {
  2850. var b = 0;
  2851. var n = v.length - 1;
  2852. var pw = Math.pow;
  2853. var bn = TWEEN.Interpolation.Utils.Bernstein;
  2854. for (var i = 0; i <= n; i++) {
  2855. b += pw(1 - k, n - i) * pw(k, i) * v[i] * bn(n, i);
  2856. }
  2857. return b;
  2858. },
  2859. CatmullRom: function CatmullRom(v, k) {
  2860. var m = v.length - 1;
  2861. var f = m * k;
  2862. var i = Math.floor(f);
  2863. var fn = TWEEN.Interpolation.Utils.CatmullRom;
  2864. if (v[0] === v[m]) {
  2865. if (k < 0) {
  2866. i = Math.floor(f = m * (1 + k));
  2867. }
  2868. return fn(v[(i - 1 + m) % m], v[i], v[(i + 1) % m], v[(i + 2) % m], f - i);
  2869. } else {
  2870. if (k < 0) {
  2871. return v[0] - (fn(v[0], v[0], v[1], v[1], -f) - v[0]);
  2872. }
  2873. if (k > 1) {
  2874. return v[m] - (fn(v[m], v[m], v[m - 1], v[m - 1], f - m) - v[m]);
  2875. }
  2876. return fn(v[i ? i - 1 : 0], v[i], v[m < i + 1 ? m : i + 1], v[m < i + 2 ? m : i + 2], f - i);
  2877. }
  2878. },
  2879. Utils: {
  2880. Linear: function Linear(p0, p1, t) {
  2881. return (p1 - p0) * t + p0;
  2882. },
  2883. Bernstein: function Bernstein(n, i) {
  2884. var fc = TWEEN.Interpolation.Utils.Factorial;
  2885. return fc(n) / fc(i) / fc(n - i);
  2886. },
  2887. Factorial: function () {
  2888. var a = [1];
  2889. return function (n) {
  2890. var s = 1;
  2891. if (a[n]) {
  2892. return a[n];
  2893. }
  2894. for (var i = n; i > 1; i--) {
  2895. s *= i;
  2896. }
  2897. a[n] = s;
  2898. return s;
  2899. };
  2900. }(),
  2901. CatmullRom: function CatmullRom(p0, p1, p2, p3, t) {
  2902. var v0 = (p2 - p0) * 0.5;
  2903. var v1 = (p3 - p1) * 0.5;
  2904. var t2 = t * t;
  2905. var t3 = t * t2;
  2906. return (2 * p1 - 2 * p2 + v0 + v1) * t3 + (-3 * p1 + 3 * p2 - 2 * v0 - v1) * t2 + v0 * t + p1;
  2907. }
  2908. }
  2909. };
  2910. /**
  2911. * @author Mofei Zhu<mapv@zhuwenlong.com>
  2912. * This file is to draw text
  2913. */
  2914. var drawText = {
  2915. draw: function draw(context, dataSet, options) {
  2916. var data = dataSet instanceof DataSet ? dataSet.get() : dataSet;
  2917. context.save();
  2918. // set from options
  2919. for (var key in options) {
  2920. context[key] = options[key];
  2921. }
  2922. var offset = options.offset || {
  2923. x: 0,
  2924. y: 0
  2925. };
  2926. var rects = [];
  2927. var size = options._size || options.size;
  2928. if (size) {
  2929. context.font = "bold " + size + "px Arial";
  2930. } else {
  2931. size = 12;
  2932. }
  2933. var textKey = options.textKey || 'text';
  2934. if (!options.textAlign) {
  2935. context.textAlign = 'center';
  2936. }
  2937. if (!options.textBaseline) {
  2938. context.textBaseline = 'middle';
  2939. }
  2940. if (options.avoid) {
  2941. // 标注避让
  2942. for (var i = 0, len = data.length; i < len; i++) {
  2943. var coordinates = data[i].geometry._coordinates || data[i].geometry.coordinates;
  2944. var x = coordinates[0] + offset.x;
  2945. var y = coordinates[1] + offset.y;
  2946. var text = data[i][textKey];
  2947. var textWidth = context.measureText(text).width;
  2948. // 根据文本宽度和高度调整x,y位置,使得绘制文本时候坐标点在文本中心点,这个计算出的是左上角坐标
  2949. var px = x - textWidth / 2;
  2950. var py = y - size / 2;
  2951. var rect = {
  2952. sw: {
  2953. x: px,
  2954. y: py + size
  2955. },
  2956. ne: {
  2957. x: px + textWidth,
  2958. y: py
  2959. }
  2960. };
  2961. if (!hasOverlay(rects, rect)) {
  2962. rects.push(rect);
  2963. px = px + textWidth / 2;
  2964. py = py + size / 2;
  2965. context.fillText(text, px, py);
  2966. }
  2967. }
  2968. } else {
  2969. for (var i = 0, len = data.length; i < len; i++) {
  2970. var coordinates = data[i].geometry._coordinates || data[i].geometry.coordinates;
  2971. var x = coordinates[0] + offset.x;
  2972. var y = coordinates[1] + offset.y;
  2973. var text = data[i][textKey];
  2974. context.fillText(text, x, y);
  2975. }
  2976. }
  2977. context.restore();
  2978. }
  2979. };
  2980. /*
  2981. * 当前文字区域和已有的文字区域是否有重叠部分
  2982. */
  2983. function hasOverlay(rects, overlay) {
  2984. for (var i = 0; i < rects.length; i++) {
  2985. if (isRectOverlay(rects[i], overlay)) {
  2986. return true;
  2987. }
  2988. }
  2989. return false;
  2990. }
  2991. //判断2个矩形是否有重叠部分
  2992. function isRectOverlay(rect1, rect2) {
  2993. //minx、miny 2个矩形右下角最小的x和y
  2994. //maxx、maxy 2个矩形左上角最大的x和y
  2995. var minx = Math.min(rect1.ne.x, rect2.ne.x);
  2996. var miny = Math.min(rect1.sw.y, rect2.sw.y);
  2997. var maxx = Math.max(rect1.sw.x, rect2.sw.x);
  2998. var maxy = Math.max(rect1.ne.y, rect2.ne.y);
  2999. if (minx > maxx && miny > maxy) {
  3000. return true;
  3001. }
  3002. return false;
  3003. }
  3004. /**
  3005. * @author Mofei Zhu<mapv@zhuwenlong.com>
  3006. * This file is to draw text
  3007. */
  3008. var drawIcon = {
  3009. draw: function draw(context, dataSet, options) {
  3010. var data = dataSet instanceof DataSet ? dataSet.get() : dataSet;
  3011. context.fillStyle = 'white';
  3012. context.textAlign = 'center';
  3013. context.textBaseline = 'middle';
  3014. var offset = options.offset || {
  3015. x: 0,
  3016. y: 0
  3017. };
  3018. // set from options
  3019. // for (var key in options) {
  3020. // context[key] = options[key];
  3021. // }
  3022. // console.log(data)
  3023. for (var i = 0, len = data.length; i < len; i++) {
  3024. if (data[i].geometry) {
  3025. var deg = data[i].deg || options.deg;
  3026. var icon = data[i].icon || options.icon;
  3027. var coordinates = data[i].geometry._coordinates || data[i].geometry.coordinates;
  3028. var x = coordinates[0];
  3029. var y = coordinates[1];
  3030. if (deg) {
  3031. context.save();
  3032. context.translate(x, y);
  3033. context.rotate(deg * Math.PI / 180);
  3034. context.translate(-x, -y);
  3035. }
  3036. var width = options._width || options.width || icon.width;
  3037. var height = options._height || options.height || icon.height;
  3038. x = x - width / 2 + offset.x;
  3039. y = y - height / 2 + offset.y;
  3040. if (options.sx && options.sy && options.swidth && options.sheight && options.width && options.height) {
  3041. context.drawImage(icon, options.sx, options.sy, options.swidth, options.sheight, x, y, width, height);
  3042. } else if (options.width && options.height) {
  3043. context.drawImage(icon, x, y, width, height);
  3044. } else {
  3045. context.drawImage(icon, x, y);
  3046. }
  3047. if (deg) {
  3048. context.restore();
  3049. }
  3050. }
  3051. }
  3052. }
  3053. };
  3054. /**
  3055. * @author kyle / http://nikai.us/
  3056. */
  3057. if (typeof window !== 'undefined') {
  3058. requestAnimationFrame(animate);
  3059. }
  3060. function animate(time) {
  3061. requestAnimationFrame(animate);
  3062. TWEEN.update(time);
  3063. }
  3064. var BaseLayer = function () {
  3065. function BaseLayer(map, dataSet, options) {
  3066. classCallCheck(this, BaseLayer);
  3067. if (!(dataSet instanceof DataSet)) {
  3068. dataSet = new DataSet(dataSet);
  3069. }
  3070. this.dataSet = dataSet;
  3071. this.map = map;
  3072. }
  3073. createClass(BaseLayer, [{
  3074. key: "getDefaultContextConfig",
  3075. value: function getDefaultContextConfig() {
  3076. return {
  3077. globalAlpha: 1,
  3078. globalCompositeOperation: 'source-over',
  3079. imageSmoothingEnabled: true,
  3080. strokeStyle: '#000000',
  3081. fillStyle: '#000000',
  3082. shadowOffsetX: 0,
  3083. shadowOffsetY: 0,
  3084. shadowBlur: 0,
  3085. shadowColor: 'rgba(0, 0, 0, 0)',
  3086. lineWidth: 1,
  3087. lineCap: 'butt',
  3088. lineJoin: 'miter',
  3089. miterLimit: 10,
  3090. lineDashOffset: 0,
  3091. font: '10px sans-serif',
  3092. textAlign: 'start',
  3093. textBaseline: 'alphabetic'
  3094. };
  3095. }
  3096. }, {
  3097. key: "initDataRange",
  3098. value: function initDataRange(options) {
  3099. var self = this;
  3100. self.intensity = new Intensity({
  3101. maxSize: self.options.maxSize,
  3102. minSize: self.options.minSize,
  3103. gradient: self.options.gradient,
  3104. max: self.options.max || this.dataSet.getMax('count')
  3105. });
  3106. self.category = new Category(self.options.splitList);
  3107. self.choropleth = new Choropleth(self.options.splitList);
  3108. if (self.options.splitList === undefined) {
  3109. self.category.generateByDataSet(this.dataSet);
  3110. }
  3111. if (self.options.splitList === undefined) {
  3112. var min = self.options.min || this.dataSet.getMin('count');
  3113. var max = self.options.max || this.dataSet.getMax('count');
  3114. self.choropleth.generateByMinMax(min, max);
  3115. }
  3116. }
  3117. }, {
  3118. key: "getLegend",
  3119. value: function getLegend(options) {
  3120. var draw = this.options.draw;
  3121. var legend = null;
  3122. var self = this;
  3123. if (self.options.draw == 'intensity' || self.options.draw == 'heatmap') {
  3124. return this.intensity.getLegend(options);
  3125. } else if (self.options.draw == 'category') {
  3126. return this.category.getLegend(options);
  3127. }
  3128. }
  3129. }, {
  3130. key: "processData",
  3131. value: function processData(data) {
  3132. var self = this;
  3133. var draw = self.options.draw;
  3134. if (draw == 'bubble' || draw == 'intensity' || draw == 'category' || draw == 'choropleth' || draw == 'simple') {
  3135. for (var i = 0; i < data.length; i++) {
  3136. var item = data[i];
  3137. if (self.options.draw == 'bubble') {
  3138. data[i]._size = self.intensity.getSize(item.count);
  3139. } else {
  3140. data[i]._size = undefined;
  3141. }
  3142. var styleType = '_fillStyle';
  3143. if (data[i].geometry.type === 'LineString' || self.options.styleType === 'stroke') {
  3144. styleType = '_strokeStyle';
  3145. }
  3146. if (self.options.draw == 'intensity') {
  3147. data[i][styleType] = self.intensity.getColor(item.count);
  3148. } else if (self.options.draw == 'category') {
  3149. data[i][styleType] = self.category.get(item.count);
  3150. } else if (self.options.draw == 'choropleth') {
  3151. data[i][styleType] = self.choropleth.get(item.count);
  3152. }
  3153. }
  3154. }
  3155. }
  3156. }, {
  3157. key: "isEnabledTime",
  3158. value: function isEnabledTime() {
  3159. var animationOptions = this.options.animation;
  3160. var flag = animationOptions && !(animationOptions.enabled === false);
  3161. return flag;
  3162. }
  3163. }, {
  3164. key: "argCheck",
  3165. value: function argCheck(options) {
  3166. if (options.draw == 'heatmap') {
  3167. if (options.strokeStyle) {
  3168. console.warn('[heatmap] options.strokeStyle is discard, pleause use options.strength [eg: options.strength = 0.1]');
  3169. }
  3170. }
  3171. }
  3172. }, {
  3173. key: "drawContext",
  3174. value: function drawContext(context, dataSet, options, nwPixel) {
  3175. var self = this;
  3176. switch (self.options.draw) {
  3177. case 'heatmap':
  3178. drawHeatmap.draw(context, dataSet, self.options);
  3179. break;
  3180. case 'grid':
  3181. case 'honeycomb':
  3182. self.options.offset = {
  3183. x: nwPixel.x,
  3184. y: nwPixel.y
  3185. };
  3186. if (self.options.draw == 'grid') {
  3187. drawGrid.draw(context, dataSet, self.options);
  3188. } else {
  3189. drawHoneycomb.draw(context, dataSet, self.options);
  3190. }
  3191. break;
  3192. case 'text':
  3193. drawText.draw(context, dataSet, self.options);
  3194. break;
  3195. case 'icon':
  3196. drawIcon.draw(context, dataSet, self.options);
  3197. break;
  3198. case 'clip':
  3199. context.save();
  3200. context.fillStyle = self.options.fillStyle || 'rgba(0, 0, 0, 0.5)';
  3201. context.fillRect(0, 0, context.canvas.width, context.canvas.height);
  3202. drawSimple.draw(context, dataSet, self.options);
  3203. context.beginPath();
  3204. pathSimple.drawDataSet(context, dataSet, self.options);
  3205. context.clip();
  3206. clear(context);
  3207. context.restore();
  3208. break;
  3209. default:
  3210. if (self.options.context == "webgl") {
  3211. webglDrawSimple.draw(self.canvasLayer.canvas.getContext('webgl'), dataSet, self.options);
  3212. } else {
  3213. drawSimple.draw(context, dataSet, self.options);
  3214. }
  3215. }
  3216. }
  3217. }, {
  3218. key: "isPointInPath",
  3219. value: function isPointInPath(context, pixel) {
  3220. var context = this.canvasLayer.canvas.getContext(this.context);
  3221. var data = this.dataSet.get();
  3222. for (var i = 0; i < data.length; i++) {
  3223. context.beginPath();
  3224. pathSimple.draw(context, data[i], this.options);
  3225. var x = pixel.x * this.canvasLayer.devicePixelRatio;
  3226. var y = pixel.y * this.canvasLayer.devicePixelRatio;
  3227. if (context.isPointInPath(x, y) || context.isPointInStroke(x, y)) {
  3228. return data[i];
  3229. }
  3230. }
  3231. }
  3232. }, {
  3233. key: "clickEvent",
  3234. value: function clickEvent(pixel, e) {
  3235. var dataItem = this.isPointInPath(this.getContext(), pixel);
  3236. if (dataItem) {
  3237. this.options.methods.click(dataItem, e);
  3238. } else {
  3239. this.options.methods.click(null, e);
  3240. }
  3241. }
  3242. }, {
  3243. key: "mousemoveEvent",
  3244. value: function mousemoveEvent(pixel, e) {
  3245. var dataItem = this.isPointInPath(this.getContext(), pixel);
  3246. if (dataItem) {
  3247. this.options.methods.mousemove(dataItem, e);
  3248. } else {
  3249. this.options.methods.mousemove(null, e);
  3250. }
  3251. }
  3252. /**
  3253. * obj.options
  3254. */
  3255. }, {
  3256. key: "update",
  3257. value: function update(obj, isDraw) {
  3258. var self = this;
  3259. var _options = obj.options;
  3260. var options = self.options;
  3261. for (var i in _options) {
  3262. options[i] = _options[i];
  3263. }
  3264. self.init(options);
  3265. if (isDraw !== false) {
  3266. self.draw();
  3267. }
  3268. }
  3269. }, {
  3270. key: "setOptions",
  3271. value: function setOptions(options) {
  3272. var self = this;
  3273. self.init(options);
  3274. self.draw();
  3275. }
  3276. }, {
  3277. key: "set",
  3278. value: function set$$1(obj) {
  3279. var self = this;
  3280. var ctx = this.getContext();
  3281. var conf = this.getDefaultContextConfig();
  3282. for (var i in conf) {
  3283. ctx[i] = conf[i];
  3284. }
  3285. self.init(obj.options);
  3286. self.draw();
  3287. }
  3288. }, {
  3289. key: "destroy",
  3290. value: function destroy() {
  3291. this.unbindEvent();
  3292. this.hide();
  3293. }
  3294. }, {
  3295. key: "initAnimator",
  3296. value: function initAnimator() {
  3297. var self = this;
  3298. var animationOptions = self.options.animation;
  3299. if (self.options.draw == 'time' || self.isEnabledTime()) {
  3300. if (!animationOptions.stepsRange) {
  3301. animationOptions.stepsRange = {
  3302. start: this.dataSet.getMin('time') || 0,
  3303. end: this.dataSet.getMax('time') || 0
  3304. };
  3305. }
  3306. this.steps = { step: animationOptions.stepsRange.start };
  3307. self.animator = new TWEEN.Tween(this.steps).onUpdate(function () {
  3308. self._canvasUpdate(this.step);
  3309. }).repeat(Infinity);
  3310. this.addAnimatorEvent();
  3311. var duration = animationOptions.duration * 1000 || 5000;
  3312. self.animator.to({ step: animationOptions.stepsRange.end }, duration);
  3313. self.animator.start();
  3314. } else {
  3315. self.animator && self.animator.stop();
  3316. }
  3317. }
  3318. }, {
  3319. key: "addAnimatorEvent",
  3320. value: function addAnimatorEvent() {}
  3321. }, {
  3322. key: "animatorMovestartEvent",
  3323. value: function animatorMovestartEvent() {
  3324. var animationOptions = this.options.animation;
  3325. if (this.isEnabledTime() && this.animator) {
  3326. this.steps.step = animationOptions.stepsRange.start;
  3327. this.animator.stop();
  3328. }
  3329. }
  3330. }, {
  3331. key: "animatorMoveendEvent",
  3332. value: function animatorMoveendEvent() {
  3333. if (this.isEnabledTime() && this.animator) {
  3334. this.animator.start();
  3335. }
  3336. }
  3337. }]);
  3338. return BaseLayer;
  3339. }();
  3340. var AnimationLayer = function (_BaseLayer) {
  3341. inherits(AnimationLayer, _BaseLayer);
  3342. function AnimationLayer(map, dataSet, options) {
  3343. classCallCheck(this, AnimationLayer);
  3344. var _this = possibleConstructorReturn(this, (AnimationLayer.__proto__ || Object.getPrototypeOf(AnimationLayer)).call(this, map, dataSet, options));
  3345. _this.map = map;
  3346. _this.options = options || {};
  3347. _this.dataSet = dataSet;
  3348. _this.init(options);
  3349. var canvasLayer = new CanvasLayer({
  3350. map: map,
  3351. update: _this._canvasUpdate.bind(_this)
  3352. });
  3353. _this.canvasLayer = canvasLayer;
  3354. _this.transferToMercator();
  3355. var self = _this;
  3356. dataSet.on('change', function () {
  3357. self.transferToMercator();
  3358. canvasLayer.draw();
  3359. });
  3360. _this.ctx = canvasLayer.canvas.getContext('2d');
  3361. _this.start();
  3362. return _this;
  3363. }
  3364. createClass(AnimationLayer, [{
  3365. key: "init",
  3366. value: function init(options) {
  3367. var self = this;
  3368. self.options = options;
  3369. this.initDataRange(options);
  3370. this.context = self.options.context || '2d';
  3371. if (self.options.zIndex) {
  3372. this.canvasLayer && this.canvasLayer.setZIndex(self.options.zIndex);
  3373. }
  3374. if (self.options.max) {
  3375. this.intensity.setMax(self.options.max);
  3376. }
  3377. if (self.options.min) {
  3378. this.intensity.setMin(self.options.min);
  3379. }
  3380. this.initAnimator();
  3381. }
  3382. // 经纬度左边转换为墨卡托坐标
  3383. }, {
  3384. key: "transferToMercator",
  3385. value: function transferToMercator() {
  3386. var projection = this.map.getMapType().getProjection();
  3387. if (this.options.coordType !== 'bd09mc') {
  3388. var data = this.dataSet.get();
  3389. data = this.dataSet.transferCoordinate(data, function (coordinates) {
  3390. var pixel = projection.lngLatToPoint({
  3391. lng: coordinates[0],
  3392. lat: coordinates[1]
  3393. });
  3394. return [pixel.x, pixel.y];
  3395. }, 'coordinates', 'coordinates_mercator');
  3396. this.dataSet._set(data);
  3397. }
  3398. }
  3399. }, {
  3400. key: "_canvasUpdate",
  3401. value: function _canvasUpdate() {
  3402. var ctx = this.ctx;
  3403. if (!ctx) {
  3404. return;
  3405. }
  3406. //clear(ctx);
  3407. var map = this.map;
  3408. var zoomUnit = Math.pow(2, 18 - map.getZoom());
  3409. var projection = map.getMapType().getProjection();
  3410. var mcCenter = projection.lngLatToPoint(map.getCenter());
  3411. var nwMc = new BMap.Pixel(mcCenter.x - map.getSize().width / 2 * zoomUnit, mcCenter.y + map.getSize().height / 2 * zoomUnit); //左上角墨卡托坐标
  3412. clear(ctx);
  3413. var dataGetOptions = {
  3414. fromColumn: this.options.coordType == 'bd09mc' ? 'coordinates' : 'coordinates_mercator',
  3415. transferCoordinate: function transferCoordinate(coordinate) {
  3416. if (!coordinate) {
  3417. return;
  3418. }
  3419. var x = (coordinate[0] - nwMc.x) / zoomUnit;
  3420. var y = (nwMc.y - coordinate[1]) / zoomUnit;
  3421. return [x, y];
  3422. }
  3423. };
  3424. this.data = this.dataSet.get(dataGetOptions);
  3425. this.processData(this.data);
  3426. this.drawAnimation();
  3427. }
  3428. }, {
  3429. key: "drawAnimation",
  3430. value: function drawAnimation() {
  3431. var ctx = this.ctx;
  3432. var data = this.data;
  3433. if (!data) {
  3434. return;
  3435. }
  3436. ctx.save();
  3437. ctx.globalCompositeOperation = 'destination-out';
  3438. ctx.fillStyle = 'rgba(0, 0, 0, .1)';
  3439. ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height);
  3440. ctx.restore();
  3441. ctx.save();
  3442. if (this.options.shadowColor) {
  3443. ctx.shadowColor = this.options.shadowColor;
  3444. }
  3445. if (this.options.shadowBlur) {
  3446. ctx.shadowBlur = this.options.shadowBlur;
  3447. }
  3448. if (this.options.globalAlpha) {
  3449. ctx.globalAlpha = this.options.globalAlpha;
  3450. }
  3451. if (this.options.globalCompositeOperation) {
  3452. ctx.globalCompositeOperation = this.options.globalCompositeOperation;
  3453. }
  3454. var options = this.options;
  3455. for (var i = 0; i < data.length; i++) {
  3456. if (data[i].geometry.type === 'Point') {
  3457. ctx.beginPath();
  3458. var maxSize = data[i].size || this.options.size;
  3459. var minSize = data[i].minSize || this.options.minSize || 0;
  3460. if (data[i]._size === undefined) {
  3461. data[i]._size = minSize;
  3462. }
  3463. ctx.arc(data[i].geometry._coordinates[0], data[i].geometry._coordinates[1], data[i]._size, 0, Math.PI * 2, true);
  3464. ctx.closePath();
  3465. data[i]._size++;
  3466. if (data[i]._size > maxSize) {
  3467. data[i]._size = minSize;
  3468. }
  3469. ctx.lineWidth = 1;
  3470. ctx.strokeStyle = data[i].strokeStyle || data[i]._strokeStyle || options.strokeStyle || 'yellow';
  3471. ctx.stroke();
  3472. var fillStyle = data[i].fillStyle || data[i]._fillStyle || options.fillStyle;
  3473. if (fillStyle) {
  3474. ctx.fillStyle = fillStyle;
  3475. ctx.fill();
  3476. }
  3477. } else if (data[i].geometry.type === 'LineString') {
  3478. ctx.beginPath();
  3479. var size = data[i].size || this.options.size || 5;
  3480. var minSize = data[i].minSize || this.options.minSize || 0;
  3481. if (data[i]._index === undefined) {
  3482. data[i]._index = 0;
  3483. }
  3484. var index = data[i]._index;
  3485. ctx.arc(data[i].geometry._coordinates[index][0], data[i].geometry._coordinates[index][1], size, 0, Math.PI * 2, true);
  3486. ctx.closePath();
  3487. data[i]._index++;
  3488. if (data[i]._index >= data[i].geometry._coordinates.length) {
  3489. data[i]._index = 0;
  3490. }
  3491. ctx.lineWidth = options.lineWidth || 1;
  3492. var strokeStyle = data[i].strokeStyle || options.strokeStyle;
  3493. var fillStyle = data[i].fillStyle || options.fillStyle || 'yellow';
  3494. ctx.fillStyle = fillStyle;
  3495. ctx.fill();
  3496. if (strokeStyle) {
  3497. ctx.strokeStyle = strokeStyle;
  3498. ctx.stroke();
  3499. }
  3500. }
  3501. }
  3502. ctx.restore();
  3503. }
  3504. }, {
  3505. key: "animate",
  3506. value: function animate() {
  3507. this.drawAnimation();
  3508. var animateTime = this.options.animateTime || 100;
  3509. this.timeout = setTimeout(this.animate.bind(this), animateTime);
  3510. }
  3511. }, {
  3512. key: "start",
  3513. value: function start() {
  3514. this.stop();
  3515. this.animate();
  3516. }
  3517. }, {
  3518. key: "stop",
  3519. value: function stop() {
  3520. clearTimeout(this.timeout);
  3521. }
  3522. }, {
  3523. key: "unbindEvent",
  3524. value: function unbindEvent() {}
  3525. }, {
  3526. key: "hide",
  3527. value: function hide() {
  3528. this.canvasLayer.hide();
  3529. this.stop();
  3530. }
  3531. }, {
  3532. key: "show",
  3533. value: function show() {
  3534. this.start();
  3535. }
  3536. }]);
  3537. return AnimationLayer;
  3538. }(BaseLayer);
  3539. /**
  3540. * @author kyle / http://nikai.us/
  3541. */
  3542. var Layer = function (_BaseLayer) {
  3543. inherits(Layer, _BaseLayer);
  3544. function Layer(map, dataSet, options) {
  3545. classCallCheck(this, Layer);
  3546. var _this = possibleConstructorReturn(this, (Layer.__proto__ || Object.getPrototypeOf(Layer)).call(this, map, dataSet, options));
  3547. var self = _this;
  3548. var data = null;
  3549. options = options || {};
  3550. self.init(options);
  3551. self.argCheck(options);
  3552. self.transferToMercator();
  3553. var canvasLayer = _this.canvasLayer = new CanvasLayer({
  3554. map: map,
  3555. context: _this.context,
  3556. paneName: options.paneName,
  3557. mixBlendMode: options.mixBlendMode,
  3558. enableMassClear: options.enableMassClear,
  3559. zIndex: options.zIndex,
  3560. update: function update() {
  3561. self._canvasUpdate();
  3562. }
  3563. });
  3564. dataSet.on('change', function () {
  3565. self.transferToMercator();
  3566. canvasLayer.draw();
  3567. });
  3568. _this.clickEvent = _this.clickEvent.bind(_this);
  3569. _this.mousemoveEvent = _this.mousemoveEvent.bind(_this);
  3570. _this.bindEvent();
  3571. return _this;
  3572. }
  3573. createClass(Layer, [{
  3574. key: "clickEvent",
  3575. value: function clickEvent(e) {
  3576. var pixel = e.pixel;
  3577. get(Layer.prototype.__proto__ || Object.getPrototypeOf(Layer.prototype), "clickEvent", this).call(this, pixel, e);
  3578. }
  3579. }, {
  3580. key: "mousemoveEvent",
  3581. value: function mousemoveEvent(e) {
  3582. var pixel = e.pixel;
  3583. get(Layer.prototype.__proto__ || Object.getPrototypeOf(Layer.prototype), "mousemoveEvent", this).call(this, pixel, e);
  3584. }
  3585. }, {
  3586. key: "bindEvent",
  3587. value: function bindEvent(e) {
  3588. var map = this.map;
  3589. if (this.options.methods) {
  3590. if (this.options.methods.click) {
  3591. map.setDefaultCursor("default");
  3592. map.addEventListener('click', this.clickEvent);
  3593. }
  3594. if (this.options.methods.mousemove) {
  3595. map.addEventListener('mousemove', this.mousemoveEvent);
  3596. }
  3597. }
  3598. }
  3599. }, {
  3600. key: "unbindEvent",
  3601. value: function unbindEvent(e) {
  3602. var map = this.map;
  3603. if (this.options.methods) {
  3604. if (this.options.methods.click) {
  3605. map.removeEventListener('click', this.clickEvent);
  3606. }
  3607. if (this.options.methods.mousemove) {
  3608. map.removeEventListener('mousemove', this.mousemoveEvent);
  3609. }
  3610. }
  3611. }
  3612. // 经纬度左边转换为墨卡托坐标
  3613. }, {
  3614. key: "transferToMercator",
  3615. value: function transferToMercator() {
  3616. var projection = this.map.getMapType().getProjection();
  3617. if (this.options.coordType !== 'bd09mc') {
  3618. var data = this.dataSet.get();
  3619. data = this.dataSet.transferCoordinate(data, function (coordinates) {
  3620. var pixel = projection.lngLatToPoint({
  3621. lng: coordinates[0],
  3622. lat: coordinates[1]
  3623. });
  3624. return [pixel.x, pixel.y];
  3625. }, 'coordinates', 'coordinates_mercator');
  3626. this.dataSet._set(data);
  3627. }
  3628. }
  3629. }, {
  3630. key: "getContext",
  3631. value: function getContext() {
  3632. return this.canvasLayer.canvas.getContext(this.context);
  3633. }
  3634. }, {
  3635. key: "_canvasUpdate",
  3636. value: function _canvasUpdate(time) {
  3637. if (!this.canvasLayer) {
  3638. return;
  3639. }
  3640. var self = this;
  3641. var animationOptions = self.options.animation;
  3642. var map = this.canvasLayer._map;
  3643. var zoomUnit = Math.pow(2, 18 - map.getZoom());
  3644. var projection = map.getMapType().getProjection();
  3645. var mcCenter = projection.lngLatToPoint(map.getCenter());
  3646. var nwMc = new BMap.Pixel(mcCenter.x - map.getSize().width / 2 * zoomUnit, mcCenter.y + map.getSize().height / 2 * zoomUnit); //左上角墨卡托坐标
  3647. var context = this.getContext();
  3648. if (self.isEnabledTime()) {
  3649. if (time === undefined) {
  3650. clear(context);
  3651. return;
  3652. }
  3653. if (this.context == '2d') {
  3654. context.save();
  3655. context.globalCompositeOperation = 'destination-out';
  3656. context.fillStyle = 'rgba(0, 0, 0, .1)';
  3657. context.fillRect(0, 0, context.canvas.width, context.canvas.height);
  3658. context.restore();
  3659. }
  3660. } else {
  3661. clear(context);
  3662. }
  3663. if (this.context == '2d') {
  3664. for (var key in self.options) {
  3665. context[key] = self.options[key];
  3666. }
  3667. } else {
  3668. context.clear(context.COLOR_BUFFER_BIT);
  3669. }
  3670. if (self.options.minZoom && map.getZoom() < self.options.minZoom || self.options.maxZoom && map.getZoom() > self.options.maxZoom) {
  3671. return;
  3672. }
  3673. var scale = 1;
  3674. if (this.context != '2d') {
  3675. scale = this.canvasLayer.devicePixelRatio;
  3676. }
  3677. var dataGetOptions = {
  3678. fromColumn: self.options.coordType == 'bd09mc' ? 'coordinates' : 'coordinates_mercator',
  3679. transferCoordinate: function transferCoordinate(coordinate) {
  3680. var x = (coordinate[0] - nwMc.x) / zoomUnit * scale;
  3681. var y = (nwMc.y - coordinate[1]) / zoomUnit * scale;
  3682. return [x, y];
  3683. }
  3684. };
  3685. if (time !== undefined) {
  3686. dataGetOptions.filter = function (item) {
  3687. var trails = animationOptions.trails || 10;
  3688. if (time && item.time > time - trails && item.time < time) {
  3689. return true;
  3690. } else {
  3691. return false;
  3692. }
  3693. };
  3694. }
  3695. // get data from data set
  3696. var data = self.dataSet.get(dataGetOptions);
  3697. this.processData(data);
  3698. var nwPixel = map.pointToPixel(new BMap.Point(0, 0));
  3699. if (self.options.unit == 'm') {
  3700. if (self.options.size) {
  3701. self.options._size = self.options.size / zoomUnit;
  3702. }
  3703. if (self.options.width) {
  3704. self.options._width = self.options.width / zoomUnit;
  3705. }
  3706. if (self.options.height) {
  3707. self.options._height = self.options.height / zoomUnit;
  3708. }
  3709. } else {
  3710. self.options._size = self.options.size;
  3711. self.options._height = self.options.height;
  3712. self.options._width = self.options.width;
  3713. }
  3714. this.drawContext(context, data, self.options, nwPixel);
  3715. //console.timeEnd('draw');
  3716. //console.timeEnd('update')
  3717. self.options.updateCallback && self.options.updateCallback(time);
  3718. }
  3719. }, {
  3720. key: "init",
  3721. value: function init(options) {
  3722. var self = this;
  3723. self.options = options;
  3724. this.initDataRange(options);
  3725. this.context = self.options.context || '2d';
  3726. if (self.options.zIndex) {
  3727. this.canvasLayer && this.canvasLayer.setZIndex(self.options.zIndex);
  3728. }
  3729. if (self.options.max) {
  3730. this.intensity.setMax(self.options.max);
  3731. }
  3732. if (self.options.min) {
  3733. this.intensity.setMin(self.options.min);
  3734. }
  3735. this.initAnimator();
  3736. }
  3737. }, {
  3738. key: "addAnimatorEvent",
  3739. value: function addAnimatorEvent() {
  3740. this.map.addEventListener('movestart', this.animatorMovestartEvent.bind(this));
  3741. this.map.addEventListener('moveend', this.animatorMoveendEvent.bind(this));
  3742. }
  3743. }, {
  3744. key: "show",
  3745. value: function show() {
  3746. this.map.addOverlay(this.canvasLayer);
  3747. }
  3748. }, {
  3749. key: "hide",
  3750. value: function hide() {
  3751. this.map.removeOverlay(this.canvasLayer);
  3752. }
  3753. }, {
  3754. key: "draw",
  3755. value: function draw() {
  3756. this.canvasLayer.draw();
  3757. }
  3758. }]);
  3759. return Layer;
  3760. }(BaseLayer);
  3761. /**
  3762. * Copyright 2012 Google Inc. All Rights Reserved.
  3763. *
  3764. * Licensed under the Apache License, Version 2.0 (the "License");
  3765. * you may not use this file except in compliance with the License.
  3766. * You may obtain a copy of the License at
  3767. *
  3768. * http://www.apache.org/licenses/LICENSE-2.0
  3769. *
  3770. * Unless required by applicable law or agreed to in writing, software
  3771. * distributed under the License is distributed on an "AS IS" BASIS,
  3772. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  3773. * See the License for the specific language governing permissions and
  3774. * limitations under the License.
  3775. */
  3776. /**
  3777. * @fileoverview Extends OverlayView to provide a canvas "Layer".
  3778. * @author Brendan Kenny
  3779. */
  3780. /**
  3781. * A map layer that provides a canvas over the slippy map and a callback
  3782. * system for efficient animation. Requires canvas and CSS 2D transform
  3783. * support.
  3784. * @constructor
  3785. * @extends google.maps.OverlayView
  3786. * @param {CanvasLayerOptions=} opt_options Options to set in this CanvasLayer.
  3787. */
  3788. function CanvasLayer$2(opt_options) {
  3789. /**
  3790. * If true, canvas is in a map pane and the OverlayView is fully functional.
  3791. * See google.maps.OverlayView.onAdd for more information.
  3792. * @type {boolean}
  3793. * @private
  3794. */
  3795. this.isAdded_ = false;
  3796. /**
  3797. * If true, each update will immediately schedule the next.
  3798. * @type {boolean}
  3799. * @private
  3800. */
  3801. this.isAnimated_ = false;
  3802. /**
  3803. * The name of the MapPane in which this layer will be displayed.
  3804. * @type {string}
  3805. * @private
  3806. */
  3807. this.paneName_ = CanvasLayer$2.DEFAULT_PANE_NAME_;
  3808. /**
  3809. * A user-supplied function called whenever an update is required. Null or
  3810. * undefined if a callback is not provided.
  3811. * @type {?function=}
  3812. * @private
  3813. */
  3814. this.updateHandler_ = null;
  3815. /**
  3816. * A user-supplied function called whenever an update is required and the
  3817. * map has been resized since the last update. Null or undefined if a
  3818. * callback is not provided.
  3819. * @type {?function}
  3820. * @private
  3821. */
  3822. this.resizeHandler_ = null;
  3823. /**
  3824. * The LatLng coordinate of the top left of the current view of the map. Will
  3825. * be null when this.isAdded_ is false.
  3826. * @type {google.maps.LatLng}
  3827. * @private
  3828. */
  3829. this.topLeft_ = null;
  3830. /**
  3831. * The map-pan event listener. Will be null when this.isAdded_ is false. Will
  3832. * be null when this.isAdded_ is false.
  3833. * @type {?function}
  3834. * @private
  3835. */
  3836. this.centerListener_ = null;
  3837. /**
  3838. * The map-resize event listener. Will be null when this.isAdded_ is false.
  3839. * @type {?function}
  3840. * @private
  3841. */
  3842. this.resizeListener_ = null;
  3843. /**
  3844. * If true, the map size has changed and this.resizeHandler_ must be called
  3845. * on the next update.
  3846. * @type {boolean}
  3847. * @private
  3848. */
  3849. this.needsResize_ = true;
  3850. /**
  3851. * A browser-defined id for the currently requested callback. Null when no
  3852. * callback is queued.
  3853. * @type {?number}
  3854. * @private
  3855. */
  3856. this.requestAnimationFrameId_ = null;
  3857. var canvas = document.createElement('canvas');
  3858. canvas.style.position = 'absolute';
  3859. canvas.style.top = 0;
  3860. canvas.style.left = 0;
  3861. canvas.style.pointerEvents = 'none';
  3862. /**
  3863. * The canvas element.
  3864. * @type {!HTMLCanvasElement}
  3865. */
  3866. this.canvas = canvas;
  3867. /**
  3868. * The CSS width of the canvas, which may be different than the width of the
  3869. * backing store.
  3870. * @private {number}
  3871. */
  3872. this.canvasCssWidth_ = 300;
  3873. /**
  3874. * The CSS height of the canvas, which may be different than the height of
  3875. * the backing store.
  3876. * @private {number}
  3877. */
  3878. this.canvasCssHeight_ = 150;
  3879. /**
  3880. * A value for scaling the CanvasLayer resolution relative to the CanvasLayer
  3881. * display size.
  3882. * @private {number}
  3883. */
  3884. this.resolutionScale_ = 1;
  3885. /**
  3886. * Simple bind for functions with no args for bind-less browsers (Safari).
  3887. * @param {Object} thisArg The this value used for the target function.
  3888. * @param {function} func The function to be bound.
  3889. */
  3890. function simpleBindShim(thisArg, func) {
  3891. return function () {
  3892. func.apply(thisArg);
  3893. };
  3894. }
  3895. /**
  3896. * A reference to this.repositionCanvas_ with this bound as its this value.
  3897. * @type {function}
  3898. * @private
  3899. */
  3900. this.repositionFunction_ = simpleBindShim(this, this.repositionCanvas_);
  3901. /**
  3902. * A reference to this.resize_ with this bound as its this value.
  3903. * @type {function}
  3904. * @private
  3905. */
  3906. this.resizeFunction_ = simpleBindShim(this, this.resize_);
  3907. /**
  3908. * A reference to this.update_ with this bound as its this value.
  3909. * @type {function}
  3910. * @private
  3911. */
  3912. this.requestUpdateFunction_ = simpleBindShim(this, this.update_);
  3913. // set provided options, if any
  3914. if (opt_options) {
  3915. this.setOptions(opt_options);
  3916. }
  3917. }
  3918. var global$4 = typeof window === 'undefined' ? {} : window;
  3919. if (global$4.google && global$4.google.maps) {
  3920. CanvasLayer$2.prototype = new google.maps.OverlayView();
  3921. /**
  3922. * The default MapPane to contain the canvas.
  3923. * @type {string}
  3924. * @const
  3925. * @private
  3926. */
  3927. CanvasLayer$2.DEFAULT_PANE_NAME_ = 'overlayLayer';
  3928. /**
  3929. * Transform CSS property name, with vendor prefix if required. If browser
  3930. * does not support transforms, property will be ignored.
  3931. * @type {string}
  3932. * @const
  3933. * @private
  3934. */
  3935. CanvasLayer$2.CSS_TRANSFORM_ = function () {
  3936. var div = document.createElement('div');
  3937. var transformProps = ['transform', 'WebkitTransform', 'MozTransform', 'OTransform', 'msTransform'];
  3938. for (var i = 0; i < transformProps.length; i++) {
  3939. var prop = transformProps[i];
  3940. if (div.style[prop] !== undefined) {
  3941. return prop;
  3942. }
  3943. }
  3944. // return unprefixed version by default
  3945. return transformProps[0];
  3946. }();
  3947. /**
  3948. * The requestAnimationFrame function, with vendor-prefixed or setTimeout-based
  3949. * fallbacks. MUST be called with window as thisArg.
  3950. * @type {function}
  3951. * @param {function} callback The function to add to the frame request queue.
  3952. * @return {number} The browser-defined id for the requested callback.
  3953. * @private
  3954. */
  3955. CanvasLayer$2.prototype.requestAnimFrame_ = global$4.requestAnimationFrame || global$4.webkitRequestAnimationFrame || global$4.mozRequestAnimationFrame || global$4.oRequestAnimationFrame || global$4.msRequestAnimationFrame || function (callback) {
  3956. return global$4.setTimeout(callback, 1000 / 60);
  3957. };
  3958. /**
  3959. * The cancelAnimationFrame function, with vendor-prefixed fallback. Does not
  3960. * fall back to clearTimeout as some platforms implement requestAnimationFrame
  3961. * but not cancelAnimationFrame, and the cost is an extra frame on onRemove.
  3962. * MUST be called with window as thisArg.
  3963. * @type {function}
  3964. * @param {number=} requestId The id of the frame request to cancel.
  3965. * @private
  3966. */
  3967. CanvasLayer$2.prototype.cancelAnimFrame_ = global$4.cancelAnimationFrame || global$4.webkitCancelAnimationFrame || global$4.mozCancelAnimationFrame || global$4.oCancelAnimationFrame || global$4.msCancelAnimationFrame || function (requestId) {};
  3968. /**
  3969. * Sets any options provided. See CanvasLayerOptions for more information.
  3970. * @param {CanvasLayerOptions} options The options to set.
  3971. */
  3972. CanvasLayer$2.prototype.setOptions = function (options) {
  3973. if (options.animate !== undefined) {
  3974. this.setAnimate(options.animate);
  3975. }
  3976. if (options.paneName !== undefined) {
  3977. this.setPaneName(options.paneName);
  3978. }
  3979. if (options.updateHandler !== undefined) {
  3980. this.setUpdateHandler(options.updateHandler);
  3981. }
  3982. if (options.resizeHandler !== undefined) {
  3983. this.setResizeHandler(options.resizeHandler);
  3984. }
  3985. if (options.resolutionScale !== undefined) {
  3986. this.setResolutionScale(options.resolutionScale);
  3987. }
  3988. if (options.map !== undefined) {
  3989. this.setMap(options.map);
  3990. }
  3991. };
  3992. /**
  3993. * Set the animated state of the layer. If true, updateHandler will be called
  3994. * repeatedly, once per frame. If false, updateHandler will only be called when
  3995. * a map property changes that could require the canvas content to be redrawn.
  3996. * @param {boolean} animate Whether the canvas is animated.
  3997. */
  3998. CanvasLayer$2.prototype.setAnimate = function (animate) {
  3999. this.isAnimated_ = !!animate;
  4000. if (this.isAnimated_) {
  4001. this.scheduleUpdate();
  4002. }
  4003. };
  4004. /**
  4005. * @return {boolean} Whether the canvas is animated.
  4006. */
  4007. CanvasLayer$2.prototype.isAnimated = function () {
  4008. return this.isAnimated_;
  4009. };
  4010. /**
  4011. * Set the MapPane in which this layer will be displayed, by name. See
  4012. * {@code google.maps.MapPanes} for the panes available.
  4013. * @param {string} paneName The name of the desired MapPane.
  4014. */
  4015. CanvasLayer$2.prototype.setPaneName = function (paneName) {
  4016. this.paneName_ = paneName;
  4017. this.setPane_();
  4018. };
  4019. /**
  4020. * @return {string} The name of the current container pane.
  4021. */
  4022. CanvasLayer$2.prototype.getPaneName = function () {
  4023. return this.paneName_;
  4024. };
  4025. /**
  4026. * Adds the canvas to the specified container pane. Since this is guaranteed to
  4027. * execute only after onAdd is called, this is when paneName's existence is
  4028. * checked (and an error is thrown if it doesn't exist).
  4029. * @private
  4030. */
  4031. CanvasLayer$2.prototype.setPane_ = function () {
  4032. if (!this.isAdded_) {
  4033. return;
  4034. }
  4035. // onAdd has been called, so panes can be used
  4036. var panes = this.getPanes();
  4037. if (!panes[this.paneName_]) {
  4038. throw new Error('"' + this.paneName_ + '" is not a valid MapPane name.');
  4039. }
  4040. panes[this.paneName_].appendChild(this.canvas);
  4041. };
  4042. /**
  4043. * Set a function that will be called whenever the parent map and the overlay's
  4044. * canvas have been resized. If opt_resizeHandler is null or unspecified, any
  4045. * existing callback is removed.
  4046. * @param {?function=} opt_resizeHandler The resize callback function.
  4047. */
  4048. CanvasLayer$2.prototype.setResizeHandler = function (opt_resizeHandler) {
  4049. this.resizeHandler_ = opt_resizeHandler;
  4050. };
  4051. /**
  4052. * Sets a value for scaling the canvas resolution relative to the canvas
  4053. * display size. This can be used to save computation by scaling the backing
  4054. * buffer down, or to support high DPI devices by scaling it up (by e.g.
  4055. * window.devicePixelRatio).
  4056. * @param {number} scale
  4057. */
  4058. CanvasLayer$2.prototype.setResolutionScale = function (scale) {
  4059. if (typeof scale === 'number') {
  4060. this.resolutionScale_ = scale;
  4061. this.resize_();
  4062. }
  4063. };
  4064. /**
  4065. * Set a function that will be called when a repaint of the canvas is required.
  4066. * If opt_updateHandler is null or unspecified, any existing callback is
  4067. * removed.
  4068. * @param {?function=} opt_updateHandler The update callback function.
  4069. */
  4070. CanvasLayer$2.prototype.setUpdateHandler = function (opt_updateHandler) {
  4071. this.updateHandler_ = opt_updateHandler;
  4072. };
  4073. /**
  4074. * @inheritDoc
  4075. */
  4076. CanvasLayer$2.prototype.onAdd = function () {
  4077. if (this.isAdded_) {
  4078. return;
  4079. }
  4080. this.isAdded_ = true;
  4081. this.setPane_();
  4082. this.resizeListener_ = google.maps.event.addListener(this.getMap(), 'resize', this.resizeFunction_);
  4083. this.centerListener_ = google.maps.event.addListener(this.getMap(), 'center_changed', this.repositionFunction_);
  4084. this.resize_();
  4085. this.repositionCanvas_();
  4086. };
  4087. /**
  4088. * @inheritDoc
  4089. */
  4090. CanvasLayer$2.prototype.onRemove = function () {
  4091. if (!this.isAdded_) {
  4092. return;
  4093. }
  4094. this.isAdded_ = false;
  4095. this.topLeft_ = null;
  4096. // remove canvas and listeners for pan and resize from map
  4097. this.canvas.parentElement.removeChild(this.canvas);
  4098. if (this.centerListener_) {
  4099. google.maps.event.removeListener(this.centerListener_);
  4100. this.centerListener_ = null;
  4101. }
  4102. if (this.resizeListener_) {
  4103. google.maps.event.removeListener(this.resizeListener_);
  4104. this.resizeListener_ = null;
  4105. }
  4106. // cease canvas update callbacks
  4107. if (this.requestAnimationFrameId_) {
  4108. this.cancelAnimFrame_.call(global$4, this.requestAnimationFrameId_);
  4109. this.requestAnimationFrameId_ = null;
  4110. }
  4111. };
  4112. /**
  4113. * The internal callback for resize events that resizes the canvas to keep the
  4114. * map properly covered.
  4115. * @private
  4116. */
  4117. CanvasLayer$2.prototype.resize_ = function () {
  4118. if (!this.isAdded_) {
  4119. return;
  4120. }
  4121. var map = this.getMap();
  4122. var mapWidth = map.getDiv().offsetWidth;
  4123. var mapHeight = map.getDiv().offsetHeight;
  4124. var newWidth = mapWidth * this.resolutionScale_;
  4125. var newHeight = mapHeight * this.resolutionScale_;
  4126. var oldWidth = this.canvas.width;
  4127. var oldHeight = this.canvas.height;
  4128. // resizing may allocate a new back buffer, so do so conservatively
  4129. if (oldWidth !== newWidth || oldHeight !== newHeight) {
  4130. this.canvas.width = newWidth;
  4131. this.canvas.height = newHeight;
  4132. this.needsResize_ = true;
  4133. this.scheduleUpdate();
  4134. }
  4135. // reset styling if new sizes don't match; resize of data not needed
  4136. if (this.canvasCssWidth_ !== mapWidth || this.canvasCssHeight_ !== mapHeight) {
  4137. this.canvasCssWidth_ = mapWidth;
  4138. this.canvasCssHeight_ = mapHeight;
  4139. this.canvas.style.width = mapWidth + 'px';
  4140. this.canvas.style.height = mapHeight + 'px';
  4141. }
  4142. };
  4143. /**
  4144. * @inheritDoc
  4145. */
  4146. CanvasLayer$2.prototype.draw = function () {
  4147. this.repositionCanvas_();
  4148. };
  4149. /**
  4150. * Internal callback for map view changes. Since the Maps API moves the overlay
  4151. * along with the map, this function calculates the opposite translation to
  4152. * keep the canvas in place.
  4153. * @private
  4154. */
  4155. CanvasLayer$2.prototype.repositionCanvas_ = function () {
  4156. // TODO(bckenny): *should* only be executed on RAF, but in current browsers
  4157. // this causes noticeable hitches in map and overlay relative
  4158. // positioning.
  4159. var map = this.getMap();
  4160. // topLeft can't be calculated from map.getBounds(), because bounds are
  4161. // clamped to -180 and 180 when completely zoomed out. Instead, calculate
  4162. // left as an offset from the center, which is an unwrapped LatLng.
  4163. var top = map.getBounds().getNorthEast().lat();
  4164. var center = map.getCenter();
  4165. var scale = Math.pow(2, map.getZoom());
  4166. var left = center.lng() - this.canvasCssWidth_ * 180 / (256 * scale);
  4167. this.topLeft_ = new google.maps.LatLng(top, left);
  4168. // Canvas position relative to draggable map's container depends on
  4169. // overlayView's projection, not the map's. Have to use the center of the
  4170. // map for this, not the top left, for the same reason as above.
  4171. var projection = this.getProjection();
  4172. var divCenter = projection.fromLatLngToDivPixel(center);
  4173. var offsetX = -Math.round(this.canvasCssWidth_ / 2 - divCenter.x);
  4174. var offsetY = -Math.round(this.canvasCssHeight_ / 2 - divCenter.y);
  4175. this.canvas.style[CanvasLayer$2.CSS_TRANSFORM_] = 'translate(' + offsetX + 'px,' + offsetY + 'px)';
  4176. this.scheduleUpdate();
  4177. };
  4178. /**
  4179. * Internal callback that serves as main animation scheduler via
  4180. * requestAnimationFrame. Calls resize and update callbacks if set, and
  4181. * schedules the next frame if overlay is animated.
  4182. * @private
  4183. */
  4184. CanvasLayer$2.prototype.update_ = function () {
  4185. this.requestAnimationFrameId_ = null;
  4186. if (!this.isAdded_) {
  4187. return;
  4188. }
  4189. if (this.isAnimated_) {
  4190. this.scheduleUpdate();
  4191. }
  4192. if (this.needsResize_ && this.resizeHandler_) {
  4193. this.needsResize_ = false;
  4194. this.resizeHandler_();
  4195. }
  4196. if (this.updateHandler_) {
  4197. this.updateHandler_();
  4198. }
  4199. };
  4200. /**
  4201. * A convenience method to get the current LatLng coordinate of the top left of
  4202. * the current view of the map.
  4203. * @return {google.maps.LatLng} The top left coordinate.
  4204. */
  4205. CanvasLayer$2.prototype.getTopLeft = function () {
  4206. return this.topLeft_;
  4207. };
  4208. /**
  4209. * Schedule a requestAnimationFrame callback to updateHandler. If one is
  4210. * already scheduled, there is no effect.
  4211. */
  4212. CanvasLayer$2.prototype.scheduleUpdate = function () {
  4213. if (this.isAdded_ && !this.requestAnimationFrameId_) {
  4214. this.requestAnimationFrameId_ = this.requestAnimFrame_.call(global$4, this.requestUpdateFunction_);
  4215. }
  4216. };
  4217. }
  4218. /**
  4219. * @author kyle / http://nikai.us/
  4220. */
  4221. var Layer$2 = function (_BaseLayer) {
  4222. inherits(Layer, _BaseLayer);
  4223. function Layer(map, dataSet, options) {
  4224. classCallCheck(this, Layer);
  4225. var _this = possibleConstructorReturn(this, (Layer.__proto__ || Object.getPrototypeOf(Layer)).call(this, map, dataSet, options));
  4226. var self = _this;
  4227. var data = null;
  4228. options = options || {};
  4229. self.init(options);
  4230. self.argCheck(options);
  4231. var canvasLayerOptions = {
  4232. map: map,
  4233. animate: false,
  4234. updateHandler: function updateHandler() {
  4235. self._canvasUpdate();
  4236. },
  4237. resolutionScale: resolutionScale
  4238. };
  4239. var canvasLayer = _this.canvasLayer = new CanvasLayer$2(canvasLayerOptions);
  4240. _this.clickEvent = _this.clickEvent.bind(_this);
  4241. _this.mousemoveEvent = _this.mousemoveEvent.bind(_this);
  4242. _this.bindEvent();
  4243. return _this;
  4244. }
  4245. createClass(Layer, [{
  4246. key: "clickEvent",
  4247. value: function clickEvent(e) {
  4248. var pixel = e.pixel;
  4249. get(Layer.prototype.__proto__ || Object.getPrototypeOf(Layer.prototype), "clickEvent", this).call(this, pixel, e);
  4250. }
  4251. }, {
  4252. key: "mousemoveEvent",
  4253. value: function mousemoveEvent(e) {
  4254. var pixel = e.pixel;
  4255. get(Layer.prototype.__proto__ || Object.getPrototypeOf(Layer.prototype), "mousemoveEvent", this).call(this, pixel, e);
  4256. }
  4257. }, {
  4258. key: "bindEvent",
  4259. value: function bindEvent(e) {
  4260. var map = this.map;
  4261. if (this.options.methods) {
  4262. if (this.options.methods.click) {
  4263. map.setDefaultCursor("default");
  4264. map.addListener('click', this.clickEvent);
  4265. }
  4266. if (this.options.methods.mousemove) {
  4267. map.addListener('mousemove', this.mousemoveEvent);
  4268. }
  4269. }
  4270. }
  4271. }, {
  4272. key: "unbindEvent",
  4273. value: function unbindEvent(e) {
  4274. var map = this.map;
  4275. if (this.options.methods) {
  4276. if (this.options.methods.click) {
  4277. map.removeListener('click', this.clickEvent);
  4278. }
  4279. if (this.options.methods.mousemove) {
  4280. map.removeListener('mousemove', this.mousemoveEvent);
  4281. }
  4282. }
  4283. }
  4284. }, {
  4285. key: "getContext",
  4286. value: function getContext() {
  4287. return this.canvasLayer.canvas.getContext(this.context);
  4288. }
  4289. }, {
  4290. key: "_canvasUpdate",
  4291. value: function _canvasUpdate(time) {
  4292. if (!this.canvasLayer) {
  4293. return;
  4294. }
  4295. var self = this;
  4296. var animationOptions = self.options.animation;
  4297. var context = this.getContext();
  4298. if (self.isEnabledTime()) {
  4299. if (time === undefined) {
  4300. clear(context);
  4301. return;
  4302. }
  4303. if (this.context == '2d') {
  4304. context.save();
  4305. context.globalCompositeOperation = 'destination-out';
  4306. context.fillStyle = 'rgba(0, 0, 0, .1)';
  4307. context.fillRect(0, 0, context.canvas.width, context.canvas.height);
  4308. context.restore();
  4309. }
  4310. } else {
  4311. clear(context);
  4312. }
  4313. if (this.context == '2d') {
  4314. for (var key in self.options) {
  4315. context[key] = self.options[key];
  4316. }
  4317. } else {
  4318. context.clear(context.COLOR_BUFFER_BIT);
  4319. }
  4320. if (self.options.minZoom && map.getZoom() < self.options.minZoom || self.options.maxZoom && map.getZoom() > self.options.maxZoom) {
  4321. return;
  4322. }
  4323. var scale = 1;
  4324. if (this.context != '2d') {
  4325. scale = this.canvasLayer.devicePixelRatio;
  4326. }
  4327. var map = this.map;
  4328. var mapProjection = map.getProjection();
  4329. var scale = Math.pow(2, map.zoom) * resolutionScale;
  4330. var offset = mapProjection.fromLatLngToPoint(this.canvasLayer.getTopLeft());
  4331. var dataGetOptions = {
  4332. //fromColumn: self.options.coordType == 'bd09mc' ? 'coordinates' : 'coordinates_mercator',
  4333. transferCoordinate: function transferCoordinate(coordinate) {
  4334. var latLng = new google.maps.LatLng(coordinate[1], coordinate[0]);
  4335. var worldPoint = mapProjection.fromLatLngToPoint(latLng);
  4336. var pixel = {
  4337. x: (worldPoint.x - offset.x) * scale,
  4338. y: (worldPoint.y - offset.y) * scale
  4339. };
  4340. return [pixel.x, pixel.y];
  4341. }
  4342. };
  4343. if (time !== undefined) {
  4344. dataGetOptions.filter = function (item) {
  4345. var trails = animationOptions.trails || 10;
  4346. if (time && item.time > time - trails && item.time < time) {
  4347. return true;
  4348. } else {
  4349. return false;
  4350. }
  4351. };
  4352. }
  4353. // get data from data set
  4354. var data = self.dataSet.get(dataGetOptions);
  4355. this.processData(data);
  4356. var latLng = new google.maps.LatLng(0, 0);
  4357. var worldPoint = mapProjection.fromLatLngToPoint(latLng);
  4358. var pixel = {
  4359. x: (worldPoint.x - offset.x) * scale,
  4360. y: (worldPoint.y - offset.y) * scale
  4361. };
  4362. if (self.options.unit == 'm' && self.options.size) {
  4363. self.options._size = self.options.size / zoomUnit;
  4364. } else {
  4365. self.options._size = self.options.size;
  4366. }
  4367. this.drawContext(context, new DataSet(data), self.options, pixel);
  4368. //console.timeEnd('draw');
  4369. //console.timeEnd('update')
  4370. self.options.updateCallback && self.options.updateCallback(time);
  4371. }
  4372. }, {
  4373. key: "init",
  4374. value: function init(options) {
  4375. var self = this;
  4376. self.options = options;
  4377. this.initDataRange(options);
  4378. this.context = self.options.context || '2d';
  4379. if (self.options.zIndex) {
  4380. this.canvasLayer && this.canvasLayer.setZIndex(self.options.zIndex);
  4381. }
  4382. this.initAnimator();
  4383. }
  4384. }, {
  4385. key: "addAnimatorEvent",
  4386. value: function addAnimatorEvent() {
  4387. this.map.addListener('movestart', this.animatorMovestartEvent.bind(this));
  4388. this.map.addListener('moveend', this.animatorMoveendEvent.bind(this));
  4389. }
  4390. }, {
  4391. key: "show",
  4392. value: function show() {
  4393. this.map.addOverlay(this.canvasLayer);
  4394. }
  4395. }, {
  4396. key: "hide",
  4397. value: function hide() {
  4398. this.map.removeOverlay(this.canvasLayer);
  4399. }
  4400. }, {
  4401. key: "draw",
  4402. value: function draw() {
  4403. self.canvasLayer.draw();
  4404. }
  4405. }]);
  4406. return Layer;
  4407. }(BaseLayer);
  4408. /**
  4409. * @author kyle / http://nikai.us/
  4410. */
  4411. var geojson = {
  4412. getDataSet: function getDataSet(geoJson) {
  4413. var data = [];
  4414. var features = geoJson.features;
  4415. for (var i = 0; i < features.length; i++) {
  4416. var feature = features[i];
  4417. var geometry = feature.geometry;
  4418. var properties = feature.properties;
  4419. var item = {};
  4420. for (var key in properties) {
  4421. item[key] = properties[key];
  4422. }
  4423. item.geometry = geometry;
  4424. data.push(item);
  4425. }
  4426. return new DataSet(data);
  4427. }
  4428. };
  4429. /**
  4430. * @author kyle / http://nikai.us/
  4431. */
  4432. var csv = {
  4433. CSVToArray: function CSVToArray(strData, strDelimiter) {
  4434. // Check to see if the delimiter is defined. If not,
  4435. // then default to comma.
  4436. strDelimiter = strDelimiter || ",";
  4437. // Create a regular expression to parse the CSV values.
  4438. var objPattern = new RegExp(
  4439. // Delimiters.
  4440. "(\\" + strDelimiter + "|\\r?\\n|\\r|^)" +
  4441. // Quoted fields.
  4442. "(?:\"([^\"]*(?:\"\"[^\"]*)*)\"|" +
  4443. // Standard fields.
  4444. "([^\"\\" + strDelimiter + "\\r\\n]*))", "gi");
  4445. // Create an array to hold our data. Give the array
  4446. // a default empty first row.
  4447. var arrData = [[]];
  4448. // Create an array to hold our individual pattern
  4449. // matching groups.
  4450. var arrMatches = null;
  4451. // Keep looping over the regular expression matches
  4452. // until we can no longer find a match.
  4453. while (arrMatches = objPattern.exec(strData)) {
  4454. // Get the delimiter that was found.
  4455. var strMatchedDelimiter = arrMatches[1];
  4456. // Check to see if the given delimiter has a length
  4457. // (is not the start of string) and if it matches
  4458. // field delimiter. If id does not, then we know
  4459. // that this delimiter is a row delimiter.
  4460. if (strMatchedDelimiter.length && strMatchedDelimiter !== strDelimiter) {
  4461. // Since we have reached a new row of data,
  4462. // add an empty row to our data array.
  4463. arrData.push([]);
  4464. }
  4465. var strMatchedValue;
  4466. // Now that we have our delimiter out of the way,
  4467. // let's check to see which kind of value we
  4468. // captured (quoted or unquoted).
  4469. if (arrMatches[2]) {
  4470. // We found a quoted value. When we capture
  4471. // this value, unescape any double quotes.
  4472. strMatchedValue = arrMatches[2].replace(new RegExp("\"\"", "g"), "\"");
  4473. } else {
  4474. // We found a non-quoted value.
  4475. strMatchedValue = arrMatches[3];
  4476. }
  4477. // Now that we have our value string, let's add
  4478. // it to the data array.
  4479. arrData[arrData.length - 1].push(strMatchedValue);
  4480. }
  4481. // Return the parsed data.
  4482. return arrData;
  4483. },
  4484. getDataSet: function getDataSet(csvStr) {
  4485. var arr = this.CSVToArray(csvStr, ',');
  4486. var data = [];
  4487. var header = arr[0];
  4488. for (var i = 1; i < arr.length - 1; i++) {
  4489. var line = arr[i];
  4490. var item = {};
  4491. for (var j = 0; j < line.length; j++) {
  4492. var value = line[j];
  4493. if (header[j] == 'geometry') {
  4494. value = JSON.parse(value);
  4495. }
  4496. item[header[j]] = value;
  4497. }
  4498. data.push(item);
  4499. }
  4500. return new DataSet(data);
  4501. }
  4502. };
  4503. exports.version = version;
  4504. exports.canvasClear = clear;
  4505. exports.canvasResolutionScale = resolutionScale$1;
  4506. exports.canvasDrawSimple = drawSimple;
  4507. exports.canvasDrawHeatmap = drawHeatmap;
  4508. exports.canvasDrawGrid = drawGrid;
  4509. exports.canvasDrawHoneycomb = drawHoneycomb;
  4510. exports.webglDrawSimple = webglDrawSimple;
  4511. exports.webglDrawPoint = point;
  4512. exports.webglDrawLine = line;
  4513. exports.webglDrawPolygon = polygon;
  4514. exports.utilCityCenter = cityCenter;
  4515. exports.utilCurve = curve;
  4516. exports.utilForceEdgeBundling = ForceEdgeBundling;
  4517. exports.utilDataRangeIntensity = Intensity;
  4518. exports.utilDataRangeCategory = Category;
  4519. exports.utilDataRangeChoropleth = Choropleth;
  4520. exports.Map = MapHelper;
  4521. exports.baiduMapCanvasLayer = CanvasLayer;
  4522. exports.baiduMapAnimationLayer = AnimationLayer;
  4523. exports.baiduMapLayer = Layer;
  4524. exports.googleMapCanvasLayer = CanvasLayer$2;
  4525. exports.googleMapLayer = Layer$2;
  4526. exports.DataSet = DataSet;
  4527. exports.geojson = geojson;
  4528. exports.csv = csv;
  4529. Object.defineProperty(exports, '__esModule', { value: true });
  4530. })));