umychart.wechat.3.0.js 500 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568756975707571757275737574757575767577757875797580758175827583758475857586758775887589759075917592759375947595759675977598759976007601760276037604760576067607760876097610761176127613761476157616761776187619762076217622762376247625762676277628762976307631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700770177027703770477057706770777087709771077117712771377147715771677177718771977207721772277237724772577267727772877297730773177327733773477357736773777387739774077417742774377447745774677477748774977507751775277537754775577567757775877597760776177627763776477657766776777687769777077717772777377747775777677777778777977807781778277837784778577867787778877897790779177927793779477957796779777987799780078017802780378047805780678077808780978107811781278137814781578167817781878197820782178227823782478257826782778287829783078317832783378347835783678377838783978407841784278437844784578467847784878497850785178527853785478557856785778587859786078617862786378647865786678677868786978707871787278737874787578767877787878797880788178827883788478857886788778887889789078917892789378947895789678977898789979007901790279037904790579067907790879097910791179127913791479157916791779187919792079217922792379247925792679277928792979307931793279337934793579367937793879397940794179427943794479457946794779487949795079517952795379547955795679577958795979607961796279637964796579667967796879697970797179727973797479757976797779787979798079817982798379847985798679877988798979907991799279937994799579967997799879998000800180028003800480058006800780088009801080118012801380148015801680178018801980208021802280238024802580268027802880298030803180328033803480358036803780388039804080418042804380448045804680478048804980508051805280538054805580568057805880598060806180628063806480658066806780688069807080718072807380748075807680778078807980808081808280838084808580868087808880898090809180928093809480958096809780988099810081018102810381048105810681078108810981108111811281138114811581168117811881198120812181228123812481258126812781288129813081318132813381348135813681378138813981408141814281438144814581468147814881498150815181528153815481558156815781588159816081618162816381648165816681678168816981708171817281738174817581768177817881798180818181828183818481858186818781888189819081918192819381948195819681978198819982008201820282038204820582068207820882098210821182128213821482158216821782188219822082218222822382248225822682278228822982308231823282338234823582368237823882398240824182428243824482458246824782488249825082518252825382548255825682578258825982608261826282638264826582668267826882698270827182728273827482758276827782788279828082818282828382848285828682878288828982908291829282938294829582968297829882998300830183028303830483058306830783088309831083118312831383148315831683178318831983208321832283238324832583268327832883298330833183328333833483358336833783388339834083418342834383448345834683478348834983508351835283538354835583568357835883598360836183628363836483658366836783688369837083718372837383748375837683778378837983808381838283838384838583868387838883898390839183928393839483958396839783988399840084018402840384048405840684078408840984108411841284138414841584168417841884198420842184228423842484258426842784288429843084318432843384348435843684378438843984408441844284438444844584468447844884498450845184528453845484558456845784588459846084618462846384648465846684678468846984708471847284738474847584768477847884798480848184828483848484858486848784888489849084918492849384948495849684978498849985008501850285038504850585068507850885098510851185128513851485158516851785188519852085218522852385248525852685278528852985308531853285338534853585368537853885398540854185428543854485458546854785488549855085518552855385548555855685578558855985608561856285638564856585668567856885698570857185728573857485758576857785788579858085818582858385848585858685878588858985908591859285938594859585968597859885998600860186028603860486058606860786088609861086118612861386148615861686178618861986208621862286238624862586268627862886298630863186328633863486358636863786388639864086418642864386448645864686478648864986508651865286538654865586568657865886598660866186628663866486658666866786688669867086718672867386748675867686778678867986808681868286838684868586868687868886898690869186928693869486958696869786988699870087018702870387048705870687078708870987108711871287138714871587168717871887198720872187228723872487258726872787288729873087318732873387348735873687378738873987408741874287438744874587468747874887498750875187528753875487558756875787588759876087618762876387648765876687678768876987708771877287738774877587768777877887798780878187828783878487858786878787888789879087918792879387948795879687978798879988008801880288038804880588068807880888098810881188128813881488158816881788188819882088218822882388248825882688278828882988308831883288338834883588368837883888398840884188428843884488458846884788488849885088518852885388548855885688578858885988608861886288638864886588668867886888698870887188728873887488758876887788788879888088818882888388848885888688878888888988908891889288938894889588968897889888998900890189028903890489058906890789088909891089118912891389148915891689178918891989208921892289238924892589268927892889298930893189328933893489358936893789388939894089418942894389448945894689478948894989508951895289538954895589568957895889598960896189628963896489658966896789688969897089718972897389748975897689778978897989808981898289838984898589868987898889898990899189928993899489958996899789988999900090019002900390049005900690079008900990109011901290139014901590169017901890199020902190229023902490259026902790289029903090319032903390349035903690379038903990409041904290439044904590469047904890499050905190529053905490559056905790589059906090619062906390649065906690679068906990709071907290739074907590769077907890799080908190829083908490859086908790889089909090919092909390949095909690979098909991009101910291039104910591069107910891099110911191129113911491159116911791189119912091219122912391249125912691279128912991309131913291339134913591369137913891399140914191429143914491459146914791489149915091519152915391549155915691579158915991609161916291639164916591669167916891699170917191729173917491759176917791789179918091819182918391849185918691879188918991909191919291939194919591969197919891999200920192029203920492059206920792089209921092119212921392149215921692179218921992209221922292239224922592269227922892299230923192329233923492359236923792389239924092419242924392449245924692479248924992509251925292539254925592569257925892599260926192629263926492659266926792689269927092719272927392749275927692779278927992809281928292839284928592869287928892899290929192929293929492959296929792989299930093019302930393049305930693079308930993109311931293139314931593169317931893199320932193229323932493259326932793289329933093319332933393349335933693379338933993409341934293439344934593469347934893499350935193529353935493559356935793589359936093619362936393649365936693679368936993709371937293739374937593769377937893799380938193829383938493859386938793889389939093919392939393949395939693979398939994009401940294039404940594069407940894099410941194129413941494159416941794189419942094219422942394249425942694279428942994309431943294339434943594369437943894399440944194429443944494459446944794489449945094519452945394549455945694579458945994609461946294639464946594669467946894699470947194729473947494759476947794789479948094819482948394849485948694879488948994909491949294939494949594969497949894999500950195029503950495059506950795089509951095119512951395149515951695179518951995209521952295239524952595269527952895299530953195329533953495359536953795389539954095419542954395449545954695479548954995509551955295539554955595569557955895599560956195629563956495659566956795689569957095719572957395749575957695779578957995809581958295839584958595869587958895899590959195929593959495959596959795989599960096019602960396049605960696079608960996109611961296139614961596169617961896199620962196229623962496259626962796289629963096319632963396349635963696379638963996409641964296439644964596469647964896499650965196529653965496559656965796589659966096619662966396649665966696679668966996709671967296739674967596769677967896799680968196829683968496859686968796889689969096919692969396949695969696979698969997009701970297039704970597069707970897099710971197129713971497159716971797189719972097219722972397249725972697279728972997309731973297339734973597369737973897399740974197429743974497459746974797489749975097519752975397549755975697579758975997609761976297639764976597669767976897699770977197729773977497759776977797789779978097819782978397849785978697879788978997909791979297939794979597969797979897999800980198029803980498059806980798089809981098119812981398149815981698179818981998209821982298239824982598269827982898299830983198329833983498359836983798389839984098419842984398449845984698479848984998509851985298539854985598569857985898599860986198629863986498659866986798689869987098719872987398749875987698779878987998809881988298839884988598869887988898899890989198929893989498959896989798989899990099019902990399049905990699079908990999109911991299139914991599169917991899199920992199229923992499259926992799289929993099319932993399349935993699379938993999409941994299439944994599469947994899499950995199529953995499559956995799589959996099619962996399649965996699679968996999709971997299739974997599769977997899799980998199829983998499859986998799889989999099919992999399949995999699979998999910000100011000210003100041000510006100071000810009100101001110012100131001410015100161001710018100191002010021100221002310024100251002610027100281002910030100311003210033100341003510036100371003810039100401004110042100431004410045100461004710048100491005010051100521005310054100551005610057100581005910060100611006210063100641006510066100671006810069100701007110072100731007410075100761007710078100791008010081100821008310084100851008610087100881008910090100911009210093100941009510096100971009810099101001010110102101031010410105101061010710108101091011010111101121011310114101151011610117101181011910120101211012210123101241012510126101271012810129101301013110132101331013410135101361013710138101391014010141101421014310144101451014610147101481014910150101511015210153101541015510156101571015810159101601016110162101631016410165101661016710168101691017010171101721017310174101751017610177101781017910180101811018210183101841018510186101871018810189101901019110192101931019410195101961019710198101991020010201102021020310204102051020610207102081020910210102111021210213102141021510216102171021810219102201022110222102231022410225102261022710228102291023010231102321023310234102351023610237102381023910240102411024210243102441024510246102471024810249102501025110252102531025410255102561025710258102591026010261102621026310264102651026610267102681026910270102711027210273102741027510276102771027810279102801028110282102831028410285102861028710288102891029010291102921029310294102951029610297102981029910300103011030210303103041030510306103071030810309103101031110312103131031410315103161031710318103191032010321103221032310324103251032610327103281032910330103311033210333103341033510336103371033810339103401034110342103431034410345103461034710348103491035010351103521035310354103551035610357103581035910360103611036210363103641036510366103671036810369103701037110372103731037410375103761037710378103791038010381103821038310384103851038610387103881038910390103911039210393103941039510396103971039810399104001040110402104031040410405104061040710408104091041010411104121041310414104151041610417104181041910420104211042210423104241042510426104271042810429104301043110432104331043410435104361043710438104391044010441104421044310444104451044610447104481044910450104511045210453104541045510456104571045810459104601046110462104631046410465104661046710468104691047010471104721047310474104751047610477104781047910480104811048210483104841048510486104871048810489104901049110492104931049410495104961049710498104991050010501105021050310504105051050610507105081050910510105111051210513105141051510516105171051810519105201052110522105231052410525105261052710528105291053010531105321053310534105351053610537105381053910540105411054210543105441054510546105471054810549105501055110552105531055410555105561055710558105591056010561105621056310564105651056610567105681056910570105711057210573105741057510576105771057810579105801058110582105831058410585105861058710588105891059010591105921059310594105951059610597105981059910600106011060210603106041060510606106071060810609106101061110612106131061410615106161061710618106191062010621106221062310624106251062610627106281062910630106311063210633106341063510636106371063810639106401064110642106431064410645106461064710648106491065010651106521065310654106551065610657106581065910660106611066210663106641066510666106671066810669106701067110672106731067410675106761067710678106791068010681106821068310684106851068610687106881068910690106911069210693106941069510696106971069810699107001070110702107031070410705107061070710708107091071010711107121071310714107151071610717107181071910720107211072210723107241072510726107271072810729107301073110732107331073410735107361073710738107391074010741107421074310744107451074610747107481074910750107511075210753107541075510756107571075810759107601076110762107631076410765107661076710768107691077010771107721077310774107751077610777107781077910780107811078210783107841078510786107871078810789107901079110792107931079410795107961079710798107991080010801108021080310804108051080610807108081080910810108111081210813108141081510816108171081810819108201082110822108231082410825108261082710828108291083010831108321083310834108351083610837108381083910840108411084210843108441084510846108471084810849108501085110852108531085410855108561085710858108591086010861108621086310864108651086610867108681086910870108711087210873108741087510876108771087810879108801088110882108831088410885108861088710888108891089010891108921089310894108951089610897108981089910900109011090210903109041090510906109071090810909109101091110912109131091410915109161091710918109191092010921109221092310924109251092610927109281092910930109311093210933109341093510936109371093810939109401094110942109431094410945109461094710948109491095010951109521095310954109551095610957109581095910960109611096210963109641096510966109671096810969109701097110972109731097410975109761097710978109791098010981109821098310984109851098610987109881098910990109911099210993109941099510996109971099810999110001100111002110031100411005110061100711008110091101011011110121101311014110151101611017110181101911020110211102211023110241102511026110271102811029110301103111032110331103411035110361103711038110391104011041110421104311044110451104611047110481104911050110511105211053110541105511056110571105811059110601106111062110631106411065110661106711068110691107011071110721107311074110751107611077110781107911080110811108211083110841108511086110871108811089110901109111092110931109411095110961109711098110991110011101111021110311104111051110611107111081110911110111111111211113111141111511116111171111811119111201112111122111231112411125111261112711128111291113011131111321113311134111351113611137111381113911140111411114211143111441114511146111471114811149111501115111152111531115411155111561115711158111591116011161111621116311164111651116611167111681116911170111711117211173111741117511176111771117811179111801118111182111831118411185111861118711188111891119011191111921119311194111951119611197111981119911200112011120211203112041120511206112071120811209112101121111212112131121411215112161121711218112191122011221112221122311224112251122611227112281122911230112311123211233112341123511236112371123811239112401124111242112431124411245112461124711248112491125011251112521125311254112551125611257112581125911260112611126211263112641126511266112671126811269112701127111272112731127411275112761127711278112791128011281112821128311284112851128611287112881128911290112911129211293112941129511296112971129811299113001130111302113031130411305113061130711308113091131011311113121131311314113151131611317113181131911320113211132211323113241132511326113271132811329113301133111332113331133411335113361133711338113391134011341113421134311344113451134611347113481134911350113511135211353113541135511356113571135811359113601136111362113631136411365113661136711368113691137011371113721137311374113751137611377113781137911380113811138211383113841138511386113871138811389113901139111392113931139411395113961139711398113991140011401114021140311404114051140611407114081140911410114111141211413114141141511416114171141811419114201142111422114231142411425114261142711428114291143011431114321143311434114351143611437114381143911440114411144211443114441144511446114471144811449114501145111452114531145411455114561145711458114591146011461114621146311464114651146611467114681146911470114711147211473114741147511476114771147811479114801148111482114831148411485114861148711488114891149011491114921149311494114951149611497114981149911500115011150211503115041150511506115071150811509115101151111512115131151411515115161151711518115191152011521115221152311524115251152611527115281152911530115311153211533115341153511536115371153811539115401154111542115431154411545115461154711548115491155011551115521155311554115551155611557115581155911560115611156211563115641156511566115671156811569115701157111572115731157411575115761157711578115791158011581115821158311584115851158611587115881158911590115911159211593115941159511596115971159811599116001160111602116031160411605116061160711608116091161011611116121161311614116151161611617116181161911620116211162211623116241162511626116271162811629116301163111632116331163411635116361163711638116391164011641116421164311644116451164611647116481164911650116511165211653116541165511656116571165811659116601166111662116631166411665116661166711668116691167011671116721167311674116751167611677116781167911680116811168211683116841168511686116871168811689116901169111692116931169411695116961169711698116991170011701117021170311704117051170611707117081170911710117111171211713117141171511716117171171811719117201172111722117231172411725117261172711728117291173011731117321173311734117351173611737117381173911740117411174211743117441174511746117471174811749117501175111752117531175411755117561175711758117591176011761117621176311764117651176611767117681176911770117711177211773117741177511776117771177811779117801178111782117831178411785117861178711788117891179011791117921179311794117951179611797117981179911800118011180211803118041180511806118071180811809118101181111812118131181411815118161181711818118191182011821118221182311824118251182611827118281182911830118311183211833118341183511836118371183811839118401184111842118431184411845118461184711848118491185011851118521185311854118551185611857118581185911860118611186211863118641186511866118671186811869118701187111872118731187411875118761187711878118791188011881118821188311884118851188611887118881188911890118911189211893118941189511896118971189811899119001190111902119031190411905119061190711908119091191011911119121191311914119151191611917119181191911920119211192211923119241192511926119271192811929119301193111932119331193411935119361193711938119391194011941119421194311944119451194611947119481194911950119511195211953119541195511956119571195811959119601196111962119631196411965119661196711968119691197011971119721197311974119751197611977119781197911980119811198211983119841198511986119871198811989119901199111992119931199411995119961199711998119991200012001120021200312004120051200612007120081200912010120111201212013120141201512016120171201812019120201202112022120231202412025120261202712028120291203012031120321203312034120351203612037120381203912040120411204212043120441204512046120471204812049120501205112052120531205412055120561205712058120591206012061120621206312064120651206612067120681206912070120711207212073120741207512076120771207812079120801208112082120831208412085120861208712088120891209012091120921209312094120951209612097120981209912100121011210212103121041210512106121071210812109121101211112112121131211412115121161211712118121191212012121121221212312124121251212612127121281212912130121311213212133121341213512136121371213812139121401214112142121431214412145121461214712148121491215012151121521215312154121551215612157121581215912160121611216212163121641216512166121671216812169121701217112172121731217412175121761217712178121791218012181121821218312184121851218612187121881218912190121911219212193121941219512196121971219812199122001220112202122031220412205122061220712208122091221012211122121221312214122151221612217122181221912220122211222212223122241222512226122271222812229122301223112232122331223412235122361223712238122391224012241122421224312244122451224612247122481224912250122511225212253122541225512256122571225812259122601226112262122631226412265122661226712268122691227012271122721227312274122751227612277122781227912280122811228212283122841228512286122871228812289122901229112292122931229412295122961229712298122991230012301123021230312304123051230612307123081230912310123111231212313123141231512316123171231812319123201232112322123231232412325123261232712328123291233012331123321233312334123351233612337123381233912340123411234212343123441234512346123471234812349123501235112352123531235412355123561235712358123591236012361123621236312364123651236612367123681236912370123711237212373123741237512376123771237812379123801238112382123831238412385123861238712388123891239012391123921239312394123951239612397123981239912400124011240212403124041240512406124071240812409124101241112412124131241412415124161241712418124191242012421124221242312424124251242612427124281242912430124311243212433124341243512436124371243812439124401244112442124431244412445124461244712448124491245012451124521245312454124551245612457124581245912460124611246212463124641246512466124671246812469124701247112472124731247412475124761247712478124791248012481124821248312484124851248612487124881248912490124911249212493124941249512496124971249812499125001250112502125031250412505125061250712508125091251012511125121251312514125151251612517125181251912520125211252212523125241252512526125271252812529125301253112532125331253412535125361253712538125391254012541125421254312544125451254612547125481254912550125511255212553125541255512556125571255812559125601256112562125631256412565125661256712568125691257012571125721257312574125751257612577125781257912580125811258212583125841258512586125871258812589125901259112592125931259412595125961259712598125991260012601126021260312604126051260612607126081260912610126111261212613126141261512616126171261812619126201262112622126231262412625126261262712628126291263012631126321263312634126351263612637126381263912640126411264212643126441264512646126471264812649126501265112652126531265412655126561265712658126591266012661126621266312664126651266612667126681266912670126711267212673126741267512676126771267812679126801268112682126831268412685126861268712688126891269012691126921269312694126951269612697126981269912700127011270212703127041270512706127071270812709127101271112712127131271412715127161271712718127191272012721127221272312724127251272612727127281272912730127311273212733127341273512736127371273812739127401274112742127431274412745127461274712748127491275012751127521275312754127551275612757127581275912760127611276212763127641276512766127671276812769127701277112772127731277412775127761277712778127791278012781127821278312784127851278612787127881278912790127911279212793127941279512796127971279812799128001280112802128031280412805128061280712808128091281012811128121281312814128151281612817128181281912820128211282212823128241282512826128271282812829128301283112832128331283412835128361283712838128391284012841128421284312844128451284612847128481284912850128511285212853128541285512856128571285812859128601286112862128631286412865128661286712868128691287012871128721287312874128751287612877128781287912880128811288212883128841288512886128871288812889128901289112892128931289412895128961289712898128991290012901129021290312904129051290612907129081290912910129111291212913129141291512916129171291812919129201292112922129231292412925129261292712928129291293012931129321293312934129351293612937129381293912940129411294212943129441294512946129471294812949129501295112952129531295412955129561295712958129591296012961129621296312964129651296612967129681296912970129711297212973129741297512976129771297812979129801298112982129831298412985129861298712988129891299012991129921299312994129951299612997129981299913000130011300213003130041300513006130071300813009130101301113012130131301413015130161301713018130191302013021130221302313024130251302613027130281302913030130311303213033130341303513036130371303813039130401304113042130431304413045130461304713048130491305013051130521305313054130551305613057130581305913060130611306213063130641306513066130671306813069130701307113072130731307413075130761307713078130791308013081130821308313084130851308613087130881308913090130911309213093130941309513096130971309813099131001310113102131031310413105131061310713108131091311013111131121311313114131151311613117131181311913120131211312213123131241312513126131271312813129131301313113132131331313413135131361313713138131391314013141131421314313144131451314613147131481314913150131511315213153131541315513156131571315813159131601316113162131631316413165131661316713168131691317013171131721317313174131751317613177131781317913180131811318213183131841318513186131871318813189131901319113192131931319413195131961319713198131991320013201132021320313204132051320613207132081320913210132111321213213132141321513216132171321813219132201322113222132231322413225132261322713228132291323013231132321323313234132351323613237132381323913240132411324213243132441324513246132471324813249132501325113252132531325413255132561325713258132591326013261132621326313264132651326613267132681326913270132711327213273132741327513276132771327813279132801328113282132831328413285132861328713288132891329013291132921329313294132951329613297132981329913300133011330213303133041330513306133071330813309133101331113312133131331413315133161331713318133191332013321133221332313324133251332613327133281332913330133311333213333133341333513336133371333813339133401334113342133431334413345133461334713348133491335013351133521335313354133551335613357133581335913360133611336213363133641336513366133671336813369133701337113372133731337413375133761337713378133791338013381133821338313384133851338613387133881338913390133911339213393133941339513396133971339813399134001340113402134031340413405134061340713408134091341013411134121341313414134151341613417134181341913420134211342213423134241342513426134271342813429134301343113432134331343413435134361343713438134391344013441134421344313444134451344613447134481344913450134511345213453134541345513456134571345813459134601346113462134631346413465134661346713468134691347013471134721347313474134751347613477134781347913480134811348213483134841348513486134871348813489134901349113492134931349413495134961349713498134991350013501135021350313504135051350613507135081350913510135111351213513135141351513516135171351813519135201352113522135231352413525135261352713528135291353013531135321353313534135351353613537135381353913540135411354213543135441354513546135471354813549135501355113552135531355413555135561355713558135591356013561135621356313564135651356613567135681356913570135711357213573135741357513576135771357813579135801358113582135831358413585135861358713588135891359013591135921359313594135951359613597135981359913600136011360213603136041360513606136071360813609136101361113612136131361413615136161361713618136191362013621136221362313624136251362613627136281362913630136311363213633136341363513636136371363813639136401364113642136431364413645136461364713648136491365013651136521365313654136551365613657136581365913660136611366213663136641366513666136671366813669136701367113672136731367413675136761367713678136791368013681136821368313684136851368613687136881368913690136911369213693136941369513696136971369813699137001370113702137031370413705137061370713708137091371013711137121371313714137151371613717137181371913720137211372213723137241372513726137271372813729137301373113732137331373413735137361373713738137391374013741137421374313744137451374613747137481374913750137511375213753137541375513756137571375813759137601376113762137631376413765137661376713768137691377013771137721377313774137751377613777137781377913780137811378213783137841378513786137871378813789137901379113792137931379413795137961379713798137991380013801138021380313804138051380613807138081380913810138111381213813138141381513816138171381813819138201382113822138231382413825138261382713828138291383013831138321383313834138351383613837138381383913840138411384213843138441384513846138471384813849138501385113852138531385413855138561385713858138591386013861138621386313864138651386613867138681386913870138711387213873138741387513876138771387813879138801388113882138831388413885138861388713888138891389013891138921389313894138951389613897138981389913900139011390213903139041390513906139071390813909139101391113912139131391413915139161391713918139191392013921139221392313924139251392613927139281392913930139311393213933139341393513936139371393813939139401394113942139431394413945139461394713948139491395013951139521395313954139551395613957139581395913960139611396213963139641396513966
  1. /*
  2. copyright (c) 2018 jones
  3. http://www.apache.org/licenses/LICENSE-2.0
  4. 开源项目 https://github.com/jones2000/HQChart
  5. jones_2000@163.com
  6. 封装图形控件 (微信小程序版本)
  7. */
  8. //日志
  9. import { JSConsole } from "./umychart.console.wechat.js"
  10. import { JSNetwork } from "./umychart.network.wechart.js"
  11. import { JSCanvasElement } from "./umychart.element.wechart.js";
  12. //行情数据结构体 及涉及到的行情算法(复权,周期等)
  13. import {
  14. ChartData, HistoryData,
  15. SingleData, MinuteData,
  16. CUSTOM_DAY_PERIOD_START,
  17. CUSTOM_DAY_PERIOD_END,
  18. CUSTOM_MINUTE_PERIOD_START,
  19. CUSTOM_MINUTE_PERIOD_END,
  20. CUSTOM_SECOND_PERIOD_START,
  21. CUSTOM_SECOND_PERIOD_END,
  22. Rect,
  23. DataPlus,g_DataPlus,
  24. JSCHART_EVENT_ID,
  25. JSCHART_DATA_FIELD_ID,
  26. JSCHART_BUTTON_ID,
  27. JSCHART_CORSSCURSOR_STATUS_ID,
  28. PhoneDBClick,
  29. OVERLAY_STATUS_ID,
  30. } from "./umychart.data.wechat.js";
  31. import {
  32. JSKLineInfoMap,
  33. KLINE_INFO_TYPE,
  34. JSMinuteInfoMap,
  35. } from "./umychart.klineinfo.wechat.js";
  36. import
  37. {
  38. JSCommonCoordinateData,
  39. MARKET_SUFFIX_NAME ,
  40. g_FuturesTimeData,
  41. g_NYMEXTimeData,
  42. g_COMEXTimeData,
  43. g_NYBOTTimeData,
  44. g_LMETimeData,
  45. g_CBOTTimeData,
  46. g_TOCOMTimeData,
  47. g_IPETimeData,
  48. GetfloatPrecision,
  49. } from "./umychart.coordinatedata.wechat.js";
  50. import { JSCommonComplier } from "./umychart.complier.wechat.js"; //通达信编译器
  51. import { JSCommonIndexScript, JSIndexScript } from "./umychart.index.data.wechat.js"; //系统指标定义
  52. import { HQIndexFormula } from "./umychart.hqIndexformula.wechat.js"; //通达信编译器
  53. import
  54. {
  55. IChartFramePainting,
  56. AverageWidthFrame,
  57. MinuteFrame,
  58. MinuteHScreenFrame,
  59. ZOOM_SEED,
  60. KLineFrame,
  61. KLineHScreenFrame,
  62. OverlayMinuteFrame,
  63. OverlayMinuteHScreenFrame,
  64. OverlayKLineFrame,
  65. OverlayKLineHScreenFrame,
  66. DepthChartFrame,
  67. } from "./umychart.chartframe.wechat.js"
  68. //图形库
  69. import {
  70. IChartPainting,
  71. ChartSingleText,
  72. ChartKLine,
  73. ChartLine,
  74. ChartSubLine,
  75. ChartPointDot,
  76. ChartStick,
  77. ChartLineStick,
  78. ChartStickLine,
  79. ChartOverlayKLine,
  80. ChartMinuteInfo,
  81. ChartRectangle,
  82. ChartMultiText,
  83. ChartMultiLine,
  84. ChartMultiBar,
  85. ChartCorssCursor,
  86. ChartBuySell,
  87. ChartMACD,
  88. ChartSplashPaint,
  89. ChartBackground,
  90. ChartMinuteVolumBar,
  91. ChartMultiHtmlDom,
  92. ChartLock,
  93. ChartVolStick,
  94. ChartBand,
  95. ChartOverlayMinutePriceLine,
  96. ChartLineMultiData,
  97. ChartStraightLine,
  98. DepthChartCorssCursor,
  99. ChartOrderbookDepth,
  100. ChartMinutePriceLine,
  101. ChartText,
  102. ChartStraightArea,
  103. } from "./umychart.chartpaint.wechat.js";
  104. //扩展画法图形库
  105. import {
  106. IExtendChartPainting,
  107. KLineTooltipPaint,
  108. BarragePaint,
  109. MinuteTooltipPaint,
  110. BackgroundPaint,
  111. StockChipPhone,
  112. g_ExtendChartPaintFactory,
  113. } from "./umychart.extendchart.wechat.js";
  114. import {
  115. IndexInfo,
  116. BaseIndex,
  117. ScriptIndex,
  118. APIScriptIndex,
  119. OverlayScriptIndex,
  120. MarketLongShortIndex,
  121. MarketTimingIndex,
  122. MarketAttentionIndex,
  123. MarketHeatIndex,
  124. CustonIndexHeatIndex,
  125. BenfordIndex,
  126. } from './umychart.index.wechat.js'
  127. import{
  128. g_JSChartResource,
  129. JSCHART_LANGUAGE_ID,
  130. g_JSChartLocalization,
  131. } from './umychart.resource.wechat.js'
  132. import
  133. {
  134. CoordinateInfo,
  135. IFrameSplitOperator,
  136. FrameSplitKLinePriceY,
  137. FrameSplitY,
  138. FrameSplitKLineX,
  139. FrameSplitMinutePriceY,
  140. FrameSplitMinuteX,
  141. FrameSplitXData,
  142. SplitData,
  143. PriceSplitData,
  144. FrameSplitXDepth,
  145. IChangeStringFormat,
  146. HQPriceStringFormat,
  147. HQDateStringFormat,
  148. HQMinuteTimeStringFormat,
  149. g_DivTooltipDataForamt,
  150. } from './umychart.framesplit.wechat.js'
  151. import
  152. {
  153. IChartTitlePainting,
  154. DynamicKLineTitlePainting,
  155. DynamicMinuteTitlePainting,
  156. DynamicChartTitlePainting,
  157. DynamicTitleData,
  158. STRING_FORMAT_TYPE,
  159. } from './umychart.charttitle.wechat.js'
  160. import
  161. {
  162. IChartDrawPicture,
  163. } from "./umychart.ChartDrawPicture.wechart.js"
  164. import { HQCHART_VERSION } from "./umychart.version.wechat.js"
  165. function JSChart(element)
  166. {
  167. this.JSChartContainer; //画图控件
  168. this.CanvasElement = element;
  169. this.AddEventCallback = function (obj) //事件回调 {event:事件id, callback:回调函数}
  170. {
  171. if (this.JSChartContainer && typeof (this.JSChartContainer.AddEventCallback) == 'function')
  172. {
  173. JSConsole.Chart.Log('[JSChart:AddEventCallback] ', obj);
  174. this.JSChartContainer.AddEventCallback(obj);
  175. }
  176. }
  177. //设置语言 'EN', 'CN'
  178. this.SetLanguage=function(language)
  179. {
  180. if(this.JSChartContainer && typeof(this.JSChartContainer.SetLanguage)=='function')
  181. {
  182. JSConsole.Chart.Log('[JSChart:SetLanguage] ', language);
  183. this.JSChartContainer.SetLanguage(language);
  184. }
  185. }
  186. this.OnSize = function (option)
  187. {
  188. if (option)
  189. {
  190. if (IFrameSplitOperator.IsNumber(option.Width)) this.CanvasElement.Width=option.Width;
  191. if (IFrameSplitOperator.IsNumber(option.Height)) this.CanvasElement.Height=option.Height;
  192. }
  193. if (option && option.Redraw==false) return;
  194. if (this.JSChartContainer)
  195. {
  196. if (option && option.Type==1 && this.JSChartContainer.OnSize)
  197. {
  198. this.JSChartContainer.OnSize();
  199. }
  200. else
  201. {
  202. if (this.JSChartContainer.Frame) this.JSChartContainer.Frame.SetSizeChange(true);
  203. this.JSChartContainer.Draw();
  204. }
  205. }
  206. }
  207. this.SetChartBorder=function(chart, option)
  208. {
  209. if (!option.Border) return;
  210. var item=option.Border;
  211. if (IFrameSplitOperator.IsNumber(option.Border.Left)) chart.Frame.ChartBorder.Left=option.Border.Left;
  212. else option.Border.Left=chart.Frame.ChartBorder.Left;
  213. if (IFrameSplitOperator.IsNumber(option.Border.Right)) chart.Frame.ChartBorder.Right=option.Border.Right;
  214. else option.Border.Right=chart.Frame.ChartBorder.Right;
  215. if (IFrameSplitOperator.IsNumber(option.Border.Top)) chart.Frame.ChartBorder.Top=option.Border.Top;
  216. else option.Border.Top=chart.Frame.ChartBorder.Top;
  217. if (IFrameSplitOperator.IsNumber(option.Border.Bottom)) chart.Frame.ChartBorder.Bottom=option.Border.Bottom;
  218. else option.Border.Bottom=chart.Frame.ChartBorder.Bottom;
  219. if (item.AutoLeft)
  220. {
  221. chart.Frame.AutoLeftBorder={ };
  222. if (IFrameSplitOperator.IsNumber(item.AutoLeft.Blank)) chart.Frame.AutoLeftBorder.Blank=item.AutoLeft.Blank;
  223. if (IFrameSplitOperator.IsNumber(item.AutoLeft.MinWidth)) chart.Frame.AutoLeftBorder.MinWidth=item.AutoLeft.MinWidth;
  224. }
  225. if (item.AutoRight)
  226. {
  227. chart.Frame.AutoRightBorder={ };
  228. if (IFrameSplitOperator.IsNumber(item.AutoRight.Blank)) chart.Frame.AutoRightBorder.Blank=item.AutoRight.Blank;
  229. if (IFrameSplitOperator.IsNumber(item.AutoRight.MinWidth)) chart.Frame.AutoRightBorder.MinWidth=item.AutoRight.MinWidth;
  230. }
  231. }
  232. //缺口设置 KLine:{ PriceGap:{ Enable, Count } }
  233. this.SetPriceGapConfig=function(chart, option)
  234. {
  235. if (!option || !option.PriceGap) return;
  236. var klineChart=chart.ChartPaint[0];
  237. if (!klineChart) return;
  238. var item=option.PriceGap;
  239. if (IFrameSplitOperator.IsBool(item.Enable)) klineChart.PriceGap.Enable=item.Enable;
  240. if (IFrameSplitOperator.IsNumber(item.Count)) klineChart.PriceGap.Count=item.Count;
  241. }
  242. this.SetFastSlideConfig=function(chart, option)
  243. {
  244. if (!option.FastSlide) return;
  245. var item=option.FastSlide;
  246. if (IFrameSplitOperator.IsNumber(item.MinDistance)) chart.FastSlideConfig.MinDistance=item.MinDistance;
  247. if (IFrameSplitOperator.IsNumber(item.MinSpeed)) chart.FastSlideConfig.MinSpeed=item.MinSpeed;
  248. if (IFrameSplitOperator.IsNumber(item.MaxTime)) chart.FastSlideConfig.MaxTime=item.MaxTime;
  249. if (IFrameSplitOperator.IsBool(item.Enable)) chart.FastSlideConfig.Enable=item.Enable;
  250. }
  251. this.SetDataMoveConfig=function(chart, option)
  252. {
  253. if (!option.DataMove) return;
  254. var item=option.DataMove;
  255. if (item.Touch)
  256. {
  257. var subItem=item.Touch;
  258. if (IFrameSplitOperator.IsBool(subItem.EnableLR)) chart.DataMoveConfig.Touch.EnableLR=subItem.EnableLR;
  259. }
  260. }
  261. this.SetCorssCursorConfig=function(chart, option)
  262. {
  263. if (!option || !option.CorssCursorInfo) return;
  264. var item=option.CorssCursorInfo;
  265. if (IFrameSplitOperator.IsNumber(item.Left)) chart.ChartCorssCursor.ShowTextMode.Left = item.Left;
  266. if (IFrameSplitOperator.IsNumber(item.Right)) chart.ChartCorssCursor.ShowTextMode.Right = item.Right;
  267. if (IFrameSplitOperator.IsNumber(item.Bottom)) chart.ChartCorssCursor.ShowTextMode.Bottom = item.Bottom;
  268. if (IFrameSplitOperator.IsBool(item.IsShowCorss)) chart.ChartCorssCursor.IsShowCorss = item.IsShowCorss;
  269. if (IFrameSplitOperator.IsNumber(item.HPenType)) chart.ChartCorssCursor.HPenType = item.HPenType;
  270. if (IFrameSplitOperator.IsNumber(item.VPenType)) chart.ChartCorssCursor.VPenType = item.VPenType;
  271. if (IFrameSplitOperator.IsNumber(item.PriceFormatType)) chart.ChartCorssCursor.StringFormatY.PriceFormatType=item.PriceFormatType;
  272. if (IFrameSplitOperator.IsNumber(item.DataFormatType)) chart.ChartCorssCursor.StringFormatY.DataFormatType=item.DataFormatType;
  273. if (IFrameSplitOperator.IsBool(item.IsShowCorssPoint)) chart.ChartCorssCursor.CorssPointConfig.Enable=item.IsShowCorssPoint;
  274. if (item.YDecimals) //Y轴文字小数位数
  275. {
  276. var subItem=item.YDecimals;
  277. if (IFrameSplitOperator.IsNumber(subItem.Value)) chart.ChartCorssCursor.StringFormatY.DecimalsConfig.Value=subItem.Value;
  278. if (IFrameSplitOperator.IsNumber(subItem.Type)) chart.ChartCorssCursor.StringFormatY.DecimalsConfig.Type=subItem.Type;
  279. }
  280. }
  281. //历史K线图
  282. this.CreateKLineChartContainer = function (option)
  283. {
  284. var chart = null;
  285. if (option.Type === "历史K线图横屏") chart = new KLineChartHScreenContainer(this.CanvasElement);
  286. else chart = new KLineChartContainer(this.CanvasElement);
  287. if (option.NetworkFilter) chart.NetworkFilter = option.NetworkFilter;
  288. if (option.KLine) //k线图的属性设置
  289. {
  290. if (option.KLine.DragMode >= 0) chart.DragMode = option.KLine.DragMode;
  291. if (option.KLine.Right >= 0) chart.Right = option.KLine.Right;
  292. if (option.KLine.Period >= 0) chart.Period = option.KLine.Period;
  293. if (option.KLine.MaxRequestDataCount > 0) chart.MaxRequestDataCount = option.KLine.MaxRequestDataCount;
  294. if (option.KLine.Info && option.KLine.Info.length > 0) chart.SetKLineInfo(option.KLine.Info, false);
  295. if (option.KLine.Policy && option.KLine.Policy.length > 0) chart.SetPolicyInfo(option.KLine.Policy, false);
  296. if (option.KLine.KLineDoubleClick == false) chart.MinuteDialog = this.MinuteDialog = null;
  297. if (option.KLine.MaxRequestMinuteDayCount > 0) chart.MaxRequestMinuteDayCount = option.KLine.MaxRequestMinuteDayCount;
  298. if (option.KLine.DrawType) chart.KLineDrawType = option.KLine.DrawType;
  299. if (option.KLine.RightSpaceCount >= 0) chart.RightSpaceCount = option.KLine.RightSpaceCount;
  300. if (option.KLine.DataWidth>=1) chart.KLineSize={ DataWidth:option.KLine.DataWidth };
  301. if (IFrameSplitOperator.IsNumber(option.KLine.RightFormula)) chart.RightFormula=option.KLine.RightFormula;
  302. }
  303. if (IFrameSplitOperator.IsString(option.SplashTitle)) chart.LoadDataSplashTitle = option.SplashTitle; //设置提示信息内容
  304. if (IFrameSplitOperator.IsBool(option.EnableZoomIndexWindow)) chart.EnableZoomIndexWindow=option.EnableZoomIndexWindow; //双击缩放附图
  305. if (!option.Windows || option.Windows.length <= 0) return null;
  306. if (option.Language)
  307. {
  308. var value=g_JSChartLocalization.GetLanguageID(option.Language);
  309. if (IFrameSplitOperator.IsNumber(value)) chart.LanguageID=value;
  310. }
  311. if (option.SourceDatatLimit) chart.SetSourceDatatLimit(option.SourceDatatLimit);
  312. if (option.EnableZoomUpDown) chart.EnableZoomUpDown=option.EnableZoomUpDown;
  313. if (option.EnableMoveData) chart.EnableMoveData=option.EnableMoveData;
  314. if (option.TouchMoveMinAngle) chart.TouchMoveMinAngle=option.TouchMoveMinAngle;
  315. if (IFrameSplitOperator.IsBool(option.EnableScrollUpDown)) chart.EnableScrollUpDown=option.EnableScrollUpDown;
  316. if (option.ZoomStepPixel>0) chart.ZoomStepPixel=option.ZoomStepPixel;
  317. if (IFrameSplitOperator.IsNumber(option.DrawMoveWaitTime)) chart.DrawMoveWaitTime=option.DrawMoveWaitTime;
  318. if (IFrameSplitOperator.IsNumber(option.PressTime)) chart.PressTime=option.PressTime;
  319. this.SetFastSlideConfig(chart, option);
  320. this.SetDataMoveConfig(chart, option);
  321. //创建子窗口
  322. chart.Create(option.Windows.length);
  323. this.SetChartBorder(chart, option);
  324. if (option.KLine)
  325. {
  326. var item=option.KLine;
  327. var klineChart=chart.ChartPaint[0];
  328. if (option.KLine.PageSize > 0)
  329. {
  330. let maxPageSize = chart.GetMaxPageSize();
  331. if (maxPageSize < option.KLine.PageSize) chart.PageSize = maxPageSize;
  332. else chart.PageSize = option.KLine.PageSize;
  333. JSConsole.Chart.Log(`[JSChart:CreateKLineChartContainer] PageSize=${option.KLine.PageSize}, MaxPageSize=${maxPageSize}`, );
  334. }
  335. if (option.KLine.InfoDrawType) chart.ChartPaint[0].InfoDrawType = option.KLine.InfoDrawType;
  336. if (IFrameSplitOperator.IsNumber(item.OneLimitBarType)) klineChart.OneLimitBarType=item.OneLimitBarType;
  337. }
  338. if (option.DragDownload)
  339. {
  340. if (option.DragDownload.Day && option.DragDownload.Day.Enable == true) chart.DragDownload.Day.Enable = true;
  341. if (option.DragDownload.Minute && option.DragDownload.Minute.Enable == true) chart.DragDownload.Minute.Enable = true;
  342. }
  343. if (option.IsApiPeriod == true) chart.IsApiPeriod = option.IsApiPeriod;
  344. if (option.CorssCursorTouchEnd == true) chart.CorssCursorTouchEnd = option.CorssCursorTouchEnd;
  345. if (option.IsClickShowCorssCursor == true) chart.IsClickShowCorssCursor = option.IsClickShowCorssCursor;
  346. if (option.IsFullDraw == true) chart.IsFullDraw = option.IsFullDraw;
  347. this.SetCorssCursorConfig(chart, option);
  348. if (option.CorssCursorInfo)
  349. {
  350. var item=option.CorssCursorInfo;
  351. if (IFrameSplitOperator.IsBool(item.IsShowClose)) chart.ChartCorssCursor.IsShowClose = item.IsShowClose; //Y轴显示收盘价
  352. }
  353. if (typeof (option.UpdateUICallback) == 'function') //数据到达回调
  354. chart.UpdateUICallback = option.UpdateUICallback;
  355. if (IFrameSplitOperator.IsNonEmptyArray(option.Frame))
  356. {
  357. for (var i=0; i<option.Frame.length;++i)
  358. {
  359. var item = option.Frame[i];
  360. if (!chart.Frame.SubFrame[i]) continue;
  361. chart.SetSubFrameAttribute(chart.Frame.SubFrame[i],null,item);
  362. }
  363. }
  364. if (option.KLine)
  365. {
  366. var item=option.KLine;
  367. var klineChart=chart.ChartPaint[0];
  368. if (IFrameSplitOperator.IsBool(item.ShowKLine)) klineChart.IsShow = item.ShowKLine;
  369. if (IFrameSplitOperator.IsBool(item.IsShowMaxMinPrice)) klineChart.IsShowMaxMinPrice = item.IsShowMaxMinPrice;
  370. this.SetPriceGapConfig(chart, option.KLine);
  371. }
  372. if (option.KLineTitle)
  373. {
  374. var item=option.KLineTitle;
  375. var chartTitle=chart.TitlePaint[0];
  376. if (option.KLineTitle.IsShowName == false) chart.TitlePaint[0].IsShowName = false;
  377. if (option.KLineTitle.IsShowSettingInfo == false) chart.TitlePaint[0].IsShowSettingInfo = false;
  378. if (option.KLineTitle.IsShow == false) chart.TitlePaint[0].IsShow = false;
  379. if (IFrameSplitOperator.IsBool(item.IsShowDateTime)) chartTitle.IsShowDateTime=item.IsShowDateTime;
  380. if (option.KLineTitle.UpdateUICallback) chart.TitlePaint[0].UpdateUICallback = option.KLineTitle.UpdateUICallback
  381. if (IFrameSplitOperator.IsPlusNumber(item.LineCount)) chartTitle.LineCount = item.LineCount;
  382. if (IFrameSplitOperator.IsPlusNumber(item.ColumnCount)) chartTitle.ColumnCount = item.ColumnCount;
  383. if (IFrameSplitOperator.IsNumber(item.TextSpace)) chart.TitlePaint[0].TextSpace=item.TextSpace;
  384. if (IFrameSplitOperator.IsNumber(item.PeriodSpace)) chart.TitlePaint[0].PeriodSpace=item.PeriodSpace;
  385. if (IFrameSplitOperator.IsNumber(item.DateTimeSpace)) chart.TitlePaint[0].DateTimeSpace=item.DateTimeSpace;
  386. if (IFrameSplitOperator.IsNumber(item.NameSpace)) chart.TitlePaint[0].NameSpace=item.NameSpace;
  387. if (item.ShowPostion) //显示位置高级配置
  388. {
  389. var subItem=item.ShowPostion;
  390. if (!chartTitle.ShowPositionConfig) chartTitle.ShowPositionConfig={ Margin:{ } };
  391. if (IFrameSplitOperator.IsNumber(subItem.Type)) chartTitle.ShowPositionConfig.Type=subItem.Type;
  392. if (subItem.Margin)
  393. {
  394. if (IFrameSplitOperator.IsNumber(subItem.Margin.Left)) chartTitle.ShowPositionConfig.Margin.Left=subItem.Margin.Left;
  395. if (IFrameSplitOperator.IsNumber(subItem.Margin.Right)) chartTitle.ShowPositionConfig.Margin.Right=subItem.Margin.Right;
  396. if (IFrameSplitOperator.IsNumber(subItem.Margin.Bottom)) chartTitle.ShowPositionConfig.Margin.Bottom=subItem.Margin.Bottom;
  397. if (IFrameSplitOperator.IsNumber(subItem.Margin.Top)) chartTitle.ShowPositionConfig.Margin.Top=subItem.Margin.Top;
  398. }
  399. }
  400. }
  401. //叠加股票 只支持叠加1个股票
  402. if (option.Overlay)
  403. {
  404. for (var i=0;i<option.Overlay.length;++i )
  405. {
  406. var item = option.Overlay[i];
  407. chart.OverlaySymbol(item.Symbol,item);
  408. }
  409. }
  410. if (option.ExtendChart) //创建扩展画法
  411. {
  412. for (var i in option.ExtendChart)
  413. {
  414. var item = option.ExtendChart[i];
  415. chart.CreateExtendChart(item.Name, item);
  416. }
  417. }
  418. let scriptData = new JSCommonIndexScript.JSIndexScript(); //系统指标
  419. if (option.ColorIndex) //五彩K线
  420. {
  421. var item = option.ColorIndex;
  422. let indexInfo = scriptData.Get(item.Index);
  423. if (indexInfo) chart.ColorIndex = new ScriptIndex(indexInfo.Name, indexInfo.Script, indexInfo.Args, indexInfo); //脚本执行
  424. }
  425. if (option.TradeIndex) //交易指标
  426. {
  427. var item = option.TradeIndex;
  428. let indexInfo = scriptData.Get(item.Index);
  429. if (indexInfo) chart.TradeIndex = new ScriptIndex(indexInfo.Name, indexInfo.Script, indexInfo.Args, indexInfo); //脚本执行
  430. }
  431. for (var i=0; i<option.Windows.length; ++i) //创建子窗口的指标
  432. {
  433. var item = option.Windows[i];
  434. if (item.Script)
  435. {
  436. chart.WindowIndex[i] = new ScriptIndex(item.Name, item.Script, item.Args, item); //脚本执行
  437. }
  438. else if (item.API) //使用API挂接指标数据 API:{ Name:指标名字, Script:指标脚本可以为空, Args:参数可以为空, Url:指标执行地址 }
  439. {
  440. var apiItem = item.API;
  441. chart.WindowIndex[i] = new APIScriptIndex(apiItem.Name, apiItem.Script, apiItem.Args, item);
  442. }
  443. else
  444. {
  445. var indexItem = JSIndexMap.Get(item.Index); //自定义指标
  446. if (indexItem)
  447. {
  448. chart.WindowIndex[i] = indexItem.Create();
  449. chart.CreateWindowIndex(i);
  450. }
  451. else //系统指标里查找
  452. {
  453. let indexInfo = scriptData.Get(item.Index);
  454. if (!indexInfo) continue;
  455. JSIndexScript.ModifyAttribute(indexInfo, item);
  456. indexInfo.ID = item.Index;
  457. chart.WindowIndex[i] = new ScriptIndex(indexInfo.Name, indexInfo.Script, indexInfo.Args, indexInfo); //脚本执行
  458. if (item.StringFormat > 0) chart.WindowIndex[i].StringFormat = item.StringFormat;
  459. if (item.FloatPrecision >= 0) chart.WindowIndex[i].FloatPrecision = item.FloatPrecision;
  460. }
  461. }
  462. chart.SetSubFrameAttribute(chart.Frame.SubFrame[i], item, null);
  463. }
  464. //叠加指标
  465. if (IFrameSplitOperator.IsNonEmptyArray(option.OverlayIndex))
  466. {
  467. for(var i=0;i<option.OverlayIndex.length;++i)
  468. {
  469. var item=option.OverlayIndex[i];
  470. if (item.Windows>=chart.Frame.SubFrame.length) continue;
  471. var itemString = JSON.stringify(item);
  472. var obj = JSON.parse(itemString);
  473. if (item.Index) obj.IndexName=item.Index;
  474. if (item.Windows>=0) obj.WindowIndex=item.Windows;
  475. chart.CreateOverlayWindowsIndex(obj);
  476. }
  477. }
  478. return chart;
  479. }
  480. //自定义指数历史K线图
  481. this.CreateCustomKLineChartContainer = function (option) {
  482. var chart = new CustomKLineChartContainer(this.CanvasElement);
  483. if (option.KLine) //k线图的属性设置
  484. {
  485. if (option.KLine.DragMode >= 0) chart.DragMode = option.KLine.DragMode;
  486. if (option.KLine.Right >= 0) chart.Right = option.KLine.Right;
  487. if (option.KLine.Period >= 0) chart.Period = option.KLine.Period;
  488. if (option.KLine.MaxRequestDataCount > 0) chart.MaxRequestDataCount = option.KLine.MaxRequestDataCount;
  489. if (option.KLine.Info && option.KLine.Info.length > 0) chart.SetKLineInfo(option.KLine.Info, false);
  490. if (option.KLine.KLineDoubleClick == false) chart.MinuteDialog = this.MinuteDialog = null;
  491. if (option.KLine.PageSize > 0) chart.PageSize = option.KLine.PageSize;
  492. if (option.KLine.IsShowTooltip == false) chart.IsShowTooltip = false;
  493. }
  494. if (option.CustomStock) chart.CustomStock = option.CustomStock;
  495. if (option.QueryDate) chart.QueryDate = option.QueryDate;
  496. if (typeof (option.UpdateUICallback) == 'function') chart.UpdateUICallback = option.UpdateUICallback;
  497. if (!option.Windows || option.Windows.length <= 0) return null;
  498. //创建子窗口
  499. chart.Create(option.Windows.length);
  500. if (option.Border) {
  501. if (!isNaN(option.Border.Left)) chart.Frame.ChartBorder.Left = option.Border.Left;
  502. if (!isNaN(option.Border.Right)) chart.Frame.ChartBorder.Right = option.Border.Right;
  503. if (!isNaN(option.Border.Top)) chart.Frame.ChartBorder.Top = option.Border.Top;
  504. if (!isNaN(option.Border.Bottom)) chart.Frame.ChartBorder.Bottom = option.Border.Bottom;
  505. }
  506. if (option.IsShowCorssCursorInfo == false) //取消显示十字光标刻度信息
  507. {
  508. chart.ChartCorssCursor.IsShowText = option.IsShowCorssCursorInfo;
  509. }
  510. if (option.Frame) {
  511. for (var i in option.Frame) {
  512. var item = option.Frame[i];
  513. if (item.SplitCount) chart.Frame.SubFrame[i].Frame.YSplitOperator.SplitCount = item.SplitCount;
  514. if (item.StringFormat) chart.Frame.SubFrame[i].Frame.YSplitOperator.StringFormat = item.StringFormat;
  515. if (item.XMessageAlign == 'bottom') chart.Frame.SubFrame[i].Frame.XMessageAlign = item.XMessageAlign;
  516. }
  517. }
  518. if (option.KLineTitle) {
  519. if (option.KLineTitle.IsShowName == false) chart.TitlePaint[0].IsShowName = false;
  520. if (option.KLineTitle.IsShowSettingInfo == false) chart.TitlePaint[0].IsShowSettingInfo = false;
  521. }
  522. //创建子窗口的指标
  523. let scriptData = new JSCommonIndexScript.JSIndexScript();
  524. for (var i in option.Windows) {
  525. var item = option.Windows[i];
  526. if (item.Script) {
  527. chart.WindowIndex[i] = new ScriptIndex(item.Name, item.Script, item.Args, item); //脚本执行
  528. }
  529. else {
  530. var indexItem = JSIndexMap.Get(item.Index);
  531. if (indexItem) {
  532. chart.WindowIndex[i] = indexItem.Create();
  533. chart.CreateWindowIndex(i);
  534. }
  535. else //系统指标里查找
  536. {
  537. let indexInfo = scriptData.Get(item.Index);
  538. if (!indexInfo) continue;
  539. if (item.Lock) indexInfo.Lock = item.Lock;
  540. chart.WindowIndex[i] = new ScriptIndex(indexInfo.Name, indexInfo.Script, indexInfo.Args, indexInfo); //脚本执行
  541. }
  542. }
  543. if (item.Modify != null)
  544. chart.Frame.SubFrame[i].Frame.ModifyIndex = item.Modify;
  545. if (item.Change != null)
  546. chart.Frame.SubFrame[i].Frame.ChangeIndex = item.Change;
  547. if (!isNaN(item.TitleHeight)) chart.Frame.SubFrame[i].Frame.ChartBorder.TitleHeight = item.TitleHeight;
  548. }
  549. return chart;
  550. }
  551. //分钟走势图
  552. this.CreateMinuteChartContainer = function (option)
  553. {
  554. var chart = null;
  555. if (option.Type === "分钟走势图横屏") chart = new MinuteChartHScreenContainer(this.CanvasElement);
  556. else chart = new MinuteChartContainer(this.CanvasElement);
  557. if (option.NetworkFilter) chart.NetworkFilter = option.NetworkFilter;
  558. var windowsCount = 2;
  559. if (option.Windows && option.Windows.length > 0) windowsCount += option.Windows.length; //指标窗口从第3个窗口开始
  560. if (option.TouchMoveMinAngle) chart.TouchMoveMinAngle=option.TouchMoveMinAngle;
  561. if (IFrameSplitOperator.IsBool(option.EnableScrollUpDown)) chart.EnableScrollUpDown=option.EnableScrollUpDown;
  562. if (option.Info && option.Info.length > 0) chart.SetMinuteInfo(option.Info, false);
  563. if (IFrameSplitOperator.IsString(option.SplashTitle)) chart.LoadDataSplashTitle = option.SplashTitle; //设置提示信息内容
  564. if (IFrameSplitOperator.IsBool(option.EnableZoomIndexWindow)) chart.EnableZoomIndexWindow=option.EnableZoomIndexWindow; //双击缩放附图
  565. if (IFrameSplitOperator.IsNumber(option.DrawMoveWaitTime)) chart.DrawMoveWaitTime=option.DrawMoveWaitTime;
  566. if (IFrameSplitOperator.IsNumber(option.PressTime)) chart.PressTime=option.PressTime;
  567. if (IFrameSplitOperator.IsBool(option.EnableNightDayBG)) chart.EnableNightDayBG=option.EnableNightDayBG;
  568. if (option.Language)
  569. {
  570. var value=g_JSChartLocalization.GetLanguageID(option.Language);
  571. if (IFrameSplitOperator.IsNumber(value)) chart.LanguageID=value;
  572. }
  573. this.SetFastSlideConfig(chart, option);
  574. chart.Create(windowsCount); //创建子窗口
  575. if (option.CorssCursorTouchEnd == true) chart.CorssCursorTouchEnd = option.CorssCursorTouchEnd;
  576. if (IFrameSplitOperator.IsBool(option.IsClickShowCorssCursor)) chart.IsClickShowCorssCursor = option.IsClickShowCorssCursor;
  577. if (option.IsFullDraw == true) chart.IsFullDraw = option.IsFullDraw;
  578. this.SetCorssCursorConfig(chart, option);
  579. if (option.CorssCursorInfo) //十字光标设置
  580. {
  581. var item=option.CorssCursorInfo;
  582. if (IFrameSplitOperator.IsBool(option.CorssCursorInfo.IsFixXLastTime)) chart.ChartCorssCursor.IsFixXLastTime=option.CorssCursorInfo.IsFixXLastTime;
  583. if (IFrameSplitOperator.IsNumber(item.RightTextFormat)) chart.ChartCorssCursor.TextFormat.Right=item.RightTextFormat;
  584. if (IFrameSplitOperator.IsBool(item.IsOnlyDrawMinute)) chart.ChartCorssCursor.IsOnlyDrawMinute = item.IsOnlyDrawMinute; //Y轴显示收盘价
  585. }
  586. if (option.MinuteInfo) chart.CreateMinuteInfo(option.MinuteInfo);
  587. if (option.DayCount > 1) chart.DayCount = option.DayCount;
  588. this.SetChartBorder(chart, option);
  589. if (option.Frame)
  590. {
  591. for (var i=0 ;i<option.Frame.length;++i)
  592. {
  593. var item = option.Frame[i];
  594. if (!chart.Frame.SubFrame[i]) continue;
  595. chart.SetSubFrameAttribute(chart.Frame.SubFrame[i], null, item);
  596. }
  597. chart.UpdateXShowText();
  598. }
  599. if (option.MinuteTitle)
  600. {
  601. var item=option.MinuteTitle;
  602. var chartTitle= chart.TitlePaint[0];
  603. if (option.MinuteTitle.IsShowName == false) chart.TitlePaint[0].IsShowName = false;
  604. if (option.MinuteTitle.IsShow == false) chart.TitlePaint[0].IsShow = false;
  605. if (option.MinuteTitle.UpdateUICallback) chart.TitlePaint[0].UpdateUICallback = option.MinuteTitle.UpdateUICallback
  606. if (IFrameSplitOperator.IsPlusNumber(item.LineCount)) chartTitle.LineCount = item.LineCount;
  607. if (IFrameSplitOperator.IsPlusNumber(item.ColumnCount)) chartTitle.ColumnCount =item.ColumnCount;
  608. if (IFrameSplitOperator.IsNumber(item.TextSpace)) chart.TitlePaint[0].TextSpace=item.TextSpace;
  609. if (item.ShowPostion) //显示位置高级配置
  610. {
  611. var subItem=item.ShowPostion;
  612. if (!chartTitle.ShowPositionConfig) chartTitle.ShowPositionConfig={ Margin:{ } };
  613. if (IFrameSplitOperator.IsNumber(subItem.Type)) chartTitle.ShowPositionConfig.Type=subItem.Type;
  614. if (subItem.Margin)
  615. {
  616. if (IFrameSplitOperator.IsNumber(subItem.Margin.Left)) chartTitle.ShowPositionConfig.Margin.Left=subItem.Margin.Left;
  617. if (IFrameSplitOperator.IsNumber(subItem.Margin.Right)) chartTitle.ShowPositionConfig.Margin.Right=subItem.Margin.Right;
  618. if (IFrameSplitOperator.IsNumber(subItem.Margin.Bottom)) chartTitle.ShowPositionConfig.Margin.Bottom=subItem.Margin.Bottom;
  619. if (IFrameSplitOperator.IsNumber(subItem.Margin.Top)) chartTitle.ShowPositionConfig.Margin.Top=subItem.Margin.Top;
  620. }
  621. }
  622. }
  623. if (option.MinuteVol)
  624. {
  625. var item=option.MinuteVol;
  626. if (IFrameSplitOperator.IsNumber(item.BarColorType)) chart.ChartPaint[2].BarColorType=item.BarColorType;
  627. }
  628. if (typeof (option.UpdateUICallback) == 'function') //数据到达回调
  629. chart.UpdateUICallback = option.UpdateUICallback;
  630. if (option.ExtendChart) //创建扩展画法
  631. {
  632. for (var i in option.ExtendChart) {
  633. var item = option.ExtendChart[i];
  634. chart.CreateExtendChart(item.Name, item);
  635. }
  636. }
  637. //叠加股票 只支持1只股票
  638. if (IFrameSplitOperator.IsNonEmptyArray(option.Overlay))
  639. {
  640. for (var i=0;i<option.Overlay.length; ++i)
  641. {
  642. var item = option.Overlay[i];
  643. chart.OverlaySymbol(item.Symbol,item);
  644. }
  645. }
  646. if (option.MinuteLine)
  647. {
  648. if (option.MinuteLine.IsDrawAreaPrice == false) chart.ChartPaint[0].IsDrawArea = false;
  649. if (option.MinuteLine.IsShowAveragePrice == false)
  650. {
  651. chart.ChartPaint[1].IsShow = false;
  652. chart.TitlePaint[0].IsShowAveragePrice=false; //标题栏均线也不显示
  653. for(var i in chart.ExtendChartPaint)
  654. {
  655. var item=chart.ExtendChartPaint[i];
  656. if (item.ClassName=="MinuteTooltipPaint") item.IsShowAveragePrice=false;
  657. }
  658. }
  659. if (option.MinuteLine.SplitType>0) chart.Frame.SubFrame[0].Frame.YSplitOperator.SplitType=option.MinuteLine.SplitType;
  660. }
  661. let scriptData = new JSCommonIndexScript.JSIndexScript();
  662. for (var i=0; i<option.Windows.length; ++i) //分钟数据指标从第3个指标窗口设置
  663. {
  664. var index=i+2;
  665. var item = option.Windows[i];
  666. if (item.Script)
  667. {
  668. chart.WindowIndex[2+i] = new ScriptIndex(item.Name, item.Script, item.Args, item); //脚本执行
  669. }
  670. else if (item.API) //使用API挂接指标数据 API:{ Name:指标名字, Script:指标脚本可以为空, Args:参数可以为空, Url:指标执行地址 }
  671. {
  672. var apiItem = item.API;
  673. chart.WindowIndex[2+i] = new APIScriptIndex(apiItem.Name, apiItem.Script, apiItem.Args, item);
  674. }
  675. else
  676. {
  677. var indexItem = JSIndexMap.Get(item.Index);
  678. if (indexItem)
  679. {
  680. chart.WindowIndex[2+i] = indexItem.Create(); //创建子窗口的指标
  681. chart.CreateWindowIndex(index);
  682. }
  683. else
  684. {
  685. let indexInfo = scriptData.Get(item.Index);
  686. if (!indexInfo) continue;
  687. JSIndexScript.ModifyAttribute(indexInfo, item);
  688. indexInfo.ID=item.Index;
  689. chart.WindowIndex[2+i] = new ScriptIndex(indexInfo.Name, indexInfo.Script, indexInfo.Args, indexInfo); //脚本执行
  690. if (item.StringFormat > 0) chart.WindowIndex[index].StringFormat = item.StringFormat;
  691. if (item.FloatPrecision >= 0) chart.WindowIndex[index].FloatPrecision = item.FloatPrecision;
  692. }
  693. }
  694. chart.SetSubFrameAttribute(chart.Frame.SubFrame[index], item, null);
  695. }
  696. //叠加指标
  697. if (IFrameSplitOperator.IsNonEmptyArray(option.OverlayIndex))
  698. {
  699. for(var i=0;i<option.OverlayIndex.length;++i)
  700. {
  701. var item=option.OverlayIndex[i];
  702. if (item.Windows>=chart.Frame.SubFrame.length) continue;
  703. var itemString = JSON.stringify(item);
  704. var obj = JSON.parse(itemString);
  705. if (item.Index) obj.IndexName=item.Index;
  706. if (item.Windows>=0) obj.WindowIndex=item.Windows;
  707. chart.CreateOverlayWindowsIndex(obj);
  708. }
  709. }
  710. if (option.LatestPointFlash)
  711. {
  712. var item=option.LatestPointFlash;
  713. if (item.Enable)
  714. {
  715. chart.CreateExtendChart("LatestPointFlashPaint", item);
  716. }
  717. }
  718. return chart;
  719. }
  720. this.CreateKLineTrainChartContainer = function (option)
  721. {
  722. if (option.Type=="简单K线训练" || option.Type=="简单K线训练横屏")
  723. {
  724. var bHScreen=(option.Type=='简单K线训练横屏'? true:false);
  725. var chart=new KLineTrainSimpleChartContainer(this.CanvasElement,bHScreen);
  726. }
  727. else
  728. {
  729. var bHScreen = (option.Type == 'K线训练横屏' ? true : false);
  730. var chart = new KLineTrainChartContainer(this.CanvasElement, bHScreen);
  731. }
  732. if (option.NetworkFilter) chart.NetworkFilter = option.NetworkFilter;
  733. if (option.IsApiPeriod == true) chart.IsApiPeriod = option.IsApiPeriod;
  734. if (option.KLine) //k线图的属性设置
  735. {
  736. if (option.KLine.Right >= 0) chart.Right = option.KLine.Right;
  737. if (option.KLine.Period >= 0) chart.Period = option.KLine.Period;
  738. if (option.KLine.MaxRequestDataCount > 0) chart.MaxRequestDataCount = option.KLine.MaxRequestDataCount;
  739. if (option.KLine.Info && option.KLine.Info.length > 0) chart.SetKLineInfo(option.KLine.Info, false);
  740. if (option.KLine.PageSize > 0) chart.PageSize = option.KLine.PageSize;
  741. if (option.KLine.IsShowTooltip == false) chart.IsShowTooltip = false;
  742. if (option.KLine.MaxRequestMinuteDayCount > 0) chart.MaxRequestMinuteDayCount = option.KLine.MaxRequestMinuteDayCount;
  743. if (option.KLine.DrawType) chart.KLineDrawType = option.KLine.DrawType;
  744. }
  745. if (option.Train)
  746. {
  747. if (option.Train.DataCount) chart.TrainDataCount = option.Train.DataCount;
  748. if (option.Train.Callback) chart.TrainCallback = option.Train.Callback;
  749. if (option.Train.StartDate) chart.TrainStartDate = option.Train.StartDate;
  750. }
  751. if (!option.Windows || option.Windows.length <= 0) return null;
  752. //创建子窗口
  753. chart.Create(option.Windows.length);
  754. this.SetChartBorder(chart, option);
  755. if (option.ExtendChart) //创建扩展画法
  756. {
  757. for (var i in option.ExtendChart)
  758. {
  759. var item = option.ExtendChart[i];
  760. chart.CreateExtendChart(item.Name, item);
  761. }
  762. }
  763. if (option.IsShowCorssCursorInfo == false) chart.ChartCorssCursor.IsShowText = option.IsShowCorssCursorInfo;//取消显示十字光标刻度信息
  764. if (option.CorssCursorTouchEnd == true) chart.CorssCursorTouchEnd = option.CorssCursorTouchEnd;
  765. if (option.IsClickShowCorssCursor == true) chart.IsClickShowCorssCursor = option.IsClickShowCorssCursor;
  766. if (option.IsFullDraw == true) chart.IsFullDraw = option.IsFullDraw;
  767. if (option.CorssCursorInfo)
  768. {
  769. var item=option.CorssCursorInfo;
  770. if (!isNaN(option.CorssCursorInfo.Left)) chart.ChartCorssCursor.ShowTextMode.Left = option.CorssCursorInfo.Left;
  771. if (!isNaN(option.CorssCursorInfo.Right)) chart.ChartCorssCursor.ShowTextMode.Right = option.CorssCursorInfo.Right;
  772. if (!isNaN(option.CorssCursorInfo.Bottom)) chart.ChartCorssCursor.ShowTextMode.Bottom = option.CorssCursorInfo.Bottom;
  773. if (option.CorssCursorInfo.IsShowCorss === false) chart.ChartCorssCursor.IsShowCorss = option.CorssCursorInfo.IsShowCorss;
  774. if (IFrameSplitOperator.IsBool(item.IsShowClose)) chart.ChartCorssCursor.IsShowClose = item.IsShowClose; //Y轴显示收盘价
  775. if (option.CorssCursorInfo.HPenType > 0) chart.ChartCorssCursor.HPenType = option.CorssCursorInfo.HPenType;
  776. if (option.CorssCursorInfo.VPenType > 0) chart.ChartCorssCursor.VPenType = option.CorssCursorInfo.VPenType;
  777. if (IFrameSplitOperator.IsBool(item.IsFixXLastTime)) chart.ChartCorssCursor.IsFixXLastTime=item.IsFixXLastTime;
  778. }
  779. if (IFrameSplitOperator.IsNonEmptyArray(option.Frame))
  780. {
  781. for (var i=0;i<option.Frame.length;++i)
  782. {
  783. if (!chart.Frame.SubFrame[i]) continue;
  784. var item = option.Frame[i];
  785. if (item.SplitCount) chart.Frame.SubFrame[i].Frame.YSplitOperator.SplitCount = item.SplitCount;
  786. if (item.StringFormat) chart.Frame.SubFrame[i].Frame.YSplitOperator.StringFormat = item.StringFormat;
  787. if (item.Height>0) chart.Frame.SubFrame[i].Height = item.Height;
  788. if (IFrameSplitOperator.IsBool(item.IsShowLeftText)) chart.Frame.SubFrame[i].Frame.IsShowYText[0] = item.IsShowLeftText; //显示左边刻度
  789. if (IFrameSplitOperator.IsBool(item.IsShowRightText)) chart.Frame.SubFrame[i].Frame.IsShowYText[1] = item.IsShowRightText; //显示右边刻度
  790. if (item.Custom) chart.Frame.SubFrame[i].Frame.YSplitOperator.Custom=item.Custom;
  791. }
  792. }
  793. if (option.KLine)
  794. {
  795. if (IFrameSplitOperator.IsBool(option.KLine.ShowKLine)) chart.ChartPaint[0].IsShow = option.KLine.ShowKLine;
  796. if (IFrameSplitOperator.IsBool(option.KLine.IsShowMaxMinPrice)) chart.ChartPaint[0].IsShowMaxMinPrice = option.KLine.IsShowMaxMinPrice;
  797. this.SetPriceGapConfig(chart, option.KLine);
  798. }
  799. //股票名称 日期 周期都不显示
  800. chart.TitlePaint[0].IsShowName = false;
  801. chart.TitlePaint[0].IsShowSettingInfo = false;
  802. chart.TitlePaint[0].IsShowDateTime = false;
  803. //创建子窗口的指标
  804. let scriptData = new JSCommonIndexScript.JSIndexScript();
  805. for (var i=0;i<option.Windows.length;++i)
  806. {
  807. var item = option.Windows[i];
  808. if (item.Script)
  809. {
  810. chart.WindowIndex[i] = new ScriptIndex(item.Name, item.Script, item.Args, item); //脚本执行
  811. }
  812. else
  813. {
  814. let indexItem = JSIndexMap.Get(item.Index);
  815. if (indexItem)
  816. {
  817. chart.WindowIndex[i] = indexItem.Create();
  818. chart.CreateWindowIndex(i);
  819. }
  820. else
  821. {
  822. let indexInfo = scriptData.Get(item.Index);
  823. if (!indexInfo) continue;
  824. if (item.Lock) indexInfo.Lock = item.Lock;
  825. chart.WindowIndex[i] = new ScriptIndex(indexInfo.Name, indexInfo.Script, indexInfo.Args, indexInfo); //脚本执行
  826. }
  827. }
  828. if (item.Modify != null) chart.Frame.SubFrame[i].Frame.ModifyIndex = item.Modify;
  829. if (item.Change != null) chart.Frame.SubFrame[i].Frame.ChangeIndex = item.Change;
  830. if (IFrameSplitOperator.IsNumber(item.TitleHeight)) chart.Frame.SubFrame[i].Frame.ChartBorder.TitleHeight = item.TitleHeight;
  831. }
  832. return chart;
  833. }
  834. //深度图
  835. this.CreateDepthChartContainer=function(option)
  836. {
  837. var chart=null;
  838. chart=new DepthChartContainer(this.CanvasElement);
  839. if (option.NetworkFilter) chart.NetworkFilter=option.NetworkFilter;
  840. if (option.EnableScrollUpDown==true) chart.EnableScrollUpDown=option.EnableScrollUpDown;
  841. if (IFrameSplitOperator.IsPlusNumber(option.MaxVolRate)) chart.MaxVolRate=option.MaxVolRate;
  842. if (option.ZoomStepPixel>0) chart.ZoomStepPixel=option.ZoomStepPixel;
  843. if (IFrameSplitOperator.IsString(option.SplashTitle)) chart.LoadDataSplashTitle = option.SplashTitle; //设置提示信息内容
  844. if (option.Language)
  845. {
  846. var value=g_JSChartLocalization.GetLanguageID(option.Language);
  847. if (IFrameSplitOperator.IsNumber(value)) chart.LanguageID=value;
  848. }
  849. chart.Create(option.Listener);
  850. if (option.Border)
  851. {
  852. if (IFrameSplitOperator.IsNumber(option.Border.Left)) chart.Frame.ChartBorder.Left=option.Border.Left;
  853. else option.Border.Left=chart.Frame.ChartBorder.Left;
  854. if (IFrameSplitOperator.IsNumber(option.Border.Right)) chart.Frame.ChartBorder.Right=option.Border.Right;
  855. else option.Border.Right=chart.Frame.ChartBorder.Right;
  856. if (IFrameSplitOperator.IsNumber(option.Border.Top)) chart.Frame.ChartBorder.Top=option.Border.Top;
  857. else option.Border.Top=chart.Frame.ChartBorder.Top;
  858. if (IFrameSplitOperator.IsNumber(option.Border.Bottom)) chart.Frame.ChartBorder.Bottom=option.Border.Bottom;
  859. else option.Border.Bottom=chart.Frame.ChartBorder.Bottom;
  860. }
  861. if (option.IsFullDraw == true) chart.IsFullDraw = option.IsFullDraw;
  862. if (option.CorssCursorTouchEnd===true) chart.CorssCursorTouchEnd = option.CorssCursorTouchEnd;
  863. if (option.CorssCursorInfo)
  864. {
  865. var item=option.CorssCursorInfo;
  866. if (IFrameSplitOperator.IsNumber(item.HPenType)) chart.ChartCorssCursor.HPenType=item.HPenType;
  867. if (IFrameSplitOperator.IsNumber(item.VPenType)) chart.ChartCorssCursor.VPenType=item.VPenType;
  868. if (IFrameSplitOperator.IsBool(item.IsShowTooltip)) chart.ChartCorssCursor.IsShowTooltip=item.IsShowTooltip;
  869. }
  870. if (option.Frame)
  871. {
  872. var item=option.Frame
  873. if (item.SplitCount) chart.Frame.YSplitOperator.SplitCount=item.SplitCount;
  874. if (IFrameSplitOperator.IsNumber(item.SplitType)) chart.Frame.YSplitOperator.SplitType=item.SplitType;
  875. if (IFrameSplitOperator.IsNumber(item.Height)) chart.Frame.Height = item.Height;
  876. if (IFrameSplitOperator.IsNumber(item.LineType)) chart.Frame.YSplitOperator.LineType=item.LineType;
  877. if (Array.isArray(item.IgnoreYValue)) chart.Frame.YSplitOperator.IgnoreYValue=item.IgnoreYValue;
  878. if (item.IsShowLeftText===false || item.IsShowLeftText===true)
  879. {
  880. chart.Frame.IsShowYText[0]=item.IsShowLeftText;
  881. chart.Frame.YSplitOperator.IsShowLeftText=item.IsShowLeftText; //显示左边刻度
  882. }
  883. if (item.IsShowRightText===false || item.IsShowRightText===true)
  884. {
  885. chart.Frame.IsShowYText[1]=item.IsShowRightText;
  886. chart.Frame.YSplitOperator.IsShowRightText=item.IsShowRightText; //显示右边刻度
  887. }
  888. if (item.IsShowXLine==false) chart.Frame.IsShowXLine=item.IsShowXLine;
  889. if (item.IsShowYLine==false) chart.Frame.IsShowYLine=item.IsShowYLine;
  890. if (IFrameSplitOperator.IsNumber(item.XSplitCount)) chart.Frame.XSplitOperator.SplitCount=item.XSplitCount;
  891. }
  892. return chart;
  893. }
  894. //根据option内容绘制图形
  895. this.SetOption = function (option)
  896. {
  897. JSConsole.Chart.Log('[JSChart::SetOption]', option)
  898. var chart = null;
  899. switch (option.Type)
  900. {
  901. case "历史K线图":
  902. case '历史K线图横屏':
  903. chart = this.CreateKLineChartContainer(option);
  904. break;
  905. case "自定义指数历史K线图":
  906. chart = this.CreateCustomKLineChartContainer(option);
  907. break;
  908. case "分钟走势图":
  909. case "分钟走势图横屏":
  910. chart = this.CreateMinuteChartContainer(option);
  911. break;
  912. case 'K线训练':
  913. case 'K线训练横屏':
  914. case "简单K线训练":
  915. case "简单K线训练横屏":
  916. chart = this.CreateKLineTrainChartContainer(option);
  917. break;
  918. case "深度图":
  919. chart=this.CreateDepthChartContainer(option);
  920. break;
  921. default:
  922. return false;
  923. }
  924. if (!chart) return false;
  925. this.JSChartContainer = chart;
  926. if (option.OnCreatedCallback) option.OnCreatedCallback(chart);
  927. //是否自动更新
  928. if (option.IsAutoUpdate == true || option.IsAutoUpate == true) chart.IsAutoUpdate = true;
  929. if (option.AutoUpdateFrequency > 0) chart.AutoUpdateFrequency = option.AutoUpdateFrequency;
  930. //注册事件
  931. for(var i in option.EventCallback)
  932. {
  933. var item=option.EventCallback[i];
  934. chart.AddEventCallback(item);
  935. }
  936. //设置股票代码
  937. if (!option.Symbol) return false;
  938. chart.Draw();
  939. chart.ChangeSymbol(option.Symbol);
  940. this.JSChartContainer.Draw();
  941. }
  942. //切换股票代码接口
  943. this.ChangeSymbol = function (symbol)
  944. {
  945. if (this.JSChartContainer) this.JSChartContainer.ChangeSymbol(symbol);
  946. }
  947. //K线切换指标
  948. this.ChangeIndex = function (windowIndex, indexName, option)
  949. {
  950. if (this.JSChartContainer && typeof (this.JSChartContainer.ChangeIndex) == 'function')
  951. this.JSChartContainer.ChangeIndex(windowIndex, indexName, option);
  952. }
  953. //切换一个窗口指标,包含叠加指标,以及这个窗口的属性
  954. this.ChangeIndexWindow=function(windowIndex, option)
  955. {
  956. if (this.JSChartContainer && typeof(this.JSChartContainer.ChangeIndexWindow)=='function')
  957. this.JSChartContainer.ChangeIndexWindow(windowIndex, option);
  958. }
  959. //切换K线指标
  960. this.ChangeScriptIndex = function (windowIndex, indexData)
  961. {
  962. if (this.JSChartContainer && typeof (this.JSChartContainer.ChangeScriptIndex) == 'function')
  963. this.JSChartContainer.ChangeScriptIndex(windowIndex, indexData);
  964. }
  965. //获取当前显示的指标信息
  966. this.GetIndexInfo = function ()
  967. {
  968. if (this.JSChartContainer && typeof (this.JSChartContainer.GetIndexInfo) == 'function')
  969. return this.JSChartContainer.GetIndexInfo();
  970. else
  971. return [];
  972. }
  973. //K线周期切换
  974. this.ChangePeriod = function (period, option)
  975. {
  976. if (this.JSChartContainer && typeof (this.JSChartContainer.ChangePeriod) == 'function')
  977. this.JSChartContainer.ChangePeriod(period, option);
  978. }
  979. //切换系统指示
  980. this.ChangeInstructionIndex = function (indexName)
  981. {
  982. if (this.JSChartContainer && typeof (this.JSChartContainer.ChangeInstructionIndex) == 'function')
  983. this.JSChartContainer.ChangeInstructionIndex(indexName);
  984. }
  985. //切换自定义指示
  986. this.ChangeInstructionScriptIndex = function (indexData)
  987. {
  988. if (this.JSChartContainer && typeof (this.JSChartContainer.ChangeInstructionIndex) == 'function')
  989. this.JSChartContainer.ChangeInstructionScriptIndex(indexData);
  990. }
  991. //增加一个指标窗口
  992. this.AddIndexWindow=function(indexName,option)
  993. {
  994. if (this.JSChartContainer && typeof(this.JSChartContainer.AddIndexWindow)=='function')
  995. this.JSChartContainer.AddIndexWindow(indexName,option);
  996. }
  997. this.AddScriptIndexWindow=function(indexInfo, option)
  998. {
  999. if (this.JSChartContainer && typeof(this.JSChartContainer.AddScriptIndexWindow)=='function')
  1000. this.JSChartContainer.AddScriptIndexWindow(indexInfo,option);
  1001. }
  1002. this.AddAPIIndexWindow=function(indexData, option)
  1003. {
  1004. if (this.JSChartContainer && typeof(this.JSChartContainer.AddAPIIndexWindow)=='function')
  1005. this.JSChartContainer.AddAPIIndexWindow(indexData,option);
  1006. }
  1007. //删除一个指标窗口
  1008. this.RemoveIndexWindow=function(id)
  1009. {
  1010. if (this.JSChartContainer && typeof(this.JSChartContainer.RemoveIndexWindow)=='function')
  1011. this.JSChartContainer.RemoveIndexWindow(id);
  1012. }
  1013. //取消指示
  1014. this.CancelInstructionIndex = function ()
  1015. {
  1016. if (this.JSChartContainer && typeof (this.JSChartContainer.CancelInstructionIndex) == 'function')
  1017. this.JSChartContainer.CancelInstructionIndex();
  1018. }
  1019. //切换指标模板
  1020. this.ChangeIndexTemplate = function (option)
  1021. {
  1022. if (this.JSChartContainer && typeof (this.JSChartContainer.ChangeIndexTemplate) == 'function') {
  1023. JSConsole.Chart.Log('[JSChart:ChangeIndexTemplate] ', option);
  1024. this.JSChartContainer.ChangeIndexTemplate(option);
  1025. }
  1026. }
  1027. this.ChangeIndexWindowCount=function(count, option)
  1028. {
  1029. if (this.JSChartContainer && typeof (this.JSChartContainer.ChangeIndexWindowCount) == 'function')
  1030. this.JSChartContainer.ChangeIndexWindowCount(count, option);
  1031. }
  1032. this.CreateChartDrawPicture=function(name,option)
  1033. {
  1034. if(this.JSChartContainer && typeof(this.JSChartContainer.CreateChartDrawPicture)=='function')
  1035. {
  1036. JSConsole.Chart.Log('[JSChart:CreateChartDrawPicture] ', name);
  1037. this.JSChartContainer.CreateChartDrawPicture(name,option);
  1038. }
  1039. }
  1040. //K线复权切换
  1041. this.ChangeRight = function (right)
  1042. {
  1043. if (this.JSChartContainer && typeof (this.JSChartContainer.ChangeRight) == 'function')
  1044. this.JSChartContainer.ChangeRight(right);
  1045. }
  1046. //设置当前屏的起始日期 { Date:起始日期(必填), Time:起始时间(分钟K线必填) PageSize:一屏显示的数据个数(可选)}
  1047. this.SetFirstShowDate=function(obj)
  1048. {
  1049. if (this.JSChartContainer && typeof(this.JSChartContainer.SetFirstShowDate)=='function')
  1050. this.JSChartContainer.SetFirstShowDate(obj);
  1051. }
  1052. //K线切换类型 0=实心K线 1=收盘价线 2=美国线 3=空心K线
  1053. this.ChangeKLineDrawType = function (drawType)
  1054. {
  1055. if (this.JSChartContainer && typeof (this.JSChartContainer.ChangeKLineDrawType) == 'function')
  1056. this.JSChartContainer.ChangeKLineDrawType(drawType);
  1057. }
  1058. //叠加股票
  1059. this.OverlaySymbol = function (symbol,option)
  1060. {
  1061. if (this.JSChartContainer && typeof (this.JSChartContainer.OverlaySymbol) == 'function')
  1062. this.JSChartContainer.OverlaySymbol(symbol, option);
  1063. }
  1064. //设置强制横屏
  1065. this.ForceLandscape = function (bForceLandscape) {
  1066. if (this.JSChartContainer) {
  1067. JSConsole.Chart.Log("[JSChart::ForceLandscape] bForceLandscape=" + bForceLandscape);
  1068. this.JSChartContainer.IsForceLandscape = bForceLandscape;
  1069. }
  1070. }
  1071. //锁|解锁指标
  1072. this.EnableLockIndex=function (aryData)
  1073. {
  1074. if (this.JSChartContainer && typeof (this.JSChartContainer.EnableLockIndex) == 'function')
  1075. {
  1076. JSConsole.Chart.Log('[JSChart:EnableLockIndex] aryData', aryData);
  1077. this.JSChartContainer.EnableLockIndex(aryData);
  1078. }
  1079. }
  1080. //历史分钟数据 更改日期
  1081. this.ChangeTradeDate = function (tradeDate)
  1082. {
  1083. if (this.JSChartContainer && typeof (this.JSChartContainer.ChangeTradeDate) == 'function')
  1084. {
  1085. JSConsole.Chart.Log('[JSChart:ChangeTradeDate] date', tradeDate);
  1086. this.JSChartContainer.ChangeTradeDate(tradeDate);
  1087. }
  1088. }
  1089. //多日走势图
  1090. this.ChangeDayCount = function (count)
  1091. {
  1092. if (this.JSChartContainer && typeof (this.JSChartContainer.ChangeDayCount) == 'function')
  1093. {
  1094. JSConsole.Chart.Log('[JSChart:ChangeDayCount] count', count);
  1095. this.JSChartContainer.ChangeDayCount(count);
  1096. }
  1097. }
  1098. this.StopAutoUpdate = function ()
  1099. {
  1100. if (this.JSChartContainer && typeof (this.JSChartContainer.StopAutoUpdate) == 'function') {
  1101. JSConsole.Chart.Log("[JSChart::StopAutoUpdate] Stop.");
  1102. this.JSChartContainer.StopAutoUpdate();
  1103. }
  1104. }
  1105. this.StopAutoUpdata = this.StopAutoUpdate;
  1106. this.ChartDestroy=function()
  1107. {
  1108. if (this.JSChartContainer && typeof (this.JSChartContainer.ChartDestroy) == 'function') {
  1109. JSConsole.Chart.Log("[JSChart::ChartDestroy]");
  1110. this.JSChartContainer.ChartDestroy();
  1111. }
  1112. }
  1113. this.OnTouchStart = function (e)
  1114. {
  1115. if (this.JSChartContainer) this.JSChartContainer.ontouchstart(e);
  1116. }
  1117. this.OnTouchMove = function (e)
  1118. {
  1119. if (this.JSChartContainer) this.JSChartContainer.ontouchmove(e);
  1120. }
  1121. this.OnTouchEnd = function (e)
  1122. {
  1123. if (this.JSChartContainer) this.JSChartContainer.ontouchend(e);
  1124. }
  1125. this.SaveToImage = function (callback)
  1126. {
  1127. if (this.JSChartContainer && typeof (this.JSChartContainer.SaveToImage) == 'function')
  1128. this.JSChartContainer.SaveToImage(callback);
  1129. }
  1130. this.EnableSplashScreen=function(option)
  1131. {
  1132. if(this.JSChartContainer && typeof(this.JSChartContainer.EnableSplashScreen)=='function')
  1133. this.JSChartContainer.EnableSplashScreen(option);
  1134. }
  1135. //叠加指标
  1136. this.AddOverlayIndex=function(obj) //{WindowIndex:窗口ID, IndexName:指标ID, Identify:叠加指标ID(可选), API}
  1137. {
  1138. if (this.JSChartContainer && typeof(this.JSChartContainer.AddOverlayIndex)=='function')
  1139. this.JSChartContainer.AddOverlayIndex(obj);
  1140. }
  1141. //删除叠加指标
  1142. this.DeleteOverlayWindowsIndex=function(identify)
  1143. {
  1144. if (this.JSChartContainer && typeof(this.JSChartContainer.DeleteOverlayWindowsIndex)=='function')
  1145. this.JSChartContainer.DeleteOverlayWindowsIndex(identify);
  1146. }
  1147. this.ChangePriceGap=function(option)
  1148. {
  1149. if(this.JSChartContainer && typeof(this.JSChartContainer.ChangePriceGap)=='function')
  1150. {
  1151. JSConsole.Chart.Log('[JSChart:ChangePriceGap] ');
  1152. return this.JSChartContainer.ChangePriceGap(option);
  1153. }
  1154. }
  1155. //手动更新指标 aryIndex=[ {ID:主图指标ID, OverlayID:叠加指标ID }] ,option={ Draw:true/false }
  1156. this.UpdateWindowIndexV2=function(aryIndex, option)
  1157. {
  1158. if (this.JSChartContainer && typeof(this.JSChartContainer.UpdateWindowIndexV2)=='function')
  1159. return this.JSChartContainer.UpdateWindowIndexV2(aryIndex, option);
  1160. }
  1161. }
  1162. JSChart.LastVersion=null; //最新的版本号
  1163. //初始化
  1164. JSChart.Init=function (uielement)
  1165. {
  1166. JSConsole.Chart.Log('[JSChart.Init] uielement', uielement);
  1167. var jsChartControl = new JSChart(uielement);
  1168. jsChartControl.OnSize();
  1169. return jsChartControl;
  1170. }
  1171. JSChart.SetDomain = function (domain, cacheDomain)
  1172. {
  1173. if (domain)
  1174. {
  1175. g_JSChartResource.Domain = domain;
  1176. g_JSChartResource.Index.StockHistoryDayApiUrl = domain + "/API/StockHistoryDay"; //历史数据api
  1177. g_JSChartResource.Index.MarketLongShortApiUrl = domain + "/API/FactorTiming"; //市场多空
  1178. g_JSChartResource.Index.MarketAttentionApiUrl = domain + "/API/MarketAttention"; //市场关注度
  1179. g_JSChartResource.Index.MarketHeatApiUrl = domain + "/API/MarketHeat"; //行业,指数热度
  1180. }
  1181. if (cacheDomain) g_JSChartResource.CacheDomain = cacheDomain;
  1182. JSCommonComplier.JSComplier.SetDomain(domain, cacheDomain); //编译器数据api域名修改
  1183. }
  1184. //自定义风格
  1185. JSChart.SetStyle = function (style) {
  1186. if (style) g_JSChartResource.SetStyle(style);
  1187. }
  1188. JSChart.GetResource = function () //获取颜色配置 (设置配必须啊在JSChart.Init()之前)
  1189. {
  1190. return g_JSChartResource;
  1191. }
  1192. JSChart.GetMinuteTimeStringData=function()
  1193. {
  1194. return JSCommonCoordinateData.MinuteTimeStringData;
  1195. }
  1196. JSChart.GetMinuteCoordinateData=function()
  1197. {
  1198. return JSCommonCoordinateData.MinuteCoordinateData;
  1199. }
  1200. JSChart.GetKLineZoom = function () //K线缩放配置
  1201. {
  1202. return ZOOM_SEED;
  1203. }
  1204. JSChart.SetKLineZoom=function(aryZoom) //设置K线缩放比例
  1205. {
  1206. ZOOM_SEED.length=0;
  1207. for(var i=0;i<aryZoom.length;++i)
  1208. {
  1209. ZOOM_SEED[i]=aryZoom[i];
  1210. }
  1211. }
  1212. JSChart.SetUSATimeType=function(type) //设置 0=标准时间 1=夏令时间 3=美国时间
  1213. {
  1214. g_NYMEXTimeData.TimeType=type;
  1215. g_COMEXTimeData.TimeType=type;
  1216. g_NYBOTTimeData.TimeType=type;
  1217. g_CBOTTimeData.TimeType=type;
  1218. }
  1219. JSChart.GetChinaFuturesTimeData=function() //获取国内期货交易时间配置
  1220. {
  1221. return g_FuturesTimeData;
  1222. }
  1223. JSChart.GetInternalTimeData=function(name) //内置品种交易时间
  1224. {
  1225. switch(name)
  1226. {
  1227. case "NYMEXTimeData": //纽约商业交易所
  1228. return g_NYMEXTimeData;
  1229. case "COMEXTimeData": //纽约商品交易所
  1230. return g_COMEXTimeData;
  1231. case "NYBOTTimeData": //纽约期货交易所
  1232. return g_NYBOTTimeData;
  1233. case "CBOTTimeData": //芝加哥期货交易所
  1234. return g_CBOTTimeData;
  1235. case "LMETimeData": //伦敦金属交易所
  1236. return g_LMETimeData;
  1237. case "FuturesTimeData": //国内期货
  1238. return g_FuturesTimeData;
  1239. case "TOCOMTimeData": //东京商品交易所(TOCOM
  1240. return g_TOCOMTimeData;
  1241. case "IPETimeData":
  1242. return g_IPETimeData; //美国洲际交易所
  1243. default:
  1244. return null;
  1245. }
  1246. }
  1247. JSChart.GetDivTooltipDataFormat=function() //div tooltip数据格式化
  1248. {
  1249. return g_DivTooltipDataForamt;
  1250. }
  1251. //注册外部扩展图形
  1252. //option:{ Create:创建类方法 }
  1253. JSChart.RegisterExtendChartClass=function(name, option)
  1254. {
  1255. return g_ExtendChartPaintFactory.Add(name,option);
  1256. }
  1257. //一些公共函数
  1258. JSChart.ToFixedPoint=function(value)
  1259. {
  1260. return ToFixedPoint(value);
  1261. }
  1262. JSChart.ToFixedRect=function(value)
  1263. {
  1264. return ToFixedRect(value);
  1265. }
  1266. JSChart.AddPeriodCallback=function(obj) //添加自定义周期方法 { Period:周期ID, Callback:回调 }
  1267. {
  1268. g_DataPlus.AddPeriodCallback(obj);
  1269. }
  1270. JSChart.RemovePeriodCallback=function(obj) //添加自定义周期方法 { Period:周期ID, }
  1271. {
  1272. g_DataPlus.RemovePeriodCallback(obj);
  1273. }
  1274. var JSCHART_OPERATOR_ID =
  1275. {
  1276. OP_SCROLL_LEFT: 1,
  1277. OP_SCROLL_RIGHT: 2,
  1278. OP_ZOOM_OUT: 3, //缩小
  1279. OP_ZOOM_IN: 4, //放大
  1280. OP_GOTO_HOME: 5, //第1页数据
  1281. OP_GOTO_END:6, //第1天的数据
  1282. OP_GOTO:16, //移动到某一个天或某一个分钟
  1283. }
  1284. /*
  1285. 图形控件
  1286. */
  1287. function JSChartContainer(uielement)
  1288. {
  1289. this.ClassName = 'JSChartContainer';
  1290. var _self = this;
  1291. this.Frame; //框架画法
  1292. this.ChartPaint = new Array(); //图形画法
  1293. this.ChartPaintEx = []; //图形扩展画法
  1294. this.ChartInfo = new Array(); //K线上信息地雷
  1295. this.ChartInfoPaint; //信息地理
  1296. this.ExtendChartPaint = new Array(); //扩展画法
  1297. this.TitlePaint = new Array(); //标题画法
  1298. this.OverlayChartPaint = new Array(); //叠加信息画法
  1299. this.ChartDrawPicture = new Array(); //画图工具
  1300. this.CurrentChartDrawPicture = null; //当前的画图工具
  1301. this.SelectChartDrawPicture = null; //当前选中的画图
  1302. this.ChartCorssCursor; //十字光标
  1303. this.IsClickShowCorssCursor = false; //手势点击显示十字光标
  1304. this.ChartSplashPaint = null; //等待提示
  1305. this.LoadDataSplashTitle = '数据加载中';
  1306. this.Canvas = uielement.GetContext("2d"); //画布
  1307. this.UIElement = uielement;
  1308. this.MouseDrag;
  1309. this.DragMode = 1; //拖拽模式 0 禁止拖拽 1 数据拖拽
  1310. this.PhoneTouchInfo; //手机手势信息 {Start:起始点, End:结束点}
  1311. this.EnableScrollUpDown=false; //是否可以上下滚动图形(手机端才有)
  1312. this.TouchTimer = null; //触屏定时器
  1313. this.LastDrawStatus; //最后一次画的状态
  1314. this.LastDrawID=1; //最后一次画的ID
  1315. this.SnapshotType = 0;
  1316. this.CursorIndex = 0; //十字光标X轴索引
  1317. this.LastPoint = new Point(); //鼠标位置
  1318. this.IsForceLandscape = false; //是否强制横屏
  1319. this.CorssCursorTouchEnd = false; //手离开屏幕自动隐藏十字光标
  1320. this.TouchMoveMinAngle=70; //左右移动最小角度
  1321. this.EnableAnimation = false; //是否开启动画
  1322. //坐标轴风格方法 double-更加数值型分割 price-更加股票价格分割
  1323. this.FrameSplitData = new Map();
  1324. this.FrameSplitData.set("double", new SplitData());
  1325. this.FrameSplitData.set("price", new PriceSplitData());
  1326. this.UpdateUICallback; //数据到达通知前端
  1327. this.IsOnTouch = false; //当前是否正式手势操作
  1328. this.PhonePinch=null; //双指操作信息
  1329. this.TouchDrag=null; //手势拖动操作信息
  1330. this.IsFullDraw=false; //是否使用重绘模式 (可能会卡)
  1331. this.LanguageID = JSCHART_LANGUAGE_ID.LANGUAGE_CHINESE_ID;
  1332. this.PressTime=800; //长按十字光标显示时间
  1333. this.IsPress=false; //是否长按
  1334. //公共函数转发,不然要导出麻烦
  1335. this.FormatDateString = IFrameSplitOperator.FormatDateString;
  1336. this.FormatValueString = IFrameSplitOperator.FormatValueString;
  1337. this.ToFixedPoint = ToFixedPoint;
  1338. this.ToFixedRect = ToFixedRect;
  1339. this.FormatTimeString = IFrameSplitOperator.FormatTimeString;
  1340. //this.JSCHART_EVENT_ID = JSCHART_EVENT_ID;
  1341. //事件回调
  1342. this.mapEvent = new Map(); //通知外部调用 key:JSCHART_EVENT_ID value:{Callback:回调,}
  1343. this.NetworkFilter; //网络请求回调 function(data, callback);
  1344. this.IsDestroy=false; //是否已经销毁了
  1345. //手势移动 十字光标
  1346. this.LastMovePoint;
  1347. this.DrawMoveTimer=null;
  1348. this.DrawMoveWaitTime=60;
  1349. //双击缩放附图窗口
  1350. this.EnableZoomIndexWindow=false; //是否支持双击缩放附图窗口
  1351. this.PhoneDBClick=new PhoneDBClick();
  1352. //十字光标长留(手势才有)
  1353. this.ClickModel={ IsShowCorssCursor:false, PreventHide:false }; //PreventHide 阻止隐藏十字光标
  1354. this.EnableClickModel=false;
  1355. this.FastSlideConfig={ MinDistance:500, MinSpeed:3, MaxTime:250, Enable:false }; //快速滑动配置 MinDistance=最小的距离 MinSpeed=最小速度 MaxTime=最大间隔时间(ms)
  1356. this.DataMoveConfig={ Touch:{ EnableLR: true} }; //数据移动配置
  1357. //全局配置
  1358. this.GlobalOption=
  1359. {
  1360. RightHorizontal: { Show:true, },
  1361. CorssCursorStatus:{ Value:null }, //十字光标状态 只读
  1362. LatestPoint:null, //最新的点位置 { X:, Y: }
  1363. }
  1364. this.ClearGlobalOption=function()
  1365. {
  1366. if (!this.GlobalOption) return;
  1367. this.GlobalOption.LatestPoint=null;
  1368. }
  1369. this.ChartDestroy=function() //销毁
  1370. {
  1371. this.IsDestroy=true;
  1372. this.StopAutoUpdate();
  1373. }
  1374. this.AddEventCallback = function (object) //设置事件回调 {event:事件id, callback:回调函数}
  1375. {
  1376. if (!object || !object.event || !object.callback) return;
  1377. var data = { Callback: object.callback, Source: object };
  1378. this.mapEvent.set(object.event, data);
  1379. }
  1380. this.RemoveEventCallback = function (eventid)
  1381. {
  1382. if (!this.mapEvent.has(eventid)) return;
  1383. this.mapEvent.delete(eventid);
  1384. }
  1385. this.GetEvent=function(eventId)
  1386. {
  1387. if (!this.mapEvent.has(eventId)) return null;
  1388. var item = this.mapEvent.get(eventId);
  1389. return item;
  1390. }
  1391. this.GetEventCallback=this.GetEvent;
  1392. this.GetIndexEvent = function () { return this.GetEvent(JSCHART_EVENT_ID.RECV_INDEX_DATA); } //接收指标数据
  1393. this.GetBarrageEvent=function() { return this.GetEvent(JSCHART_EVENT_ID.BARRAGE_PLAY_END);} //获取弹幕事件
  1394. this.GetEnableSplashEvent=function() { return this.GetEvent(JSCHART_EVENT_ID.ON_ENABLE_SPLASH_DRAW); } //开启/关闭文字提示信息事件
  1395. this.UpdateCorssCursorStatus=function()
  1396. {
  1397. if (!this.ChartCorssCursor) return false;
  1398. if (!this.GlobalOption || !this.GlobalOption.CorssCursorStatus) return false;
  1399. var status=this.ChartCorssCursor.Status;
  1400. //状态改变了
  1401. if (this.GlobalOption.CorssCursorStatus.Value!=status)
  1402. {
  1403. this.GlobalOption.CorssCursorStatus.Value=status;
  1404. var event=this.GetEventCallback(JSCHART_EVENT_ID.ON_CORSSCURSOR_STATUS_CHANGE);
  1405. if (event && event.Callback)
  1406. {
  1407. var sendData={ Status:status, IsShowLine:(status&JSCHART_CORSSCURSOR_STATUS_ID.LINE_ID)>0 };
  1408. event.Callback(event, sendData, this);
  1409. }
  1410. }
  1411. return true;
  1412. }
  1413. //判断是单个手指
  1414. this.IsPhoneDragging = function (e)
  1415. {
  1416. // JSConsole.Chart.Log(e);
  1417. var changed = e.changedTouches.length;
  1418. var touching = e.touches.length;
  1419. return changed == 1 && touching == 1;
  1420. }
  1421. //是否是2个手指操所
  1422. this.IsPhonePinching = function (e)
  1423. {
  1424. var changed = e.changedTouches.length;
  1425. var touching = e.touches.length;
  1426. return (changed == 1 || changed == 2) && touching == 2;
  1427. }
  1428. this.IsSingleTouch=function(e) //是否是单点触屏
  1429. {
  1430. var touchCount=e.touches.length;
  1431. return touchCount==1;
  1432. }
  1433. this.GetMoveAngle=function(pt,pt2) //计算角度
  1434. {
  1435. var xMove=Math.abs(pt.X-pt2.X);
  1436. var yMove=Math.abs(pt.Y-pt2.Y);
  1437. var angle=Math.atan(xMove/yMove)*180/Math.PI;
  1438. return angle;
  1439. }
  1440. this.GetToucheData = function (e, isForceLandscape)
  1441. {
  1442. var touches = new Array();
  1443. for (var i = 0; i < e.touches.length; ++i)
  1444. {
  1445. var item = e.touches[i];
  1446. if (isForceLandscape)
  1447. {
  1448. touches.push( { clientX: item.y, clientY: item.x, pageX: item.y, pageY: item.x });
  1449. }
  1450. else
  1451. {
  1452. touches.push( {clientX: item.x, clientY: item.y, pageX: item.x, pageY: item.y });
  1453. }
  1454. }
  1455. return touches;
  1456. }
  1457. this.ClearDrawMoveTimer=function()
  1458. {
  1459. if (this.DrawMoveTimer != null)
  1460. {
  1461. clearTimeout(this.DrawMoveTimer);
  1462. this.DrawMoveTimer=null;
  1463. }
  1464. }
  1465. this.ClearTouchTimer=function()
  1466. {
  1467. if (this.TouchTimer != null)
  1468. {
  1469. clearTimeout(this.TouchTimer);
  1470. this.TouchTimer=null;
  1471. this.IsPress=false;
  1472. }
  1473. }
  1474. this.TryPhoneClickButton=function(x,y,e)
  1475. {
  1476. if (this.TryClickLock || this.TryClickIndexTitle)
  1477. {
  1478. if (this.TryClickLock && this.TryClickLock(x, y)) return true;
  1479. if (this.TryClickIndexTitle && this.TryClickIndexTitle(x, y)) return true;
  1480. }
  1481. var button=this.PtInExtendChartButtons(x,y);
  1482. if (button && this.ClickExtendChartButton)
  1483. {
  1484. this.ClickExtendChartButton(button, e);
  1485. return true;
  1486. }
  1487. if (this.TryClickCrossCursor(x,y))
  1488. {
  1489. return true;
  1490. }
  1491. return false;
  1492. }
  1493. this.TryClickCrossCursor=function(x,y,e)
  1494. {
  1495. if (!this.ChartCorssCursor) return;
  1496. var button=this.ChartCorssCursor.PtInButton(x,y);
  1497. if (!button) return false;
  1498. if (button.Type==1)
  1499. {
  1500. var event=this.GetEventCallback(JSCHART_EVENT_ID.ON_CLICK_CROSSCURSOR_RIGHT);
  1501. if (event && event.Callback)
  1502. {
  1503. var sendData={ Button:button, e };
  1504. event.Callback(event,sendData,this);
  1505. }
  1506. }
  1507. else if (button.Type==2)
  1508. {
  1509. var event=this.GetEventCallback(JSCHART_EVENT_ID.ON_CLICK_CROSSCURSOR_BOTTOM);
  1510. if (event && event.Callback)
  1511. {
  1512. var sendData={ Button:button, e };
  1513. event.Callback(event,sendData,this);
  1514. }
  1515. }
  1516. return true;
  1517. }
  1518. this.ClickExtendChartButton=function(button, e)
  1519. {
  1520. var event=this.GetEventCallback(JSCHART_EVENT_ID.ON_CLICK_EXTENDCHART_BUTTON);
  1521. if (event && event.Callback)
  1522. {
  1523. var data={ Info:button, PreventDefault:false }; //PreventDefault 是否阻止内置的点击处理
  1524. event.Callback(event,data,this);
  1525. if (data.PreventDefault) return;
  1526. }
  1527. }
  1528. //手机拖拽
  1529. this.ontouchstart = function (e)
  1530. {
  1531. if (this.ChartSplashPaint && this.ChartSplashPaint.IsEnableSplash == true) return;
  1532. var jsChart = this;
  1533. //if (jsChart.DragMode == 0) return;
  1534. this.IsOnTouch=true;
  1535. this.IsPress=false;
  1536. this.PhonePinch = null;
  1537. this.TouchDrawCount=0;
  1538. this.TouchDrag=null;
  1539. if (this.ClickModel) this.ClickModel.PreventHide=false;
  1540. if (this.IsPhoneDragging(e))
  1541. {
  1542. var touches = this.GetToucheData(e, jsChart.IsForceLandscape);
  1543. var pt={ X:touches[0].clientX, Y:touches[0].clientY };
  1544. if (this.TryPhoneClickButton(pt.X,pt.Y,e)) return;
  1545. //长按2秒,十字光标
  1546. if (this.TouchTimer != null) clearTimeout(this.TouchTimer);
  1547. var bStartTimer=this.ChartCorssCursor.IsShow == true;
  1548. //长按十字光标停留
  1549. if (this.EnableClickModel)
  1550. {
  1551. if (this.ClickModel.IsShowCorssCursor==true) bStartTimer=false;
  1552. else bStartTimer= true;
  1553. }
  1554. var drag ={ Click: {}, LastMove: {}, StartTime:Date.now() }; //LastMove=最后移动的位置
  1555. var touchDrag={ Click:{}, LastMove:{}, StartTime:Date.now() };
  1556. var touches = this.GetToucheData(e, jsChart.IsForceLandscape);
  1557. drag.Click.X = touches[0].clientX;
  1558. drag.Click.Y = touches[0].clientY;
  1559. drag.LastMove.X = touches[0].clientX;
  1560. drag.LastMove.Y = touches[0].clientY;
  1561. this.MouseDrag=drag;
  1562. touchDrag.Click.X=touches[0].clientX;
  1563. touchDrag.Click.Y=touches[0].clientY;
  1564. touchDrag.LastMove.X=touches[0].clientX;
  1565. touchDrag.LastMove.Y=touches[0].clientY;
  1566. this.TouchDrag=touchDrag;
  1567. this.PhoneTouchInfo={ Start:{X:touches[0].clientX, Y:touches[0].clientY }, End:{ X:touches[0].clientX, Y:touches[0].clientY } };
  1568. if (this.SelectChartDrawPicture) this.SelectChartDrawPicture.IsSelected=false;
  1569. this.SelectChartDrawPicture=null;
  1570. var isDrawPictrue=false;
  1571. if (this.CurrentChartDrawPicture) //画图工具模式
  1572. {
  1573. var drawPicture=this.CurrentChartDrawPicture;
  1574. if (drawPicture.Status==2)
  1575. {
  1576. this.SetChartDrawPictureThirdPoint(drag.Click.X,drag.Click.Y,true);
  1577. }
  1578. else
  1579. {
  1580. this.SetChartDrawPictureFirstPoint(drag.Click.X,drag.Click.Y,true);
  1581. //只有1个点 直接完成
  1582. if (this.FinishChartDrawPicturePoint()) this.DrawDynamicInfo({Corss:false, Tooltip:false});
  1583. }
  1584. return;
  1585. }
  1586. else
  1587. {
  1588. var pt=this.PointAbsoluteToRelative(touches[0].clientX,touches[0].clientY, true);
  1589. var drawPictrueData={ X:pt.X, Y:pt.Y, PixelRatio:this.UIElement.PixelRatio };
  1590. if (this.GetChartDrawPictureByPoint(drawPictrueData))
  1591. {
  1592. if (drawPictrueData.ChartDrawPicture.EnableMove===true)
  1593. drawPictrueData.ChartDrawPicture.Status=20;
  1594. drawPictrueData.ChartDrawPicture.ValueToPoint();
  1595. drawPictrueData.ChartDrawPicture.MovePointIndex=drawPictrueData.PointIndex;
  1596. drawPictrueData.ChartDrawPicture.IsSelected=true;
  1597. this.CurrentChartDrawPicture=drawPictrueData.ChartDrawPicture;
  1598. this.SelectChartDrawPicture=drawPictrueData.ChartDrawPicture;
  1599. let event=this.GetEventCallback(JSCHART_EVENT_ID.ON_CLICK_DRAWPICTURE); //选中画图工具事件
  1600. if (event && event.Callback)
  1601. {
  1602. let sendData={ DrawPicture: drawPictrueData.ChartDrawPicture };
  1603. event.Callback(event,sendData,this);
  1604. }
  1605. this.DrawDynamicInfo();
  1606. return;
  1607. }
  1608. }
  1609. if (bStartTimer)
  1610. {
  1611. this.TouchTimer = setTimeout(function () {
  1612. jsChart.IsPress=true;
  1613. if (drag.Click.X == drag.LastMove.X && drag.Click.Y == drag.LastMove.Y) //手指没有移动,出现十字光标
  1614. {
  1615. var mouseDrag = jsChart.MouseDrag;
  1616. jsChart.MouseDrag = null;
  1617. //移动十字光标
  1618. var x = drag.Click.X;
  1619. var y = drag.Click.Y;
  1620. if (jsChart.IsForceLandscape) y = jsChart.UIElement.Height - drag.Click.Y; //强制横屏Y计算
  1621. if (jsChart.EnableClickModel===true) jsChart.ClickModel.IsShowCorssCursor=true;
  1622. jsChart.OnMouseMove(x, y, e);
  1623. }
  1624. }, jsChart.PressTime);
  1625. }
  1626. if (this.EnableZoomIndexWindow)
  1627. {
  1628. this.PhoneDBClick.AddTouchStart(touches[0].clientX, touches[0].clientY, Date.now());
  1629. JSConsole.Chart.Log("[JSChartContainer::OnTouchStart] PhoneDBClick ", this.PhoneDBClick);
  1630. }
  1631. if (this.EnableClickModel)
  1632. {
  1633. //if (this.ClickModel.IsShowCorssCursor===true) this.MoveCorssCursor(drag.Click,e)
  1634. }
  1635. else if (jsChart.IsClickShowCorssCursor)
  1636. {
  1637. var x = drag.Click.X;
  1638. var y = drag.Click.Y;
  1639. jsChart.OnMouseMove(x, y, e,true);
  1640. }
  1641. this.TouchEvent({ EventID:JSCHART_EVENT_ID.ON_PHONE_TOUCH, FunctionName:"OnTouchStart"}, e);
  1642. }
  1643. else if (this.IsPhonePinching(e))
  1644. {
  1645. var phonePinch = { "Start": {}, "Last": {} };
  1646. var touches = this.GetToucheData(e, jsChart.IsForceLandscape);
  1647. phonePinch.Start = { X: touches[0].pageX, Y: touches[0].pageY, X2: touches[1].pageX, Y2: touches[1].pageY };
  1648. phonePinch.Last = { X: touches[0].pageX, Y: touches[0].pageY, X2: touches[1].pageX, Y2: touches[1].pageY };
  1649. jsChart.PhonePinch = phonePinch;
  1650. }
  1651. }
  1652. this.StartMoveTimer=function(touches, e)
  1653. {
  1654. var x = touches[0].clientX;
  1655. var y = touches[0].clientY;
  1656. this.LastMovePoint={ X:x, Y:y };
  1657. if (this.DrawMoveTimer) return;
  1658. this.DrawMoveTimer=setTimeout(()=>
  1659. {
  1660. if (!this.LastMovePoint) return;
  1661. this.OnMouseMove(this.LastMovePoint.X, this.LastMovePoint.Y, e);
  1662. this.DrawMoveTimer=null;
  1663. }, this.DrawMoveWaitTime);
  1664. }
  1665. this.ontouchmove = function (e)
  1666. {
  1667. if (this.ChartSplashPaint && this.ChartSplashPaint.IsEnableSplash == true) return;
  1668. var jsChart = this;
  1669. var touches = this.GetToucheData(e, jsChart.IsForceLandscape);
  1670. if (this.IsPhoneDragging(e))
  1671. {
  1672. var drag = jsChart.MouseDrag;
  1673. if (drag == null)
  1674. {
  1675. this.StartMoveTimer(touches, e);
  1676. }
  1677. else
  1678. {
  1679. var moveSetp = Math.abs(drag.LastMove.X - touches[0].clientX);
  1680. moveSetp = parseInt(moveSetp);
  1681. var isMoveCorssCursor=false;
  1682. if (this.EnableClickModel)
  1683. {
  1684. if (this.ClickModel.IsShowCorssCursor===true) isMoveCorssCursor=true;
  1685. else isMoveCorssCursor=false;
  1686. }
  1687. if (this.CurrentChartDrawPicture && this.CurrentChartDrawPicture.EnableMove===true)
  1688. {
  1689. var drawPicture=this.CurrentChartDrawPicture;
  1690. if (drawPicture.Status==1 || drawPicture.Status==2)
  1691. {
  1692. if(moveSetp<5 && moveUpDown<5) return;
  1693. if(this.SetChartDrawPictureSecondPoint(touches[0].clientX,touches[0].clientY,true))
  1694. {
  1695. this.DrawDynamicInfo();
  1696. }
  1697. }
  1698. else if (drawPicture.Status==3)
  1699. {
  1700. if(this.SetChartDrawPictureThirdPoint(touches[0].clientX,touches[0].clientY,true))
  1701. {
  1702. this.DrawDynamicInfo();
  1703. }
  1704. }
  1705. else if (drawPicture.Status==20) //画图工具移动
  1706. {
  1707. if(moveSetp<5 && moveUpDown<5) return;
  1708. if(this.MoveChartDrawPicture(touches[0].clientX-drag.LastMove.X,touches[0].clientY-drag.LastMove.Y,true))
  1709. {
  1710. this.DrawDynamicInfo();
  1711. }
  1712. }
  1713. drag.LastMove.X=touches[0].clientX;
  1714. drag.LastMove.Y=touches[0].clientY;
  1715. }
  1716. else if (isMoveCorssCursor)
  1717. {
  1718. jsChart.MouseDrag=null;
  1719. jsChart.MoveCorssCursor(drag.Click,e); //移动十字光标
  1720. }
  1721. else if (jsChart.DragMode == 1) //数据左右拖拽
  1722. {
  1723. var moveAngle=this.GetMoveAngle(drag.LastMove,{X:touches[0].clientX, Y:touches[0].clientY});
  1724. var moveUpDown=Math.abs(drag.LastMove.Y-touches[0].clientY);
  1725. if ( ((moveUpDown>0 && moveSetp<=3) || moveAngle<=this.TouchMoveMinAngle) && this.EnableScrollUpDown==true )
  1726. {
  1727. var event=this.GetEventCallback(JSCHART_EVENT_ID.ON_TOUCH_SCROLL_UP_DOWN);
  1728. var isEnd=true; //是否退出
  1729. if (event && event.Callback)
  1730. {
  1731. var sendData={ DragData:drag, PreventDefault:false };
  1732. event.Callback(event, sendData, this);
  1733. isEnd=(sendData.PreventDefault===false);
  1734. }
  1735. if (isEnd)
  1736. {
  1737. this.ClearTouchTimer();
  1738. return;
  1739. }
  1740. }
  1741. if (this.EnableMoveData && this.EnableMoveData.Touch===false)
  1742. {
  1743. jsChart.MouseDrag = null;
  1744. return;
  1745. }
  1746. if (moveSetp < 5) return;
  1747. var isLeft = true;
  1748. if (drag.LastMove.X < touches[0].clientX) isLeft = false;//右移数据
  1749. if (this.DataMoveConfig.Touch.EnableLR)
  1750. {
  1751. if (jsChart.DataMove(moveSetp, isLeft))
  1752. {
  1753. jsChart.UpdataDataoffset();
  1754. jsChart.UpdatePointByCursorIndex();
  1755. jsChart.UpdateFrameMaxMin();
  1756. jsChart.ResetFrameXYSplit();
  1757. jsChart.Draw();
  1758. this.OnKLinePageChange("OnTouchMove");
  1759. }
  1760. else
  1761. {
  1762. if (jsChart.DragDownloadData) jsChart.DragDownloadData();
  1763. }
  1764. }
  1765. drag.LastMove.X = touches[0].clientX;
  1766. drag.LastMove.Y = touches[0].clientY;
  1767. }
  1768. }
  1769. if (this.PhoneTouchInfo)
  1770. {
  1771. this.PhoneTouchInfo.End.X=touches[0].clientX;
  1772. this.PhoneTouchInfo.End.Y=touches[0].clientY;
  1773. }
  1774. if (this.TouchDrag)
  1775. {
  1776. var touchDrag=this.TouchDrag;
  1777. touchDrag.LastMove.X=touches[0].clientX;
  1778. touchDrag.LastMove.Y=touches[0].clientY;
  1779. }
  1780. }
  1781. else if (this.IsPhonePinching(e))
  1782. {
  1783. var phonePinch = jsChart.PhonePinch;
  1784. if (!phonePinch) return;
  1785. phonePinch.Operator=null;
  1786. if (this.EnableZoomUpDown && this.EnableZoomUpDown.Touch===false) return;
  1787. var yHeight = Math.abs(touches[0].pageY - touches[1].pageY);
  1788. var yLastHeight = Math.abs(phonePinch.Last.Y - phonePinch.Last.Y2);
  1789. var yStep = yHeight - yLastHeight;
  1790. var xHeight = Math.abs(touches[0].pageX - touches[1].pageX);
  1791. var xLastHeight = Math.abs(phonePinch.Last.X - phonePinch.Last.X2);
  1792. var xStep = xHeight - xLastHeight;
  1793. var minStep=this.ZoomStepPixel;
  1794. if (Math.abs(yStep) < minStep && Math.abs(xStep) < minStep) return;
  1795. var step = yStep;
  1796. if (Math.abs(yStep) < minStep) step = xStep;
  1797. if (step > 0) //放大
  1798. {
  1799. var cursorIndex = { IsLockRight:this.IsZoomLockRight };
  1800. cursorIndex.Index = parseInt(Math.abs(jsChart.CursorIndex - 0.5).toFixed(0));
  1801. if (!jsChart.Frame.ZoomUp(cursorIndex)) return;
  1802. phonePinch.Operator="ZoomUp";
  1803. jsChart.CursorIndex = cursorIndex.Index;
  1804. jsChart.UpdatePointByCursorIndex();
  1805. jsChart.UpdataDataoffset();
  1806. jsChart.UpdateFrameMaxMin();
  1807. jsChart.ResetFrameXYSplit();
  1808. jsChart.Draw();
  1809. this.OnKLinePageChange("OnTouchMove");
  1810. }
  1811. else //缩小
  1812. {
  1813. var cursorIndex = { IsLockRight:this.IsZoomLockRight };
  1814. cursorIndex.Index = parseInt(Math.abs(jsChart.CursorIndex - 0.5).toFixed(0));
  1815. if (!jsChart.Frame.ZoomDown(cursorIndex)) return;
  1816. phonePinch.Operator="ZoomDown";
  1817. jsChart.CursorIndex = cursorIndex.Index;
  1818. jsChart.UpdataDataoffset();
  1819. jsChart.UpdatePointByCursorIndex();
  1820. jsChart.UpdateFrameMaxMin();
  1821. jsChart.ResetFrameXYSplit();
  1822. jsChart.Draw();
  1823. this.OnKLinePageChange("OnTouchMove");
  1824. }
  1825. phonePinch.Last = { X: touches[0].pageX, Y: touches[0].pageY, X2: touches[1].pageX, Y2: touches[1].pageY };
  1826. }
  1827. }
  1828. this.ontouchend = function (e)
  1829. {
  1830. if (this.ChartSplashPaint && this.ChartSplashPaint.IsEnableSplash == true) return;
  1831. this.FastSlideEvent();
  1832. var bClearDrawPicture=true;
  1833. if (this.CurrentChartDrawPicture)
  1834. {
  1835. var drawPicture=this.CurrentChartDrawPicture;
  1836. if (drawPicture.Status==2 || drawPicture.Status==1 || drawPicture.Status==3)
  1837. {
  1838. drawPicture.PointStatus=drawPicture.Status;
  1839. if (this.FinishChartDrawPicturePoint())
  1840. this.DrawDynamicInfo();
  1841. else
  1842. bClearDrawPicture=false;
  1843. }
  1844. else if (drawPicture.Status==20)
  1845. {
  1846. if (this.FinishMoveChartDrawPicture())
  1847. this.DrawDynamicInfo();
  1848. }
  1849. }
  1850. if (this.EnableZoomIndexWindow)
  1851. {
  1852. var time=Date.now();
  1853. this.PhoneDBClick.AddTouchEnd(time);
  1854. if (this.PhoneDBClick.IsVaildDBClick())
  1855. {
  1856. this.OnTouchDBClick(this.PhoneDBClick.Start);
  1857. this.PhoneDBClick.Clear();
  1858. }
  1859. }
  1860. this.IsOnTouch = false;
  1861. this.LastMovePoint=null;
  1862. if (bClearDrawPicture===true) this.CurrentChartDrawPicture=null;
  1863. JSConsole.Chart.Log('[JSChartContainer:ontouchend] IsOnTouch=' + this.IsOnTouch +' LastDrawStatus=' + this.LastDrawStatus);
  1864. this.ClearDrawMoveTimer();
  1865. this.ClearTouchTimer();
  1866. this.TouchEvent({ EventID:JSCHART_EVENT_ID.ON_PHONE_TOUCH, FunctionName:"OnTouchEnd"}, e);
  1867. this.OnTouchFinished();
  1868. this.TouchDrawCount=0;
  1869. this.PhonePinch=null;
  1870. this.TouchDrag=null;
  1871. }
  1872. this.OnTouchFinished=function()
  1873. {
  1874. if (this.EnableClickModel===true)
  1875. {
  1876. if (this.ClickModel.IsShowCorssCursor==true && this.ClickModel.PreventHide) return;
  1877. if (this.ClickModel.IsShowCorssCursor==true && this.TouchDrawCount>0) return;
  1878. this.ClickModel.IsShowCorssCursor=false;
  1879. this.Draw();
  1880. return;
  1881. }
  1882. this.Draw();//手放开 重新绘制
  1883. }
  1884. this.OnTouchDBClick=function(points)
  1885. {
  1886. var x=points[0].X, y=points[0].Y;
  1887. JSConsole.Chart.Log('[JSChartContainer:OnTouchDBClick] Phone dbclick', x, y);
  1888. var frameId=this.Frame.PtInFrame(x,y);
  1889. JSConsole.Chart.Log("[JSChartContainer::OnTouchDBClick] frameId",frameId);
  1890. if (frameId>=this.Frame.ZoomStartWindowIndex)
  1891. {
  1892. if (this.ZoomIndexWindow(frameId, {X:x, Y:y}))
  1893. {
  1894. this.Frame.SetSizeChange(true);
  1895. this.Draw();
  1896. return true;
  1897. }
  1898. }
  1899. return false;
  1900. }
  1901. this.PtInExtendChartButtons=function(x,y)
  1902. {
  1903. for(var i=0;i<this.ExtendChartPaint.length; ++i)
  1904. {
  1905. var item=this.ExtendChartPaint[i];
  1906. if (item.PtInButtons)
  1907. {
  1908. var button=item.PtInButtons(x,y);
  1909. if (button)
  1910. {
  1911. button.Chart=item;
  1912. return button;
  1913. }
  1914. }
  1915. }
  1916. return null;
  1917. }
  1918. this.ZoomIndexWindow=function(frameID, option) //最大化/最小化指标窗口
  1919. {
  1920. if (frameID<0 || frameID>=this.Frame.SubFrame.length) return false;
  1921. return this.Frame.ZoomIndexWindow(frameID, option);
  1922. }
  1923. this.TouchEvent=function(obj,e)
  1924. {
  1925. var eventID=obj.EventID;
  1926. var event=this.GetEvent(eventID);
  1927. if (!event || !event.Callback) return false;
  1928. var drag=this.PhoneTouchInfo
  1929. if (!drag || !drag.Start || !drag.End ) return false;
  1930. var clientX=drag.End.X;
  1931. var clientY=drag.End.Y;
  1932. var x=drag.End.X;
  1933. var y=drag.End.Y;
  1934. var data=
  1935. {
  1936. X:clientX, Y:clientY, FrameID:-1, FunctionName:obj.FunctionName,
  1937. Drag:
  1938. {
  1939. Start:{ X:drag.Start.X, Y:drag.Start.Y },
  1940. End:{ X:drag.End.X, Y:drag.End.Y }
  1941. }
  1942. };
  1943. var isInClient=false;
  1944. var rtClient = new Rect(this.Frame.ChartBorder.GetLeft(), this.Frame.ChartBorder.GetTop(), this.Frame.ChartBorder.GetWidth(), this.Frame.ChartBorder.GetHeight());
  1945. isInClient = rtClient.IsPointIn(x, y);
  1946. if (isInClient)
  1947. {
  1948. if (this.Frame && this.Frame.IsHScreen)
  1949. {
  1950. var yValueExtend={};
  1951. var yValue=this.Frame.GetYData(x,yValueExtend);
  1952. if (IFrameSplitOperator.IsNumber(yValueExtend.FrameID) && yValueExtend.FrameID>=0)
  1953. {
  1954. var xValue=this.Frame.GetXData(y);
  1955. data.FrameID=yValueExtend.FrameID;
  1956. data.Data={ X:xValue, Y:yValue } ;
  1957. }
  1958. }
  1959. else
  1960. {
  1961. var yValueExtend={};
  1962. var yValue=this.Frame.GetYData(y,yValueExtend);
  1963. if (IFrameSplitOperator.IsNumber(yValueExtend.FrameID) && yValueExtend.FrameID>=0)
  1964. {
  1965. var xValue=this.Frame.GetXData(x);
  1966. data.FrameID=yValueExtend.FrameID;
  1967. data.Data={ X:xValue, Y:yValue } ;
  1968. }
  1969. }
  1970. }
  1971. event.Callback(event, data, this);
  1972. return true;
  1973. }
  1974. this.FullDraw=function(drawType)
  1975. {
  1976. var self = this;
  1977. if (this.ChartCorssCursor) this.ChartCorssCursor.Status=0;
  1978. this.Canvas.clearRect(0, 0, this.UIElement.Width, this.UIElement.Height);
  1979. if (this.ChartSplashPaint && this.ChartSplashPaint.IsEnableSplash) //动画
  1980. {
  1981. this.Frame.ClearCoordinateText();
  1982. this.Frame.Draw({ IsEnableSplash:this.ChartSplashPaint.IsEnableSplash}); //框架
  1983. this.ChartSplashPaint.Draw();
  1984. this.LastDrawStatus = 'FullDraw';
  1985. this.Canvas.draw();
  1986. this.UpdateCorssCursorStatus();
  1987. return;
  1988. }
  1989. this.Frame.SetDrawOtherChart(() =>
  1990. {
  1991. for (var i in this.ExtendChartPaint)
  1992. {
  1993. var item = this.ExtendChartPaint[i];
  1994. if (item.IsCallbackDraw) item.Draw();
  1995. }
  1996. });
  1997. this.Frame.Draw(); //框架
  1998. if (this.Frame.DrawCustomVertical)
  1999. {
  2000. var eventCVericalDraw = this.GetEvent(JSCHART_EVENT_ID.ON_CUSTOM_VERTICAL_DRAW);
  2001. this.Frame.DrawCustomVertical(eventCVericalDraw);
  2002. }
  2003. this.Frame.CalculateLock();
  2004. for (var i=0; i<this.ChartPaint.length; ++i) //图形
  2005. {
  2006. var item = this.ChartPaint[i];
  2007. if (item.ChartFrame && this.IsHideFrame(item.ChartFrame)) continue;
  2008. if (item.IsDrawFirst) item.Draw();
  2009. }
  2010. if (this.Frame.DrawOveraly)
  2011. this.Frame.DrawOveraly(true); //画叠加指标
  2012. for (var i=0; i<this.ChartPaint.length; ++i) //图形2 框架内图形
  2013. {
  2014. var item = this.ChartPaint[i];
  2015. if (item.ChartFrame && this.IsHideFrame(item.ChartFrame)) continue;
  2016. if (!item.IsDrawFirst) item.Draw();
  2017. }
  2018. for (var i=0; i<this.ChartPaintEx.length; ++i) //扩展图形
  2019. {
  2020. var item = this.ChartPaintEx[i];
  2021. item.Draw();
  2022. }
  2023. for (var i=0; i<this.OverlayChartPaint.length; ++i) //叠加股票
  2024. {
  2025. var item = this.OverlayChartPaint[i];
  2026. item.Draw();
  2027. }
  2028. if (this.Frame.DrawOveraly)
  2029. this.Frame.DrawOveraly(false); //画叠加指标
  2030. if (this.Frame.DrawInsideHorizontal) this.Frame.DrawInsideHorizontal(); //框架内部坐标
  2031. this.KLineIncreaseCustomHorizontal();
  2032. if (this.Frame.DrawCustomHorizontal) this.Frame.DrawCustomHorizontal();
  2033. if (this.ChartInfoPaint) this.ChartInfoPaint.Draw();
  2034. this.Frame.DrawLock();
  2035. this.Frame.DrawLogo();
  2036. var bOnTouchDraw=drawType == 'DrawDynamicInfo' || this.IsOnTouch;
  2037. if (this.EnableClickModel==true) //长按十字长留模式
  2038. {
  2039. bOnTouchDraw=(this.ClickModel.IsShowCorssCursor==true);
  2040. }
  2041. var bDrawTooltip=true;
  2042. if (this.CurrentChartDrawPicture && this.CurrentChartDrawPicture.Status!=10) bDrawTooltip=false;
  2043. for (var i=0; i<this.ExtendChartPaint.length; ++i) //动态扩展图形 在动态标题以后画
  2044. {
  2045. var item = this.ExtendChartPaint[i];
  2046. if (item.IsCallbackDraw) continue;
  2047. if (item.ClassName=="KLineTooltipPaint" || item.ClassName=="MinuteTooltipPaint") continue;
  2048. if (item.IsDynamic) continue;
  2049. if (item.DrawAfterTitle) continue; //在绘制标题以后在绘制
  2050. item.Draw();
  2051. }
  2052. if (bOnTouchDraw)
  2053. {
  2054. if (self.ChartCorssCursor && bDrawTooltip) //十字光标
  2055. {
  2056. self.ChartCorssCursor.LastPoint = self.LastPoint;
  2057. self.ChartCorssCursor.CursorIndex = self.CursorIndex;
  2058. self.ChartCorssCursor.Draw();
  2059. }
  2060. }
  2061. var eventTitleDraw = this.GetEvent(JSCHART_EVENT_ID.ON_TITLE_DRAW);
  2062. var eventIndexTitleDraw = this.GetEvent(JSCHART_EVENT_ID.ON_INDEXTITLE_DRAW);
  2063. for (var i=0; i<self.TitlePaint.length; ++i) //标题
  2064. {
  2065. var item = self.TitlePaint[i];
  2066. if (!item.IsDynamic) continue;
  2067. if (item.ClassName == 'DynamicChartTitlePainting') item.OnDrawEvent = eventIndexTitleDraw
  2068. else item.OnDrawEvent = eventTitleDraw;
  2069. item.CursorIndex = self.CursorIndex;
  2070. if (!bOnTouchDraw) //手势离开屏幕 去最后一个数据
  2071. {
  2072. if (this.ChartPaint[0] && this.ChartPaint[0].Data && this.ChartPaint[0].Data.Data)
  2073. {
  2074. var lastDataIndex=this.GetLastDataIndex();
  2075. if (IFrameSplitOperator.IsNumber(lastDataIndex)) item.CursorIndex=lastDataIndex;
  2076. }
  2077. }
  2078. if (item.FullDraw) item.FullDraw();
  2079. }
  2080. if (bOnTouchDraw)
  2081. {
  2082. for (var i=0; i<this.ExtendChartPaint.length; ++i) //动态扩展图形 在动态标题以后画
  2083. {
  2084. var item = this.ExtendChartPaint[i];
  2085. if (item.IsCallbackDraw) continue;
  2086. if (item.ClassName=="KLineTooltipPaint" && !bDrawTooltip) continue;
  2087. if (item.ClassName=="MinuteTooltipPaint" && !bDrawTooltip) continue;
  2088. item.LatestPoint={ X:this.LastPoint.X, Y:this.LastPoint.Y };
  2089. if (item.IsDynamic && item.DrawAfterTitle) item.Draw();
  2090. }
  2091. }
  2092. for(var i=0;i<this.ChartDrawPicture.length;++i)
  2093. {
  2094. var item=this.ChartDrawPicture[i];
  2095. if (item.IsDrawFirst) continue;
  2096. if (item.IsDrawMain && item.IsDrawMain()) continue;
  2097. item.Draw();
  2098. }
  2099. if (this.CurrentChartDrawPicture && this.CurrentChartDrawPicture.Status!=10)
  2100. {
  2101. this.CurrentChartDrawPicture.Draw();
  2102. }
  2103. this.LastDrawStatus = 'FullDraw';
  2104. this.Canvas.draw(false);
  2105. this.UpdateCorssCursorStatus();
  2106. }
  2107. //窗口高度是否是0
  2108. this.IsHideFrame=function(frame)
  2109. {
  2110. if (!frame) return false;
  2111. if (!IFrameSplitOperator.IsNumber(frame.Identify)) return false;
  2112. if (frame.Identify<0) return false;
  2113. if (!this.Frame.SubFrame) return false;
  2114. var item= this.Frame.SubFrame[frame.Identify];
  2115. if (!item) return false;
  2116. return item.Height<=0;
  2117. }
  2118. //当前屏K线涨幅Y轴刻度
  2119. this.KLineIncreaseCustomHorizontal=function()
  2120. {
  2121. if (!this.Frame || !this.Frame.SubFrame) return;
  2122. var frame=this.Frame.SubFrame[0].Frame;
  2123. if (!frame) return;
  2124. var defaultfloatPrecision=GetfloatPrecision(this.Symbol);
  2125. var isPercentage=false; //是否是百分比坐标
  2126. if (frame.YSplitOperator && frame.YSplitOperator.CoordinateType==1) isPercentage=true;
  2127. var isOverlayCoordinate=false; //是否包含叠加股票刻度
  2128. for(var i=0;i<frame.CustomHorizontalInfo.length;++i)
  2129. {
  2130. var info=frame.CustomHorizontalInfo[i];
  2131. if (info.Type==4) isOverlayCoordinate=true;
  2132. if ((isPercentage && info.Type==3) || info.Type==2)
  2133. {
  2134. var item=this.ChartPaint[0];
  2135. if (!item) continue;
  2136. var data=item.Data;
  2137. if (!data || !IFrameSplitOperator.IsNonEmptyArray(data.Data)) continue;
  2138. if (!IFrameSplitOperator.IsNumber(item.DrawKRange.Start) || !IFrameSplitOperator.IsNumber(item.DrawKRange.End)) continue;
  2139. var startKLine=data.Data[item.DrawKRange.Start];
  2140. var endKLine=data.Data[item.DrawKRange.End];
  2141. var value=(endKLine.Close-startKLine.Close)/startKLine.Close;
  2142. info.Value=endKLine.Close;
  2143. if (info.Type==2)
  2144. {
  2145. info.Message[1]=endKLine.Close.toFixed(defaultfloatPrecision);
  2146. if (endKLine.Close>endKLine.Open) info.LineColor=g_JSChartResource.FrameLatestPrice.UpBarColor;
  2147. else if (endKLine.Close<endKLine.Open) info.LineColor=g_JSChartResource.FrameLatestPrice.DownBarColor;
  2148. else info.LineColor=g_JSChartResource.FrameLatestPrice.UnchagneBarColor;
  2149. }
  2150. else
  2151. {
  2152. info.Message[1]=value.toFixed(2)+"%";
  2153. }
  2154. if (this.Name) info.Title=this.Name;
  2155. }
  2156. }
  2157. if (isOverlayCoordinate)
  2158. {
  2159. //叠加股票自定义刻度需要移除重新添加
  2160. var newCustomHorizontalInfo= frame.CustomHorizontalInfo.filter(function(value, index, ary)
  2161. {
  2162. return value.Type!=4
  2163. });
  2164. frame.CustomHorizontalInfo=newCustomHorizontalInfo;
  2165. }
  2166. for(var i=0; i<this.OverlayChartPaint.length; ++i)
  2167. {
  2168. var item=this.OverlayChartPaint[i];
  2169. if (!item) continue;
  2170. if (item.YInfoType!=4) continue;
  2171. var data=item.Data;
  2172. if (!data || !IFrameSplitOperator.IsNonEmptyArray(data.Data)) continue;
  2173. if (!IFrameSplitOperator.IsNumber(item.DrawKRange.Start) || !IFrameSplitOperator.IsNumber(item.DrawKRange.End)) continue;
  2174. var startKLine=data.Data[item.DrawKRange.Start];
  2175. var endKLine=data.Data[item.DrawKRange.End];
  2176. var value=(endKLine.Close-startKLine.Close)/startKLine.Close*100;
  2177. var info=new CoordinateInfo();
  2178. info.Value=endKLine.Close/item.ShowRange.FirstOverlayOpen*item.ShowRange.FirstOpen;
  2179. info.Message[1]=value.toFixed(2)+"%";
  2180. info.LineType=-1;
  2181. info.Type=item.YInfoType; //叠加股票
  2182. info.LineColor=item.Color;
  2183. info.TextColor=g_JSChartResource.FrameLatestPrice.OverlayTextColor;
  2184. if (item.Title) info.Title=item.Title;
  2185. frame.CustomHorizontalInfo.push(info);
  2186. }
  2187. }
  2188. //获取最后一个数据的相对于当前屏的索引
  2189. this.GetLastDataIndex=function()
  2190. {
  2191. if (!this.ChartPaint[0] || !this.ChartPaint[0].Data || !this.ChartPaint[0].Data.Data) return null;
  2192. var hisData=this.ChartPaint[0].Data;
  2193. var dataCount=hisData.Data.length;
  2194. if (dataCount>0) return (dataCount-1)-hisData.DataOffset;
  2195. return null;
  2196. }
  2197. this.Draw = function ()
  2198. {
  2199. if (this.IsDestroy) return;
  2200. if (this.IsFullDraw)
  2201. {
  2202. this.FullDraw('Draw');
  2203. ++this.TouchDrawCount;
  2204. return;
  2205. }
  2206. if (this.IsOnTouch == true && (this.ClassName == 'MinuteChartContainer' || this.ClassName =='MinuteChartHScreenContainer')) return;
  2207. var self = this;
  2208. this.Canvas.clearRect(0, 0, this.UIElement.Width, this.UIElement.Height);
  2209. this.Frame.SetDrawOtherChart(() =>
  2210. {
  2211. for (var i in this.ExtendChartPaint)
  2212. {
  2213. var item = this.ExtendChartPaint[i];
  2214. if (item.IsCallbackDraw) item.Draw();
  2215. }
  2216. });
  2217. //框架
  2218. this.Frame.Draw();
  2219. if (this.Frame.DrawCustomVertical)
  2220. {
  2221. var eventCVericalDraw = this.GetEvent(JSCHART_EVENT_ID.ON_CUSTOM_VERTICAL_DRAW);
  2222. this.Frame.DrawCustomVertical(eventCVericalDraw);
  2223. }
  2224. if (this.ChartSplashPaint && this.ChartSplashPaint.IsEnableSplash)
  2225. {
  2226. this.Frame.DrawInsideHorizontal();
  2227. this.ChartSplashPaint.Draw();
  2228. this.LastDrawStatus = 'Draw';
  2229. this.Canvas.draw();
  2230. return;
  2231. }
  2232. for (var i=0; i<this.ChartPaint.length; ++i)
  2233. {
  2234. var item = this.ChartPaint[i];
  2235. if (item.IsDrawFirst) item.Draw();
  2236. }
  2237. if (this.Frame.DrawOveraly)
  2238. this.Frame.DrawOveraly(true); //画叠加指标
  2239. //框架内图形
  2240. for (var i=0; i<this.ChartPaint.length; ++i)
  2241. {
  2242. var item = this.ChartPaint[i];
  2243. if (!item.IsDrawFirst) item.Draw();
  2244. }
  2245. for (var i=0; i<this.ChartPaintEx.length; ++i)
  2246. {
  2247. var item = this.ChartPaintEx[i];
  2248. item.Draw();
  2249. }
  2250. //叠加股票
  2251. for (var i=0; i<this.OverlayChartPaint.length; ++i)
  2252. {
  2253. var item = this.OverlayChartPaint[i];
  2254. item.Draw();
  2255. }
  2256. if (this.Frame.DrawOveraly)
  2257. this.Frame.DrawOveraly(false); //画叠加指标
  2258. //框架外图形
  2259. for (var i=0; i<this.ExtendChartPaint.length; ++i)
  2260. {
  2261. var item = this.ExtendChartPaint[i];
  2262. if (item.IsCallbackDraw) continue;
  2263. if (!item.IsDynamic && !item.IsAnimation) item.Draw();
  2264. }
  2265. //框架内部坐标
  2266. if (this.Frame.DrawInsideHorizontal) this.Frame.DrawInsideHorizontal();
  2267. if (this.Frame.DrawCustomHorizontal) this.Frame.DrawCustomHorizontal();
  2268. if (this.ChartInfoPaint) this.ChartInfoPaint.Draw();
  2269. this.Frame.DrawLock();
  2270. this.Frame.DrawLogo();
  2271. var eventTitleDraw = this.GetEvent(JSCHART_EVENT_ID.ON_TITLE_DRAW);
  2272. var eventIndexTitleDraw = this.GetEvent(JSCHART_EVENT_ID.ON_INDEXTITLE_DRAW);
  2273. for (var i=0; i<this.TitlePaint.length; ++i)
  2274. {
  2275. var item = this.TitlePaint[i];
  2276. if (!item.IsDynamic) continue;
  2277. if (item.ClassName == 'DynamicChartTitlePainting') item.OnDrawEvent = eventIndexTitleDraw
  2278. else item.OnDrawEvent = eventTitleDraw;
  2279. if (typeof (item.DrawTitle) == 'function') item.DrawTitle();
  2280. }
  2281. for(var i=0;i<this.ChartDrawPicture.length;++i)
  2282. {
  2283. var item=this.ChartDrawPicture[i];
  2284. if (item.IsDrawFirst) continue;
  2285. if (item.IsDrawMain && item.IsDrawMain()) continue;
  2286. item.Draw();
  2287. }
  2288. if (this.CurrentChartDrawPicture && this.CurrentChartDrawPicture.Status!=10)
  2289. {
  2290. this.CurrentChartDrawPicture.Draw();
  2291. }
  2292. this.LastDrawStatus='Draw';
  2293. if (this.IsOnTouch) //手势移动的时候不保存图片
  2294. {
  2295. this.Canvas.draw(false);
  2296. }
  2297. else
  2298. {
  2299. ++this.LastDrawID;
  2300. //坑!!.画图是异步, 保存当前屏图放在回调里面
  2301. //JSConsole.Chart.Log('[JSChartContainer:Draw][ID=' + this.UIElement.ID + '] draw and save snapshot. DrawID=' + this.LastDrawID + ' .....');
  2302. var lastDrawID=this.LastDrawID;
  2303. this.Canvas.draw(false, function ()
  2304. {
  2305. //if (lastDrawID == self.LastDrawID)
  2306. self.Frame.Snapshot(self.SnapshotType); //只保存最后一次的截图
  2307. //JSConsole.Chart.Log('[JSChartContainer:Draw] finish. DrawID('+ lastDrawID +','+ self.LastDrawID +')');
  2308. });
  2309. }
  2310. //JSConsole.Chart.Log('[JSChartContainer:Draw][ID=' + this.UIElement.ID + '] draw dynamic info ......');
  2311. //动态标题都不画了(Canvas.draw 异步画的,如果下面再画会被截屏进去) 只有数据移动的时候在画
  2312. }
  2313. //画动态信息
  2314. this.TempImage=null;
  2315. this.DrawDynamicInfo = function ()
  2316. {
  2317. if (this.IsFullDraw)
  2318. {
  2319. this.FullDraw('DrawDynamicInfo');
  2320. ++this.TouchDrawCount;
  2321. return;
  2322. }
  2323. var self = this;
  2324. var width = this.Frame.ChartBorder.GetChartWidth();
  2325. var height = this.Frame.ChartBorder.GetChartHeight();
  2326. if (self.SnapshotType==1)
  2327. {
  2328. if (this.Frame.ScreenImageData == null) return;
  2329. wx.canvasPutImageData({
  2330. canvasId: this.UIElement.ID,
  2331. x: 0,y: 0,width: width,height: height,
  2332. data: this.Frame.ScreenImageData,
  2333. success(res) { self.DrawDynamicChart(true); }
  2334. })
  2335. }
  2336. else
  2337. {
  2338. if (this.Frame.ScreenImagePath == null) return;
  2339. if (self.Canvas && self.Canvas.DomNode) //新版本2D画布
  2340. {
  2341. //JSConsole.Chart.Log("[DrawDynamicInfo] ScreenImagePath ", this.Frame.ScreenImagePath);
  2342. if (!this.TempImage) this.TempImage= self.Canvas.DomNode.createImage(); //新版本的必须要装成image类 比较坑
  2343. this.TempImage.src = this.Frame.ScreenImagePath;
  2344. //JSConsole.Chart.Log("[DrawDynamicInfo] tempImage ", this.TempImage);
  2345. this.TempImage.onload=()=>
  2346. {
  2347. //JSConsole.Chart.Log("[DrawDynamicInfo] onload ", self.TempImage);
  2348. self.Canvas.clearRect(0, 0, width, height);
  2349. self.Canvas.drawImage(self.TempImage, 0, 0, width, height);
  2350. self.DrawDynamicChart(false);
  2351. }
  2352. }
  2353. else
  2354. {
  2355. self.Canvas.drawImage(this.Frame.ScreenImagePath, 0, 0, width, height);
  2356. self.DrawDynamicChart(false);
  2357. }
  2358. }
  2359. }
  2360. this.DrawDynamicChart = function (bReserve)
  2361. {
  2362. var self = this;
  2363. if (self.ChartCorssCursor)
  2364. {
  2365. self.ChartCorssCursor.LastPoint = self.LastPoint;
  2366. self.ChartCorssCursor.CursorIndex = self.CursorIndex;
  2367. self.ChartCorssCursor.Draw();
  2368. }
  2369. for (var i in self.TitlePaint)
  2370. {
  2371. var item = self.TitlePaint[i];
  2372. if (!item.IsDynamic) continue;
  2373. item.CursorIndex = self.CursorIndex;
  2374. item.Draw();
  2375. }
  2376. for (var i in this.ExtendChartPaint) //动态扩展图形 在动态标题以后画
  2377. {
  2378. var item = this.ExtendChartPaint[i];
  2379. if (item.IsDynamic && item.DrawAfterTitle) item.Draw();
  2380. }
  2381. if (this.EnableAnimation)
  2382. {
  2383. for (var i in this.ExtendChartPaint) //动画
  2384. {
  2385. var item = this.ExtendChartPaint[i];
  2386. if (item.IsAnimation === true) item.Draw();
  2387. }
  2388. }
  2389. this.LastDrawStatus = 'DrawDynamicInfo';
  2390. JSConsole.Chart.Log('[JSChartContainer:DrawDynamicChart][ID=' + this.UIElement.ID + '] draw .....');
  2391. self.Canvas.draw(bReserve, function () {
  2392. JSConsole.Chart.Log('[JSChartContainer:DrawDynamicChart] finish.');
  2393. });
  2394. }
  2395. this.DrawAnimation = function () //绘制动画 如弹幕
  2396. {
  2397. if (!this.EnableAnimation) return;
  2398. if (this.Frame.ScreenImagePath && !this.IsOnTouch)
  2399. {
  2400. for (var i in this.ExtendChartPaint)
  2401. {
  2402. var item = this.ExtendChartPaint[i];
  2403. if (item.IsAnimation === true) item.IsMoveStep = true; //移动弹幕
  2404. }
  2405. this.DrawDynamicInfo();
  2406. }
  2407. var self = this;
  2408. this.UIElement.WebGLCanvas.requestAnimationFrame(() => { this.DrawAnimation(); });
  2409. }
  2410. this.StartAnimation = function (option)
  2411. {
  2412. JSConsole.Chart.Log('[JSChartContainer::StartAnimation] ', this.UIElement.WebGLCanvas);
  2413. if (!this.UIElement.WebGLCanvas) return;
  2414. var bCreated = false; //是否已经创建了弹幕画法
  2415. var barrageData = null;
  2416. for (var i in this.ExtendChartPaint)
  2417. {
  2418. var item = this.ExtendChartPaint[i];
  2419. if (item.ClassName === 'BarragePaint')
  2420. {
  2421. bCreated = true;
  2422. barrageData = item.BarrageList;
  2423. break;
  2424. }
  2425. }
  2426. if (!bCreated)
  2427. {
  2428. var chart = new BarragePaint();
  2429. chart.Canvas = this.Canvas;
  2430. chart.ChartBorder = this.Frame.ChartBorder;
  2431. chart.ChartFrame = this.Frame;
  2432. chart.HQChart = this;
  2433. chart.SetOption(option);
  2434. this.ExtendChartPaint.push(chart);
  2435. barrageData = chart.BarrageList;
  2436. }
  2437. this.EnableAnimation = true;
  2438. var self = this;
  2439. this.UIElement.WebGLCanvas.requestAnimationFrame(()=> { this.DrawAnimation(); });
  2440. return barrageData;
  2441. }
  2442. this.StopAnimation = function ()
  2443. {
  2444. this.EnableAnimation = false;
  2445. this.DrawDynamicInfo();
  2446. }
  2447. this.OnMouseMove = function (x, y, e, bFullDraw)
  2448. {
  2449. var lastY = this.LastPoint.Y;
  2450. this.LastPoint.X = x;
  2451. this.LastPoint.Y = y;
  2452. var lastCursorIndex = this.CursorIndex;
  2453. this.CursorIndex = this.Frame.GetXData(x);
  2454. if ( this.ClassName=="KLineChartContainer" || this.ClassName=="KLineChartHScreenContainer" )
  2455. {
  2456. if (lastCursorIndex == this.CursorIndex && Math.abs(lastY - y) < 1) return; //一个一个数据移动
  2457. }
  2458. else
  2459. {
  2460. if (parseInt(lastCursorIndex - 0.5) == parseInt(this.CursorIndex - 0.5) && Math.abs(lastY - y) < 1) return; //一个一个数据移动
  2461. }
  2462. if (bFullDraw)
  2463. {
  2464. this.FullDraw();
  2465. }
  2466. else
  2467. {
  2468. if (this.IsForceLandscape) this.Draw();//横屏图片太大不让贴,分两张图贴,多次截图的函数是坏的, 直接重画了
  2469. else this.DrawDynamicInfo();
  2470. }
  2471. }
  2472. this.MoveCorssCursor=function(point, e)
  2473. {
  2474. var x = point.X;
  2475. var y = point.Y;
  2476. this.OnMouseMove(x,y,e,true);
  2477. }
  2478. this.OnDoubleClick = function (x, y, e)
  2479. {
  2480. //JSConsole.Chart.Log(e);
  2481. }
  2482. this.UpdatePointByCursorIndex = function ()
  2483. {
  2484. var x=null, y=null;
  2485. x= this.Frame.GetXFromIndex(this.CursorIndex);
  2486. var index = Math.abs(this.CursorIndex - 0.5);
  2487. index = parseInt(index.toFixed(0));
  2488. if (this.ClassName == 'KLineChartContainer') index = this.CursorIndex;
  2489. var data = this.Frame.Data;
  2490. if (data.DataOffset + index < data.Data.length)
  2491. {
  2492. var close=data.Data[data.DataOffset + index].Close;
  2493. y=this.Frame.GetYFromData(close);
  2494. }
  2495. if (this.ClassName=="KLineChartHScreenContainer" || this.ClassName=="MinuteChartHScreenContainer")
  2496. { //横屏坐标互换下
  2497. this.LastPoint.Y=x;
  2498. if (IFrameSplitOperator.IsNumber(y)) this.LastPoint.X=y;
  2499. }
  2500. else
  2501. {
  2502. this.LastPoint.X=x;
  2503. if (IFrameSplitOperator.IsNumber(y)) this.LastPoint.Y=y;
  2504. }
  2505. }
  2506. this.ResetFrameXYSplit = function ()
  2507. {
  2508. if (typeof (this.Frame.ResetXYSplit) == 'function') this.Frame.ResetXYSplit();
  2509. }
  2510. this.UpdateFrameMaxMinV2=function()
  2511. {
  2512. var mapFrame=new Map(); //key=frameid, value:{ ChartPaint:[] }
  2513. for(var i=0;i<this.Frame.SubFrame.length;++i)
  2514. {
  2515. var subItem=this.Frame.SubFrame[i];
  2516. if (!subItem || !subItem.Frame) continue;
  2517. var frame=subItem.Frame;
  2518. frame.YCustomSplit=true; //自定义刻度每次都调用
  2519. var key=frame.Identify;
  2520. var item=
  2521. {
  2522. ID:key, Frame:frame, ChartPaint:[] , Max:null, Min:null,
  2523. OverlayFrame:[], //共享坐标
  2524. SingleOverlay:[], //独立坐标
  2525. MainOverlayFrame:[null, null], //叠加坐标在主坐标显示[0]=left [1]=right
  2526. };
  2527. for(var j=0;j<subItem.OverlayIndex.length;++j)
  2528. {
  2529. var overlayItem=subItem.OverlayIndex[j];
  2530. var overlayFrame=overlayItem.Frame;
  2531. if (overlayFrame.IsShowMainFrame===1) item.MainOverlayFrame[0]= overlayFrame;
  2532. else if (overlayFrame.IsShowMainFrame===2) item.MainOverlayFrame[1]= overlayFrame;
  2533. if (overlayFrame.IsShareY)
  2534. {
  2535. if (!overlayFrame.MainFrame) continue;
  2536. if (overlayFrame.IsCalculateYMaxMin===false) continue; //叠加坐标Y轴不调整
  2537. item.OverlayFrame.push(overlayFrame);
  2538. for(var k=0; k<overlayItem.ChartPaint.length; ++k)
  2539. {
  2540. var chart=overlayItem.ChartPaint[k];
  2541. item.ChartPaint.push(chart);
  2542. }
  2543. }
  2544. else
  2545. {
  2546. item.SingleOverlay.push(overlayItem);
  2547. }
  2548. }
  2549. mapFrame.set(key, item);
  2550. }
  2551. for(var i=0;i<this.ChartPaint.length;++i)
  2552. {
  2553. var chart=this.ChartPaint[i];
  2554. var key=chart.ChartFrame.Identify;
  2555. if (!mapFrame.has(key)) continue;
  2556. var finder=mapFrame.get(key);
  2557. finder.ChartPaint.push(chart);
  2558. }
  2559. for(var i=0;i<this.OverlayChartPaint.length;++i)
  2560. {
  2561. var chart=this.OverlayChartPaint[i];
  2562. if (!chart.ChartFrame) continue;
  2563. var key=chart.ChartFrame.Identify;
  2564. if (!mapFrame.has(key)) continue;
  2565. var finder=mapFrame.get(key);
  2566. finder.ChartPaint.push(chart);
  2567. }
  2568. for(var mapItem of mapFrame)
  2569. {
  2570. var item=mapItem[1];
  2571. var frame=item.Frame;
  2572. //计算主框架最大最小
  2573. for(var i=0;i<item.ChartPaint.length;++i)
  2574. {
  2575. var chart=item.ChartPaint[i];
  2576. if (chart.IsShow==false) continue; //隐藏的图形不计算
  2577. if (chart.NotSupportMessage) continue;
  2578. if (!chart.ChartFrame) continue;
  2579. var range=chart.GetMaxMin();
  2580. if (range==null || range.Max==null || range.Min==null) continue;
  2581. if (item.Max==null || item.Max<range.Max) item.Max=range.Max;
  2582. if (item.Min==null || item.Min>range.Min) item.Min=range.Min;
  2583. }
  2584. if (item.Frame.YSpecificMaxMin) //固定坐标
  2585. {
  2586. item.Min=item.Frame.YSpecificMaxMin.Max;
  2587. item.Max=item.Frame.YSpecificMaxMin.Min;
  2588. }
  2589. if (!IFrameSplitOperator.IsNumber(frame.YMaxMin.Max) || frame.YMaxMin.Max!=item.Max)
  2590. {
  2591. frame.YMaxMin.Max=item.Max;
  2592. frame.XYSplit=true;
  2593. }
  2594. if (!IFrameSplitOperator.IsNumber(frame.YMaxMin.Min) || frame.YMaxMin.Min!=item.Min)
  2595. {
  2596. frame.YMaxMin.Min=item.Min
  2597. frame.XYSplit=true;
  2598. }
  2599. if (frame.XYSplit)
  2600. {
  2601. var max=10, min=0;
  2602. if (item.Max!=null) max=item.Max;
  2603. if (item.Min!=null) min=item.Min;
  2604. frame.HorizontalMax=max;
  2605. frame.HorizontalMin=min;
  2606. }
  2607. else
  2608. {
  2609. frame.XSplit=true;
  2610. }
  2611. //共享Y轴叠加指标坐标同步
  2612. for(var j=0;j<item.OverlayFrame.length;++j)
  2613. {
  2614. item.OverlayFrame[j].XYSplit=true;
  2615. }
  2616. //叠加坐标显示在主图坐标 需要同步
  2617. for(var i=0;i<item.MainOverlayFrame.length;++i)
  2618. {
  2619. var subItem=item.MainOverlayFrame[i];
  2620. if (subItem) subItem.XYSplit=true;
  2621. }
  2622. //独立坐标叠加指标
  2623. for(var i=0;i<item.SingleOverlay.length;++i)
  2624. {
  2625. var overlayItem=item.SingleOverlay[i];
  2626. overlayItem.UpdateFrameMaxMin();
  2627. }
  2628. }
  2629. }
  2630. this.UpdateFrameMaxMin = function ()
  2631. {
  2632. this.UpdateFrameMaxMinV2();
  2633. return;
  2634. var frameMaxMinData = new Array();
  2635. var chartPaint = new Array();
  2636. for (var i=0; i<this.ChartPaint.length; ++i)
  2637. {
  2638. var item=this.ChartPaint[i];
  2639. if (item.IsShow==false) continue; //隐藏的图形不计算
  2640. chartPaint.push(item);
  2641. }
  2642. for (var i=0; i<this.OverlayChartPaint.length; ++i)
  2643. {
  2644. chartPaint.push(this.OverlayChartPaint[i]);
  2645. }
  2646. for (var i=0; i<chartPaint.length; ++i)
  2647. {
  2648. var paint = chartPaint[i];
  2649. var range = paint.GetMaxMin();
  2650. if (range == null || range.Max == null || range.Min == null) continue;
  2651. var frameItem = null;
  2652. for (var j=0; j<frameMaxMinData.length; ++j)
  2653. {
  2654. if (frameMaxMinData[j].Frame == paint.ChartFrame)
  2655. {
  2656. frameItem = frameMaxMinData[j];
  2657. break;
  2658. }
  2659. }
  2660. if (frameItem)
  2661. {
  2662. if (frameItem.Range.Max < range.Max) frameItem.Range.Max = range.Max;
  2663. if (frameItem.Range.Min > range.Min) frameItem.Range.Min = range.Min;
  2664. }
  2665. else
  2666. {
  2667. frameItem = { OverlayFrame:[] };
  2668. frameItem.Frame = paint.ChartFrame;
  2669. frameItem.Range = range;
  2670. frameMaxMinData.push(frameItem);
  2671. }
  2672. }
  2673. var mapFrame=new Map();
  2674. for(var i=0;i<frameMaxMinData.length;++i)
  2675. {
  2676. var item=frameMaxMinData[i];
  2677. mapFrame.set(item.Frame.Identify,item);
  2678. }
  2679. //叠加坐标Y轴使用主图指标, 最大最小值
  2680. for(var i=0;i<this.Frame.SubFrame.length;++i)
  2681. {
  2682. var subFrame=this.Frame.SubFrame[i];
  2683. for(var j=0;j<subFrame.OverlayIndex.length;++j)
  2684. {
  2685. var overlayItem=subFrame.OverlayIndex[j];
  2686. var overlayFrame=overlayItem.Frame;
  2687. if (overlayFrame.IsShareY!=true) continue;
  2688. if (!overlayFrame.MainFrame) continue;
  2689. if (!mapFrame.has(overlayFrame.MainFrame.Identify)) continue;
  2690. var frameItem=mapFrame.get(overlayFrame.MainFrame.Identify);
  2691. if (!frameItem) continue;
  2692. frameItem.OverlayFrame.push(overlayFrame);
  2693. if (overlayFrame.IsCalculateYMaxMin===false) continue; //叠加坐标Y轴不调整
  2694. for(var k=0; k<overlayItem.ChartPaint.length; ++k)
  2695. {
  2696. var paint=overlayItem.ChartPaint[k];
  2697. var range=paint.GetMaxMin();
  2698. if (range==null || range.Max==null || range.Min==null) continue;
  2699. if (frameItem.Range.Max<range.Max) frameItem.Range.Max=range.Max;
  2700. if (frameItem.Range.Min>range.Min) frameItem.Range.Min=range.Min;
  2701. }
  2702. }
  2703. }
  2704. for (var i=0; i<frameMaxMinData.length; ++i)
  2705. {
  2706. var item = frameMaxMinData[i];
  2707. if (!item.Frame || !item.Range) continue;
  2708. if (item.Range.Max == null || item.Range.Min == null) continue;
  2709. if (item.Frame.YSpecificMaxMin)
  2710. {
  2711. item.Frame.HorizontalMax = item.Frame.YSpecificMaxMin.Max;
  2712. item.Frame.HorizontalMin = item.Frame.YSpecificMaxMin.Min;
  2713. }
  2714. else
  2715. {
  2716. item.Frame.HorizontalMax = item.Range.Max;
  2717. item.Frame.HorizontalMin = item.Range.Min;
  2718. }
  2719. item.Frame.XYSplit = true;
  2720. for(var j=0; j<item.OverlayFrame.length; ++j)
  2721. {
  2722. item.OverlayFrame[j].XYSplit=true;
  2723. }
  2724. }
  2725. //更新独立子坐标
  2726. for(var i=0;i<this.Frame.SubFrame.length;++i)
  2727. {
  2728. var subFrame=this.Frame.SubFrame[i];
  2729. for(var j=0;j<subFrame.OverlayIndex.length;++j)
  2730. {
  2731. var overlayItem=subFrame.OverlayIndex[j];
  2732. if (overlayItem.Frame.IsShareY===true) continue;
  2733. overlayItem.UpdateFrameMaxMin();
  2734. }
  2735. }
  2736. }
  2737. this.DataMoveLeft = function () {
  2738. var data = null;
  2739. if (!this.Frame.Data) data = this.Frame.Data;
  2740. else data = this.Frame.SubFrame[0].Frame.Data;
  2741. if (!data) return false;
  2742. if (data.DataOffset <= 0) return false;
  2743. --data.DataOffset;
  2744. return true;
  2745. }
  2746. this.DataMoveRight = function () {
  2747. var data = null;
  2748. if (!this.Frame.Data) data = this.Frame.Data;
  2749. else data = this.Frame.SubFrame[0].Frame.Data;
  2750. if (!data) return false;
  2751. var xPointcount = 0;
  2752. if (this.Frame.XPointCount) xPointcount = this.Frame.XPointCount;
  2753. else xPointcount = this.Frame.SubFrame[0].Frame.XPointCount;
  2754. if (!xPointcount) return false;
  2755. if (xPointcount + data.DataOffset >= data.Data.length) return false;
  2756. ++data.DataOffset;
  2757. return true;
  2758. }
  2759. this.UpdataDataoffset = function ()
  2760. {
  2761. var data = null;
  2762. if (this.Frame.Data) data = this.Frame.Data;
  2763. else data = this.Frame.SubFrame[0].Frame.Data;
  2764. if (!data) return;
  2765. for (var i=0; i<this.ChartPaint.length; ++i)
  2766. {
  2767. var item = this.ChartPaint[i];
  2768. if (!item.Data) continue;
  2769. item.Data.DataOffset = data.DataOffset;
  2770. }
  2771. for (var i=0; i<this.OverlayChartPaint.length; ++i)
  2772. {
  2773. var item = this.OverlayChartPaint[i];
  2774. if (!item.Data) continue;
  2775. item.Data.DataOffset = data.DataOffset;
  2776. }
  2777. //叠加指标当前显示的数据偏移
  2778. for (var i=0; i<this.Frame.SubFrame.length; ++i)
  2779. {
  2780. var subFrame=this.Frame.SubFrame[i];
  2781. for(var j=0; j<subFrame.OverlayIndex.length; ++j)
  2782. {
  2783. var overlayItem=subFrame.OverlayIndex[j];
  2784. for(var k=0; k<overlayItem.ChartPaint.length; ++k)
  2785. {
  2786. var item=overlayItem.ChartPaint[k];
  2787. if (!item.Data) continue;
  2788. item.Data.DataOffset=data.DataOffset;
  2789. }
  2790. }
  2791. }
  2792. }
  2793. this.DataMove = function (step, isLeft)
  2794. {
  2795. step=parseInt(step/this.StepPixel);
  2796. if (step<=0) return false;
  2797. var data = null;
  2798. if (!this.Frame.Data) data = this.Frame.Data;
  2799. else data = this.Frame.SubFrame[0].Frame.Data;
  2800. if (!data) return false;
  2801. var xPointcount = 0;
  2802. if (this.Frame.XPointCount) xPointcount = this.Frame.XPointCount;
  2803. else xPointcount = this.Frame.SubFrame[0].Frame.XPointCount;
  2804. if (!xPointcount) return false;
  2805. if (isLeft) //-->
  2806. {
  2807. if (this.RightSpaceCount > 0)
  2808. {
  2809. if (xPointcount + data.DataOffset >= data.Data.length + this.RightSpaceCount) return false;
  2810. data.DataOffset += step;
  2811. if (data.DataOffset + xPointcount >= data.Data.length + this.RightSpaceCount)
  2812. data.DataOffset = data.Data.length - (xPointcount - this.RightSpaceCount);
  2813. }
  2814. else
  2815. {
  2816. if (xPointcount + data.DataOffset >= data.Data.length) return false;
  2817. data.DataOffset += step;
  2818. if (data.DataOffset + xPointcount >= data.Data.length)
  2819. data.DataOffset = data.Data.length - xPointcount;
  2820. }
  2821. return true;
  2822. }
  2823. else //<--
  2824. {
  2825. if (data.DataOffset <= 0) return false;
  2826. data.DataOffset -= step;
  2827. if (data.DataOffset < 0) data.DataOffset = 0;
  2828. return true;
  2829. }
  2830. }
  2831. //获取鼠标在当前子窗口id
  2832. this.GetSubFrameIndex = function (x, y) {
  2833. if (!this.Frame.SubFrame || this.Frame.SubFrame.length <= 0) return -1;
  2834. for (var i in this.Frame.SubFrame) {
  2835. var frame = this.Frame.SubFrame[i].Frame;
  2836. var left = frame.ChartBorder.GetLeft();
  2837. var top = frame.ChartBorder.GetTop();
  2838. var height = frame.ChartBorder.GetHeight();
  2839. var width = frame.ChartBorder.GetWidth();
  2840. this.Canvas.rect(left, top, width, height);
  2841. if (this.Canvas.isPointInPath(x, y)) return parseInt(i);
  2842. }
  2843. return 0;
  2844. }
  2845. //根据X坐标获取数据索引
  2846. this.GetDataIndexByPoint = function (x) {
  2847. var frame = this.Frame;
  2848. if (this.Frame.SubFrame && this.Frame.SubFrame.length > 0) frame = this.Frame.SubFrame[0].Frame;
  2849. var data = null;
  2850. if (this.Frame.Data)
  2851. data = this.Frame.Data;
  2852. else
  2853. data = this.Frame.SubFrame[0].Frame.Data;
  2854. if (!data || !frame) return;
  2855. var index = parseInt(frame.GetXData(x));
  2856. //JSConsole.Chart.Log('x='+ x +' date='+data.Data[data.DataOffset+index].Date);
  2857. return data.DataOffset + index;
  2858. }
  2859. this.SaveToImage = function (callback)
  2860. {
  2861. let width = this.UIElement.Width;
  2862. let height = this.UIElement.Height;;
  2863. JSConsole.Chart.Log('[JSChartContainer::SaveToImage]', this.UIElement);
  2864. wx.canvasToTempFilePath({
  2865. x: 0,
  2866. y: 0,
  2867. width: width,
  2868. height: height,
  2869. canvasId: this.UIElement.ID,
  2870. success: function (res)
  2871. {
  2872. let data = { ImagePath: res.tempFilePath, Width: width, Height: height };
  2873. if (typeof (callback) == 'function') callback(data);
  2874. }
  2875. })
  2876. }
  2877. //全屏提示信息 { Title:提示信息, Draw:false/true 是否立即重绘, }
  2878. this.EnableSplashScreen=function(option)
  2879. {
  2880. if (!this.ChartSplashPaint) return;
  2881. if (!option) return;
  2882. if (IFrameSplitOperator.IsString(option.Title)) this.ChartSplashPaint.SetTitle(option.Title);
  2883. this.ChartSplashPaint.EnableSplash(true);
  2884. if (option.Draw===false) return;
  2885. this.Draw();
  2886. }
  2887. //设置指标窗口属性 windowItem=SetOption.Windows[i], frameItem=SetOption.Frames[i];
  2888. this.SetSubFrameAttribute=function(subFrame, windowItem, frameItem)
  2889. {
  2890. if (!subFrame || !subFrame.Frame) return;
  2891. var frame=subFrame.Frame;
  2892. if (windowItem)
  2893. {
  2894. if (IFrameSplitOperator.IsNumber(windowItem.IndexParamSpace)) frame.IndexParamSpace = windowItem.IndexParamSpace;
  2895. if (IFrameSplitOperator.IsNumber(windowItem.IndexTitleSpace))frame.IndexTitleSpace = windowItem.IndexTitleSpace;
  2896. if (IFrameSplitOperator.IsBool(windowItem.IsDrawTitleBG)) frame.IsDrawTitleBG=windowItem.IsDrawTitleBG;
  2897. if (IFrameSplitOperator.IsBool(windowItem.IsShowNameArrow)) frame.IsShowNameArrow=windowItem.IsShowNameArrow;
  2898. if (IFrameSplitOperator.IsBool(windowItem.IsShowTitleArrow)) frame.IsShowTitleArrow=windowItem.IsShowTitleArrow;
  2899. if (IFrameSplitOperator.IsBool(windowItem.IsSinlgeLine)) frame.IsSinlgeLine=windowItem.IsSinlgeLine;
  2900. if (IFrameSplitOperator.IsNumber(windowItem.TitleHeight)) frame.ChartBorder.TitleHeight = windowItem.TitleHeight;
  2901. if (IFrameSplitOperator.IsBool(windowItem.IsShowIndexName)) frame.IsShowIndexName = windowItem.IsShowIndexName;
  2902. if (!IFrameSplitOperator.IsUndefined(windowItem.HorizontalReserved)) frame.HorizontalReserved=windowItem.HorizontalReserved;
  2903. }
  2904. if (frameItem)
  2905. {
  2906. if (IFrameSplitOperator.IsNumber(frameItem.SplitCount)) frame.YSplitOperator.SplitCount = frameItem.SplitCount;
  2907. if (frameItem.Custom) frame.YSplitOperator.Custom = frameItem.Custom;
  2908. if (frameItem.StringFormat) frame.YSplitOperator.StringFormat = frameItem.StringFormat;
  2909. if (IFrameSplitOperator.IsNumber(frameItem.SplitType))
  2910. {
  2911. frame.YSplitOperator.SplitType = frameItem.SplitType;
  2912. frame.YSplitOperator.DefaultSplitType=frameItem.SplitType;
  2913. }
  2914. if (IFrameSplitOperator.IsNumber(frameItem.FilterType)) frame.YSplitOperator.FilterType=frameItem.FilterType;
  2915. if (IFrameSplitOperator.IsNumber(frameItem.FloatPrecision)) frame.YSplitOperator.FloatPrecision = frameItem.FloatPrecision; //强制指定小数位数(主图有效)
  2916. if (IFrameSplitOperator.IsBool(frameItem.IsShowBorder)) frame.IsShowBorder = frameItem.IsShowBorder;
  2917. if (IFrameSplitOperator.IsBool(frameItem.IsShowXLine)) frame.IsShowXLine = frameItem.IsShowXLine;
  2918. if (IFrameSplitOperator.IsBool(frameItem.IsShowYLine)) frame.IsShowYLine=frameItem.IsShowYLine;
  2919. if (frameItem.XMessageAlign == 'bottom') frame.XMessageAlign = frameItem.XMessageAlign;
  2920. if (IFrameSplitOperator.IsBool(frameItem.IsShowTitle)) frame.IsShowTitle = frameItem.IsShowTitle;
  2921. if (IFrameSplitOperator.IsBool(frameItem.IsShowIndexTitle)) frame.IsShowTitle=frameItem.IsShowIndexTitle;
  2922. if (IFrameSplitOperator.IsBool(frameItem.IsShowLeftText)) frame.IsShowYText[0] = frameItem.IsShowLeftText; //显示左边刻度
  2923. if (IFrameSplitOperator.IsBool(frameItem.IsShowRightText)) frame.IsShowYText[1] = frameItem.IsShowRightText; //显示右边刻度
  2924. if (IFrameSplitOperator.IsNumber(frameItem.TopSpace)) frame.ChartBorder.TopSpace = frameItem.TopSpace;
  2925. if (IFrameSplitOperator.IsNumber(frameItem.BottomSpace)) frame.ChartBorder.BottomSpace = frameItem.BottomSpace;
  2926. if (IFrameSplitOperator.IsNumber(frameItem.Height)) subFrame.Height = frameItem.Height;
  2927. if (IFrameSplitOperator.IsNumber(frameItem.BorderLine)) frame.BorderLine=frameItem.BorderLine;
  2928. if (IFrameSplitOperator.IsNumber(frameItem.YTextBaseline)) frame.YTextBaseline=frameItem.YTextBaseline;
  2929. //分时图
  2930. if (frameItem.RightText && frame.YSplitOperator.RightTextConfig) //主图右侧坐标设置
  2931. {
  2932. var subItem=frameItem.RightText;
  2933. if (IFrameSplitOperator.IsNumber(subItem.Format)) frame.YSplitOperator.RightTextConfig.Format=subItem.Format;
  2934. if (subItem.Format==2) frame.MultiTextFormat=1;
  2935. if (subItem.Percentage && IFrameSplitOperator.IsNumber(subItem.Percentage.Dec)) frame.YSplitOperator.RightTextConfig.Percentage.Dec=subItem.Percentage.Dec;
  2936. }
  2937. }
  2938. }
  2939. this.SetSubFrameOption=function(subFrame, option)
  2940. {
  2941. if (!option) return;
  2942. if (option.Window)
  2943. {
  2944. var item=option.Window;
  2945. if (IFrameSplitOperator.IsBool(item.IsDrawTitleBG)) subFrame.Frame.IsDrawTitleBG=item.IsDrawTitleBG;
  2946. if (IFrameSplitOperator.IsBool(item.IsShowNameArrow)) subFrame.Frame.IsShowNameArrow=item.IsShowNameArrow;
  2947. }
  2948. if (IFrameSplitOperator.IsNumber(option.SplitCount)) subFrame.Frame.YSplitOperator.SplitCount=option.SplitCount;
  2949. if (IFrameSplitOperator.IsNumber(option.TitleHeight)) subFrame.Frame.ChartBorder.TitleHeight=option.TitleHeight;
  2950. if (IFrameSplitOperator.IsBool(option.IsShowTitleArrow)) subFrame.Frame.IsShowTitleArrow=option.IsShowTitleArrow;
  2951. if (IFrameSplitOperator.IsBool(option.IsSinlgeLine)) subFrame.Frame.IsSinlgeLine=option.IsSinlgeLine;
  2952. if (IFrameSplitOperator.IsBool(option.IsShowIndexName)) subFrame.Frame.IsShowIndexName=option.IsShowIndexName;
  2953. if (IFrameSplitOperator.IsBool(option.IsShowOverlayIndexName)) subFrame.Frame.IsShowOverlayIndexName=option.IsShowOverlayIndexName;
  2954. if (IFrameSplitOperator.IsNumber(option.IndexParamSpace)) subFrame.Frame.IndexParamSpace=option.IndexParamSpace;
  2955. if (IFrameSplitOperator.IsNumber(option.IndexTitleSpace)) subFrame.Frame.IndexTitleSpace=option.IndexTitleSpace;
  2956. if (IFrameSplitOperator.IsBool(option.IsShowXLine)) subFrame.Frame.IsShowXLine=option.IsShowXLine;
  2957. if (IFrameSplitOperator.IsBool(option.IsShowYLine)) subFrame.Frame.IsShowYLine=option.IsShowYLine;
  2958. if (IFrameSplitOperator.IsBool(option.IsShowIndexTitle)) subFrame.Frame.IsShowTitle=option.IsShowIndexTitle;
  2959. if (IFrameSplitOperator.IsBool(option.IsShowLeftText)) subFrame.Frame.IsShowYText[0] = option.IsShowLeftText; //显示左边刻度
  2960. if (IFrameSplitOperator.IsBool(option.IsShowRightText)) subFrame.Frame.IsShowYText[1] = option.IsShowRightText; //显示右边刻度
  2961. if (IFrameSplitOperator.IsNumber(option.Height)) subFrame.Height=option.Height; //高度
  2962. }
  2963. this.AddNewSubFrame=function(option)
  2964. {
  2965. var index=this.Frame.SubFrame.length;
  2966. var subFrame=this.CreateSubFrameItem(index);
  2967. this.Frame.SubFrame[index]=subFrame;
  2968. var titlePaint=new DynamicChartTitlePainting();
  2969. titlePaint.Frame=this.Frame.SubFrame[index].Frame;
  2970. titlePaint.Canvas=this.Canvas;
  2971. titlePaint.LanguageID=this.LanguageID;
  2972. titlePaint.GetEventCallback=(id)=> { return this.GetEventCallback(id); }
  2973. this.TitlePaint[index+1]=titlePaint;
  2974. this.SetSubFrameOption(subFrame,option);
  2975. this.UpdateSubFrameDataWidth(subFrame.Frame);
  2976. //最后一个显示X轴坐标
  2977. for(var i=0;i<this.Frame.SubFrame.length;++i)
  2978. {
  2979. var item=this.Frame.SubFrame[i].Frame;
  2980. if (i==this.Frame.SubFrame.length-1) item.XSplitOperator.ShowText=true;
  2981. else item.XSplitOperator.ShowText=false;
  2982. }
  2983. this.UpdataDataoffset(); //更新数据偏移
  2984. this.Frame.SetSizeChange(true);
  2985. if (this.UpdateXShowText) this.UpdateXShowText();
  2986. this.ResetFrameXYSplit();
  2987. this.UpdateFrameMaxMin(); //调整坐标最大 最小值
  2988. this.Draw();
  2989. return index;
  2990. }
  2991. this.UpdateSubFrameDataWidth=function(frame)
  2992. {
  2993. //同步柱子宽度
  2994. var mainFrame=this.Frame.SubFrame[0].Frame;
  2995. frame.XPointCount= mainFrame.XPointCount;
  2996. frame.ZoomIndex= mainFrame.ZoomIndex;
  2997. frame.DataWidth= mainFrame.DataWidth;
  2998. frame.DistanceWidth= mainFrame.DistanceWidth;
  2999. frame.LastCalculateStatus.Width=mainFrame.LastCalculateStatus.Width;
  3000. frame.LastCalculateStatus.XPointCount=mainFrame.LastCalculateStatus.XPointCount;
  3001. }
  3002. //增加一个指标窗口
  3003. this.AddIndexWindow=function(indexName,option)
  3004. {
  3005. //查找系统指标
  3006. let scriptData = new JSCommonIndexScript.JSIndexScript();
  3007. let indexInfo = scriptData.Get(indexName);
  3008. if (!indexInfo) return;
  3009. JSIndexScript.ModifyAttribute(indexInfo, option);
  3010. var index=this.AddNewSubFrame(option);
  3011. /*
  3012. var indexData =
  3013. {
  3014. Name:indexInfo.Name, Script:indexInfo.Script, Args: indexInfo.Args, ID:indexName ,
  3015. //扩展属性 可以是空
  3016. KLineType:indexInfo.KLineType, YSpecificMaxMin:indexInfo.YSpecificMaxMin, YSplitScale:indexInfo.YSplitScale,
  3017. FloatPrecision:indexInfo.FloatPrecision, Condition:indexInfo.Condition,StringFormat:indexInfo.StringFormat,
  3018. OutName:indexInfo.OutName
  3019. };
  3020. if (option)
  3021. {
  3022. if (option.FloatPrecision>=0) indexData.FloatPrecision=option.FloatPrecision;
  3023. if (option.StringFormat>0) indexData.StringFormat=option.StringFormat;
  3024. if (option.Args) indexData.Args=option.Args;
  3025. }
  3026. */
  3027. this.WindowIndex[index] = new ScriptIndex(indexInfo.Name, indexInfo.Script, indexInfo.Args,indexInfo); //脚本执行
  3028. if (this.ClassName=="MinuteChartContainer" || this.ClassName=="MinuteChartHScreenContainer")
  3029. var bindData=this.SourceData;
  3030. else
  3031. var bindData=this.ChartPaint[0].Data;
  3032. this.BindIndexData(index,bindData); //执行脚本
  3033. }
  3034. //增加一个自定义指标窗口
  3035. this.AddScriptIndexWindow=function(indexInfo, option)
  3036. {
  3037. if (!indexInfo || !indexInfo.Script || !indexInfo.Name) return;
  3038. var index=this.AddNewSubFrame(option);
  3039. this.WindowIndex[index] = new ScriptIndex(indexInfo.Name, indexInfo.Script, indexInfo.Args, indexInfo)
  3040. if (this.ClassName=="MinuteChartContainer" || this.ClassName=="MinuteChartHScreenContainer")
  3041. var bindData=this.SourceData;
  3042. else
  3043. var bindData=this.ChartPaint[0].Data;
  3044. this.BindIndexData(index,bindData); //执行脚本
  3045. }
  3046. //增加一个远程指标窗口
  3047. this.AddAPIIndexWindow=function(indexInfo, option)
  3048. {
  3049. if (!indexInfo.API) return;
  3050. var apiItem = indexInfo.API;
  3051. var index=this.AddNewSubFrame(option);
  3052. this.WindowIndex[index] = new APIScriptIndex(apiItem.Name, apiItem.Script, apiItem.Args, indexInfo);
  3053. if (this.ClassName=="MinuteChartContainer" || this.ClassName=="MinuteChartHScreenContainer")
  3054. var bindData=this.SourceData;
  3055. else
  3056. var bindData=this.ChartPaint[0].Data;
  3057. this.BindIndexData(index,bindData); //执行脚本
  3058. }
  3059. this.SetLanguage=function(language)
  3060. {
  3061. var languageID=g_JSChartLocalization.GetLanguageID(language);
  3062. if (!IFrameSplitOperator.IsNumber(languageID))
  3063. {
  3064. console.warn(`[JSChartContainer::SetLanguage] language=${language} error`);
  3065. return;
  3066. }
  3067. if (this.LanguageID==languageID) return;
  3068. this.LanguageID=languageID;
  3069. if (this.ChartCorssCursor && this.ChartCorssCursor.StringFormatY) this.ChartCorssCursor.StringFormatY.LanguageID=this.LanguageID;
  3070. for(var i=0; i<this.TitlePaint.length; ++i)
  3071. {
  3072. var item=this.TitlePaint[i];
  3073. if (item) item.LanguageID=this.LanguageID;
  3074. }
  3075. for(var i=0; i<this.ExtendChartPaint.length; ++i) //tooltip 等扩展图形
  3076. {
  3077. var item=this.ExtendChartPaint[i];
  3078. if (item) item.LanguageID=this.LanguageID;
  3079. }
  3080. if (this.Frame && this.Frame.SetLanguage) this.Frame.SetLanguage(this.LanguageID);
  3081. this.Frame.SetSizeChange(true);
  3082. this.Draw();
  3083. }
  3084. this.CreateOverlayFrame=function()
  3085. {
  3086. switch(this.ClassName)
  3087. {
  3088. case "KLineChartContainer":
  3089. return new OverlayKLineFrame();
  3090. case "KLineChartHScreenContainer":
  3091. return new OverlayKLineHScreenFrame();
  3092. case "MinuteChartContainer":
  3093. return new OverlayMinuteFrame();
  3094. case "MinuteChartHScreenContainer":
  3095. return new OverlayMinuteHScreenFrame();
  3096. }
  3097. }
  3098. this.GetMainData=function()
  3099. {
  3100. switch(this.ClassName)
  3101. {
  3102. case "MinuteChartContainer":
  3103. case "MinuteChartHScreenContainer":
  3104. return this.SourceData;
  3105. case "KLineChartContainer":
  3106. case "KLineChartHScreenContainer":
  3107. return this.ChartPaint[0].Data;
  3108. }
  3109. }
  3110. this.BindAllOverlayIndexData=function(hisData)
  3111. {
  3112. if (!this.Frame || !this.Frame.SubFrame) return;
  3113. //叠加指标
  3114. for(var i=0;i<this.Frame.SubFrame.length;++i)
  3115. {
  3116. var item=this.Frame.SubFrame[i];
  3117. for(var j=0; j<item.OverlayIndex.length; ++j)
  3118. {
  3119. var overlayItem=item.OverlayIndex[j];
  3120. this.BindOverlayIndexData(overlayItem,i,hisData)
  3121. }
  3122. }
  3123. }
  3124. //叠加指标
  3125. this.BindOverlayIndexData=function(overlayItem, windowIndex, hisData)
  3126. {
  3127. if (!overlayItem.Script) return;
  3128. if (typeof(overlayItem.Script.RequestData)=='function')
  3129. {
  3130. overlayItem.Script.RequestData(this,windowIndex,hisData);
  3131. return;
  3132. }
  3133. if (typeof(overlayItem.Script.ExecuteScript)=='function')
  3134. {
  3135. overlayItem.Script.ExecuteScript(this,windowIndex,hisData);
  3136. return;
  3137. }
  3138. overlayItem.Script.BindData(this,windowIndex,hisData);
  3139. }
  3140. this.GetOverlayIndexEvent=function()
  3141. {
  3142. return this.GetEventCallback(JSCHART_EVENT_ID.RECV_OVERLAY_INDEX_DATA);
  3143. }
  3144. //删除指定窗口的所有叠加指标
  3145. this.DeleteWindowsOverlayIndex=function(windowIndex)
  3146. {
  3147. if (!IFrameSplitOperator.IsNumber(windowIndex)) return;
  3148. if (windowIndex<0 || windowIndex>=this.Frame.SubFrame.length) return;
  3149. var subFrame=this.Frame.SubFrame[windowIndex];
  3150. if (!IFrameSplitOperator.IsNonEmptyArray(subFrame.OverlayIndex)) return;
  3151. var aryIndexID=[];
  3152. for(var i=0; i<subFrame.OverlayIndex.length; ++i)
  3153. {
  3154. var overlayItem=subFrame.OverlayIndex[i];
  3155. aryIndexID.push(overlayItem.Identify);
  3156. for(var j=0;j<overlayItem.ChartPaint.length;++j) //图形销毁事件
  3157. {
  3158. var overlayChart=overlayItem.ChartPaint[j];
  3159. if (overlayChart && overlayChart.OnDestroy) overlayChart.OnDestroy();
  3160. }
  3161. overlayItem.ChartPaint=[];
  3162. }
  3163. subFrame.OverlayIndex=[];
  3164. var titlePaint=this.TitlePaint[windowIndex+1];
  3165. for(var i=0;i<aryIndexID.length;++i)
  3166. {
  3167. var identify=aryIndexID[i];
  3168. if (titlePaint.OverlayIndex.has(identify))
  3169. titlePaint.OverlayIndex.delete(identify);
  3170. if (titlePaint.OverlayDynamicTitle.has(identify))
  3171. titlePaint.OverlayDynamicTitle.delete(identify);
  3172. }
  3173. }
  3174. //删除叠加指标, 没有重绘
  3175. this.DeleteOverlayIndex=function(identify, windowIndex)
  3176. {
  3177. var findIndex=null;
  3178. if (IFrameSplitOperator.IsNumber(windowIndex))
  3179. {
  3180. if (windowIndex>=0 && windowIndex<this.Frame.SubFrame.length)
  3181. {
  3182. var item=this.Frame.SubFrame[windowIndex];
  3183. for(var j=0; j<item.OverlayIndex.length; ++j)
  3184. {
  3185. var overlayItem=item.OverlayIndex[j];
  3186. if (overlayItem.Identify===identify)
  3187. {
  3188. for(var k=0;k<overlayItem.ChartPaint.length;++k) //图形销毁事件
  3189. {
  3190. var overlayChart=overlayItem.ChartPaint[k];
  3191. if (overlayChart && overlayChart.OnDestroy) overlayChart.OnDestroy();
  3192. }
  3193. item.OverlayIndex.splice(j, 1);
  3194. findIndex=windowIndex
  3195. break;
  3196. }
  3197. }
  3198. }
  3199. }
  3200. else
  3201. {
  3202. for(var i=0; i<this.Frame.SubFrame.length; ++i)
  3203. {
  3204. var item=this.Frame.SubFrame[i];
  3205. for(var j=0; j<item.OverlayIndex.length; ++j)
  3206. {
  3207. var overlayItem=item.OverlayIndex[j];
  3208. if (overlayItem.Identify===identify)
  3209. {
  3210. for(var k=0;k<overlayItem.ChartPaint.length;++k) //图形销毁事件
  3211. {
  3212. var overlayChart=overlayItem.ChartPaint[k];
  3213. if (overlayChart && overlayChart.OnDestroy) overlayChart.OnDestroy();
  3214. }
  3215. item.OverlayIndex.splice(j, 1);
  3216. findIndex=i;
  3217. break;
  3218. }
  3219. }
  3220. }
  3221. }
  3222. if (findIndex==null)
  3223. {
  3224. console.warn(`[JSChartContainer::DeleteOverlayIndex] can't find overlay index. [identify=${identify}]`);
  3225. return false;
  3226. }
  3227. var windowsIndex=findIndex+1;
  3228. var titlePaint=this.TitlePaint[windowsIndex];
  3229. if (titlePaint.OverlayIndex.has(identify))
  3230. titlePaint.OverlayIndex.delete(identify);
  3231. if (titlePaint.OverlayDynamicTitle.has(identify))
  3232. titlePaint.OverlayDynamicTitle.delete(identify);
  3233. return true;
  3234. }
  3235. //获取扩展画法
  3236. this.GetExtendChartByClassName=function(name)
  3237. {
  3238. for(var i=0; i<this.ExtendChartPaint.length; ++i)
  3239. {
  3240. var item=this.ExtendChartPaint[i];
  3241. if (item.ClassName==name) return { Index:i, Chart:item };
  3242. }
  3243. return null
  3244. }
  3245. //获取多个扩展画法
  3246. this.GetExtendChartByClassNameV2=function(name)
  3247. {
  3248. var aryChart=[];
  3249. for(var i=0; i<this.ExtendChartPaint.length; ++i)
  3250. {
  3251. var item=this.ExtendChartPaint[i];
  3252. if (item.ClassName==name)
  3253. {
  3254. aryChart.push({ Index:i, Chart:item });
  3255. }
  3256. }
  3257. if (aryChart.length<=0) return null;
  3258. return aryChart;
  3259. }
  3260. //画图工具
  3261. //把X, Y绝对位置转成的相对位置的点
  3262. this.PointAbsoluteToRelative=function(x, y)
  3263. {
  3264. var pt={ X:x, Y:y };
  3265. //var uiRect=this.getBoundingClientRect(); //dom返回的是没有放大倍数的值
  3266. //pt.X=x-uiRect.left; //手机端 dom返回的是没有放大倍数的值
  3267. //pt.Y=y-uiRect.top;
  3268. return pt;
  3269. }
  3270. //获取当前的点对应的 画图工具的图形
  3271. //data.X data.Y 鼠标位置 返回 data.ChartDrawPicture 数据在画图工具 data.PointIndex 在画图工具对应点索引
  3272. this.GetChartDrawPictureByPoint=function(data)
  3273. {
  3274. var x=data.X*data.PixelRatio;
  3275. var y=data.Y*data.PixelRatio;
  3276. for(var i=0;i<this.ChartDrawPicture.length; ++i)
  3277. {
  3278. var item =this.ChartDrawPicture[i];
  3279. var pointIndex=item.IsPointIn(x, y, this.ChartDrawOption, { X:data.X, Y:data.Y });
  3280. if (pointIndex===false) continue;
  3281. if (pointIndex>=0)
  3282. {
  3283. data.ChartDrawPicture=item;
  3284. data.PointIndex=pointIndex;
  3285. return true;
  3286. }
  3287. }
  3288. return false;
  3289. }
  3290. this.SetChartDrawPictureFirstPoint = function (x, y)
  3291. {
  3292. var drawPicture = this.CurrentChartDrawPicture;
  3293. if (!drawPicture) return false;
  3294. if (!this.Frame.SubFrame || this.Frame.SubFrame.length <= 0) return false;
  3295. for (var i=0; i<this.Frame.SubFrame.length; ++i)
  3296. {
  3297. var frame = this.Frame.SubFrame[i].Frame;
  3298. var left = frame.ChartBorder.GetLeft();
  3299. var right=frame.ChartBorder.GetRight();
  3300. var top = frame.ChartBorder.GetTopEx();
  3301. var bottom=frame.ChartBorder.GetBottomEx();
  3302. var height = bottom-top;
  3303. var width = frame.ChartBorder.GetWidth();
  3304. if (x>=left && x<=right && y>=top && y<=bottom)
  3305. {
  3306. drawPicture.Frame = frame;
  3307. break;
  3308. }
  3309. }
  3310. if (!drawPicture.Frame) return false;
  3311. drawPicture.Point[0] = new Point();
  3312. drawPicture.Point[0].X = x ;
  3313. drawPicture.Point[0].Y = y;
  3314. drawPicture.Status = 1; //第1个点完成
  3315. return true;
  3316. }
  3317. this.SetChartDrawPictureSecondPoint = function (x, y)
  3318. {
  3319. var drawPicture = this.CurrentChartDrawPicture;
  3320. if (!drawPicture) return false;
  3321. drawPicture.Point[1] = new Point();
  3322. drawPicture.Point[1].X = x;
  3323. drawPicture.Point[1].Y = y;
  3324. drawPicture.Status = 2; //设置第2个点
  3325. return true;
  3326. }
  3327. //xStep,yStep 移动的偏移量
  3328. this.MoveChartDrawPicture = function (xStep, yStep)
  3329. {
  3330. var drawPicture = this.CurrentChartDrawPicture;
  3331. if (!drawPicture) return false;
  3332. //JSConsole.Chart.Log("xStep="+xStep+" yStep="+yStep);
  3333. drawPicture.Move(xStep, yStep);
  3334. return true;
  3335. }
  3336. this.FinishChartDrawPicturePoint = function ()
  3337. {
  3338. var drawPicture = this.CurrentChartDrawPicture;
  3339. if (!drawPicture) return false;
  3340. if (drawPicture.PointCount != drawPicture.Point.length) return false;
  3341. drawPicture.Status = 10; //完成
  3342. drawPicture.PointToValue();
  3343. this.ChartDrawPicture.push(drawPicture);
  3344. this.CurrentChartDrawPicture = null;
  3345. //通知上层画好了
  3346. var event=this.GetEventCallback(JSCHART_EVENT_ID.ON_FINISH_DRAWPICTURE); //完成画图工具事件
  3347. if (event && event.Callback)
  3348. {
  3349. let sendData={ DrawPicture: drawPicture };
  3350. event.Callback(event,sendData,this);
  3351. }
  3352. //单个回调
  3353. if (drawPicture.FinishedCallback) drawPicture.FinishedCallback(drawPicture);
  3354. if (drawPicture.OnFinish) drawPicture.OnFinish();
  3355. return true;
  3356. }
  3357. this.FinishMoveChartDrawPicture = function ()
  3358. {
  3359. var drawPicture = this.CurrentChartDrawPicture;
  3360. if (!drawPicture) return false;
  3361. if (drawPicture.PointCount != drawPicture.Point.length) return false;
  3362. drawPicture.Status = 10; //完成
  3363. drawPicture.PointToValue();
  3364. this.CurrentChartDrawPicture = null;
  3365. return true;
  3366. }
  3367. //清空所有的画线工具
  3368. this.ClearChartDrawPicture = function (drawPicture)
  3369. {
  3370. if (!drawPicture)
  3371. {
  3372. this.ChartDrawPicture = [];
  3373. this.Draw();
  3374. }
  3375. else
  3376. {
  3377. for (var i=0;i<this.ChartDrawPicture.length;++i)
  3378. {
  3379. if (this.ChartDrawPicture[i] == drawPicture)
  3380. {
  3381. this.ChartDrawPicture.splice(i, 1);
  3382. this.Draw();
  3383. }
  3384. }
  3385. }
  3386. }
  3387. //获取画图工具当前选中图形的Guid
  3388. this.GetActiveDrawPicture=function()
  3389. {
  3390. var result={ Move: { Guid:null }, Select:{ Guid:null }, MoveOn: {Guid:null} };
  3391. if (this.CurrentChartDrawPicture)
  3392. result.Move={ Guid: this.CurrentChartDrawPicture.Guid };
  3393. if (this.SelectChartDrawPicture)
  3394. result.Select={ Guid:this.SelectChartDrawPicture.Guid, Chart:this.SelectChartDrawPicture };
  3395. if (this.MoveOnChartDrawPicture)
  3396. result.MoveOn={ Guid:this.MoveOnChartDrawPicture.Guid };
  3397. return result;
  3398. }
  3399. //获取当天的显示的指标
  3400. this.GetIndexInfo = function ()
  3401. {
  3402. var aryIndex = [];
  3403. for(var i=0, j=0; i<this.WindowIndex.length; ++i)
  3404. {
  3405. var item = this.WindowIndex[i];
  3406. if (!item) continue;
  3407. var info = { Name: item.Name, WindowIndex:i, IsOverlay:false };
  3408. if (item.ID) info.ID = item.ID;
  3409. if (IFrameSplitOperator.IsNonEmptyArray(item.Arguments)) //参数
  3410. {
  3411. info.Args=[];
  3412. for(j=0;j<item.Arguments.length;++j)
  3413. {
  3414. var argItem=item.Arguments[j];
  3415. info.Args.push( { Name:argItem.Name, Value:argItem.Value} );
  3416. }
  3417. }
  3418. aryIndex.push(info);
  3419. }
  3420. this.GetOverlayIndexInfo(aryIndex); //叠加指标
  3421. return aryIndex;
  3422. }
  3423. //获取叠加指标
  3424. this.GetOverlayIndexInfo=function(aryIndex)
  3425. {
  3426. for(var i=0, j=0, k=0; i<this.Frame.SubFrame.length; ++i)
  3427. {
  3428. var item=this.Frame.SubFrame[i];
  3429. if (!IFrameSplitOperator.IsNonEmptyArray(item.OverlayIndex)) continue;
  3430. for(j=0; j<item.OverlayIndex.length; ++j)
  3431. {
  3432. var overlayItem=item.OverlayIndex[j];
  3433. if (!overlayItem.Script) continue;
  3434. var indexData=overlayItem.Script;
  3435. var info={ Name:indexData.Name, ID:indexData.ID, WindowIndex:i, IsOverlay:true, Identify:overlayItem.Identify };
  3436. if (IFrameSplitOperator.IsNonEmptyArray(indexData.Arguments)) //参数
  3437. {
  3438. info.Args=[];
  3439. for(k=0;k<indexData.Arguments.length;++k)
  3440. {
  3441. var argItem=indexData.Arguments[k];
  3442. info.Args.push( { Name:argItem.Name, Value:argItem.Value} );
  3443. }
  3444. }
  3445. aryIndex.push(info);
  3446. }
  3447. }
  3448. }
  3449. //删除扩展画法
  3450. this.DeleteExtendChart=function(data)
  3451. {
  3452. if (data.Index>=this.ExtendChartPaint.length) return;
  3453. if (this.ExtendChartPaint[data.Index]!=data.Chart) return;
  3454. if (typeof(data.Chart.Clear)=='function') data.Chart.Clear();
  3455. this.ExtendChartPaint.splice(data.Index,1);
  3456. }
  3457. //删除扩展画法
  3458. this.DeleteExtendChartByID=function(id)
  3459. {
  3460. for(var i=0;i<this.ExtendChartPaint.length;++i)
  3461. {
  3462. var item=this.ExtendChartPaint[i];
  3463. if (item.ID==id)
  3464. {
  3465. this.ExtendChartPaint.splice(i, 1);
  3466. return true;
  3467. }
  3468. }
  3469. return false;
  3470. }
  3471. //切换窗口指标 option={ Window:{}, OverlayIndex:[], Frame:{ }, Delete:{Window:true/false, Overlay:true/false }}
  3472. this.ChangeIndexWindow=function(windowIndex, option)
  3473. {
  3474. JSConsole.Chart.Log('[KLineChartContainer::ChangeIndexWindow] windowIndex, option', windowIndex, option);
  3475. if (windowIndex<0 || windowIndex>=this.Frame.SubFrame.length) return false;
  3476. if (!option) return false;
  3477. var frame=this.Frame.SubFrame[windowIndex];
  3478. if (option.Delete)
  3479. {
  3480. var item=option.Delete;
  3481. if (item.Window===true) this.DeleteIndexPaint(windowIndex); //删除主指标
  3482. if (item.Overlay===true) this.DeleteWindowsOverlayIndex(windowIndex); //清空叠加指标
  3483. }
  3484. //清空标题栏
  3485. var titleIndex=windowIndex+1;
  3486. this.TitlePaint[titleIndex].Data=[];
  3487. this.TitlePaint[titleIndex].Title=null;
  3488. if (option.Window) //主指标
  3489. {
  3490. this.DeleteIndexPaint(windowIndex); //删除主指标
  3491. var item=option.Window;
  3492. if (item.Script) //自定义指标脚本
  3493. {
  3494. this.WindowIndex[windowIndex]=new ScriptIndex(item.Name,item.Script,item.Args,item); //脚本执行
  3495. }
  3496. else if (item.API) //后台指标
  3497. {
  3498. var apiItem=item.API;
  3499. this.WindowIndex[windowIndex]=new APIScriptIndex(apiItem.Name,apiItem.Script,apiItem.Args,item);
  3500. }
  3501. else
  3502. {
  3503. var indexID=item.Index;
  3504. var indexItem=JSIndexMap.Get(indexID);
  3505. if (indexItem)
  3506. {
  3507. this.WindowIndex[windowIndex]=indexItem.Create();
  3508. this.CreateWindowIndex(windowIndex);
  3509. }
  3510. else
  3511. {
  3512. var systemScript = new JSIndexScript();
  3513. var indexInfo = systemScript.Get(indexID);
  3514. if (indexInfo)
  3515. {
  3516. JSIndexScript.ModifyAttribute(indexInfo,item);
  3517. this.WindowIndex[windowIndex]=new ScriptIndex(indexInfo.Name,indexInfo.Script,indexInfo.Args,indexInfo); //脚本执行
  3518. }
  3519. }
  3520. }
  3521. this.SetSubFrameAttribute(frame, item, option.Frame);
  3522. }
  3523. //叠加指标
  3524. var aryOverlayIndex=[];
  3525. if (IFrameSplitOperator.IsNonEmptyArray(option.OverlayIndex))
  3526. {
  3527. this.DeleteWindowsOverlayIndex(windowIndex); //清空叠加指标
  3528. for(var i=0;i<option.OverlayIndex.length;++i)
  3529. {
  3530. var item=option.OverlayIndex[i];
  3531. if (item.Index) item.IndexName=item.Index;
  3532. item.WindowIndex=windowIndex;
  3533. if (item.Windows>=0) item.WindowIndex=item.Windows;
  3534. var overlay=this.CreateOverlayWindowsIndex(item);
  3535. if (!overlay) continue;
  3536. aryOverlayIndex.push({ WindowsIndex:item.WindowIndex, Overlay:overlay });
  3537. }
  3538. }
  3539. //刷新指标
  3540. var bindData=this.ChartPaint[0].Data;
  3541. this.BindIndexData(windowIndex,bindData); //请求主指标
  3542. for(var i=0;i<aryOverlayIndex.length;++i) //请求叠加指标
  3543. {
  3544. var item=aryOverlayIndex[i];
  3545. this.BindOverlayIndexData(item.Overlay,item.WindowsIndex,bindData);
  3546. }
  3547. this.UpdataDataoffset(); //更新数据偏移
  3548. this.ResetFrameXYSplit();
  3549. this.UpdateFrameMaxMin(); //调整坐标最大 最小值
  3550. this.Draw();
  3551. }
  3552. this.ResetOverlaySymbolStatus=function()
  3553. {
  3554. for(var i=0;i<this.OverlayChartPaint.length; ++i)
  3555. {
  3556. var item=this.OverlayChartPaint[i];
  3557. item.Status=OVERLAY_STATUS_ID.STATUS_NONE_ID;
  3558. }
  3559. }
  3560. //手动更新指标 [ {ID:主图指标窗口索引, OverlayID:叠加指标ID }]
  3561. this.UpdateWindowIndexV2=function(aryIndex, option)
  3562. {
  3563. if (!this.Frame || !this.Frame.SubFrame) return false;
  3564. var kData=this.GetKData();
  3565. if (!kData || !IFrameSplitOperator.IsNonEmptyArray(kData.Data)) return false;
  3566. if (!IFrameSplitOperator.IsNonEmptyArray(aryIndex)) return false;
  3567. var setMainIndex=new Set(); //主图指标
  3568. var setOverlayIndex=new Set(); //附图指标
  3569. for(var i=0;i<aryIndex.length;++i)
  3570. {
  3571. var item=aryIndex[i];
  3572. if (!item) continue;
  3573. if (IFrameSplitOperator.IsNumber(item.ID)) setMainIndex.add(item.ID);
  3574. if (item.OverlayID) setOverlayIndex.add(item.OverlayID);
  3575. }
  3576. if (setMainIndex.size<=0 && setOverlayIndex.size<0) return false;
  3577. //K线数据
  3578. var bindData=new ChartData();
  3579. if (kData) bindData.Data=kData.Data;
  3580. if (this.IsKLineContainer()) //K线
  3581. {
  3582. bindData.Period=this.Period;
  3583. bindData.Right=this.Right;
  3584. }
  3585. //主图指标
  3586. if (setMainIndex.size>0)
  3587. {
  3588. for(var i=0;i<this.WindowIndex.length;++i)
  3589. {
  3590. var item=this.WindowIndex[i];
  3591. if (!item) continue;
  3592. if (setMainIndex.has(i))
  3593. {
  3594. this.BindIndexData(i,bindData);
  3595. }
  3596. }
  3597. }
  3598. //叠加指标
  3599. if (setOverlayIndex.size>0)
  3600. {
  3601. for(var i=0;i<this.Frame.SubFrame.length;++i)
  3602. {
  3603. var item=this.Frame.SubFrame[i];
  3604. for(var j=0; j<item.OverlayIndex.length; ++j)
  3605. {
  3606. var overlayItem=item.OverlayIndex[j];
  3607. if (setOverlayIndex.has(overlayItem.Identify))
  3608. {
  3609. this.BindOverlayIndexData(overlayItem,i,bindData)
  3610. }
  3611. }
  3612. }
  3613. }
  3614. var bDraw=true;
  3615. if (option && option.Draw===false) bDraw=false;
  3616. if (bDraw)
  3617. {
  3618. this.UpdataDataoffset(); //更新数据偏移
  3619. this.UpdateFrameMaxMin(); //调整坐标最大 最小值
  3620. this.Draw();
  3621. }
  3622. return true;
  3623. }
  3624. this.GetKData=function() { return null; }
  3625. this.SetSizeChange=function(bChanged)
  3626. {
  3627. this.Frame.SetSizeChange(bChanged);
  3628. for(var i=0;i<this.ExtendChartPaint.length;++i)
  3629. {
  3630. var item=this.ExtendChartPaint[i];
  3631. item.SizeChange=bChanged;
  3632. }
  3633. }
  3634. //启动|关闭锁指标 aryIndex=[{ IndexID:指标ID, LockData:{IsLocked:} } ]
  3635. this.EnableLockIndex=function(aryIndex)
  3636. {
  3637. if (!IFrameSplitOperator.IsNonEmptyArray(aryIndex)) return false;
  3638. var mapIndex=new Map();
  3639. for(var i=0;i<aryIndex.length;++i)
  3640. {
  3641. var item=aryIndex[i];
  3642. if (item.IndexID && item.LockData) mapIndex.set(item.IndexID, item);
  3643. }
  3644. var aryUpdate=[];
  3645. for(var i=0; i<this.WindowIndex.length; ++i)
  3646. {
  3647. var item=this.WindowIndex[i];
  3648. if (!item) continue;
  3649. if (mapIndex.has(item.ID))
  3650. {
  3651. var mapItem=mapIndex.get(item.ID);
  3652. item.SetLock(mapItem.LockData); //设置锁
  3653. aryUpdate.push({ ID:i});
  3654. }
  3655. }
  3656. for(var i=0; i<this.Frame.SubFrame.length; ++i)
  3657. {
  3658. var item=this.Frame.SubFrame[i];
  3659. if (!IFrameSplitOperator.IsNonEmptyArray(item.OverlayIndex)) continue;
  3660. for(var j=0; j<item.OverlayIndex.length; ++j)
  3661. {
  3662. var overlayItem=item.OverlayIndex[j];
  3663. var script=overlayItem.Script;
  3664. if (mapIndex.has(script.ID))
  3665. {
  3666. var mapItem=mapIndex.get(script.ID);
  3667. script.SetLock(mapItem.LockData);
  3668. aryUpdate.push({OverlayID:overlayItem.Identify});
  3669. }
  3670. }
  3671. }
  3672. if (!IFrameSplitOperator.IsNonEmptyArray(aryUpdate)) return false;
  3673. this.UpdateWindowIndexV2(aryUpdate);
  3674. return true;
  3675. }
  3676. this.TryClickLock=function (x, y)
  3677. {
  3678. if (!this.Frame || !IFrameSplitOperator.IsNonEmptyArray(this.Frame.SubFrame)) return false;
  3679. for (var i=0; i<this.Frame.SubFrame.length; ++i)
  3680. {
  3681. var item = this.Frame.SubFrame[i];
  3682. var chartLock=item.Frame.LockPaint;
  3683. if (!chartLock || !chartLock.LockRect) continue;
  3684. var tooltip = new TooltipData();
  3685. if (!chartLock.GetTooltipData(x, y, tooltip)) continue;
  3686. tooltip.HQChart = this;
  3687. var event=this.GetEventCallback(JSCHART_EVENT_ID.ON_CLICK_INDEX_LOCK);
  3688. if (event && event.Callback)
  3689. {
  3690. var sendData={ FrameID:item.Frame.Identify, Data:tooltip };
  3691. event.Callback(event,sendData,this);
  3692. }
  3693. if (tooltip.Data.Callback) tooltip.Data.Callback(tooltip);
  3694. return true;
  3695. }
  3696. return false;
  3697. }
  3698. this.IsKLineContainer=function()
  3699. {
  3700. if (this.ClassName=='KLineChartContainer' || this.ClassName=='KLineChartHScreenContainer' ||
  3701. this.ClassName=="KLineTrainChartContainer" || this.ClassName=="CustomKLineChartContainer" ) return true;
  3702. return false;
  3703. }
  3704. this.IsMinuteContainer=function()
  3705. {
  3706. if (this.ClassName=="MinuteChartContainer" || this.ClassName=="MinuteChartHScreenContainer") return true;
  3707. return false;
  3708. }
  3709. //快速滑动
  3710. this.FastSlideEvent=function()
  3711. {
  3712. if (!this.TouchDrag) return false;
  3713. if (!this.FastSlideConfig) return false;
  3714. var config=this.FastSlideConfig;
  3715. if (!config.Enable) return false;
  3716. var event=this.GetEventCallback(JSCHART_EVENT_ID.ON_TOUCH_FAST_SLIDE);
  3717. if (!event || !event.Callback) return false;
  3718. var drag=this.TouchDrag;
  3719. var time=Date.now();
  3720. var spanTime=time-drag.StartTime;
  3721. if (spanTime>config.MaxTime) return false;
  3722. if (!drag.Click || !drag.LastMove) return false;
  3723. var xStart=drag.Click.X;
  3724. var xEnd=drag.LastMove.X;
  3725. if (!IFrameSplitOperator.IsNumber(xStart) || !IFrameSplitOperator.IsNumber(xEnd)) return false;
  3726. var distance=xEnd-xStart;
  3727. var speed=Math.abs(distance)/spanTime;
  3728. JSConsole.Chart.Log(`[JSChartContainer:FastSlideEvent] speed=${speed}, distance=${distance}, spanTime=${spanTime}`);
  3729. if (Math.abs(distance)<config.MinDistance || speed<config.MinSpeed)
  3730. return false;
  3731. var sendData={ Speed:speed, Distance:distance, IsLeft:distance<0?true:false }
  3732. event.Callback(event, sendData, this);
  3733. return true;
  3734. }
  3735. }
  3736. function ToFixed(number, precision)
  3737. {
  3738. var b = 1;
  3739. if (isNaN(number)) return number;
  3740. if (number < 0) b = -1;
  3741. var multiplier = Math.pow(10, precision);
  3742. var value = Math.round(Math.abs(number) * multiplier) / multiplier * b;
  3743. if (/^(\d+(?:\.\d+)?)(e)([\-]?\d+)$/.test(value))
  3744. var s = value.toFixed2(precision);
  3745. else
  3746. var s = value.toString();
  3747. var rs = s.indexOf('.');
  3748. if (rs < 0 && precision > 0)
  3749. {
  3750. rs = s.length;
  3751. s += '.';
  3752. }
  3753. while (s.length <= rs + precision)
  3754. {
  3755. s += '0';
  3756. }
  3757. return s;
  3758. }
  3759. Number.prototype.toFixed2 = Number.prototype.toFixed; //备份下老的
  3760. Number.prototype.toFixed = function (precision) {
  3761. return ToFixed(this, precision)
  3762. }
  3763. function Guid()
  3764. {
  3765. function S4()
  3766. {
  3767. return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
  3768. }
  3769. return (S4() + S4() + "-" + S4() + "-" + S4() + "-" + S4() + "-" + S4() + S4() + S4());
  3770. }
  3771. //修正线段有毛刺
  3772. function ToFixedPoint(value) {
  3773. //return value;
  3774. return parseInt(value) + 0.5;
  3775. }
  3776. function ToFixedRect(value) {
  3777. //return value;
  3778. // With a bitwise or.
  3779. //rounded = (0.5 + somenum) | 0;
  3780. // A double bitwise not.
  3781. //rounded = ~~ (0.5 + somenum);
  3782. // Finally, a left bitwise shift.
  3783. var rounded;
  3784. return rounded = (0.5 + value) << 0;
  3785. }
  3786. function Point() {
  3787. this.X;
  3788. this.Y;
  3789. }
  3790. function SelectRectData() {
  3791. this.Data; //主数据
  3792. this.JSChartContainer; //行情控件
  3793. this.Start; //数据起始位子
  3794. this.End; //数据结束位置
  3795. this.XStart;//X坐标起始位置
  3796. this.XEnd; //X位置结束为止
  3797. }
  3798. //边框信息
  3799. function ChartBorder()
  3800. {
  3801. this.UIElement;
  3802. //四周间距
  3803. this.Left = 50;
  3804. this.Right = 80;
  3805. this.Top = 50;
  3806. this.Bottom = 50;
  3807. this.TitleHeight = 15; //标题高度
  3808. //上下间距
  3809. this.TopSpace = 0;
  3810. this.BottomSpace = 0;
  3811. this.LeftExtendWidth=0; //左边扩展图形宽度
  3812. this.RightExtendWidth=0;
  3813. this.GetBorder=function()
  3814. {
  3815. var data=
  3816. {
  3817. Left:this.Left,
  3818. LeftEx:this.Left+this.LeftExtendWidth,
  3819. Right:this.UIElement.Width-this.Right,
  3820. RightEx:this.UIElement.Width-this.Right-this.RightExtendWidth,
  3821. Top:this.Top,
  3822. TopEx:this.Top+this.TitleHeight+this.TopSpace,
  3823. TopTitle:this.Top+this.TitleHeight,
  3824. Bottom:this.UIElement.Height-this.Bottom,
  3825. BottomEx:this.UIElement.Height-this.Bottom-this.BottomSpace,
  3826. ChartWidth:this.UIElement.Width,
  3827. ChartHeight:this.UIElement.Height
  3828. };
  3829. return data;
  3830. }
  3831. this.GetHScreenBorder=function()
  3832. {
  3833. var data=
  3834. {
  3835. Left:this.Left,
  3836. LeftEx:this.Left+this.BottomSpace,
  3837. Right:this.UIElement.Width-this.Right,
  3838. RightEx:this.UIElement.Width-this.Right-this.TitleHeight- this.TopSpace,
  3839. RightTitle:this.UIElement.Width-this.Right-this.TitleHeight,
  3840. Top:this.Top,
  3841. TopEx:this.Top+this.LeftExtendWidth,
  3842. Bottom:this.UIElement.Height-this.Bottom,
  3843. BottomEx:this.UIElement.Height-this.Bottom-this.RightExtendWidth,
  3844. ChartWidth:this.UIElement.Width,
  3845. ChartHeight:this.UIElement.Height
  3846. };
  3847. return data;
  3848. }
  3849. this.GetChartWidth = function () {
  3850. return this.UIElement.Width;
  3851. }
  3852. this.GetChartHeight = function () {
  3853. return this.UIElement.Height;
  3854. }
  3855. this.GetLeft = function () {
  3856. return this.Left;
  3857. }
  3858. this.GetRight = function () {
  3859. return this.UIElement.Width - this.Right;
  3860. }
  3861. this.GetTop = function () {
  3862. return this.Top;
  3863. }
  3864. this.GetTopEx = function () //去掉标题,上面间距
  3865. {
  3866. return this.Top + this.TitleHeight + this.TopSpace;
  3867. }
  3868. this.GetTopTitle = function () //去掉标题
  3869. {
  3870. return this.Top + this.TitleHeight;
  3871. }
  3872. this.GetBottom = function () {
  3873. return this.UIElement.Height - this.Bottom;
  3874. }
  3875. this.GetBottomEx = function () {
  3876. return this.UIElement.Height - this.Bottom - this.BottomSpace;
  3877. }
  3878. this.GetWidth = function () {
  3879. return this.UIElement.Width - this.Left - this.Right;
  3880. }
  3881. this.GetHeight = function () {
  3882. return this.UIElement.Height - this.Top - this.Bottom;
  3883. }
  3884. this.GetHeightEx = function () //去掉标题的高度 上下间距
  3885. {
  3886. return this.UIElement.Height - this.Top - this.Bottom - this.TitleHeight - this.TopSpace - this.BottomSpace;
  3887. }
  3888. this.GetRightEx = function () //横屏去掉标题高度的 上面间距
  3889. {
  3890. return this.UIElement.Width - this.Right - this.TitleHeight - this.TopSpace;
  3891. }
  3892. this.GetWidthEx = function () //横屏去掉标题宽度 上下间距
  3893. {
  3894. return this.UIElement.Width - this.Left - this.Right - this.TitleHeight - this.TopSpace - this.BottomSpace;
  3895. }
  3896. this.GetLeftEx = function () //横屏
  3897. {
  3898. return this.Left + this.BottomSpace;
  3899. }
  3900. this.GetRightTitle = function ()//横屏
  3901. {
  3902. return this.UIElement.Width - this.Right - this.TitleHeight;
  3903. }
  3904. this.GetTitleHeight = function () {
  3905. return this.TitleHeight;
  3906. }
  3907. }
  3908. function SubFrameItem()
  3909. {
  3910. this.Frame;
  3911. this.Height;
  3912. this.OverlayIndex=[]; //叠加指标
  3913. }
  3914. function OverlayIndexItem()
  3915. {
  3916. this.Frame;
  3917. this.ChartPaint=[];
  3918. this.Identify=Guid();
  3919. this.Scprit; //脚本
  3920. this.UpdateFrameMaxMin=function() //调整坐标最大 最小值
  3921. {
  3922. var value={ Max:null, Min:null }
  3923. if (this.Frame.IsShareY) //共享Y轴坐标
  3924. {
  3925. this.Frame.XYSplit=true;
  3926. return;
  3927. }
  3928. if (this.Frame.YSpecificMaxMin) //固定坐标
  3929. {
  3930. value.Max=this.Frame.YSpecificMaxMin.Max;
  3931. value.Min=this.Frame.YSpecificMaxMin.Min;
  3932. }
  3933. else
  3934. {
  3935. for(var i=0; i<this.ChartPaint.length; ++i)
  3936. {
  3937. var paint=this.ChartPaint[i];
  3938. var range=paint.GetMaxMin();
  3939. if (IFrameSplitOperator.IsNumber(range.Max))
  3940. {
  3941. if (value.Max==null || value.Max<range.Max) value.Max=range.Max;
  3942. }
  3943. if (IFrameSplitOperator.IsNumber(range.Min))
  3944. {
  3945. if (value.Min==null || value.Min>range.Min) value.Min=range.Min;
  3946. }
  3947. }
  3948. }
  3949. if (!IFrameSplitOperator.IsNumber(this.Frame.YMaxMin.Max) || this.Frame.YMaxMin.Max!=value.Max)
  3950. {
  3951. this.Frame.YMaxMin.Max=value.Max;
  3952. this.Frame.XYSplit=true;
  3953. }
  3954. if (!IFrameSplitOperator.IsNumber(this.Frame.YMaxMin.Min) || this.Frame.YMaxMin.Min!=value.Min)
  3955. {
  3956. this.Frame.YMaxMin.Min=value.Min;
  3957. this.Frame.XYSplit=true;
  3958. }
  3959. if (this.Frame.XYSplit)
  3960. {
  3961. var max=10, min=0;
  3962. if (value.Max!=null) max=value.Max;
  3963. if (value.Min!=null) min=value.Min;
  3964. this.Frame.HorizontalMax=max;
  3965. this.Frame.HorizontalMin=min;
  3966. }
  3967. else
  3968. {
  3969. this.Frame.XYSplit=true;
  3970. }
  3971. }
  3972. }
  3973. //行情框架
  3974. function HQTradeFrame()
  3975. {
  3976. this.ClassName='HQTradeFrame';
  3977. this.SubFrame = new Array(); //SubFrameItem 数组
  3978. this.SizeChange = true; //大小是否改变
  3979. this.ChartBorder;
  3980. this.Canvas; //画布
  3981. this.ScreenImagePath; //截图路径
  3982. this.ScreenImageData=null; //截图数据
  3983. this.Data; //主数据
  3984. this.Position; //画布的位置
  3985. this.SizeChange = true;
  3986. this.SnapshotID=0;
  3987. this.CurrentSnapshotID=0;
  3988. this.SnapshotStatus=0; //0空闲 1工作
  3989. this.AutoLeftBorder=null; //{ Blank:10 留白宽度, MinWidth:最小宽度 }
  3990. this.AutoRightBorder=null; //{ Blank:10 留白宽度, MinWidth:最小宽度 }
  3991. this.ZoomWindowsInfo=null; //附图指标缩放,备份信息
  3992. this.ZoomStartWindowIndex=1; //允许缩放窗口起始位置
  3993. this.CalculateChartBorder = function () //计算每个子框架的边框信息
  3994. {
  3995. if (this.SubFrame.length <= 0) return;
  3996. var top = this.ChartBorder.GetTop();
  3997. var height = this.ChartBorder.GetHeight();
  3998. var totalHeight = 0;
  3999. for (var i=0; i<this.SubFrame.length; ++i)
  4000. {
  4001. var item = this.SubFrame[i];
  4002. totalHeight += item.Height;
  4003. }
  4004. for (var i=0; i<this.SubFrame.length; ++i)
  4005. {
  4006. var item = this.SubFrame[i];
  4007. item.Frame.ChartBorder.Top = top;
  4008. item.Frame.ChartBorder.Left = this.ChartBorder.Left;
  4009. item.Frame.ChartBorder.Right = this.ChartBorder.Right;
  4010. var frameHeight = height * (item.Height / totalHeight) + top;
  4011. item.Frame.ChartBorder.Bottom = this.ChartBorder.GetChartHeight() - frameHeight;
  4012. top = frameHeight;
  4013. }
  4014. if (this.GetEventCallback)
  4015. {
  4016. var event=this.GetEventCallback(JSCHART_EVENT_ID.ON_SIZE_FRAME);
  4017. if (event && event.Callback)
  4018. {
  4019. var sendData={ SubFrame:this.SubFrame };
  4020. event.Callback(event, sendData, this);
  4021. }
  4022. }
  4023. }
  4024. this.GetScaleTextWidth=function()
  4025. {
  4026. var width={ Left:null, Right:null };
  4027. for(var i=0; i<this.SubFrame.length; ++i)
  4028. {
  4029. var item=this.SubFrame[i];
  4030. if (item.Height<=0) continue;
  4031. var frame=item.Frame;
  4032. if (!frame) continue;
  4033. if (!frame.XSplitOperator) continue;
  4034. var maxValue=frame.HorizontalMax; //最大最小要还原
  4035. var minValue=frame.HorizontalMin;
  4036. frame.YSplitOperator.Operator();
  4037. var value=frame.GetScaleTextWidth();
  4038. frame.HorizontalMax=maxValue;
  4039. frame.HorizontalMin=minValue;
  4040. if (value && value.TextWidth)
  4041. {
  4042. var widthItem=value.TextWidth;
  4043. if (IFrameSplitOperator.IsNumber(widthItem.Left))
  4044. {
  4045. if (width.Left==null || width.Left<widthItem.Left) width.Left=widthItem.Left;
  4046. }
  4047. if (IFrameSplitOperator.IsNumber(widthItem.Right))
  4048. {
  4049. if (width.Right==null || width.Right<widthItem.Right) width.Right=widthItem.Right;
  4050. }
  4051. }
  4052. }
  4053. return width;
  4054. }
  4055. this.IsFrameXYSplit=function()
  4056. {
  4057. for(var i in this.SubFrame)
  4058. {
  4059. if (this.SubFrame[i].Frame.XYSplit) return true;
  4060. }
  4061. return false;
  4062. }
  4063. this.Draw = function (option)
  4064. {
  4065. if (this.SizeChange === true) this.CalculateChartBorder();
  4066. var isSplash=false; //是否过场动画
  4067. if (option && option.IsEnableSplash===true) isSplash=true;
  4068. if (isSplash==false && (this.AutoLeftBorder || this.AutoRightBorder) &&this.IsFrameXYSplit())
  4069. {
  4070. var textWidth=this.GetScaleTextWidth();
  4071. if (IFrameSplitOperator.IsNumber(textWidth.Left) && this.AutoLeftBorder)
  4072. {
  4073. var blank=0;
  4074. if (IFrameSplitOperator.IsNumber(this.AutoLeftBorder.Blank)) blank=this.AutoLeftBorder.Blank;
  4075. var value=textWidth.Left+blank;
  4076. if (IFrameSplitOperator.IsNumber(this.AutoLeftBorder.MinWidth))
  4077. {
  4078. if (this.AutoLeftBorder.MinWidth>value) value=this.AutoLeftBorder.MinWidth;
  4079. }
  4080. if (this.IsHScreen) this.ChartBorder.Top=value;
  4081. else this.ChartBorder.Left=value;
  4082. for(var i=0; i<this.SubFrame.length; ++i)
  4083. {
  4084. var item=this.SubFrame[i];
  4085. if (this.IsHScreen) item.Frame.ChartBorder.Top=value;
  4086. else item.Frame.ChartBorder.Left=value;
  4087. }
  4088. }
  4089. if (IFrameSplitOperator.IsNumber(textWidth.Right) && this.AutoRightBorder)
  4090. {
  4091. var blank=0;
  4092. if (IFrameSplitOperator.IsNumber(this.AutoRightBorder.Blank)) blank=this.AutoRightBorder.Blank;
  4093. var value=textWidth.Right+blank;
  4094. if (IFrameSplitOperator.IsNumber(this.AutoRightBorder.MinWidth))
  4095. {
  4096. if (this.AutoRightBorder.MinWidth>value) value=this.AutoRightBorder.MinWidth;
  4097. }
  4098. if (this.IsHScreen) this.ChartBorder.Bottom=value;
  4099. else this.ChartBorder.Right=value;
  4100. for(var i=0; i<this.SubFrame.length; ++i)
  4101. {
  4102. var item=this.SubFrame[i];
  4103. if (this.IsHScreen) item.Frame.ChartBorder.Bottom=value;
  4104. else item.Frame.ChartBorder.Right=value;
  4105. }
  4106. }
  4107. }
  4108. for (var i=0; i<this.SubFrame.length; ++i)
  4109. {
  4110. var item = this.SubFrame[i];
  4111. if (item.Height <= 0) continue;
  4112. item.Frame.Draw();
  4113. for(var j=0; j<item.OverlayIndex.length; ++j)
  4114. {
  4115. var overlayItem=item.OverlayIndex[j];
  4116. //把主坐标部分设置给子坐标下来
  4117. overlayItem.Frame.DataWidth=item.Frame.DataWidth;
  4118. overlayItem.Frame.DistanceWidth=item.Frame.DistanceWidth;
  4119. overlayItem.Frame.XPointCount=item.Frame.XPointCount;
  4120. if (overlayItem.ChartPaint.length>0 && overlayItem.Frame)
  4121. {
  4122. overlayItem.Frame.Draw();
  4123. }
  4124. }
  4125. }
  4126. this.SizeChange = false;
  4127. }
  4128. this.DrawOveraly=function(bDrawFirst)
  4129. {
  4130. for(var i=0; i<this.SubFrame.length; ++i)
  4131. {
  4132. var item=this.SubFrame[i];
  4133. if (item.Height<=0) continue; //高度是0 不画
  4134. for(var j=0;j<item.OverlayIndex.length; ++j)
  4135. {
  4136. var overlayItem=item.OverlayIndex[j];
  4137. for(var k=0; k<overlayItem.ChartPaint.length; ++k)
  4138. {
  4139. var chartItem=overlayItem.ChartPaint[k];
  4140. if (chartItem.IsShow)
  4141. {
  4142. if (bDrawFirst)
  4143. {
  4144. if (chartItem.IsDrawFirst) chartItem.Draw();
  4145. }
  4146. else
  4147. {
  4148. if (!chartItem.IsDrawFirst) chartItem.Draw();
  4149. }
  4150. }
  4151. }
  4152. }
  4153. }
  4154. }
  4155. this.DrawLock=function ()
  4156. {
  4157. for (var i=0; i<this.SubFrame.length; ++i)
  4158. {
  4159. var item = this.SubFrame[i];
  4160. item.Frame.DrawLock();
  4161. }
  4162. }
  4163. this.CalculateLock=function()
  4164. {
  4165. for (var i=0, j=0; i<this.SubFrame.length; ++i)
  4166. {
  4167. var item = this.SubFrame[i];
  4168. var aryLockData=[];
  4169. if (item.Frame.IndexLock.IsLocked) aryLockData.push({ Data:item.Frame.IndexLock, IsOverlay:false });
  4170. for(j=0; j<item.OverlayIndex.length; ++j)
  4171. {
  4172. var subItem=item.OverlayIndex[j];
  4173. if (subItem.Frame.IndexLock.IsLocked===true)
  4174. {
  4175. aryLockData.push({ Data:subItem.Frame.IndexLock, IsOverlay:true } );
  4176. }
  4177. }
  4178. item.Frame.CalculateLock(aryLockData);
  4179. }
  4180. }
  4181. this.DrawLogo=function()
  4182. {
  4183. for(var i=0;i<this.SubFrame.length;++i)
  4184. {
  4185. var item=this.SubFrame[i];
  4186. if (item.Frame.DrawLogo)
  4187. {
  4188. item.Frame.DrawLogo();
  4189. break;
  4190. }
  4191. }
  4192. }
  4193. this.DrawInsideHorizontal = function ()
  4194. {
  4195. for (var i=0; i<this.SubFrame.length; ++i)
  4196. {
  4197. var item = this.SubFrame[i];
  4198. if (item.Height <= 0) continue;
  4199. item.Frame.DrawInsideHorizontal();
  4200. }
  4201. }
  4202. this.DrawCustomHorizontal = function () //定制Y坐标
  4203. {
  4204. for (var i=0; i<this.SubFrame.length; ++i)
  4205. {
  4206. var item = this.SubFrame[i];
  4207. if (item.Frame.DrawCustomHorizontal) item.Frame.DrawCustomHorizontal();
  4208. }
  4209. }
  4210. this.DrawCustomVertical = function (event) //定制X坐标
  4211. {
  4212. for (var i in this.SubFrame)
  4213. {
  4214. var item = this.SubFrame[i];
  4215. item.Frame.DrawCustomVerticalEvent = event;
  4216. if (item.Frame.DrawCustomVertical) item.Frame.DrawCustomVertical();
  4217. }
  4218. }
  4219. this.SetSizeChange = function (sizeChange)
  4220. {
  4221. this.SizeChange = sizeChange;
  4222. for (var i in this.SubFrame)
  4223. {
  4224. var item = this.SubFrame[i];
  4225. item.Frame.SizeChange = sizeChange;
  4226. }
  4227. //画布的位置
  4228. this.Position =
  4229. {
  4230. X: this.ChartBorder.UIElement.offsetLeft,
  4231. Y: this.ChartBorder.UIElement.offsetTop,
  4232. W: this.ChartBorder.UIElement.clientWidth,
  4233. H: this.ChartBorder.UIElement.clientHeight
  4234. };
  4235. }
  4236. //this.SetSizeChage=this.SetSizeChange; //单词拼错
  4237. this.SetDrawOtherChart = function (callback) //在画完框架以后调用的扩展画法
  4238. {
  4239. for (var i in this.SubFrame)
  4240. {
  4241. var item = this.SubFrame[i];
  4242. item.Frame.DrawOtherChart = callback;
  4243. }
  4244. }
  4245. this.Snapshot=function(type)
  4246. {
  4247. if (type == 1) this.SnapshotImageData();
  4248. else this.SnapshotImagePath();
  4249. }
  4250. //图形快照
  4251. this.SnapshotImagePath = function ()
  4252. {
  4253. var self = this;
  4254. var width = this.ChartBorder.GetChartWidth();
  4255. var height = this.ChartBorder.GetChartHeight();
  4256. //JSConsole.Chart.Log('[HQTradeFrame::SnapshotImageData][ID=' + this.ChartBorder.UIElement.ID + '] invoke canvasToTempFilePath' + '(width=' + width + ',height=' + height + ')' + ' SnapshotStatus='+ this.SnapshotStatus);
  4257. //if (this.SnapshotStatus==1) return;
  4258. ++this.SnapshotID;
  4259. var id = this.SnapshotID;
  4260. this.SnapshotStatus=1;
  4261. if (this.Canvas && this.Canvas.DomNode) //新版2D画布
  4262. {
  4263. wx.canvasToTempFilePath({
  4264. x: 0,
  4265. y: 0,
  4266. width: width,
  4267. height: height,
  4268. canvas: this.Canvas.DomNode,
  4269. success: function (res) {
  4270. self.ScreenImagePath = res.tempFilePath;
  4271. self.SnapshotStatus = 0;
  4272. self.CurrentSnapshotID = id;
  4273. JSConsole.Chart.Log(`[HQTradeFrame::SnapshotImagePath] SnapshotID(${self.SnapshotID}, ${self.CurrentSnapshotID}), Path=${res.tempFilePath}`);
  4274. }
  4275. })
  4276. }
  4277. else
  4278. {
  4279. wx.canvasToTempFilePath({
  4280. x: 0,
  4281. y: 0,
  4282. width: width,
  4283. height: height,
  4284. canvasId: this.ChartBorder.UIElement.ID,
  4285. success: function (res) {
  4286. self.ScreenImagePath = res.tempFilePath;
  4287. self.SnapshotStatus = 0;
  4288. self.CurrentSnapshotID = id;
  4289. //JSConsole.Chart.Log('[HQTradeFrame::SnapshotImagePath] SnapshotID(' + self.SnapshotID + ',' + self.CurrentSnapshotID + ') Path ='+ res.tempFilePath);
  4290. }
  4291. })
  4292. }
  4293. }
  4294. this.SnapshotImageData=function()
  4295. {
  4296. var self = this;
  4297. var width = this.ChartBorder.GetChartWidth();
  4298. var height = this.ChartBorder.GetChartHeight();
  4299. JSConsole.Chart.Log(`[HQTradeFrame::SnapshotImageData][ID=${this.ChartBorder.UIElement.ID} invoke canvasGetImageData(${width}, ${height}) SnapshotStatus=${this.SnapshotStatus}`);
  4300. ++this.SnapshotID;
  4301. var id = this.SnapshotID;
  4302. this.SnapshotStatus = 1;
  4303. wx.canvasGetImageData({
  4304. canvasId: this.ChartBorder.UIElement.ID,
  4305. x: 0,
  4306. y: 0,
  4307. width: width,
  4308. height: height,
  4309. success(res)
  4310. {
  4311. self.ScreenImageData = res.data;
  4312. self.SnapshotStatus = 0;
  4313. self.CurrentSnapshotID = id;
  4314. JSConsole.Chart.Log(`[HQTradeFrame::SnapshotImageData] SnapshotID=${self.SnapshotID}, CurrentSnapshotID=${self.CurrentSnapshotID}, size=${res.data.length}`);
  4315. }
  4316. })
  4317. }
  4318. this.GetXData = function (x) { return this.SubFrame[0].Frame.GetXData(x); }
  4319. this.GetYData = function (y, outObject) //outObject 可以保存返回的额外数据)
  4320. {
  4321. var frame;
  4322. for (var i=0; i<this.SubFrame.length; ++i)
  4323. {
  4324. var item = this.SubFrame[i];
  4325. var left = item.Frame.ChartBorder.GetLeft();
  4326. var top = item.Frame.ChartBorder.GetTopEx();
  4327. var width = item.Frame.ChartBorder.GetWidth();
  4328. var height = item.Frame.ChartBorder.GetHeightEx();
  4329. var rtItem = new Rect(left, top, width, height);
  4330. if (rtItem.IsPointIn(left, y))
  4331. {
  4332. frame = item.Frame;
  4333. if (outObject) outObject.FrameID = i;
  4334. break;
  4335. }
  4336. }
  4337. if (frame != null)
  4338. {
  4339. var yValue=frame.GetYData(y);
  4340. if (frame.YSplitOperator.CoordinateType == 1) //百分比坐标 右边显示百分比信息
  4341. {
  4342. var firstOpenPrice = frame.YSplitOperator.GetFirstOpenPrice();
  4343. outObject.RightYValue = ((yValue - firstOpenPrice) / firstOpenPrice * 100).toFixed(2) + '%';
  4344. }
  4345. if (frame.GetMainOverlayFrame)
  4346. {
  4347. var aryOverlayFrame=frame.GetMainOverlayFrame();
  4348. if (aryOverlayFrame)
  4349. {
  4350. if (aryOverlayFrame[0]) //左侧
  4351. {
  4352. var leftFrame=aryOverlayFrame[0];
  4353. var value=leftFrame.GetYData(y);
  4354. outObject.RightYValue=yValue;
  4355. yValue=value;
  4356. }
  4357. if (aryOverlayFrame[1]) //右侧
  4358. {
  4359. var rightFrame=aryOverlayFrame[1];
  4360. var value=rightFrame.GetYData(y);
  4361. outObject.RightYValue=value;
  4362. }
  4363. }
  4364. }
  4365. return yValue;
  4366. }
  4367. }
  4368. this.GetXFromIndex = function (index) { return this.SubFrame[0].Frame.GetXFromIndex(index); }
  4369. this.GetYFromData = function (value) { return this.SubFrame[0].Frame.GetYFromData(value); }
  4370. this.PtInFrame=function(x,y) //鼠标哪个指标窗口
  4371. {
  4372. for(var i=0; i<this.SubFrame.length; ++i)
  4373. {
  4374. var item=this.SubFrame[i];
  4375. var left=item.Frame.ChartBorder.GetLeft();
  4376. var top=item.Frame.ChartBorder.GetTop();
  4377. var width=item.Frame.ChartBorder.GetWidth();
  4378. var height=item.Frame.ChartBorder.GetHeight();
  4379. var rtClient = new Rect(left, top, width, height);
  4380. var isInClient = rtClient.IsPointIn(x, y);
  4381. if (isInClient)
  4382. {
  4383. return i; //转成整形
  4384. }
  4385. }
  4386. return -1;
  4387. }
  4388. this.SetDayCount=function(dayCount)
  4389. {
  4390. for(var i=0;i<this.SubFrame.length;++i)
  4391. {
  4392. var item=this.SubFrame[i];
  4393. if (!item.Frame) continue;
  4394. item.Frame.DayCount=dayCount;
  4395. }
  4396. }
  4397. this.ZoomUp = function (cursorIndex)
  4398. {
  4399. var result = this.SubFrame[0].Frame.ZoomUp(cursorIndex);
  4400. this.UpdateAllFrame();
  4401. return result;
  4402. }
  4403. this.ZoomDown = function (cursorIndex)
  4404. {
  4405. var result = this.SubFrame[0].Frame.ZoomDown(cursorIndex);
  4406. this.UpdateAllFrame();
  4407. return result;
  4408. }
  4409. this.SetXShowCount=function(showCount)
  4410. {
  4411. var result=this.SubFrame[0].Frame.SetXShowCount(showCount);
  4412. this.UpdateAllFrame();
  4413. return result;
  4414. }
  4415. this.GetXShowCount=function()
  4416. {
  4417. var xPointcount=-1;
  4418. if (!IFrameSplitOperator.IsNonEmptyArray(this.SubFrame)) return xPointcount;
  4419. var subFrame=this.SubFrame[0];
  4420. if (!subFrame.Frame) return xPointcount;
  4421. xPointcount=subFrame.Frame.XPointCount;
  4422. return xPointcount;
  4423. }
  4424. this.SetDataWidth=function(dataWidth)
  4425. {
  4426. var obj=this.SubFrame[0].Frame.SetDataWidth(dataWidth);
  4427. this.UpdateAllFrame();
  4428. return obj;
  4429. }
  4430. this.OnSize=function()
  4431. {
  4432. var obj={};
  4433. this.SubFrame[0].Frame.OnSize(obj);
  4434. this.UpdateAllFrame();
  4435. return obj;
  4436. }
  4437. this.UpdateAllFrame=function()
  4438. {
  4439. var mainFrame=this.SubFrame[0].Frame;
  4440. for (var i = 1; i < this.SubFrame.length; ++i)
  4441. {
  4442. var item=this.SubFrame[i];
  4443. item.Frame.XPointCount = mainFrame.XPointCount;
  4444. item.Frame.ZoomIndex = mainFrame.ZoomIndex;
  4445. item.Frame.DataWidth = mainFrame.DataWidth;
  4446. item.Frame.DistanceWidth = mainFrame.DistanceWidth;
  4447. item.Frame.LastCalculateStatus.Width=mainFrame.LastCalculateStatus.Width;
  4448. item.Frame.LastCalculateStatus.XPointCount=mainFrame.LastCalculateStatus.XPointCount;
  4449. }
  4450. }
  4451. //设置重新计算刻度坐标
  4452. this.ResetXYSplit = function ()
  4453. {
  4454. for (let i in this.SubFrame)
  4455. {
  4456. this.SubFrame[i].Frame.XYSplit = true;
  4457. }
  4458. }
  4459. //清空Y轴坐标的最大最小值
  4460. this.ClearYCoordinateMaxMin=function(windowIndex)
  4461. {
  4462. if (IFrameSplitOperator.IsNumber(windowIndex))
  4463. {
  4464. var subItem=this.SubFrame[windowIndex];
  4465. if (!subItem || !subItem.Frame) return;
  4466. var frame=subItem.Frame;
  4467. if (frame.YMaxMin)
  4468. {
  4469. frame.YMaxMin.Max=null;
  4470. frame.YMaxMin.Min=null;
  4471. }
  4472. }
  4473. else
  4474. {
  4475. for(var i=0;i<this.SubFrame.length;++i)
  4476. {
  4477. var subItem=this.SubFrame[i];
  4478. var frame=subItem.Frame;
  4479. if (frame.YMaxMin)
  4480. {
  4481. frame.YMaxMin.Max=null;
  4482. frame.YMaxMin.Min=null;
  4483. }
  4484. }
  4485. }
  4486. }
  4487. this.SetLanguage=function(languageID)
  4488. {
  4489. for(let i in this.SubFrame)
  4490. {
  4491. var item=this.SubFrame[i];
  4492. if (item && item.Frame )
  4493. {
  4494. if (item.Frame.YSplitOperator) item.Frame.YSplitOperator.LanguageID=languageID;
  4495. if (item.Frame.XSplitOperator) item.Frame.XSplitOperator.LanguageID=languageID;
  4496. }
  4497. }
  4498. }
  4499. this.GetCurrentPageSize = function () //获取当前页显示的数据个数
  4500. {
  4501. if (this.SubFrame.length <= 0) return null;
  4502. var item = this.SubFrame[0];
  4503. if (!item || !item.Frame) return null;
  4504. return item.Frame.XPointCount;
  4505. }
  4506. this.ClearCoordinateText=function(option) //清空X,Y轴刻度文字, 线段保留
  4507. {
  4508. for(var i=0;i<this.SubFrame.length;++i)
  4509. {
  4510. var item=this.SubFrame[i];
  4511. if (!item.Frame) continue;
  4512. item.Frame.ClearCoordinateText(option);
  4513. }
  4514. }
  4515. this.RestoreIndexWindows=function()
  4516. {
  4517. if (!this.ZoomWindowsInfo) return false;
  4518. var subFrame=this.SubFrame[this.ZoomWindowsInfo.FrameID];
  4519. for(var i=this.ZoomStartWindowIndex;i<this.ZoomWindowsInfo.Data.length; ++i)
  4520. {
  4521. var restoreItem=this.ZoomWindowsInfo.Data[i];
  4522. var frameItem=this.SubFrame[i];
  4523. frameItem.Height=restoreItem.Height;
  4524. frameItem.Frame.IsMinSize=false;
  4525. frameItem.Frame.XSplitOperator.ShowText=restoreItem.ShowXText;
  4526. frameItem.Frame.XYSplit=true;
  4527. }
  4528. this.ZoomWindowsInfo=null;
  4529. return true;
  4530. }
  4531. this.ZoomIndexWindow=function(frameID, option)
  4532. {
  4533. var subFrame=this.SubFrame[frameID];
  4534. if (!subFrame) return false;
  4535. if (this.ZoomWindowsInfo) //还原
  4536. {
  4537. return this.RestoreIndexWindows();
  4538. }
  4539. else //放大
  4540. {
  4541. var zoomInfo={ FrameID:frameID, Data:[] }; //备份下放大前各个窗口的高度
  4542. for(var i=0; i<this.SubFrame.length; ++i)
  4543. {
  4544. var item=this.SubFrame[i];
  4545. zoomInfo.Data[i]={ Height:item.Height, ShowXText:item.Frame.XSplitOperator.ShowText };
  4546. }
  4547. this.ZoomWindowsInfo=zoomInfo;
  4548. var totalHeight=0;
  4549. for(var i=this.ZoomStartWindowIndex;i<this.SubFrame.length;++i)
  4550. {
  4551. var item=this.SubFrame[i];
  4552. var frame=item.Frame;
  4553. frame.XYSplit=true;
  4554. totalHeight+=item.Height;
  4555. if (i!=frameID)
  4556. {
  4557. item.Height=0;
  4558. frame.IsMinSize=true; //最小化
  4559. frame.XSplitOperator.ShowText=false;
  4560. }
  4561. }
  4562. subFrame.Height=totalHeight;
  4563. subFrame.Frame.XSplitOperator.ShowText=true;
  4564. return true;
  4565. }
  4566. }
  4567. }
  4568. //行情框架横屏
  4569. function HQTradeHScreenFrame() {
  4570. this.newMethod = HQTradeFrame; //派生
  4571. this.newMethod();
  4572. delete this.newMethod;
  4573. this.ClassName='HQTradeHScreenFrame';
  4574. this.IsHScreen = true; //是否是横屏
  4575. this.CalculateChartBorder = function () //计算每个子框架的边框信息
  4576. {
  4577. if (this.SubFrame.length <= 0) return;
  4578. var right = this.ChartBorder.Right;
  4579. var left = this.ChartBorder.GetRight();
  4580. var width = this.ChartBorder.GetWidth();
  4581. var totalHeight = 0;
  4582. for (var i in this.SubFrame) {
  4583. var item = this.SubFrame[i];
  4584. totalHeight += item.Height;
  4585. }
  4586. for (var i in this.SubFrame) {
  4587. var item = this.SubFrame[i];
  4588. item.Frame.ChartBorder.Top = this.ChartBorder.Top;
  4589. item.Frame.ChartBorder.Bottom = this.ChartBorder.Bottom;
  4590. var frameWidth = width * (item.Height / totalHeight);
  4591. item.Frame.ChartBorder.Right = right;
  4592. item.Frame.ChartBorder.Left = left - frameWidth;
  4593. right += frameWidth;
  4594. left -= frameWidth;
  4595. }
  4596. }
  4597. this.GetYData = function (x, outObject)
  4598. {
  4599. var frame;
  4600. for (var i=0; i<this.SubFrame.length; ++i)
  4601. {
  4602. var item = this.SubFrame[i];
  4603. var left = item.Frame.ChartBorder.GetLeftEx();
  4604. var top = item.Frame.ChartBorder.GetTop();
  4605. var width = item.Frame.ChartBorder.GetWidthEx();
  4606. var height = item.Frame.ChartBorder.GetHeight();
  4607. var rtItem = new Rect(left, top, width, height);
  4608. if (rtItem.IsPointIn(x, top))
  4609. {
  4610. frame = item.Frame;
  4611. if (outObject) outObject.FrameID = i;
  4612. break;
  4613. }
  4614. }
  4615. if (frame != null)
  4616. {
  4617. var xValue=frame.GetYData(x);
  4618. if (frame.GetMainOverlayFrame)
  4619. {
  4620. var aryOverlayFrame=frame.GetMainOverlayFrame();
  4621. if (aryOverlayFrame)
  4622. {
  4623. if (aryOverlayFrame[0]) //左侧
  4624. {
  4625. var leftFrame=aryOverlayFrame[0];
  4626. var value=leftFrame.GetYData(x);
  4627. outObject.RightYValue=xValue;
  4628. xValue=value;
  4629. }
  4630. if (aryOverlayFrame[1]) //右侧
  4631. {
  4632. var rightFrame=aryOverlayFrame[1];
  4633. var value=rightFrame.GetYData(x);
  4634. outObject.RightYValue=value;
  4635. }
  4636. }
  4637. }
  4638. return xValue;
  4639. }
  4640. }
  4641. }
  4642. function TooltipData() //提示信息
  4643. {
  4644. this.ChartPaint;
  4645. this.Data;
  4646. }
  4647. //基础图形的XY坐标互换柱子
  4648. function ChartXYSubBar() {
  4649. this.newMethod = ChartBar; //派生
  4650. this.newMethod();
  4651. delete this.newMethod;
  4652. this.BarID = 0;
  4653. this.Draw = function () {
  4654. if (this.NotSupportMessage) {
  4655. this.DrawNotSupportmessage();
  4656. return;
  4657. }
  4658. var dataWidth = this.ChartFrame.DataWidth;
  4659. var distanceWidth = this.ChartFrame.DistanceWidth;
  4660. var chartTop = this.ChartBorder.GetTopEx();
  4661. var xPointCount = this.ChartFrame.XPointCount;
  4662. var yOffset = this.ChartBorder.GetBottom() - distanceWidth / 2.0 - 2.0;
  4663. var xMiddle = this.ChartFrame.GetXFromIndex(0); //0 刻度
  4664. if (dataWidth >= 4) {
  4665. var barCount = this.ChartFrame.BarCount;
  4666. var subBarWidth = dataWidth;
  4667. var subBarOffset = 0;
  4668. if (barCount > 0) //多柱子需要把框架柱子宽度的平均分割
  4669. {
  4670. subBarWidth = dataWidth / barCount;
  4671. subBarOffset = subBarWidth * this.BarID;
  4672. //JSConsole.Chart.Log('[ChartXYSubBar::Draw] ', subBarWidth, this.BarID, subBarOffset);
  4673. }
  4674. xMiddle = ToFixedRect(xMiddle); //调整为整数
  4675. for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j, yOffset -= (dataWidth + distanceWidth)) {
  4676. var value = this.Data.Data[i];
  4677. if (value == null || value == 0) continue;
  4678. var yBottom = yOffset + subBarOffset;
  4679. var yTop = yOffset + subBarOffset - dataWidth;
  4680. if (yBottom < chartTop) break;
  4681. var x = this.ChartFrame.GetXFromIndex(value);
  4682. if (value > 0) {
  4683. this.Canvas.fillStyle = this.UpBarColor;
  4684. let barWidth = ToFixedRect(Math.abs(x - xMiddle));
  4685. let barHeight = subBarWidth;
  4686. if (Math.abs(chartTop - yBottom) < dataWidth) subBarWidth = Math.abs(chartTop - yBottom); //最后一根柱子可能会超出框架
  4687. this.Canvas.fillRect(xMiddle, ToFixedRect(yTop), barWidth, ToFixedRect(barHeight + 0.5));
  4688. }
  4689. else {
  4690. this.Canvas.fillStyle = this.DownBarColor;
  4691. //高度调整为整数
  4692. let barWidth = ToFixedRect(Math.abs(x - xMiddle));
  4693. let barHeight = subBarWidth;
  4694. if (Math.abs(chartTop - yBottom) < subBarWidth) barHeight = Math.abs(chartTop - yBottom); //最后一根柱子可能会超出框架
  4695. this.Canvas.fillRect(xMiddle, ToFixedRect(yTop), -barWidth, ToFixedRect(barHeight + 0.5));
  4696. }
  4697. }
  4698. }
  4699. else //太细了 直接画柱子
  4700. {
  4701. for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j, yOffset -= (dataWidth + distanceWidth)) {
  4702. var value = this.Data.Data[i];
  4703. if (value == null || value == 0) continue;
  4704. var yBottom = yOffset;
  4705. var yTop = yOffset - dataWidth;
  4706. if (yTop < chartTop) break;
  4707. var x = this.ChartFrame.GetXFromIndex(value);
  4708. var y = this.ChartFrame.GetYFromData(j);
  4709. if (value > 0) this.Canvas.strokeStyle = this.UpBarColor;
  4710. else this.Canvas.strokeStyle = this.DownBarColor;
  4711. this.Canvas.beginPath();
  4712. this.Canvas.moveTo(ToFixedPoint(x), y);
  4713. this.Canvas.lineTo(ToFixedPoint(xMiddle), y);
  4714. this.Canvas.stroke();
  4715. }
  4716. }
  4717. }
  4718. }
  4719. function ChartSubBar() {
  4720. this.newMethod = ChartBar; //派生
  4721. this.newMethod();
  4722. delete this.newMethod;
  4723. this.BarID = 0;
  4724. this.Draw = function () {
  4725. if (this.NotSupportMessage) {
  4726. this.DrawNotSupportmessage();
  4727. return;
  4728. }
  4729. var dataWidth = this.ChartFrame.DataWidth;
  4730. var distanceWidth = this.ChartFrame.DistanceWidth;
  4731. var chartright = this.ChartBorder.GetRight();
  4732. var xPointCount = this.ChartFrame.XPointCount;
  4733. var xOffset = this.ChartBorder.GetLeft() + distanceWidth / 2.0 + 2.0;
  4734. var yBottom = this.ChartFrame.GetYFromData(0);
  4735. if (dataWidth >= 4) {
  4736. var barCount = this.ChartFrame.BarCount;
  4737. var subBarWidth = dataWidth;
  4738. var subBarOffset = 0;
  4739. if (barCount > 0) //多柱子需要把框架柱子宽度的平均分割
  4740. {
  4741. subBarWidth = dataWidth / barCount;
  4742. subBarOffset = subBarWidth * this.BarID;
  4743. //JSConsole.Chart.Log('[ChartSubBar::Draw] ', subBarWidth, this.BarID, subBarOffset);
  4744. }
  4745. yBottom = ToFixedRect(yBottom); //调整为整数
  4746. for (let i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j, xOffset += (dataWidth + distanceWidth)) {
  4747. var value = this.Data.Data[i];
  4748. if (value == null || value == 0) continue;
  4749. var left = xOffset + subBarOffset
  4750. var right = xOffset + subBarOffset + subBarWidth;
  4751. if (left > chartright) break;
  4752. var x = this.ChartFrame.GetXFromIndex(j);
  4753. var y = this.ChartFrame.GetYFromData(value);
  4754. if (value > 0) {
  4755. this.Canvas.fillStyle = this.UpBarColor;
  4756. //高度调整为整数
  4757. let height = ToFixedRect(Math.abs(yBottom - y));
  4758. let barWidth = subBarWidth;
  4759. if (chartright - left < subBarWidth) barWidth = chartright - left;
  4760. if (yBottom - y > 0) y = yBottom - height;
  4761. else y = yBottom + height;
  4762. this.Canvas.fillRect(ToFixedRect(left), y, ToFixedRect(barWidth), height);
  4763. }
  4764. else {
  4765. this.Canvas.fillStyle = this.DownBarColor;
  4766. //高度调整为整数
  4767. let height = ToFixedRect(Math.abs(yBottom - y));
  4768. let barWidth = subBarWidth;
  4769. if (chartright - left < subBarWidth) barWidth = chartright - left;
  4770. if (yBottom - y > 0) y = yBottom - height;
  4771. else y = yBottom + height;
  4772. this.Canvas.fillRect(ToFixedRect(left), y, ToFixedRect(subBarWidth), -height);
  4773. }
  4774. }
  4775. }
  4776. else //太细了 直接画柱子
  4777. {
  4778. for (let i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j, xOffset += (dataWidth + distanceWidth)) {
  4779. var value = this.Data.Data[i];
  4780. if (value == null || value == 0) continue;
  4781. var left = xOffset;
  4782. var right = xOffset + dataWidth;
  4783. if (right > chartright) break;
  4784. var x = this.ChartFrame.GetXFromIndex(j);
  4785. var y = this.ChartFrame.GetYFromData(value);
  4786. if (value > 0) this.Canvas.strokeStyle = this.UpBarColor;
  4787. else this.Canvas.strokeStyle = this.DownBarColor;
  4788. this.Canvas.beginPath();
  4789. this.Canvas.moveTo(ToFixedPoint(x), y);
  4790. this.Canvas.lineTo(ToFixedPoint(x), yBottom);
  4791. this.Canvas.stroke();
  4792. }
  4793. }
  4794. }
  4795. }
  4796. //柱子 支持横屏
  4797. function ChartBar() {
  4798. this.newMethod = IChartPainting; //派生
  4799. this.newMethod();
  4800. delete this.newMethod;
  4801. this.UpBarColor = g_JSChartResource.UpBarColor;
  4802. this.DownBarColor = g_JSChartResource.DownBarColor;
  4803. this.Draw = function () {
  4804. if (this.NotSupportMessage) {
  4805. this.DrawNotSupportmessage();
  4806. return;
  4807. }
  4808. var isHScreen = (this.ChartFrame.IsHScreen === true);
  4809. var dataWidth = this.ChartFrame.DataWidth;
  4810. var distanceWidth = this.ChartFrame.DistanceWidth;
  4811. var chartright = this.ChartBorder.GetRight();
  4812. if (isHScreen) chartright = this.ChartBorder.GetBottom();
  4813. var xPointCount = this.ChartFrame.XPointCount;
  4814. var xOffset = this.ChartBorder.GetLeft() + distanceWidth / 2.0 + 2.0;
  4815. if (isHScreen) xOffset = this.ChartBorder.GetTop() + distanceWidth / 2.0 + 2.0;
  4816. var bFirstPoint = true;
  4817. var drawCount = 0;
  4818. var yBottom = this.ChartFrame.GetYFromData(0);
  4819. if (dataWidth >= 4) {
  4820. yBottom = ToFixedRect(yBottom); //调整为整数
  4821. for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j, xOffset += (dataWidth + distanceWidth)) {
  4822. var value = this.Data.Data[i];
  4823. if (value == null || value == 0) continue;
  4824. var left = xOffset;
  4825. var right = xOffset + dataWidth;
  4826. if (right > chartright) break;
  4827. var x = this.ChartFrame.GetXFromIndex(j);
  4828. var y = this.ChartFrame.GetYFromData(value);
  4829. if (value > 0) {
  4830. this.Canvas.fillStyle = this.UpBarColor;
  4831. if (isHScreen) {
  4832. let height = ToFixedRect(Math.abs(yBottom - y)); //高度调整为整数
  4833. y = Math.min(yBottom, y);
  4834. this.Canvas.fillRect(y, ToFixedRect(left), height, ToFixedRect(dataWidth));
  4835. }
  4836. else {
  4837. let height = ToFixedRect(Math.abs(yBottom - y)); //高度调整为整数
  4838. if (yBottom - y > 0) y = yBottom - height;
  4839. else y = yBottom + height;
  4840. this.Canvas.fillRect(ToFixedRect(left), y, ToFixedRect(dataWidth), height);
  4841. }
  4842. }
  4843. else {
  4844. this.Canvas.fillStyle = this.DownBarColor;
  4845. //高度调整为整数
  4846. let height = ToFixedRect(Math.abs(yBottom - y));
  4847. if (yBottom - y > 0) y = yBottom - height;
  4848. else y = yBottom + height;
  4849. this.Canvas.fillRect(ToFixedRect(left), y, ToFixedRect(dataWidth), -height);
  4850. }
  4851. }
  4852. }
  4853. else //太细了 直接画柱子
  4854. {
  4855. for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j, xOffset += (dataWidth + distanceWidth)) {
  4856. var value = this.Data.Data[i];
  4857. if (value == null || value == 0) continue;
  4858. var left = xOffset;
  4859. var right = xOffset + dataWidth;
  4860. if (right > chartright) break;
  4861. var x = this.ChartFrame.GetXFromIndex(j);
  4862. var y = this.ChartFrame.GetYFromData(value);
  4863. if (value > 0) this.Canvas.strokeStyle = this.UpBarColor;
  4864. else this.Canvas.strokeStyle = this.DownBarColor;
  4865. this.Canvas.beginPath();
  4866. if (isHScreen) {
  4867. this.Canvas.moveTo(y, ToFixedPoint(x));
  4868. this.Canvas.lineTo(yBottom, ToFixedPoint(x));
  4869. }
  4870. else {
  4871. this.Canvas.moveTo(ToFixedPoint(x), y);
  4872. this.Canvas.lineTo(ToFixedPoint(x), yBottom);
  4873. }
  4874. this.Canvas.stroke();
  4875. }
  4876. }
  4877. }
  4878. this.GetMaxMin = function () {
  4879. var xPointCount = this.ChartFrame.XPointCount;
  4880. var range = {};
  4881. range.Min = 0;
  4882. range.Max = null;
  4883. for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j) {
  4884. var value = this.Data.Data[i];
  4885. if (range.Max == null) range.Max = value;
  4886. if (range.Max < value) range.Max = value;
  4887. if (range.Min > value) range.Min = value;
  4888. }
  4889. return range;
  4890. }
  4891. }
  4892. /*
  4893. 指标列表 指标信息都在这里,不够后面再加字段
  4894. */
  4895. function JSIndexMap() {
  4896. }
  4897. JSIndexMap.Get = function (id) {
  4898. var indexMap = new Map(
  4899. [
  4900. //公司自己的指标
  4901. ["市场多空", { IsMainIndex: false, Create: function () { return new MarketLongShortIndex() } }],
  4902. ["市场择时", { IsMainIndex: false, Create: function () { return new MarketTimingIndex() } }],
  4903. ["市场关注度", { IsMainIndex: false, Create: function () { return new MarketAttentionIndex() } }],
  4904. ["指数热度", { IsMainIndex: false, Create: function () { return new MarketHeatIndex() } }],
  4905. ["自定义指数热度", { IsMainIndex: false, Create: function () { return new CustonIndexHeatIndex() }, Name: '自定义指数热度' }],
  4906. ["财务粉饰", { IsMainIndex: false, Create: function () { return new BenfordIndex() } }],
  4907. //能图指标
  4908. //["能图-趋势", { IsMainIndex: false, Create: function () { return new LighterIndex1() }, Name: '大盘/个股趋势' }],
  4909. //["能图-位置研判", { IsMainIndex: false, Create: function () { return new LighterIndex2() }, Name: '位置研判' }],
  4910. //["能图-点位研判", { IsMainIndex: false, Create: function () { return new LighterIndex3() }, Name: '点位研判' }],
  4911. //["能图-资金分析", { IsMainIndex: false, Create: function () { return new LighterIndex4() }, Name: '资金分析' }],
  4912. //["能图-市场关注度", { IsMainIndex: false, Create: function () { return new LighterIndex5() }, Name: '市场关注度' }]
  4913. ]
  4914. );
  4915. return indexMap.get(id);
  4916. }
  4917. /////////////////////////////////////////////////////////////////////////////////////////////
  4918. // K线图 控件
  4919. // this.ChartPaint[0] K线画法 这个不要修改
  4920. //
  4921. //
  4922. function KLineChartContainer(uielement)
  4923. {
  4924. var _self = this;
  4925. this.newMethod = JSChartContainer; //派生
  4926. this.newMethod(uielement);
  4927. delete this.newMethod;
  4928. this.ClassName = 'KLineChartContainer';
  4929. this.WindowIndex = new Array();
  4930. this.ColorIndex; //五彩K线
  4931. this.TradeIndex; //交易指标/专家系统
  4932. this.Symbol;
  4933. this.Name;
  4934. this.Period = 0; //周期 0=日线 1=周线 2=月线 3=年线 4=1分钟 5=5分钟 6=15分钟 7=30分钟 8=60分钟 9=季线 10=分笔线 11=120分钟 12=240分钟
  4935. this.RightFormula=0 //复权公式 0=简单复权, 1=复权因子复权
  4936. this.IsApiPeriod = false; //使用API计算周期
  4937. this.Right = 0; //复权 0 不复权 1 前复权 2 后复权
  4938. this.SourceData; //原始的历史数据
  4939. this.MaxRequestDataCount = 3000; //数据个数
  4940. this.MaxRequestMinuteDayCount = 5; //分钟数据请求的天数
  4941. this.PageSize = 200; //每页数据个数
  4942. this.KLineDrawType = 0; //0=K线 1=收盘价线 2=美国线
  4943. this.LoadDataSplashTitle = '下载历史数据';
  4944. this.IsAutoUpdate = false; //是否自动更新行情数据
  4945. this.AutoUpdateFrequency = 30000; //30秒更新一次数据
  4946. this.AutoUpdateTimer=null; //自动定时器
  4947. this.RightSpaceCount=1;
  4948. this.SourceDataLimit = new Map(); //每个周期缓存数据最大个数 key=周期 value=最大个数
  4949. this.IsZoomLockRight=false;
  4950. this.KLineSize=null; //{ DataWidth:, }
  4951. this.StepPixel = 4; //移动一个数据需要的像素
  4952. this.ZoomStepPixel = 5; //放大缩小手势需要的最小像素
  4953. this.EnableZoomUpDown=null; //是否手势/键盘/鼠标允许缩放{ Touch:true/false, Mouse:true/false, Keyboard:true/false, Wheel:true/false }
  4954. this.EnableMoveData=null; //是否可以移动K线 { Touch:true/false }
  4955. this.DragDownload = {
  4956. Day: { Enable: false, IsEnd: false, Status: 0 }, //日线数据拖拽下载(暂不支持) Status: 0空闲 1 下载中
  4957. Minute: { Enable: false, IsEnd: false, Status: 0 } //分钟数据拖拽下载
  4958. };
  4959. this.KLineApiUrl = g_JSChartResource.Domain + "/API/KLine2"; //历史K线api地址
  4960. this.MinuteKLineApiUrl = g_JSChartResource.Domain + '/API/KLine3'; //历史分钟数据
  4961. this.RealtimeApiUrl = g_JSChartResource.Domain + "/API/Stock"; //实时行情api地址
  4962. this.KLineMatchUrl = g_JSChartResource.Domain + "/API/KLineMatch"; //形态匹配
  4963. this.DragMinuteKLineApiUrl = g_JSChartResource.Domain + '/API/KLine4'; //拖动数据下载
  4964. this.DragKLineApiUrl = g_JSChartResource.Domain + '/API/KLine5'; //拖动日K数据下载
  4965. this.BeforeBindMainData = null; //function(funcName) 在BindMainData() 调用前回调用
  4966. this.AfterBindMainData = null; //function(funcName) 在BindMainData() 调用前后调用
  4967. this.FlowCapitalReady=false; //流通股本是否下载完成
  4968. this.ResetDragDownload = function ()
  4969. {
  4970. this.DragDownload.Day.Status = 0;
  4971. this.DragDownload.Day.IsEnd=false;
  4972. this.DragDownload.Minute.Status = 0;
  4973. this.DragDownload.Minute.IsEnd=false;
  4974. }
  4975. this.AddCustomKLine=function(kline, option)
  4976. {
  4977. var klineChart=this.ChartPaint[0];
  4978. if (!klineChart) return;
  4979. if (!kline) return;
  4980. if (!klineChart.CustomKLine) klineChart.CustomKLine=new Map();
  4981. if (Array.isArray(kline))
  4982. {
  4983. for(var i=0;i<kline.length;++i)
  4984. {
  4985. var item=kline[i];
  4986. klineChart.CustomKLine.set(item.Key, item.Data);
  4987. }
  4988. }
  4989. else if (kline)
  4990. {
  4991. klineChart.CustomKLine.set(kline.Key, kline.Data);
  4992. }
  4993. if (option && option.Draw==true) this.Draw();
  4994. }
  4995. this.ClearCustomKLine=function(option)
  4996. {
  4997. var klineChart=this.ChartPaint[0];
  4998. if (!klineChart) return;
  4999. klineChart.ClearCustomKLine();
  5000. if (option && option.Draw==true) this.Draw();
  5001. }
  5002. this.ChartOperator = function (obj) //图形控制函数 {ID:JSCHART_OPERATOR_ID, ...参数 }
  5003. {
  5004. var id = obj.ID;
  5005. if (id === JSCHART_OPERATOR_ID.OP_SCROLL_LEFT || id === JSCHART_OPERATOR_ID.OP_SCROLL_RIGHT) //左右移动 { Step:移动数据个数 }
  5006. {
  5007. var isLeft = (id === JSCHART_OPERATOR_ID.OP_SCROLL_LEFT ? true : false);
  5008. var step = 1;
  5009. if (obj.Step > 0) step = obj.Step;
  5010. if (this.DataMove(step * this.StepPixel, isLeft)) //每次移动一个数据
  5011. {
  5012. this.UpdataDataoffset();
  5013. this.UpdatePointByCursorIndex();
  5014. this.UpdateFrameMaxMin();
  5015. this.ResetFrameXYSplit();
  5016. this.Draw();
  5017. }
  5018. else
  5019. {
  5020. if (id===JSCHART_OPERATOR_ID.OP_SCROLL_RIGHT && this.DragDownloadData)
  5021. this.DragDownloadData();
  5022. }
  5023. }
  5024. else if (id === JSCHART_OPERATOR_ID.OP_ZOOM_IN || id === JSCHART_OPERATOR_ID.OP_ZOOM_OUT) //缩放
  5025. {
  5026. var cursorIndex = {};
  5027. cursorIndex.Index = parseInt(Math.abs(this.CursorIndex - 0.5).toFixed(0));
  5028. if (id === JSCHART_OPERATOR_ID.OP_ZOOM_IN)
  5029. {
  5030. if (!this.Frame.ZoomUp(cursorIndex)) return;
  5031. }
  5032. else
  5033. {
  5034. if (!this.Frame.ZoomDown(cursorIndex)) return;
  5035. }
  5036. this.CursorIndex = cursorIndex.Index;
  5037. this.UpdataDataoffset();
  5038. this.UpdatePointByCursorIndex();
  5039. this.UpdateFrameMaxMin();
  5040. this.Draw();
  5041. }
  5042. else if (id === JSCHART_OPERATOR_ID.OP_GOTO_HOME) //返回最新
  5043. {
  5044. var hisData = this.ChartOperator_Temp_GetHistroyData();
  5045. if (!hisData) return; //数据还没有到达
  5046. var showCount=this.Frame.SubFrame[0].Frame.XPointCount; //获取一屏显示的数据个数
  5047. showCount-=this.RightSpaceCount;
  5048. var index=hisData.Data.length-showCount;
  5049. hisData.DataOffset=index;
  5050. this.CursorIndex=0;
  5051. this.LastPoint.X=null;
  5052. this.LastPoint.Y=null;
  5053. JSConsole.Chart.Log(`[KLineChartContainer::ChartOperator] OP_GOTO_HOME, dataOffset=${hisData.DataOffset} CursorIndex=${this.CursorIndex} PageSize=${showCount}`);
  5054. this.ChartOperator_Temp_Update();
  5055. }
  5056. else if (id===JSCHART_OPERATOR_ID.OP_GOTO_END)
  5057. {
  5058. var hisData=this.ChartOperator_Temp_GetHistroyData();
  5059. if (!hisData) return; //数据还没有到达
  5060. hisData.DataOffset=0;
  5061. this.CursorIndex=0;
  5062. this.LastPoint.X=null;
  5063. this.LastPoint.Y=null;
  5064. JSConsole.Chart.Log(`[KLineChartContainer::ChartOperator] OP_GOTO_END `);
  5065. this.ChartOperator_Temp_Update();
  5066. }
  5067. else if (id==JSCHART_OPERATOR_ID.OP_GOTO) //{ Date:日期, Time: , PageSize:(可选)}
  5068. {
  5069. if (!IFrameSplitOperator.IsNumber(obj.Date)) return;
  5070. var hisData=this.ChartOperator_Temp_GetHistroyData();
  5071. if (!hisData) return; //数据还没有到达
  5072. var index=null;
  5073. if (ChartData.IsDayPeriod(this.Period,true))
  5074. {
  5075. for(var i=0;i<hisData.Data.length;++i)
  5076. {
  5077. var item=hisData.Data[i];
  5078. if (item.Date>=obj.Date)
  5079. {
  5080. index=i;
  5081. break;
  5082. }
  5083. }
  5084. }
  5085. else if (ChartData.IsMinutePeriod(this.Period,true))
  5086. {
  5087. let findTime=obj.Time;
  5088. if (IFrameSplitOperator.IsPlusNumber(findTime))
  5089. {
  5090. for(var i=0;i<hisData.Data.length;++i)
  5091. {
  5092. var item=hisData.Data[i];
  5093. if (item.Date>obj.Date || (item.Date==obj.Date && item.Time>=findTime))
  5094. {
  5095. index=i;
  5096. break;
  5097. }
  5098. }
  5099. }
  5100. else //只有日期
  5101. {
  5102. for(var i=0;i<hisData.Data.length;++i)
  5103. {
  5104. var item=hisData.Data[i];
  5105. if (item.Date>=obj.Date)
  5106. {
  5107. index=i;
  5108. break;
  5109. }
  5110. }
  5111. }
  5112. }
  5113. if (index===null)
  5114. {
  5115. JSConsole.Chart.Log(`[KLineChartContainer::ChartOperator] OP_GOTO can't find date=${obj.Date} time=${obj.Time}`);
  5116. return;
  5117. }
  5118. var oldXPointCount=this.Frame.SubFrame[0].Frame.XPointCount;
  5119. var xPointCount=oldXPointCount;
  5120. if (obj.PageSize>0) //调整一屏显示的个数
  5121. {
  5122. xPointCount=obj.PageSize;
  5123. }
  5124. if (xPointCount!=oldXPointCount)
  5125. {
  5126. //设置X轴显示数据个数
  5127. this.Frame.SetXShowCount(xPointCount);
  5128. }
  5129. hisData.DataOffset=index;
  5130. this.CursorIndex=0;
  5131. this.LastPoint.X=null;
  5132. this.LastPoint.Y=null;
  5133. this.ChartOperator_Temp_Update();
  5134. }
  5135. }
  5136. //内部函数
  5137. this.ChartOperator_Temp_GetHistroyData=function()
  5138. {
  5139. var hisData=null;
  5140. if (!this.Frame.Data) hisData=this.Frame.Data;
  5141. else hisData=this.Frame.SubFrame[0].Frame.Data;
  5142. if (!hisData) return null; //数据还没有到达
  5143. return hisData;
  5144. }
  5145. this.ChartOperator_Temp_Update=function()
  5146. {
  5147. this.UpdataDataoffset(); //更新数据偏移
  5148. this.UpdateFrameMaxMin(); //调整坐标最大 最小值
  5149. this.Frame.SetSizeChange(true);
  5150. this.Draw();
  5151. this.UpdatePointByCursorIndex(); //更新十字光标位子
  5152. }
  5153. //创建windowCount 窗口个数
  5154. this.Create = function (windowCount)
  5155. {
  5156. this.UIElement.JSChartContainer = this;
  5157. //创建十字光标
  5158. this.ChartCorssCursor = new ChartCorssCursor();
  5159. this.ChartCorssCursor.Canvas = this.Canvas;
  5160. this.ChartCorssCursor.StringFormatX = g_DivTooltipDataForamt.Create("CorssCursor_XStringFormat");
  5161. this.ChartCorssCursor.StringFormatX.GetEventCallback=(id)=> { return this.GetEventCallback(id); }
  5162. this.ChartCorssCursor.StringFormatX.LanguageID=this.LanguageID;
  5163. this.ChartCorssCursor.StringFormatY = g_DivTooltipDataForamt.Create("CorssCursor_YStringFormat");
  5164. this.ChartCorssCursor.StringFormatY.GetEventCallback=(id)=> { return this.GetEventCallback(id); }
  5165. this.ChartCorssCursor.StringFormatY.LanguageID = this.LanguageID;
  5166. this.ChartCorssCursor.StringFormatY.HQChart=this;
  5167. this.ChartCorssCursor.GetEventCallback=(id)=> { return this.GetEventCallback(id); }
  5168. //创建等待提示
  5169. this.ChartSplashPaint = new ChartSplashPaint();
  5170. this.ChartSplashPaint.Canvas = this.Canvas;
  5171. this.ChartSplashPaint.SplashTitle = this.LoadDataSplashTitle;
  5172. this.ChartSplashPaint.HQChart=this;
  5173. //创建框架容器
  5174. this.Frame = new HQTradeFrame();
  5175. this.Frame.ChartBorder = new ChartBorder();
  5176. this.Frame.ChartBorder.UIElement = this.UIElement;
  5177. this.Frame.ChartBorder.Top = 30;
  5178. this.Frame.ChartBorder.Left = 5;
  5179. this.Frame.ChartBorder.Bottom = 20;
  5180. this.Frame.Canvas = this.Canvas;
  5181. this.Frame.GetEventCallback=(id)=> { return this.GetEventCallback(id); }
  5182. this.ChartCorssCursor.Frame = this.Frame; //十字光标绑定框架
  5183. this.ChartSplashPaint.Frame = this.Frame;
  5184. this.CreateChildWindow(windowCount);
  5185. this.CreateMainKLine();
  5186. //子窗口动态标题
  5187. for (var i in this.Frame.SubFrame)
  5188. {
  5189. var titlePaint = new DynamicChartTitlePainting();
  5190. titlePaint.Frame = this.Frame.SubFrame[i].Frame;
  5191. titlePaint.Canvas = this.Canvas;
  5192. titlePaint.LanguageID = this.LanguageID;
  5193. titlePaint.GetEventCallback=(id)=> { return this.GetEventCallback(id); }
  5194. this.Frame.SubFrame[i].Frame.TitlePaint = titlePaint;
  5195. this.TitlePaint.push(titlePaint);
  5196. }
  5197. this.ChartCorssCursor.StringFormatX.Frame = this.Frame.SubFrame[0].Frame;
  5198. this.ChartCorssCursor.StringFormatY.Frame=this.Frame;
  5199. }
  5200. //创建子窗口
  5201. this.CreateChildWindow = function (windowCount)
  5202. {
  5203. var event=this.GetEventCallback(JSCHART_EVENT_ID.ON_CREATE_FRAME);
  5204. for (var i = 0; i < windowCount; ++i)
  5205. {
  5206. var border = new ChartBorder();
  5207. border.UIElement = this.UIElement;
  5208. var frame = new KLineFrame();
  5209. frame.Canvas = this.Canvas;
  5210. frame.ChartBorder = border;
  5211. frame.Identify = i; //窗口序号
  5212. frame.RightSpaceCount = this.RightSpaceCount; //右边
  5213. frame.GetEventCallback=(id)=> { return this.GetEventCallback(id); };
  5214. frame.GlobalOption=this.GlobalOption;
  5215. frame.CreateLockPaint();
  5216. frame.HorizontalMax = 20;
  5217. frame.HorizontalMin = 10;
  5218. if (i == 0)
  5219. {
  5220. frame.YSplitOperator = new FrameSplitKLinePriceY();
  5221. frame.YSplitOperator.FrameSplitData = this.FrameSplitData.get('price');
  5222. frame.YSplitOperator.FrameSplitData2 = this.FrameSplitData.get('double');
  5223. frame.GetEventCallback=(id)=> { return this.GetEventCallback(id); }
  5224. border.BottomSpace = 12; //主图上下留空间
  5225. border.TopSpace = 12;
  5226. }
  5227. else
  5228. {
  5229. frame.YSplitOperator = new FrameSplitY();
  5230. frame.YSplitOperator.FrameSplitData = this.FrameSplitData.get('double');
  5231. frame.YSplitOperator.LanguageID = this.LanguageID;
  5232. }
  5233. frame.YSplitOperator.GetEventCallback=(id)=> { return this.GetEventCallback(id); }
  5234. frame.YSplitOperator.Frame = frame;
  5235. frame.YSplitOperator.ChartBorder = border;
  5236. frame.XSplitOperator = new FrameSplitKLineX();
  5237. frame.XSplitOperator.Frame = frame;
  5238. frame.XSplitOperator.ChartBorder = border;
  5239. frame.XSplitOperator.GetEventCallback =(id)=> { return this.GetEventCallback(id); }
  5240. if (i != windowCount - 1) frame.XSplitOperator.ShowText = false;
  5241. for (var j = frame.HorizontalMin; j <= frame.HorizontalMax; j += 1)
  5242. {
  5243. frame.HorizontalInfo[j] = new CoordinateInfo();
  5244. frame.HorizontalInfo[j].Value = j;
  5245. if (i == 0 && j == frame.HorizontalMin) continue;
  5246. frame.HorizontalInfo[j].Message[1] = j.toString();
  5247. frame.HorizontalInfo[j].Font = "14px 微软雅黑";
  5248. }
  5249. var subFrame = new SubFrameItem();
  5250. frame.FrameData.SubFrameItem=subFrame;
  5251. subFrame.Frame = frame;
  5252. if (i == 0) subFrame.Height = 20;
  5253. else subFrame.Height = 10;
  5254. this.Frame.SubFrame[i] = subFrame;
  5255. if (event && event.Callback)
  5256. {
  5257. var sendData={ SubFrame:this.Frame.SubFrame[i], WindowIndex:i };
  5258. event.Callback(event, sendData, this);
  5259. }
  5260. }
  5261. }
  5262. this.CreateSubFrameItem = function (id)
  5263. {
  5264. var border = new ChartBorder();
  5265. border.UIElement = this.UIElement;
  5266. var frame = new KLineFrame();
  5267. frame.Canvas = this.Canvas;
  5268. frame.ChartBorder = border;
  5269. frame.Identify = id; //窗口序号
  5270. frame.GetEventCallback=(id)=> { return this.GetEventCallback(id); };
  5271. frame.GlobalOption=this.GlobalOption;
  5272. frame.CreateLockPaint();
  5273. frame.HorizontalMax = 20;
  5274. frame.HorizontalMin = 10;
  5275. frame.YSplitOperator = new FrameSplitY();
  5276. frame.YSplitOperator.LanguageID = this.LanguageID;
  5277. frame.YSplitOperator.FrameSplitData = this.FrameSplitData.get('double');
  5278. frame.YSplitOperator.Frame = frame;
  5279. frame.YSplitOperator.ChartBorder = border;
  5280. frame.XSplitOperator = new FrameSplitKLineX();
  5281. frame.XSplitOperator.Frame = frame;
  5282. frame.XSplitOperator.ChartBorder = border;
  5283. frame.XSplitOperator.ShowText = false;
  5284. frame.XSplitOperator.Period=this.Period;
  5285. frame.XSplitOperator.GetEventCallback =(id)=> { return this.GetEventCallback(id); }
  5286. //K线数据绑定
  5287. var xPointCouont = this.Frame.SubFrame[0].Frame.XPointCount;
  5288. frame.XPointCount = xPointCouont;
  5289. frame.Data = this.ChartPaint[0].Data;
  5290. for (var j = frame.HorizontalMin; j <= frame.HorizontalMax; j += 1)
  5291. {
  5292. frame.HorizontalInfo[j] = new CoordinateInfo();
  5293. frame.HorizontalInfo[j].Value = j;
  5294. frame.HorizontalInfo[j].Message[1] = j.toString();
  5295. frame.HorizontalInfo[j].Font = "14px 微软雅黑";
  5296. }
  5297. var subFrame = new SubFrameItem();
  5298. frame.FrameData.SubFrameItem=subFrame;
  5299. subFrame.Frame = frame;
  5300. subFrame.Height = 10;
  5301. var event=this.GetEventCallback(JSCHART_EVENT_ID.ON_CREATE_FRAME);
  5302. if (event && event.Callback)
  5303. {
  5304. var sendData={ SubFrame:subFrame, WindowIndex:id };
  5305. event.Callback(event, sendData, this);
  5306. }
  5307. return subFrame;
  5308. }
  5309. //创建主图K线画法
  5310. this.CreateMainKLine = function ()
  5311. {
  5312. var kline = new ChartKLine();
  5313. kline.Canvas = this.Canvas;
  5314. kline.ChartBorder = this.Frame.SubFrame[0].Frame.ChartBorder;
  5315. kline.ChartFrame = this.Frame.SubFrame[0].Frame;
  5316. kline.Name = "Main-KLine";
  5317. kline.DrawType = this.KLineDrawType;
  5318. kline.GetEventCallback=(id)=>{ return this.GetEventCallback(id); };
  5319. this.ChartPaint[0] = kline;
  5320. this.TitlePaint[0] = new DynamicKLineTitlePainting();
  5321. this.TitlePaint[0].Frame = this.Frame.SubFrame[0].Frame;
  5322. this.TitlePaint[0].Canvas = this.Canvas;
  5323. this.TitlePaint[0].LanguageID = this.LanguageID;
  5324. this.TitlePaint[0].HQChart=this;
  5325. }
  5326. //绑定主图K线数据
  5327. this.BindMainData = function (hisData, showCount)
  5328. {
  5329. this.ChartPaint[0].Data = hisData;
  5330. this.ChartPaint[0].Symbol = this.Symbol;
  5331. if (this.KLineSize)
  5332. {
  5333. if (this.KLineSize.DataWidth==null)
  5334. {
  5335. showCount=this.Frame.SubFrame[0].Frame.XPointCount-this.RightSpaceCount;
  5336. }
  5337. else
  5338. {
  5339. var obj=this.Frame.SetDataWidth(this.KLineSize.DataWidth);
  5340. showCount=obj.XPointCount-this.RightSpaceCount;
  5341. this.KLineSize.DataWidth=null;
  5342. }
  5343. }
  5344. for (var i in this.Frame.SubFrame)
  5345. {
  5346. var item = this.Frame.SubFrame[i].Frame;
  5347. item.XPointCount = showCount + this.RightSpaceCount;
  5348. item.Data = this.ChartPaint[0].Data;
  5349. item.XSplitOperator.Symbol = this.Symbol;
  5350. item.XSplitOperator.Period = this.Period;
  5351. }
  5352. this.TitlePaint[0].Data = this.ChartPaint[0].Data; //动态标题
  5353. this.TitlePaint[0].Symbol = this.Symbol;
  5354. this.TitlePaint[0].Name = this.Name;
  5355. this.TitlePaint[0].Period = this.Period;
  5356. this.ChartCorssCursor.StringFormatX.Data = this.ChartPaint[0].Data; //十字光标
  5357. this.Frame.Data = this.ChartPaint[0].Data;
  5358. for(var i=0; i<this.OverlayChartPaint.length; ++i) //K线叠加 主图股票数据绑定到叠加上
  5359. {
  5360. var item=this.OverlayChartPaint[i];
  5361. item.MainData=this.ChartPaint[0].Data;
  5362. }
  5363. var dataOffset = hisData.Data.length - showCount;
  5364. if (dataOffset < 0) dataOffset = 0;
  5365. this.ChartPaint[0].Data.DataOffset = dataOffset;
  5366. this.ChartCorssCursor.StringFormatY.Symbol = this.Symbol;
  5367. this.CursorIndex = showCount;
  5368. if (this.CursorIndex + dataOffset >= hisData.Data.length) this.CursorIndex = hisData.Data.length - 1 - dataOffset;
  5369. if (this.CursorIndex < 0) this.CursorIndex = 0; //不一定对啊
  5370. }
  5371. this.UpdateMainData = function (hisData, lastDataCount) //更新主图数据(不会放大缩小数据)
  5372. {
  5373. var frameHisdata = null;
  5374. if (!this.Frame.Data) frameHisdata = this.Frame.Data;
  5375. else if (this.Frame.SubFrame && this.Frame.SubFrame[0]) frameHisdata = this.Frame.SubFrame[0].Frame.Data;
  5376. if (!frameHisdata) return;
  5377. var xPointCount=this.Frame.SubFrame[0].Frame.XPointCount; //当前一屏能显示的数据个数
  5378. var newDataCount = 0;
  5379. if (lastDataCount > 0 && hisData.Data.length > lastDataCount)
  5380. {
  5381. newDataCount = hisData.Data.length - lastDataCount;
  5382. JSConsole.Chart.Log(`[KLineChartContainer::UpdateMainData] [count=${lastDataCount}->${hisData.Data.length}], [newDataCount=${newDataCount}], [Pagesize=${xPointCount}]`);
  5383. }
  5384. else if (lastDataCount==0 && hisData.Data.length>xPointCount) //历史数据为空,当前收到数据大于一屏的数据,显示最新数据
  5385. {
  5386. newDataCount=hisData.Data.length-xPointCount;
  5387. JSConsole.Chart.Log(`[KLineChartContainer::UpdateMainData] history data is empty. [count=${lastDataCount}->${hisData.Data.length}], [newDataCount=${newDataCount}], [Pagesize=${xPointCount}]`);
  5388. }
  5389. this.ChartPaint[0].Data = hisData;
  5390. this.ChartPaint[0].Symbol = this.Symbol;
  5391. if (hisData.Data.length>xPointCount) //不满一屏的, 不需要调整索引
  5392. this.ChartPaint[0].Data.DataOffset = frameHisdata.DataOffset + newDataCount; //加上数据增加的个数
  5393. for (var i in this.Frame.SubFrame)
  5394. {
  5395. var item = this.Frame.SubFrame[i].Frame;
  5396. item.Data = this.ChartPaint[0].Data;
  5397. if (i==0)
  5398. {
  5399. item.YSplitOperator.Symbol = this.Symbol;
  5400. item.YSplitOperator.Data = this.ChartPaint[0].Data; //K线数据
  5401. item.YSplitOperator.Period = this.Period; //周期
  5402. }
  5403. }
  5404. this.TitlePaint[0].Data = this.ChartPaint[0].Data; //动态标题
  5405. this.TitlePaint[0].Symbol = this.Symbol;
  5406. this.TitlePaint[0].Name = this.Name;
  5407. this.ChartCorssCursor.StringFormatX.Data = this.ChartPaint[0].Data; //十字光标
  5408. this.Frame.Data = this.ChartPaint[0].Data;
  5409. for (var i=0;i<this.OverlayChartPaint.length;++i) //主图股票数据绑定到叠加股票上
  5410. {
  5411. var item = this.OverlayChartPaint[i];
  5412. item.MainData = this.ChartPaint[0].Data;
  5413. }
  5414. this.ChartCorssCursor.StringFormatY.Symbol = this.Symbol;
  5415. }
  5416. //创建指定窗口指标
  5417. this.CreateWindowIndex = function (windowIndex)
  5418. {
  5419. this.WindowIndex[windowIndex].Create(this, windowIndex);
  5420. }
  5421. this.BindIndexData = function (windowIndex, hisData)
  5422. {
  5423. if (!this.WindowIndex[windowIndex]) return;
  5424. if (typeof (this.WindowIndex[windowIndex].RequestData) == "function") //数据需要另外下载的.
  5425. {
  5426. this.WindowIndex[windowIndex].RequestData(this, windowIndex, hisData);
  5427. return;
  5428. }
  5429. if (typeof (this.WindowIndex[windowIndex].ExecuteScript) == 'function') //脚本指标
  5430. {
  5431. this.WindowIndex[windowIndex].ExecuteScript(this, windowIndex, hisData);
  5432. return;
  5433. }
  5434. this.WindowIndex[windowIndex].BindData(this, windowIndex, hisData);
  5435. }
  5436. //执行指示(专家指示 五彩K线)
  5437. this.BindInstructionIndexData = function (hisData)
  5438. {
  5439. if (this.ColorIndex && typeof (this.ColorIndex.ExecuteScript) == 'function') //五彩K线
  5440. {
  5441. this.ColorIndex.ExecuteScript(this, 0, hisData);
  5442. }
  5443. if (this.TradeIndex && typeof (this.TradeIndex.ExecuteScript) == 'function') //交易指标
  5444. {
  5445. this.TradeIndex.ExecuteScript(this, 0, hisData);
  5446. }
  5447. }
  5448. //获取子窗口的所有画法
  5449. this.GetChartPaint = function (windowIndex)
  5450. {
  5451. var paint = new Array();
  5452. for (var i in this.ChartPaint)
  5453. {
  5454. if (i == 0) continue; //第1个K线数据除外
  5455. var item = this.ChartPaint[i];
  5456. if (item.ChartFrame == this.Frame.SubFrame[windowIndex].Frame)
  5457. paint.push(item);
  5458. }
  5459. return paint;
  5460. }
  5461. this.AutoUpdateEvent = function (bStart, explain) //自定更新事件, 是给websocket使用
  5462. {
  5463. var eventID = bStart ? JSCHART_EVENT_ID.RECV_START_AUTOUPDATE : JSCHART_EVENT_ID.RECV_STOP_AUTOUPDATE;
  5464. if (!this.mapEvent.has(eventID)) return;
  5465. var self = this;
  5466. var event = this.mapEvent.get(eventID);
  5467. var data = { Stock: { Symbol: this.Symbol, Name: this.Name, Right: this.Right, Period: this.Period }, Explain:explain };
  5468. if (bStart)
  5469. {
  5470. data.Callback = function (data) //数据到达更新回调
  5471. {
  5472. if (ChartData.IsDayPeriod(self.Period, true)) self.RecvRealtimeData(data);
  5473. else if (ChartData.IsMinutePeriod(self.Period, true)) self.RecvMinuteRealtimeData(data);
  5474. else if (ChartData.IsSecondPeriod(self.Period)) self.RecvMinuteRealtimeData(data);
  5475. }
  5476. }
  5477. event.Callback(event, data, this);
  5478. }
  5479. this.RequestHistoryData = function ()
  5480. {
  5481. var self = this;
  5482. this.CancelAutoUpdate();
  5483. this.ChartSplashPaint.SetTitle(this.LoadDataSplashTitle);
  5484. this.ChartSplashPaint.EnableSplash(true);
  5485. this.FlowCapitalReady=false;
  5486. this.ResetDragDownload();
  5487. this.Draw();
  5488. if (this.NetworkFilter)
  5489. {
  5490. var obj =
  5491. {
  5492. Name: 'KLineChartContainer::RequestHistoryData', //类名::
  5493. Explain: '日K数据',
  5494. Request: {
  5495. Url: self.KLineApiUrl, Type: 'POST',
  5496. Data:
  5497. {
  5498. symbol: self.Symbol, count: self.MaxRequestDataCount, field: ["name", "symbol", "yclose", "open", "price", "high", "low", "vol"] ,
  5499. period:this.Period,
  5500. right:this.Right
  5501. }
  5502. },
  5503. Self: this,
  5504. PreventDefault: false
  5505. };
  5506. this.NetworkFilter(obj, function (data) {
  5507. self.ChartSplashPaint.EnableSplash(false);
  5508. self.RecvHistoryData(data);
  5509. self.AutoUpdateEvent(true, "KLineChartContainer::RequestHistoryData");
  5510. self.AutoUpdate();
  5511. });
  5512. if (obj.PreventDefault == true) return; //已被上层替换,不调用默认的网络请求
  5513. }
  5514. JSNetwork.HttpRequest({
  5515. url: this.KLineApiUrl,
  5516. data:
  5517. {
  5518. "field": ["name","symbol","yclose","open","price","high","low","vol"],
  5519. "symbol": self.Symbol,
  5520. "start": -1,
  5521. "count": self.MaxRequestDataCount
  5522. },
  5523. method: 'POST',
  5524. dataType: 'json',
  5525. success: function (data) {
  5526. self.ChartSplashPaint.EnableSplash(false);
  5527. self.RecvHistoryData(data);
  5528. self.AutoUpdateEvent(true,"KLineChartContainer::RequestHistoryData");
  5529. self.AutoUpdate();
  5530. }
  5531. });
  5532. }
  5533. this.RecvHistoryData = function (recvData)
  5534. {
  5535. var data = recvData.data;
  5536. var aryDayData = KLineChartContainer.JsonDataToHistoryData(data);
  5537. //原始数据
  5538. var sourceData = new ChartData();
  5539. sourceData.Data = aryDayData;
  5540. sourceData.DataType = 0; //0=日线数据 1=分钟数据
  5541. sourceData.Symbol = data.symbol;
  5542. this.SourceData = sourceData;
  5543. if (this.BeforeBindMainData) this.BeforeBindMainData("RecvHistoryData");
  5544. //显示的数据
  5545. var bindData = new ChartData();
  5546. bindData.Data = aryDayData;
  5547. bindData.Right = this.Right;
  5548. bindData.Period = this.Period;
  5549. bindData.DataType = 0;
  5550. if (bindData.Right > 0 && !this.IsApiPeriod) //复权
  5551. {
  5552. var rightData = bindData.GetRightData(bindData.Right, { AlgorithmType: this.RightFormula });
  5553. bindData.Data = rightData;
  5554. }
  5555. if (ChartData.IsDayPeriod(bindData.Period, false) && !this.IsApiPeriod) //周期数据
  5556. {
  5557. var periodData = bindData.GetPeriodData(bindData.Period);
  5558. bindData.Data = periodData;
  5559. }
  5560. //绑定数据
  5561. this.Symbol = data.symbol;
  5562. this.Name = data.name;
  5563. this.BindMainData(bindData, this.PageSize);
  5564. if (this.AfterBindMainData) this.AfterBindMainData("RecvHistoryData");
  5565. this.Frame.SetSizeChange(true); //数据到达通知坐标框架
  5566. var firstSubFrame; //主窗口
  5567. if (this.Frame.SubFrame[0]) firstSubFrame=this.Frame.SubFrame[0].Frame;
  5568. if (firstSubFrame && firstSubFrame.YSplitOperator)
  5569. {
  5570. firstSubFrame.YSplitOperator.Symbol = this.Symbol; //绑定代码
  5571. firstSubFrame.YSplitOperator.Data = this.ChartPaint[0].Data; //K线数据
  5572. firstSubFrame.YSplitOperator.Period=this.Period; //周期
  5573. }
  5574. //请求叠加数据 (主数据下载完再下载))
  5575. this.ReqeustKLineInfoData({ FunctionName:"RecvHistoryData" });
  5576. this.RequestOverlayHistoryData();
  5577. //刷新画图
  5578. this.UpdataDataoffset(); //更新数据偏移
  5579. this.UpdatePointByCursorIndex(); //更新十字光标位子
  5580. this.UpdateFrameMaxMin(); //调整坐标最大 最小值
  5581. this.Frame.SetSizeChange(true);
  5582. this.Draw();
  5583. this.BindInstructionIndexData(bindData); //执行指示脚本
  5584. for (var i = 0; i < this.Frame.SubFrame.length; ++i) //执行指标
  5585. {
  5586. this.BindIndexData(i, bindData);
  5587. }
  5588. //叠加指标
  5589. this.BindAllOverlayIndexData(bindData);
  5590. if (this.mapEvent.has(JSCHART_EVENT_ID.RECV_HISTROY_DATA))
  5591. {
  5592. var event = this.mapEvent.get(JSCHART_EVENT_ID.RECV_HISTROY_DATA);
  5593. var data = { HistoryData: bindData, Stock: { Symbol: this.Symbol, Name: this.Name } }
  5594. event.Callback(event, data, this);
  5595. }
  5596. else //老的回调暂时保留
  5597. {
  5598. if (typeof (this.UpdateUICallback) == 'function') this.UpdateUICallback('RecvHistroyData', this); //单词拼写错误, 请使用下面的回调
  5599. if (typeof (this.UpdateUICallback) == 'function') this.UpdateUICallback('RecvHistoryData', this);
  5600. }
  5601. }
  5602. this.RequestHistoryMinuteData = function ()
  5603. {
  5604. var self = this;
  5605. this.CancelAutoUpdate();
  5606. this.ChartSplashPaint.SetTitle(this.LoadDataSplashTitle);
  5607. this.ChartSplashPaint.EnableSplash(true);
  5608. this.FlowCapitalReady=false;
  5609. this.ResetDragDownload();
  5610. this.Draw();
  5611. if (this.NetworkFilter)
  5612. {
  5613. var obj =
  5614. {
  5615. Name: 'KLineChartContainer::ReqeustHistoryMinuteData', //类名
  5616. Explain: '1分钟K线数据',
  5617. Request:
  5618. {
  5619. Url: self.MinuteKLineApiUrl, Type: 'POST', Data: {
  5620. symbol: self.Symbol, count: self.MaxRequestMinuteDayCount,
  5621. field: ["name", "symbol", "yclose", "open", "price", "high", "low", "vol"],
  5622. period:this.Period,
  5623. right:this.Right
  5624. }
  5625. },
  5626. Self: this,
  5627. PreventDefault: false
  5628. };
  5629. this.NetworkFilter(obj, function (data) {
  5630. self.ChartSplashPaint.EnableSplash(false);
  5631. self.RecvMinuteHistoryData(data);
  5632. self.AutoUpdateEvent(true,"KLineChartContainer::ReqeustHistoryMinuteData");
  5633. self.AutoUpdate();
  5634. });
  5635. if (obj.PreventDefault == true) return; //已被上层替换,不调用默认的网络请求
  5636. }
  5637. JSNetwork.HttpRequest({
  5638. url: this.MinuteKLineApiUrl,
  5639. data:
  5640. {
  5641. "field": ["name","symbol","yclose","open","price","high","low","vol"],
  5642. "symbol": self.Symbol,
  5643. "start": -1,
  5644. "count": self.MaxRequestMinuteDayCount
  5645. },
  5646. method: 'POST',
  5647. dataType: "json",
  5648. success: function (data)
  5649. {
  5650. self.ChartSplashPaint.EnableSplash(false);
  5651. self.RecvMinuteHistoryData(data);
  5652. self.AutoUpdateEvent(true,"KLineChartContainer::ReqeustHistoryMinuteData");
  5653. self.AutoUpdate();
  5654. }
  5655. });
  5656. }
  5657. this.ReqeustHistoryMinuteData=this.RequestHistoryMinuteData;
  5658. this.RecvMinuteHistoryData = function (recvData)
  5659. {
  5660. var data = recvData.data;
  5661. var aryDayData = KLineChartContainer.JsonDataToMinuteHistoryData(data);
  5662. //原始数据
  5663. var sourceData = new ChartData();
  5664. sourceData.Data = aryDayData;
  5665. sourceData.DataType = 1; //0=日线数据 1=分钟数据
  5666. sourceData.Symbol = data.symbol;
  5667. this.SourceData = sourceData;
  5668. if (this.BeforeBindMainData) this.BeforeBindMainData("RecvMinuteHistoryData");
  5669. //显示的数据
  5670. var bindData = new ChartData();
  5671. bindData.Data = aryDayData;
  5672. bindData.Right = this.Right;
  5673. bindData.Period = this.Period;
  5674. bindData.DataType = 1;
  5675. bindData.Symbol = data.symbol;
  5676. if (bindData.Right>0 && !this.IsApiPeriod && this.RightFormula>=1) //复权
  5677. {
  5678. var rightData=bindData.GetRightData(bindData.Right, { AlgorithmType: this.RightFormula } );
  5679. bindData.Data=rightData;
  5680. }
  5681. if (ChartData.IsMinutePeriod(bindData.Period, false) && !this.IsApiPeriod) //周期数据
  5682. {
  5683. var periodData = bindData.GetPeriodData(bindData.Period);
  5684. bindData.Data = periodData;
  5685. }
  5686. //绑定数据
  5687. this.Symbol = data.symbol;
  5688. this.Name = data.name;
  5689. this.BindMainData(bindData, this.PageSize);
  5690. if (this.AfterBindMainData) this.AfterBindMainData("RecvMinuteHistoryData");
  5691. this.Frame.SetSizeChange(true);
  5692. var firstSubFrame; //主窗口
  5693. if (this.Frame.SubFrame[0]) firstSubFrame=this.Frame.SubFrame[0].Frame;
  5694. if (firstSubFrame && firstSubFrame.YSplitOperator)
  5695. {
  5696. firstSubFrame.YSplitOperator.Symbol = this.Symbol; //绑定代码
  5697. firstSubFrame.YSplitOperator.Data = this.ChartPaint[0].Data; //K线数据
  5698. }
  5699. for(var i=0; i<this.OverlayChartPaint.length; ++i) //叠加股票 清空
  5700. {
  5701. var item=this.OverlayChartPaint[i];
  5702. item.Data=null;
  5703. //item.Status=OVERLAY_STATUS_ID.STATUS_NONE_ID;
  5704. }
  5705. //刷新画图
  5706. this.UpdataDataoffset(); //更新数据偏移
  5707. this.UpdatePointByCursorIndex(); //更新十字光标位子
  5708. this.UpdateFrameMaxMin(); //调整坐标最大 最小值
  5709. this.Frame.SetSizeChange(true);
  5710. this.Draw();
  5711. this.RequestOverlayHistoryMinuteData(); //请求叠加数据 (主数据下载完再下载)
  5712. this.BindInstructionIndexData(bindData); //执行指示脚本
  5713. for (var i = 0; i < this.Frame.SubFrame.length; ++i) //指标
  5714. {
  5715. this.BindIndexData(i, bindData);
  5716. }
  5717. //叠加指标
  5718. this.BindAllOverlayIndexData(bindData);
  5719. if (this.mapEvent.has(JSCHART_EVENT_ID.RECV_HISTROY_DATA))
  5720. {
  5721. var event = this.mapEvent.get(JSCHART_EVENT_ID.RECV_HISTROY_DATA);
  5722. var data = { HistoryData: bindData, Stock: { Symbol: this.Symbol, Name: this.Name } }
  5723. event.Callback(event, data, this);
  5724. }
  5725. else
  5726. {
  5727. if (typeof (this.UpdateUICallback) == 'function') this.UpdateUICallback('RecvMinuteHistoryData', this);
  5728. }
  5729. }
  5730. //请求实时行情数据
  5731. this.RequestRealtimeData = function ()
  5732. {
  5733. var self = this;
  5734. var arySymbol=[self.Symbol];
  5735. for(var i=0; i<this.OverlayChartPaint.length; ++i) //叠加的股票更新
  5736. {
  5737. var item=this.OverlayChartPaint[i];
  5738. if (!item.Symbol) continue;
  5739. if (!item.MainData) continue; //等待主图股票数据未下载完
  5740. if (item.Status!=OVERLAY_STATUS_ID.STATUS_FINISHED_ID) continue;
  5741. arySymbol.push(item.Symbol);
  5742. }
  5743. if (this.NetworkFilter)
  5744. {
  5745. var dateRange=null;
  5746. var hisData=this.ChartOperator_Temp_GetHistroyData();
  5747. if (hisData) dateRange=hisData.GetDateRange();
  5748. var obj =
  5749. {
  5750. Name: 'KLineChartContainer::RequestRealtimeData', //类名::函数名
  5751. Explain: '当天最新日线数据',
  5752. Request:
  5753. {
  5754. Url: self.RealtimeApiUrl, Data: {
  5755. symbol: arySymbol,
  5756. field: ["name", "symbol", "yclose", "open", "price", "high", "low", "vol", "amount", "date", "time"],
  5757. period:this.Period,
  5758. right:this.Right,
  5759. dateRange:dateRange
  5760. }, Type: 'POST'
  5761. },
  5762. Self: this,
  5763. PreventDefault: false
  5764. };
  5765. this.NetworkFilter(obj, function (data) {
  5766. self.RecvRealtimeData(data);
  5767. self.AutoUpdate();
  5768. });
  5769. if (obj.PreventDefault == true) return; //已被上层替换,不调用默认的网络请求
  5770. }
  5771. JSNetwork.HttpRequest({
  5772. url: this.RealtimeApiUrl,
  5773. data:
  5774. {
  5775. "field": ["name","symbol","yclose","open","price","high","low","vol","amount","date","time"],
  5776. "symbol": arySymbol,
  5777. "start": -1
  5778. },
  5779. method: 'POST',
  5780. dataType: "json",
  5781. async: true,
  5782. success: function (data) {
  5783. self.RecvRealtimeData(data);
  5784. self.AutoUpdate();
  5785. }
  5786. });
  5787. }
  5788. this.RecvRealtimeData = function (recvdata)
  5789. {
  5790. if (this.IsOnTouch == true) return; //正在操作中不更新数据
  5791. var data=recvdata.data;
  5792. var realtimeData = KLineChartContainer.JsonDataToRealtimeData(data, this.Symbol);
  5793. if (!realtimeData)
  5794. {
  5795. JSConsole.Chart.Log('[KLineChartContainer::RecvRealtimeData] recvdata error', recvdata);
  5796. return;
  5797. }
  5798. var item = this.SourceData.Data[this.SourceData.Data.length - 1]; //最新的一条数据
  5799. var lastDataCount = this.GetHistoryDataCount(); //保存下上一次的数据个数
  5800. if (this.SourceData.Data.length==0) //第1条数据
  5801. {
  5802. var newItem =new HistoryData();
  5803. HistoryData.CopyTo(newItem, realtimeData);
  5804. this.SourceData.Data.push(newItem);
  5805. }
  5806. else if (item.Date == realtimeData.Date) //实时行情数据更新
  5807. {
  5808. JSConsole.Chart.Log('[KLineChartContainer::RecvRealtimeData] update kline by minute data', realtimeData);
  5809. HistoryData.CopyTo(item, realtimeData);
  5810. }
  5811. else if (item.Date < realtimeData.Date) //新增加数据
  5812. {
  5813. JSConsole.Chart.Log('[KLineChartContainer::RecvRealtimeData] insert kline by minute data', realtimeData);
  5814. var newItem = new HistoryData();
  5815. HistoryData.CopyTo(newItem, realtimeData);
  5816. //没有前收盘就用上一个数据的收盘价
  5817. if (!IFrameSplitOperator.IsNumber(newItem.YClose) && this.SourceData.Data.length>0)
  5818. newItem.YClose=this.SourceData.Data[this.SourceData.Data.length-1].YClose;
  5819. this.SourceData.Data.push(newItem);
  5820. }
  5821. else
  5822. {
  5823. return;
  5824. }
  5825. var bindData = new ChartData();
  5826. bindData.Data = this.SourceData.Data;
  5827. bindData.Period = this.Period;
  5828. bindData.Right = this.Right;
  5829. bindData.DataType = this.SourceData.DataType;
  5830. bindData.Symbol = this.Symbol;
  5831. if (bindData.Right > 0 && ChartData.IsDayPeriod(bindData.Period,true) && !this.IsApiPeriod) //复权(日线数据才复权)
  5832. {
  5833. var rightData = bindData.GetRightData(bindData.Right, { AlgorithmType: this.RightFormula });
  5834. bindData.Data = rightData;
  5835. }
  5836. if (!this.IsApiPeriod)
  5837. {
  5838. if (ChartData.IsDayPeriod(bindData.Period, false) || ChartData.IsMinutePeriod(bindData.Period, false)) //周期数据 (0= 日线,4=1分钟线 不需要处理)
  5839. {
  5840. var periodData = bindData.GetPeriodData(bindData.Period);
  5841. bindData.Data = periodData;
  5842. }
  5843. }
  5844. //绑定数据
  5845. this.UpdateMainData(bindData, lastDataCount);
  5846. this.UpdateOverlayRealtimeData(data); //更新叠加股票数据
  5847. this.Frame.SetSizeChange(true);
  5848. this.BindInstructionIndexData(bindData); //执行指示脚本
  5849. for (var i = 0; i < this.Frame.SubFrame.length; ++i) {
  5850. this.BindIndexData(i, bindData);
  5851. }
  5852. //刷新画图
  5853. this.UpdataDataoffset(); //更新数据偏移
  5854. this.UpdatePointByCursorIndex(); //更新十字光标位子
  5855. this.UpdateFrameMaxMin(); //调整坐标最大 最小值
  5856. this.Frame.SetSizeChange(true);
  5857. this.Draw();
  5858. this.SendKLineUpdateEvent(bindData);
  5859. //叠加指标计算
  5860. this.BindAllOverlayIndexData(bindData);
  5861. }
  5862. this.UpdateOverlayRealtimeData=function(data)
  5863. {
  5864. if (!IFrameSplitOperator.IsNonEmptyArray(this.OverlayChartPaint)) return;
  5865. for(var i=0; i<this.OverlayChartPaint.length; ++i)
  5866. {
  5867. var item=this.OverlayChartPaint[i];
  5868. if (!item.Symbol) continue;
  5869. if (!item.MainData) continue; //等待主图股票数据未下载完
  5870. if (item.Status!=OVERLAY_STATUS_ID.STATUS_FINISHED_ID) continue;
  5871. var realtimeData=KLineChartContainer.JsonDataToRealtimeData(data,item.Symbol); //获取叠加股票的最新数据
  5872. if (!realtimeData) continue;
  5873. var sourceData=item.SourceData; //叠加股票的所有数据
  5874. var latestData=sourceData.Data[sourceData.Data.length-1]; //最新的一条数据
  5875. if (latestData.Date==realtimeData.Date) //实时行情数据更新
  5876. {
  5877. JSConsole.Chart.Log('[KLineChartContainer::UpdateOverlayRealtimeData] update kline by minute data',realtimeData);
  5878. latestData.Close=realtimeData.Close;
  5879. latestData.High=realtimeData.High;
  5880. latestData.Low=realtimeData.Low;
  5881. latestData.Vol=realtimeData.Vol;
  5882. latestData.Amount=realtimeData.Amount;
  5883. }
  5884. else if (latestData.Date<realtimeData.Date) //新增加数据
  5885. {
  5886. JSConsole.Chart.Log('[KLineChartContainer::UpdateOverlayRealtimeData] insert kline by minute data',realtimeData);
  5887. var newItem =new HistoryData();
  5888. newItem.YClose=realtimeData.YClose;
  5889. newItem.Open=realtimeData.Open;
  5890. newItem.Close=realtimeData.Close;
  5891. newItem.High=realtimeData.High;
  5892. newItem.Low=realtimeData.Low;
  5893. newItem.Vol=realtimeData.Vol;
  5894. newItem.Amount=realtimeData.Amount;
  5895. newItem.Date=realtimeData.Date;
  5896. sourceData.Data.push(newItem);
  5897. }
  5898. else
  5899. {
  5900. continue;
  5901. }
  5902. var bindData=new ChartData();
  5903. bindData.Data=sourceData.Data;
  5904. bindData.Period=this.Period;
  5905. bindData.Right=this.Right;
  5906. bindData.DataType=0;
  5907. if (bindData.Right>0 && MARKET_SUFFIX_NAME.IsSHSZStockA(data.symbol) && !this.IsApiPeriod) //复权数据 ,A股才有有复权
  5908. {
  5909. var rightData=bindData.GetRightData(bindData.Right, { AlgorithmType: this.RightFormula });
  5910. bindData.Data=rightData;
  5911. }
  5912. var aryOverlayData=this.SourceData.GetOverlayData(bindData.Data, this.IsApiPeriod); //和主图数据拟合以后的数据
  5913. bindData.Data=aryOverlayData;
  5914. if (ChartData.IsDayPeriod(bindData.Period,false) && !this.IsApiPeriod) //周期数据
  5915. {
  5916. var periodData=bindData.GetPeriodData(bindData.Period);
  5917. bindData.Data=periodData;
  5918. }
  5919. item.Data=bindData;
  5920. }
  5921. }
  5922. this.GetHistoryDataCount = function ()
  5923. {
  5924. var frameHisdata = null;
  5925. if (!this.Frame.Data) frameHisdata = this.Frame.Data;
  5926. else if (this.Frame.SubFrame && this.Frame.SubFrame[0]) frameHisdata = this.Frame.SubFrame[0].Frame.Data;
  5927. if (!frameHisdata) return -1;
  5928. var lastDataCount = frameHisdata.Data.length; //上一个的数据长度
  5929. return lastDataCount;
  5930. }
  5931. this.RequestMinuteRealtimeData = function ()
  5932. {
  5933. var self = this;
  5934. var arySymbol=[self.Symbol];
  5935. for(var i=0; i<this.OverlayChartPaint.length; ++i) //叠加的股票更新
  5936. {
  5937. var item=this.OverlayChartPaint[i];
  5938. if (!item.Symbol) continue;
  5939. if (!item.MainData) continue; //等待主图股票数据未下载完
  5940. if (item.Status!=OVERLAY_STATUS_ID.STATUS_FINISHED_ID) continue;
  5941. arySymbol.push(item.Symbol);
  5942. }
  5943. if (this.NetworkFilter)
  5944. {
  5945. var dateRange=null;
  5946. var hisData=this.ChartOperator_Temp_GetHistroyData();
  5947. if (hisData) dateRange=hisData.GetDateRange();
  5948. var obj =
  5949. {
  5950. Name: 'KLineChartContainer::RequestMinuteRealtimeData', //类名::
  5951. Explain: '当天1分钟K线数据',
  5952. Request: {
  5953. Url: self.RealtimeApiUrl, Data: {
  5954. symbol: arySymbol,
  5955. field: ["name", "symbol", "price", "yclose", "minutecount", "minute", "date", "time"],
  5956. period:this.Period,
  5957. right:this.Right,
  5958. dateRange:dateRange
  5959. }, Type: 'POST'
  5960. },
  5961. Self: this,
  5962. PreventDefault: false
  5963. };
  5964. this.NetworkFilter(obj, function (data) {
  5965. self.RecvMinuteRealtimeData(data);
  5966. self.AutoUpdate();
  5967. });
  5968. if (obj.PreventDefault == true) return; //已被上层替换,不调用默认的网络请求
  5969. }
  5970. JSNetwork.HttpRequest({
  5971. url: this.RealtimeApiUrl,
  5972. data:
  5973. {
  5974. "field": ["name", "symbol", "price", "yclose", "minutecount", "minute", "date", "time"],
  5975. "symbol": arySymbol,
  5976. "start": -1
  5977. },
  5978. method: 'POST',
  5979. dataType: "json",
  5980. async: true,
  5981. success: function (data) {
  5982. self.RecvMinuteRealtimeData(data);
  5983. self.AutoUpdate();
  5984. }
  5985. });
  5986. }
  5987. this.SetSourceDatatLimit = function (aryLimit)
  5988. {
  5989. this.SourceDataLimit = new Map();
  5990. for (var i in aryLimit)
  5991. {
  5992. var item = aryLimit[i];
  5993. this.SourceDataLimit.set(item.Period, item.MaxCount); //每个周期缓存数据最大个数 key=周期 value=最大个数
  5994. JSConsole.Chart.Log(`[KLineChartContainer::SetSourceDatatLimit] Period=${item.Period}, MaxCount=${item.MaxCount}`);
  5995. }
  5996. }
  5997. this.ReduceSourceData = function ()
  5998. {
  5999. if (!this.SourceDataLimit) return;
  6000. if (!this.SourceDataLimit.has(this.Period)) return;
  6001. var limitCount = this.SourceDataLimit.get(this.Period);
  6002. if (limitCount < 50) return;
  6003. var frameHisdata = null;
  6004. if (!this.Frame.Data) frameHisdata = this.Frame.Data;
  6005. else if (this.Frame.SubFrame && this.Frame.SubFrame[0]) frameHisdata = this.Frame.SubFrame[0].Frame.Data;
  6006. if (!frameHisdata) return;
  6007. var dataOffset = frameHisdata.DataOffset;
  6008. var removeCount = 0;
  6009. while (this.SourceData.Data.length > limitCount)
  6010. {
  6011. this.SourceData.Data.shift();
  6012. --dataOffset;
  6013. ++removeCount;
  6014. }
  6015. if (removeCount > 0)
  6016. {
  6017. if (dataOffset < 0) dataOffset = 0;
  6018. frameHisdata.DataOffset = dataOffset;
  6019. JSConsole.Chart.Log(`[KLineChartContainer::ReduceSourceData] remove data ${removeCount}, dataOffset=${dataOffset}`);
  6020. }
  6021. }
  6022. this.RecvMinuteRealtimeData = function (recvData)
  6023. {
  6024. var data=recvData.data;
  6025. if (this.IsOnTouch == true) return; //正在操作中不更新数据
  6026. if (data.ver == 2.0)
  6027. {
  6028. this.RecvMinuteRealtimeDataV2(data); //v2.0数据版本
  6029. return;
  6030. }
  6031. if (!data.stock || !data.stock[0] || this.Symbol != data.stock[0].symbol) return;
  6032. var realtimeData = KLineChartContainer.JsonDataToMinuteRealtimeData(data);
  6033. if (!realtimeData) return;
  6034. if (this.IsApiPeriod) this.ReduceSourceData(); //减少数据
  6035. var lastDataCount = this.GetHistoryDataCount(); //保存下上一次的数据个数
  6036. var lastSourceDataCount = this.SourceData.Data.length;
  6037. if (!this.SourceData.MergeMinuteData(realtimeData)) return;
  6038. JSConsole.Chart.Log(`[KLineChartContainer::RecvMinuteRealtimeData] update kline by 1 minute data [${lastSourceDataCount}->${this.SourceData.Data.length}]`);
  6039. var bindData = new ChartData();
  6040. bindData.Data = this.SourceData.Data;
  6041. bindData.Period = this.Period;
  6042. bindData.Right = this.Right;
  6043. bindData.DataType = this.SourceData.DataType;
  6044. bindData.Symbol = this.Symbol;
  6045. if (bindData.Right > 0 && ChartData.IsDayPeriod(bindData.Period,true) && !this.IsApiPeriod) //复权(日线数据才复权)
  6046. {
  6047. var rightData = bindData.GetRightData(bindData.Right, { AlgorithmType: this.RightFormula });
  6048. bindData.Data = rightData;
  6049. }
  6050. if (!this.IsApiPeriod)
  6051. {
  6052. if (ChartData.IsDayPeriod(bindData.Period, false) || ChartData.IsMinutePeriod(bindData.Period, false)) //周期数据 (0= 日线,4=1分钟线 不需要处理)
  6053. {
  6054. var periodData = bindData.GetPeriodData(bindData.Period);
  6055. bindData.Data = periodData;
  6056. }
  6057. }
  6058. //绑定数据
  6059. this.UpdateMainData(bindData, lastDataCount);
  6060. this.Frame.SetSizeChange(true);
  6061. this.BindInstructionIndexData(bindData); //执行指示脚本
  6062. for (var i = 0; i < this.Frame.SubFrame.length; ++i) {
  6063. this.BindIndexData(i, bindData);
  6064. }
  6065. //刷新画图
  6066. this.UpdataDataoffset(); //更新数据偏移
  6067. this.UpdatePointByCursorIndex(); //更新十字光标位子
  6068. this.UpdateFrameMaxMin(); //调整坐标最大 最小值
  6069. this.Frame.SetSizeChange(true);
  6070. this.Draw();
  6071. this.SendKLineUpdateEvent(bindData);
  6072. //叠加指标计算
  6073. this.BindAllOverlayIndexData(bindData);
  6074. }
  6075. this.RecvMinuteRealtimeDataV2 = function (data) //新版本的
  6076. {
  6077. if (this.IsOnTouch == true) return; //正在操作中不更新数据
  6078. var aryMinuteData = KLineChartContainer.JsonDataToMinuteHistoryData(data);
  6079. if (!aryMinuteData || aryMinuteData.length <= 0) return;
  6080. if (this.IsApiPeriod) this.ReduceSourceData(); //减少数据
  6081. var lastDataCount = this.GetHistoryDataCount(); //保存下上一次的数据个数
  6082. if (!this.SourceData.MergeMinuteData(aryMinuteData)) return;
  6083. JSConsole.Chart.Log(`[KLineChartContainer::RecvMinuteRealtimeDataV2] update kline by 1 minute data [${lastDataCount}->${this.SourceData.Data.length}]`);
  6084. var bindData = new ChartData();
  6085. bindData.Data = this.SourceData.Data;
  6086. bindData.Period = this.Period;
  6087. bindData.Right = this.Right;
  6088. bindData.DataType = this.SourceData.DataType;
  6089. bindData.Symbol = this.Symbol;
  6090. if (bindData.Right > 0 && ChartData.IsDayPeriod(bindData.Period, true) && !this.IsApiPeriod) //复权(日线数据才复权)
  6091. {
  6092. var rightData = bindData.GetRightData(bindData.Right, { AlgorithmType: this.RightFormula });
  6093. bindData.Data = rightData;
  6094. }
  6095. if ((ChartData.IsDayPeriod(bindData.Period, false) || ChartData.IsMinutePeriod(bindData.Period, false)) && !this.IsApiPeriod) //周期数据 (0= 日线,4=1分钟线 不需要处理)
  6096. {
  6097. var periodData = bindData.GetPeriodData(bindData.Period);
  6098. bindData.Data = periodData;
  6099. }
  6100. //绑定数据
  6101. this.UpdateMainData(bindData, lastDataCount);
  6102. this.UpdateOverlayMinuteRealtimeData(data); //更新叠加股票数据
  6103. this.Frame.SetSizeChange(true);
  6104. this.BindInstructionIndexData(bindData); //执行指示脚本
  6105. for (var i = 0; i < this.Frame.SubFrame.length; ++i) {
  6106. this.BindIndexData(i, bindData);
  6107. }
  6108. //刷新画图
  6109. this.UpdataDataoffset(); //更新数据偏移
  6110. this.UpdatePointByCursorIndex(); //更新十字光标位子
  6111. this.UpdateFrameMaxMin(); //调整坐标最大 最小值
  6112. this.Frame.SetSizeChange(true);
  6113. this.Draw();
  6114. this.SendKLineUpdateEvent(bindData);
  6115. //更新叠加指标
  6116. this.BindAllOverlayIndexData(bindData);
  6117. }
  6118. //更新当天的全量分钟数据
  6119. this.UpdateOverlayMinuteRealtimeData=function(data)
  6120. {
  6121. for(var i=0; i<this.OverlayChartPaint.length; ++i)
  6122. {
  6123. var item=this.OverlayChartPaint[i];
  6124. if (!item.Symbol) continue;
  6125. if (!item.MainData) continue; //等待主图股票数据未下载完
  6126. if (item.Status!=OVERLAY_STATUS_ID.STATUS_FINISHED_ID) continue;
  6127. if (data.ver==2.0)
  6128. var realtimeData=KLineChartContainer.JsonDataToMinuteRealtimeDataV2(data,item.Symbol); //获取叠加股票的最新数据
  6129. else
  6130. var realtimeData=KLineChartContainer.JsonDataToMinuteRealtimeData(data,item.Symbol); //获取叠加股票的最新数据
  6131. if (!realtimeData) continue;
  6132. var sourceData=item.SourceData; //叠加股票的所有数据
  6133. if (!sourceData.MergeMinuteData(realtimeData)) return;
  6134. var bindData=new ChartData();
  6135. bindData.Data=sourceData.Data;
  6136. bindData.Period=this.Period;
  6137. bindData.Right=this.Right;
  6138. bindData.DataType=0;
  6139. var aryOverlayData=this.SourceData.GetOverlayMinuteData(bindData.Data,this.IsApiPeriod); //和主图数据拟合以后的数据
  6140. bindData.Data=aryOverlayData;
  6141. if (ChartData.IsMinutePeriod(bindData.Period,false) && !this.IsApiPeriod) //周期数据
  6142. {
  6143. var periodData=bindData.GetPeriodData(bindData.Period);
  6144. bindData.Data=periodData;
  6145. }
  6146. item.Data=bindData;
  6147. }
  6148. }
  6149. this.SendKLineUpdateEvent = function (bindData)
  6150. {
  6151. var event = this.GetEvent(JSCHART_EVENT_ID.RECV_KLINE_UPDATE_DATA);
  6152. if (event && event.Callback)
  6153. {
  6154. var data = { HistoryData: bindData, Stock: { Symbol: this.Symbol, Name: this.Name } }
  6155. event.Callback(event, data, this);
  6156. return true;
  6157. }
  6158. return false;
  6159. }
  6160. this.ClearIndexPaint=function() //清空指标
  6161. {
  6162. if (this.Frame && this.Frame.SubFrame)
  6163. {
  6164. for(var i=0;i<this.Frame.SubFrame.length;++i)
  6165. {
  6166. this.DeleteIndexPaint(i, true);
  6167. var item=this.Frame.SubFrame[i];
  6168. for(var j=0; j<item.OverlayIndex.length; ++j ) //清空叠加指标
  6169. {
  6170. var overlayItem=item.OverlayIndex[j];
  6171. for(var k=0;k< overlayItem.ChartPaint.length;++k)
  6172. {
  6173. var overlayChart=overlayItem.ChartPaint[k];
  6174. if (overlayChart && overlayChart.OnDestroy) overlayChart.OnDestroy();
  6175. }
  6176. overlayItem.ChartPaint=[];
  6177. }
  6178. }
  6179. }
  6180. //清空叠加标题
  6181. for(var i=1;i<this.TitlePaint.length;++i)
  6182. {
  6183. var item=this.TitlePaint[i];
  6184. item.OverlayIndex=new Map();
  6185. }
  6186. }
  6187. //周期切换
  6188. this.ChangePeriod = function (period, option)
  6189. {
  6190. var isChangeKLineDrawType = false;
  6191. var right=null; //复权
  6192. if (option && option.KLine)
  6193. {
  6194. if (IFrameSplitOperator.IsNumber(option.KLine.DrawType)) isChangeKLineDrawType = true;
  6195. if (IFrameSplitOperator.IsNumber(option.KLine.Right)) right=option.KLine.Right;
  6196. };
  6197. if (this.Period == period)
  6198. {
  6199. if (isChangeKLineDrawType) this.ChangeKLineDrawType(option.KLine.DrawType);
  6200. return;
  6201. }
  6202. if (isChangeKLineDrawType) this.ChangeKLineDrawType(option.KLine.DrawType, false); //切换K线类型, 不重绘
  6203. var isDataTypeChange = true;
  6204. if (this.SourceData)
  6205. {
  6206. var isDataTypeChange=false;
  6207. if (period > CUSTOM_DAY_PERIOD_START && period <= CUSTOM_DAY_PERIOD_END)
  6208. {
  6209. if (this.SourceData.DataType != 0) isDataTypeChange = true;
  6210. }
  6211. else if ((period > CUSTOM_MINUTE_PERIOD_START && period <= CUSTOM_MINUTE_PERIOD_END) ||
  6212. (period > CUSTOM_SECOND_PERIOD_START && period <= CUSTOM_SECOND_PERIOD_END))
  6213. {
  6214. if (this.SourceData.DataType != 1) isDataTypeChange = true;
  6215. }
  6216. else
  6217. {
  6218. switch (period)
  6219. {
  6220. case 0: //日线
  6221. case 1: //周
  6222. case 2: //月
  6223. case 3: //年
  6224. case 21: //双周
  6225. if (this.SourceData.DataType != 0) isDataTypeChange = true;
  6226. break;
  6227. case 4: //1分钟
  6228. case 5: //5分钟
  6229. case 6: //15分钟
  6230. case 7: //30分钟
  6231. case 8: //60分钟
  6232. case 11: //2小时
  6233. case 12: //4小时
  6234. if (this.SourceData.DataType != 1) isDataTypeChange = true;
  6235. break;
  6236. }
  6237. }
  6238. }
  6239. this.Period = period;
  6240. if (right!=null) this.Right=right;
  6241. this.ClearCustomKLine();
  6242. if (isDataTypeChange == false && !this.IsApiPeriod)
  6243. {
  6244. this.Update();
  6245. return;
  6246. }
  6247. if (ChartData.IsDayPeriod(this.Period, true))
  6248. {
  6249. this.ClearIndexPaint();
  6250. this.CancelAutoUpdate(); //先停止更新
  6251. this.AutoUpdateEvent(false,"KLineChartContainer::ChangePeriod");
  6252. this.ResetOverlaySymbolStatus();
  6253. this.Frame.ClearYCoordinateMaxMin();
  6254. this.RequestHistoryData(); //请求日线数据
  6255. //this.ReqeustKLineInfoData();
  6256. }
  6257. else if (ChartData.IsMinutePeriod(this.Period, true) || ChartData.IsSecondPeriod(this.Period))
  6258. {
  6259. this.ClearIndexPaint();
  6260. this.CancelAutoUpdate(); //先停止更新
  6261. this.AutoUpdateEvent(false,"KLineChartContainer::ChangePeriod");
  6262. this.ResetOverlaySymbolStatus();
  6263. this.Frame.ClearYCoordinateMaxMin();
  6264. this.RequestHistoryMinuteData(); //请求分钟数据
  6265. }
  6266. }
  6267. //复权切换
  6268. this.ChangeRight = function (right)
  6269. {
  6270. if (!MARKET_SUFFIX_NAME.IsEnableRight(this.Period,this.Symbol,this.RightFormula)) return;
  6271. if (right < 0 || right > 2) return;
  6272. if (this.Right == right) return;
  6273. this.Right = right;
  6274. if (!this.IsApiPeriod)
  6275. {
  6276. this.Update();
  6277. return;
  6278. }
  6279. else
  6280. {
  6281. if (ChartData.IsDayPeriod(this.Period, true))
  6282. {
  6283. this.CancelAutoUpdate(); //先停止更新
  6284. this.AutoUpdateEvent(false,"KLineChartContainer::ChangeRight");
  6285. this.RequestHistoryData(); //请求日线数据
  6286. //this.ReqeustKLineInfoData();
  6287. }
  6288. else if (ChartData.IsMinutePeriod(this.Period, true) || ChartData.IsSecondPeriod(this.Period))
  6289. {
  6290. this.CancelAutoUpdate(); //先停止更新
  6291. this.AutoUpdateEvent(false,"KLineChartContainer::ChangeRight");
  6292. this.RequestHistoryMinuteData(); //请求分钟数据
  6293. }
  6294. }
  6295. }
  6296. //设置第1屏的起始日期
  6297. this.SetFirstShowDate=function(obj)
  6298. {
  6299. if (!obj || !obj.Date) return;
  6300. var option={ ID:JSCHART_OPERATOR_ID.OP_GOTO, Date:obj.Date };
  6301. if (IFrameSplitOperator.IsNumber(obj.Time)) option.Time=obj.Time;
  6302. if (IFrameSplitOperator.IsNumber(obj.PageSize)) option.PageSize=obj.PageSize;
  6303. this.ChartOperator(option);
  6304. }
  6305. //删除某一个窗口的指标 bCallDestory=是否调用图形销毁函数
  6306. this.DeleteIndexPaint = function (windowIndex, bCallDestroy)
  6307. {
  6308. if (!this.Frame.SubFrame[windowIndex]) return;
  6309. var subFrame=this.Frame.SubFrame[windowIndex].Frame;
  6310. if (!subFrame) return;
  6311. var paint=[]; //踢出当前窗口的指标画法
  6312. for (var i=0;i<this.ChartPaint.length; ++i)
  6313. {
  6314. let item = this.ChartPaint[i];
  6315. var bFind=(item.ChartFrame.Guid==subFrame.Guid || item.ChartFrame==subFrame);
  6316. if (i == 0 || !bFind)
  6317. {
  6318. paint.push(item);
  6319. }
  6320. else
  6321. {
  6322. if (bCallDestroy===true)
  6323. {
  6324. if (item && item.OnDestroy) item.OnDestroy(); //图形销毁
  6325. }
  6326. }
  6327. }
  6328. subFrame.YSpecificMaxMin = null; //清空指定最大最小值
  6329. subFrame.YSplitScale = null; //清空固定刻度
  6330. subFrame.YSplitOperator.SplitType=subFrame.YSplitOperator.DefaultSplitType; //还原Y坐标分割模式
  6331. this.ChartPaint = paint;
  6332. //清空东条标题
  6333. var titleIndex = windowIndex + 1;
  6334. this.TitlePaint[titleIndex].Data = [];
  6335. this.TitlePaint[titleIndex].Title = null;
  6336. }
  6337. this.ShowKLine = function (isShow) //显示隐藏主图K线
  6338. {
  6339. if (this.ChartPaint.length <= 0 || !this.ChartPaint[0]) return;
  6340. this.ChartPaint[0].IsShow = isShow;
  6341. }
  6342. this.SetInstructionData = function (type, instructionData) //设置指示数据
  6343. {
  6344. if (this.ChartPaint.length <= 0 || !this.ChartPaint[0]) return;
  6345. if (type == 2) //五彩K线
  6346. {
  6347. this.ChartPaint[0].ColorData = instructionData.Data;
  6348. }
  6349. else if (type == 1) //专家指示
  6350. {
  6351. this.ChartPaint[0].TradeData = { Sell: instructionData.Sell, Buy: instructionData.Buy };
  6352. }
  6353. }
  6354. this.ChangeInstructionIndex = function (indexName)
  6355. {
  6356. let scriptData = new JSCommonIndexScript.JSIndexScript();
  6357. let indexInfo = scriptData.Get(indexName);
  6358. if (!indexInfo) return;
  6359. if (indexInfo.InstructionType != 1 && indexInfo.InstructionType != 2) return;
  6360. this.ChangeInstructionScriptIndex(indexInfo);
  6361. }
  6362. this.ChangeInstructionScriptIndex = function (indexData)
  6363. {
  6364. if (indexData.InstructionType == 1) //交易系统
  6365. {
  6366. this.TradeIndex = new ScriptIndex(indexData.Name, indexData.Script, indexData.Args, indexData); //脚本执行
  6367. }
  6368. else if (indexData.InstructionType == 2) //五彩K线
  6369. {
  6370. this.ColorIndex = new ScriptIndex(indexData.Name, indexData.Script, indexData.Args, indexData); //脚本执行
  6371. }
  6372. else
  6373. {
  6374. return;
  6375. }
  6376. var bindData = this.ChartPaint[0].Data;
  6377. this.BindInstructionIndexData(bindData);
  6378. this.UpdataDataoffset(); //更新数据偏移
  6379. this.UpdateFrameMaxMin(); //调整坐标最大 最小值
  6380. this.Draw();
  6381. }
  6382. this.CancelInstructionIndex = function () //取消指示数据
  6383. {
  6384. if (this.ChartPaint.length <= 0 || !this.ChartPaint[0]) return;
  6385. this.ColorIndex=null;
  6386. this.TradeIndex=null;
  6387. this.ChartPaint[0].ColorData = null; //五彩K线数据取消掉
  6388. this.ChartPaint[0].TradeData = null; //交易系统数据取消
  6389. this.UpdataDataoffset(); //更新数据偏移
  6390. this.UpdateFrameMaxMin(); //调整坐标最大 最小值
  6391. this.Draw();
  6392. }
  6393. //切换成 脚本指标
  6394. this.ChangeScriptIndex = function (windowIndex, indexData)
  6395. {
  6396. this.DeleteIndexPaint(windowIndex, true);
  6397. this.WindowIndex[windowIndex] = new ScriptIndex(indexData.Name, indexData.Script, indexData.Args, indexData); //脚本执行
  6398. this.Frame.ClearYCoordinateMaxMin(windowIndex);
  6399. var bindData = this.ChartPaint[0].Data;
  6400. this.BindIndexData(windowIndex, bindData); //执行脚本
  6401. this.UpdataDataoffset(); //更新数据偏移
  6402. this.UpdateFrameMaxMin(); //调整坐标最大 最小值
  6403. this.Draw();
  6404. }
  6405. //K线移动
  6406. this.OnKLinePageChange=function(eventid)
  6407. {
  6408. if (!this.ChartPaint[0]) return;
  6409. var bindData=this.ChartPaint[0].Data;
  6410. for(var i=0;i<this.WindowIndex.length;++i)
  6411. {
  6412. var item=this.WindowIndex[i];
  6413. if (!item) continue;
  6414. if (item.IsUsePageData===true) this.BindIndexData(i,bindData, { Type:1 }); //执行脚本
  6415. }
  6416. //叠加指标
  6417. for(var i=0;i<this.Frame.SubFrame.length;++i)
  6418. {
  6419. var item=this.Frame.SubFrame[i];
  6420. for(var j=0; j<item.OverlayIndex.length; ++j)
  6421. {
  6422. var overlayItem=item.OverlayIndex[j];
  6423. if (overlayItem && overlayItem.Script && overlayItem.Script.IsUsePageData==true)
  6424. this.BindOverlayIndexData(overlayItem,i,bindData);
  6425. }
  6426. }
  6427. }
  6428. //切换api指标
  6429. this.ChangeAPIIndex = function (windowIndex, indexData)
  6430. {
  6431. this.DeleteIndexPaint(windowIndex, true);
  6432. //使用API挂接指标数据 API:{ Name:指标名字, Script:指标脚本可以为空, Args:参数可以为空, Url:指标执行地址 }
  6433. var apiItem = indexData.API;
  6434. this.WindowIndex[windowIndex] = new APIScriptIndex(apiItem.Name, apiItem.Script, apiItem.Args, indexData);
  6435. this.Frame.ClearYCoordinateMaxMin(windowIndex);
  6436. var bindData = this.ChartPaint[0].Data;
  6437. this.BindIndexData(windowIndex, bindData); //执行脚本
  6438. this.UpdataDataoffset(); //更新数据偏移
  6439. this.UpdateFrameMaxMin(); //调整坐标最大 最小值
  6440. this.Draw();
  6441. }
  6442. //切换指标 指定切换窗口指标
  6443. this.ChangeIndex = function (windowIndex, indexName, option)
  6444. {
  6445. if (option && option.API) //切换api指标
  6446. return this.ChangeAPIIndex(windowIndex, option);
  6447. var indexItem = JSIndexMap.Get(indexName);
  6448. if (!indexItem)
  6449. {
  6450. //查找系统指标
  6451. let scriptData = new JSCommonIndexScript.JSIndexScript();
  6452. let indexInfo = scriptData.Get(indexName);
  6453. if (!indexInfo) return;
  6454. if (indexInfo.IsMainIndex)
  6455. {
  6456. windowIndex = 0; //主图指标只能在主图显示
  6457. }
  6458. else
  6459. {
  6460. if (windowIndex == 0) windowIndex = 1; //幅图指标,不能再主图显示
  6461. }
  6462. let indexData = indexInfo;
  6463. if (option)
  6464. {
  6465. if (option.FloatPrecision >= 0) indexData.FloatPrecision = option.FloatPrecision;
  6466. if (option.StringFormat > 0) indexData.StringFormat = option.StringFormat;
  6467. if (option.Args) indexData.Args = option.Args;
  6468. if (IFrameSplitOperator.IsNumber(option.IsShortTitle)) indexData.IsShortTitle=option.IsShortTitle;
  6469. }
  6470. return this.ChangeScriptIndex(windowIndex, indexData, option);
  6471. }
  6472. //主图指标
  6473. if (indexItem.IsMainIndex)
  6474. {
  6475. if (windowIndex > 0) windowIndex = 0; //主图指标只能在主图显示
  6476. }
  6477. else
  6478. {
  6479. if (windowIndex == 0) windowIndex = 1; //幅图指标,不能再主图显示
  6480. }
  6481. var paint = new Array(); //踢出当前窗口的指标画法
  6482. for (var i in this.ChartPaint)
  6483. {
  6484. var item = this.ChartPaint[i];
  6485. if (i == 0 || item.ChartFrame != this.Frame.SubFrame[windowIndex].Frame) paint.push(item);
  6486. }
  6487. //清空指定最大最小值
  6488. this.Frame.SubFrame[windowIndex].Frame.YSpecificMaxMin = null;
  6489. this.Frame.SubFrame[windowIndex].Frame.YSplitScale=null;
  6490. this.ChartPaint = paint;
  6491. //清空东条标题
  6492. var titleIndex = windowIndex + 1;
  6493. this.TitlePaint[titleIndex].Data = [];
  6494. this.TitlePaint[titleIndex].Title = null;
  6495. this.WindowIndex[windowIndex] = indexItem.Create();
  6496. this.CreateWindowIndex(windowIndex);
  6497. var bindData = this.ChartPaint[0].Data;
  6498. this.BindIndexData(windowIndex, bindData);
  6499. this.UpdataDataoffset(); //更新数据偏移
  6500. this.UpdateFrameMaxMin(); //调整坐标最大 最小值
  6501. this.Draw();
  6502. }
  6503. this.ChangeKLineDrawType = function (drawType, isDraw)
  6504. {
  6505. if (this.KLineDrawType == drawType) return;
  6506. this.KLineDrawType = drawType;
  6507. for (var i in this.ChartPaint)
  6508. {
  6509. var item = this.ChartPaint[i];
  6510. if (i == 0) item.DrawType = this.KLineDrawType;
  6511. else if (item.ClassName == 'ChartVolStick') item.KLineDrawType = this.KLineDrawType
  6512. }
  6513. for(var i=0; i<this.OverlayChartPaint.length; ++i) //叠加K线样式修改
  6514. {
  6515. var item=this.OverlayChartPaint[i];
  6516. item.DrawType=this.KLineDrawType;
  6517. }
  6518. if (isDraw == false) return;
  6519. this.UpdateFrameMaxMin(); //调整坐标最大 最小值
  6520. this.Frame.SetSizeChange(true);
  6521. this.Draw();
  6522. }
  6523. this.ChangeIndexTemplate = function (option) //切换指标模板 可以设置指标窗口个数 每个窗口的指标
  6524. {
  6525. if (!option.Windows) return;
  6526. var count = option.Windows.length;
  6527. if (count <= 0) return;
  6528. this.Frame.RestoreIndexWindows();
  6529. var currentLength = this.Frame.SubFrame.length;
  6530. var period=null, right=null, symbol=null;
  6531. if (option.KLine)
  6532. {
  6533. if (IFrameSplitOperator.IsNumber(option.KLine.Period) && option.KLine.Period!=this.Period) period=option.KLine.Period; //周期
  6534. if (IFrameSplitOperator.IsNumber(option.KLine.Right) && option.KLine.Right!=this.Right) right=option.KLine.Right; //复权
  6535. }
  6536. if (option.Symbol) symbol=option.Symbol;
  6537. var bRefreshData= (period!=null || right!=null || symbol!=null);
  6538. for (var i = 0; i < currentLength; ++i) //清空所有的指标图型
  6539. {
  6540. this.DeleteIndexPaint(i, true);
  6541. var frame = this.Frame.SubFrame[i];
  6542. frame.YSpecificMaxMin = null;
  6543. frame.YSplitScale = null;
  6544. }
  6545. if (currentLength > count)
  6546. {
  6547. var event=this.GetEventCallback(JSCHART_EVENT_ID.ON_DELETE_FRAME);
  6548. for(var i=currentLength-1;i>=count;--i)
  6549. {
  6550. if (event && event.Callback)
  6551. {
  6552. var sendData={ SubFrame:this.Frame.SubFrame[i], WindowIndex:i };
  6553. event.Callback(event, sendData, this);
  6554. }
  6555. }
  6556. this.Frame.SubFrame.splice(count, currentLength - count);
  6557. this.WindowIndex.splice(count, currentLength - count);
  6558. this.TitlePaint.splice(count+1,currentLength-count);
  6559. }
  6560. else
  6561. {
  6562. for (var i = currentLength; i < count; ++i) //创建新的指标窗口
  6563. {
  6564. var subFrame = this.CreateSubFrameItem(i);
  6565. this.Frame.SubFrame[i] = subFrame;
  6566. var titlePaint = new DynamicChartTitlePainting();
  6567. titlePaint.Frame = this.Frame.SubFrame[i].Frame;
  6568. titlePaint.Canvas = this.Canvas;
  6569. titlePaint.LanguageID = this.LanguageID;
  6570. titlePaint.GetEventCallback=(id)=> { return this.GetEventCallback(id); }
  6571. this.TitlePaint[i + 1] = titlePaint;
  6572. }
  6573. }
  6574. var systemScript = new JSCommonIndexScript.JSIndexScript();
  6575. for (var i = 0; i < count; ++i)
  6576. {
  6577. var windowIndex = i;
  6578. var item=option.Windows[i];
  6579. var frameItem=null;
  6580. if(option.Frame && option.Frame.length>i) frameItem=option.Frame[i];
  6581. var titleIndex = windowIndex + 1;
  6582. this.TitlePaint[titleIndex].Data = [];
  6583. this.TitlePaint[titleIndex].Title = null;
  6584. this.DeleteWindowsOverlayIndex(i); //清空叠加指标
  6585. if (item.Script) //自定义指标
  6586. {
  6587. this.WindowIndex[i]=new ScriptIndex(item.Name,item.Script,item.Args,item); //脚本执行
  6588. }
  6589. else if (item.API) //后台指标
  6590. {
  6591. var apiItem=item.API;
  6592. this.WindowIndex[i]=new APIScriptIndex(apiItem.Name,apiItem.Script,apiItem.Args,item);
  6593. }
  6594. else
  6595. {
  6596. var indexID = item.Index;
  6597. var indexItem = JSIndexMap.Get(indexID);
  6598. if (indexItem)
  6599. {
  6600. this.WindowIndex[i] = indexItem.Create();
  6601. this.CreateWindowIndex(windowIndex);
  6602. }
  6603. else
  6604. {
  6605. var indexInfo = systemScript.Get(indexID);
  6606. if (indexInfo)
  6607. {
  6608. JSIndexScript.ModifyAttribute(indexInfo,item);
  6609. this.WindowIndex[i] = new ScriptIndex(indexInfo.Name, indexInfo.Script, indexInfo.Args, indexInfo); //脚本执行
  6610. }
  6611. }
  6612. }
  6613. this.SetSubFrameAttribute(this.Frame.SubFrame[i], item, frameItem);
  6614. }
  6615. //最后一个显示X轴坐标
  6616. for (var i = 0; i < this.Frame.SubFrame.length; ++i)
  6617. {
  6618. var item = this.Frame.SubFrame[i].Frame;
  6619. if (i == this.Frame.SubFrame.length - 1) item.XSplitOperator.ShowText = true;
  6620. else item.XSplitOperator.ShowText = false;
  6621. }
  6622. //叠加指标
  6623. var aryOverlayIndex=[];
  6624. if (IFrameSplitOperator.IsNonEmptyArray(option.OverlayIndex))
  6625. {
  6626. for(var i=0;i<option.OverlayIndex.length;++i)
  6627. {
  6628. var item=option.OverlayIndex[i];
  6629. if (item.Index) item.IndexName=item.Index;
  6630. if (item.Windows>=0) item.WindowIndex=item.Windows;
  6631. var overlay=this.CreateOverlayWindowsIndex(item);
  6632. if (!overlay) continue;
  6633. aryOverlayIndex.push({ WindowsIndex:item.WindowIndex, Overlay:overlay });
  6634. }
  6635. }
  6636. this.Frame.SetSizeChange(true);
  6637. if (!bRefreshData)
  6638. {
  6639. var bindData = this.ChartPaint[0].Data;
  6640. for(var i=0; i<count; ++i) //重新请求指标
  6641. {
  6642. this.BindIndexData(i, bindData);
  6643. }
  6644. for(var i=0;i<aryOverlayIndex.length;++i)
  6645. {
  6646. var item=aryOverlayIndex[i];
  6647. this.BindOverlayIndexData(item.Overlay,item.WindowsIndex,bindData);
  6648. }
  6649. this.UpdataDataoffset(); //更新数据偏移
  6650. this.ResetFrameXYSplit();
  6651. this.UpdateFrameMaxMin(); //调整坐标最大 最小值
  6652. this.Draw();
  6653. }
  6654. else
  6655. {
  6656. if (!symbol) symbol=this.Symbol;
  6657. var optionData={ KLine:{} };
  6658. if (IFrameSplitOperator.IsNumber(period)) optionData.KLine.Period=period;
  6659. if (IFrameSplitOperator.IsNumber(right)) optionData.KLine.Right=right;
  6660. this.ChangeSymbol(symbol, optionData);
  6661. }
  6662. }
  6663. this.ChangeIndexWindowCount=function(count,option)
  6664. {
  6665. if (count<=0) return;
  6666. if (this.Frame.SubFrame.length==count) return;
  6667. this.Frame.RestoreIndexWindows();
  6668. var currentLength=this.Frame.SubFrame.length;
  6669. if (currentLength>count)
  6670. {
  6671. var event=this.GetEventCallback(JSCHART_EVENT_ID.ON_DELETE_FRAME);
  6672. for(var i=currentLength-1;i>=count;--i)
  6673. {
  6674. this.DeleteIndexPaint(i);
  6675. //this.DeleteChartPaintExtend({WindowIndex:i});
  6676. if (event && event.Callback)
  6677. {
  6678. var sendData={ SubFrame:this.Frame.SubFrame[i], WindowIndex:i };
  6679. event.Callback(event, sendData, this);
  6680. }
  6681. }
  6682. this.Frame.SubFrame.splice(count,currentLength-count);
  6683. this.WindowIndex.splice(count,currentLength-count);
  6684. this.TitlePaint.splice(count+1,currentLength-count);
  6685. //最后一个显示X轴坐标
  6686. for(var i=0;i<this.Frame.SubFrame.length;++i)
  6687. {
  6688. var item=this.Frame.SubFrame[i].Frame;
  6689. if (i==this.Frame.SubFrame.length-1) item.XSplitOperator.ShowText=true;
  6690. else item.XSplitOperator.ShowText=false;
  6691. }
  6692. this.Frame.SetSizeChange(true);
  6693. this.ResetFrameXYSplit();
  6694. this.UpdateFrameMaxMin(); //调整坐标最大 最小值
  6695. this.Draw();
  6696. }
  6697. else
  6698. {
  6699. //创建新的指标窗口
  6700. for(var i=currentLength;i<count;++i)
  6701. {
  6702. var subFrame=this.CreateSubFrameItem(i);
  6703. this.Frame.SubFrame[i]=subFrame;
  6704. var titlePaint=new DynamicChartTitlePainting();
  6705. titlePaint.Frame=this.Frame.SubFrame[i].Frame;
  6706. titlePaint.Canvas=this.Canvas;
  6707. titlePaint.LanguageID=this.LanguageID;
  6708. titlePaint.GetEventCallback=(id)=> { return this.GetEventCallback(id); }
  6709. titlePaint.SelectedChart=this.SelectedChart;
  6710. titlePaint.HQChart=this;
  6711. this.TitlePaint[i+1]=titlePaint;
  6712. }
  6713. //最后一个显示X轴坐标
  6714. for(var i=0;i<this.Frame.SubFrame.length;++i)
  6715. {
  6716. var item=this.Frame.SubFrame[i].Frame;
  6717. if (i==this.Frame.SubFrame.length-1) item.XSplitOperator.ShowText=true;
  6718. else item.XSplitOperator.ShowText=false;
  6719. }
  6720. this.Frame.SetSizeChange(true);
  6721. this.ResetFrameXYSplit();
  6722. this.UpdateFrameMaxMin(); //调整坐标最大 最小值
  6723. this.Draw();
  6724. //创建指标
  6725. var indexName= [ {Index:"RSI"}, {Index:"MACD"}, {Index:"VOL"}, {Index:"UOS"}, {Index:"CHO"}, {Index:"BRAR"} ]; //增加的指标名字
  6726. if (option && option.Windows.length>0)
  6727. indexName=option.Windows; //外部设置增加窗口的默认指标
  6728. let scriptData = new JSIndexScript();
  6729. for(var i=currentLength;i<count;++i)
  6730. {
  6731. var item=indexName[i%indexName.length];
  6732. var name=item.Index;
  6733. var indexInfo = scriptData.Get(name);
  6734. if (indexInfo)
  6735. {
  6736. JSIndexScript.ModifyAttribute(indexInfo,item);
  6737. this.WindowIndex[i]=new ScriptIndex(indexInfo.Name,indexInfo.Script,indexInfo.Args,indexInfo); //脚本执行
  6738. }
  6739. var subFrame=this.Frame.SubFrame[i];
  6740. var frameItem=null;
  6741. if(option && option.Frame && option.Frame.length>i) frameItem=option.Frame[i];
  6742. this.SetSubFrameAttribute(subFrame, item, frameItem);
  6743. var bindData=this.ChartPaint[0].Data;
  6744. this.BindIndexData(i,bindData); //执行脚本
  6745. }
  6746. //this.UpdataDataoffset(); //更新数据偏移
  6747. }
  6748. }
  6749. this.RemoveIndexWindow=function(id)
  6750. {
  6751. JSConsole.Chart.Log('[KLineChartContainer::RemoveIndexWindow] remove id', id);
  6752. if (id==0) return;
  6753. if (!this.Frame.SubFrame) return;
  6754. if (id>=this.Frame.SubFrame.length) return;
  6755. var delFrame=this.Frame.SubFrame[id].Frame;
  6756. this.DeleteIndexPaint(id, true);
  6757. var event=this.GetEventCallback(JSCHART_EVENT_ID.ON_DELETE_FRAME);
  6758. if (event && event.Callback)
  6759. {
  6760. var sendData={ SubFrame:this.Frame.SubFrame[id], WindowIndex:id };
  6761. event.Callback(event, sendData, this);
  6762. }
  6763. this.Frame.SubFrame.splice(id,1);
  6764. this.WindowIndex.splice(id,1);
  6765. this.TitlePaint.splice(id+1,1); //删除对应的动态标题
  6766. for(var i=0;i<this.Frame.SubFrame.length;++i)
  6767. {
  6768. var item=this.Frame.SubFrame[i].Frame;
  6769. if (i==this.Frame.SubFrame.length-1) item.XSplitOperator.ShowText=true;
  6770. else item.XSplitOperator.ShowText=false;
  6771. item.Identify=i;
  6772. }
  6773. if (this.ChartDrawPicture.length>0)
  6774. {
  6775. var aryDrawPicture=[];
  6776. for(var i=0;i<this.ChartDrawPicture.length;++i)
  6777. {
  6778. var item=this.ChartDrawPicture[i];
  6779. if (item.Frame==delFrame) continue;
  6780. aryDrawPicture.push(item);
  6781. }
  6782. this.ChartDrawPicture=aryDrawPicture;
  6783. }
  6784. this.Frame.SetSizeChange(true);
  6785. this.UpdateFrameMaxMin();
  6786. this.ResetFrameXYSplit();
  6787. this.Draw();
  6788. }
  6789. //获取筹码图 className=指定筹码类名 否则就查询所有
  6790. this.GetStockChipChart=function(className)
  6791. {
  6792. if (className) return this.GetExtendChartByClassName(className);
  6793. var chart=this.GetExtendChartByClassName("StockChipPhone");
  6794. return chart;
  6795. }
  6796. this.CreateStockChipPhone=function(option)
  6797. {
  6798. var chart=new StockChipPhone();
  6799. chart.Canvas=this.Canvas;
  6800. chart.ChartBorder=this.Frame.ChartBorder;
  6801. chart.ChartFrame=this.Frame;
  6802. chart.HQChart=this;
  6803. chart.Left=this.Frame.ChartBorder.Right; //左边间距使用当前框架间距
  6804. chart.SetOption(option);
  6805. this.ExtendChartPaint.push(chart);
  6806. this.Frame.ChartBorder.Right+=chart.Width; //创建筹码需要增加右边的间距
  6807. this.GlobalOption.RightHorizontal.Show=false;
  6808. return chart;
  6809. }
  6810. this.DeleteStockChipChart=function()
  6811. {
  6812. var stockChip=this.GetStockChipChart();
  6813. if (!stockChip) return;
  6814. var chipWidth=stockChip.Chart.Width;
  6815. this.DeleteExtendChart(stockChip);
  6816. this.Frame.ChartBorder.Right-=chipWidth;
  6817. if (stockChip.Chart.ClassName=="StockChipPhone")
  6818. {
  6819. this.GlobalOption.RightHorizontal.Show=true;
  6820. this.Frame.ResetXYSplit();
  6821. }
  6822. this.SetSizeChange(true);
  6823. this.Draw();
  6824. }
  6825. this.CreateExtendChart = function (name, option) //创建扩展图形
  6826. {
  6827. var chart;
  6828. switch (name)
  6829. {
  6830. case 'KLineTooltip':
  6831. if (option.Create && typeof(option.Create)=='function') chart=option.Create();
  6832. else chart = new KLineTooltipPaint();
  6833. chart.Canvas = this.Canvas;
  6834. chart.ChartBorder = this.Frame.ChartBorder;
  6835. chart.ChartFrame = this.Frame;
  6836. chart.HQChart = this;
  6837. option.LanguageID = this.LanguageID;
  6838. chart.SetOption(option);
  6839. this.ExtendChartPaint.push(chart);
  6840. return chart;
  6841. case "BackgroundPaint":
  6842. case '背景图':
  6843. chart = new BackgroundPaint();
  6844. chart.Canvas = this.Canvas;
  6845. chart.ChartBorder = this.Frame.ChartBorder;
  6846. chart.ChartFrame = this.Frame;
  6847. chart.HQChart = this;
  6848. chart.SetOption(option);
  6849. this.ExtendChartPaint.push(chart);
  6850. return chart;
  6851. case "StockChipPhone":
  6852. return this.CreateStockChipPhone(option);
  6853. default:
  6854. chart=g_ExtendChartPaintFactory.Create(name);
  6855. if (!chart) return null;
  6856. chart.Canvas=this.Canvas;
  6857. chart.ChartBorder=this.Frame.ChartBorder;
  6858. chart.ChartFrame=this.Frame;
  6859. chart.HQChart=this;
  6860. chart.SetOption(option);
  6861. this.ExtendChartPaint.push(chart);
  6862. return chart;
  6863. }
  6864. }
  6865. this.TryClickIndexTitle=function(x,y)
  6866. {
  6867. for(var i in this.TitlePaint)
  6868. {
  6869. var item=this.TitlePaint[i];
  6870. if (!item.IsClickTitle) continue;
  6871. if (!item.IsClickTitle(x,y)) continue;
  6872. var data={ Point:{X:x, Y:y}, Title:item.Title, FrameID:item.Frame.Identify };
  6873. JSConsole.Chart.Log('[KLineChartContainer::TryClickIndexTitle] click title ', data);
  6874. var event=this.GetEvent(JSCHART_EVENT_ID.ON_CLICK_INDEXTITLE);
  6875. if (event && event.Callback) event.Callback(event,data,this);
  6876. return true;
  6877. }
  6878. return false;
  6879. }
  6880. this.StopAutoUpdate = function ()
  6881. {
  6882. this.IsAutoUpdate = false;
  6883. this.CancelAutoUpdate();
  6884. this.AutoUpdateEvent(false,"KLineChartContainer::StopAutoUpdate");
  6885. }
  6886. this.Update = function ()
  6887. {
  6888. if (!this.SourceData) return;
  6889. if (this.BeforeBindMainData) this.BeforeBindMainData('Update');
  6890. var bindData = new ChartData();
  6891. bindData.Data = this.SourceData.Data;
  6892. bindData.Period = this.Period;
  6893. bindData.Right = this.Right;
  6894. bindData.DataType = this.SourceData.DataType;
  6895. bindData.Symbol = this.Symbol;
  6896. if (bindData.Right > 0 && ChartData.IsDayPeriod(bindData.Period, true)) //复权(日线数据才复权)
  6897. {
  6898. var rightData = bindData.GetRightData(bindData.Right, { AlgorithmType: this.RightFormula });
  6899. bindData.Data = rightData;
  6900. }
  6901. else if (bindData.Right>0 && ChartData.IsMinutePeriod(bindData.Period,true) && this.RightFormula>=1) //复权(分钟数据复权, 复权因子模式)
  6902. {
  6903. var rightData=bindData.GetRightData(bindData.Right, { AlgorithmType: this.RightFormula });
  6904. bindData.Data=rightData;
  6905. }
  6906. if (ChartData.IsDayPeriod(bindData.Period, false) || ChartData.IsMinutePeriod(bindData.Period, false)) //周期数据 (0= 日线,4=1分钟线 不需要处理))
  6907. {
  6908. var periodData = bindData.GetPeriodData(bindData.Period);
  6909. bindData.Data = periodData;
  6910. }
  6911. //绑定数据
  6912. this.BindMainData(bindData, this.PageSize);
  6913. if (this.AfterBindMainData) this.AfterBindMainData("Update");
  6914. var firstSubFrame=null;
  6915. for (var i = 0; i < this.Frame.SubFrame.length; ++i)
  6916. {
  6917. if (i==0) firstSubFrame=this.Frame.SubFrame[i].Frame;
  6918. this.BindIndexData(i, bindData);
  6919. }
  6920. //绑定K线数据到Y轴分割
  6921. if (firstSubFrame && firstSubFrame.YSplitOperator)
  6922. {
  6923. firstSubFrame.YSplitOperator.Symbol=this.Symbol;
  6924. firstSubFrame.YSplitOperator.Data=this.ChartPaint[0].Data; //K线数据
  6925. firstSubFrame.YSplitOperator.Period=this.Period; //周期
  6926. }
  6927. //叠加数据周期调整
  6928. for(var i=0; i<this.OverlayChartPaint.length; ++i)
  6929. {
  6930. var item=this.OverlayChartPaint[i];
  6931. if (!item.SourceData) continue;
  6932. if (ChartData.IsMinutePeriod(this.Period, true)) //分钟不支持 清空掉
  6933. {
  6934. var bindData=new ChartData();
  6935. bindData.Data=item.SourceData.Data;
  6936. bindData.Period=this.Period;
  6937. bindData.Right=this.Right;
  6938. var aryOverlayData=this.SourceData.GetOverlayMinuteData(bindData.Data, this.IsApiPeriod); //和主图数据拟合以后的数据
  6939. bindData.Data=aryOverlayData;
  6940. if (ChartData.IsMinutePeriod(bindData.Period,false) && !this.IsApiPeriod) //周期数据
  6941. {
  6942. var periodData=bindData.GetPeriodData(bindData.Period);
  6943. bindData.Data=periodData;
  6944. }
  6945. item.Data=bindData;
  6946. }
  6947. else
  6948. {
  6949. var bindData = new ChartData();
  6950. bindData.Data = item.SourceData.Data;
  6951. bindData.Period = this.Period;
  6952. bindData.Right = this.Right;
  6953. if (bindData.Right > 0 && MARKET_SUFFIX_NAME.IsSHSZStockA(item.Symbol)) //复权数据
  6954. {
  6955. var rightData = bindData.GetRightData(bindData.Right, { AlgorithmType: this.RightFormula });
  6956. bindData.Data = rightData;
  6957. }
  6958. var aryOverlayData = this.SourceData.GetOverlayData(bindData.Data, this.IsApiPeriod); //和主图数据拟合以后的数据
  6959. bindData.Data = aryOverlayData;
  6960. if (ChartData.IsDayPeriod(bindData.Period, false)) //周期数据
  6961. {
  6962. var periodData = bindData.GetPeriodData(bindData.Period);
  6963. bindData.Data = periodData;
  6964. }
  6965. item.Data=bindData;
  6966. }
  6967. }
  6968. this.ReqeustKLineInfoData({FunctionName:"Update"});
  6969. //刷新画图
  6970. this.UpdataDataoffset(); //更新数据偏移
  6971. this.UpdatePointByCursorIndex(); //更新十字光标位子
  6972. this.UpdateFrameMaxMin(); //调整坐标最大 最小值
  6973. this.Frame.SetSizeChange(true);
  6974. this.Draw();
  6975. }
  6976. //切换股票代码 option={ KLine:{Right:, Period: } }
  6977. this.ChangeSymbol = function (symbol, option)
  6978. {
  6979. this.CancelAutoUpdate(); //先停止更新
  6980. this.AutoUpdateEvent(false,"KLineChartContainer::ChangeSymbol");
  6981. this.ClearCustomKLine();
  6982. this.Frame.ClearYCoordinateMaxMin();
  6983. this.ClearGlobalOption();
  6984. this.Symbol = symbol;
  6985. if (option && option.KLine)
  6986. {
  6987. var item=option.KLine;
  6988. if (IFrameSplitOperator.IsNumber(item.Right)) this.Right=item.Right;
  6989. if (IFrameSplitOperator.IsNumber(item.Period)) this.Period=item.Period;
  6990. }
  6991. if (IsIndexSymbol(symbol)) this.Right = 0; //指数没有复权
  6992. this.ClearIndexPaint();
  6993. if (ChartData.IsDayPeriod(this.Period, true))
  6994. {
  6995. this.ResetOverlaySymbolStatus();
  6996. this.RequestHistoryData(); //请求日线数据
  6997. //this.ReqeustKLineInfoData();
  6998. }
  6999. else if (ChartData.IsMinutePeriod(this.Period, true) || ChartData.IsSecondPeriod(this.Period))
  7000. {
  7001. this.ResetOverlaySymbolStatus();
  7002. this.RequestHistoryMinuteData(); //请求分钟数据
  7003. }
  7004. }
  7005. this.ReqeustKLineInfoData = function (obj)
  7006. {
  7007. if (obj && obj.FunctionName=="RecvDragDayData") //增量更新
  7008. {
  7009. obj.Update=true;
  7010. }
  7011. else
  7012. {
  7013. if (this.ChartPaint.length > 0)
  7014. {
  7015. var klinePaint = this.ChartPaint[0];
  7016. klinePaint.InfoData = new Map();
  7017. }
  7018. obj.Update=false;
  7019. }
  7020. //信息地雷信息
  7021. for (var i in this.ChartInfo)
  7022. {
  7023. this.ChartInfo[i].RequestData(this,obj);
  7024. }
  7025. }
  7026. //设置K线信息地雷
  7027. this.SetKLineInfo = function (aryInfo, bUpdate)
  7028. {
  7029. this.ChartInfo = []; //清空信息地雷
  7030. for (var i=0; i<aryInfo.length; ++i)
  7031. {
  7032. var infoItem = JSKLineInfoMap.Get(aryInfo[i]);
  7033. if (!infoItem) continue;
  7034. var item = infoItem.Create();
  7035. item.MaxRequestDataCount = this.MaxRequestDataCount;
  7036. this.ChartInfo.push(item);
  7037. }
  7038. if (bUpdate == true) this.ReqeustKLineInfoData({ FunctionName:"SetKLineInfo" });
  7039. }
  7040. //添加信息地雷
  7041. this.AddKLineInfo=function(infoName, bUpdate)
  7042. {
  7043. var classInfo=JSKLineInfoMap.GetClassInfo(infoName);
  7044. if (!classInfo)
  7045. {
  7046. console.warn("[KLineChartContainer::AddKLineInfo] can't find infoname=", infoName);
  7047. return;
  7048. }
  7049. for(var i=0; i<this.ChartInfo.length; ++i)
  7050. {
  7051. var item=this.ChartInfo[i];
  7052. if (item.ClassName==classInfo.ClassName) //已经存在
  7053. return;
  7054. }
  7055. var infoItem=JSKLineInfoMap.Get(infoName);
  7056. if (!infoItem) return;
  7057. var item=infoItem.Create();
  7058. item.MaxRequestDataCount=this.MaxRequestDataCount;
  7059. this.ChartInfo.push(item);
  7060. if (bUpdate==true)
  7061. {
  7062. item.RequestData(this); //这个页面全部刷新
  7063. }
  7064. }
  7065. //删除信息地理
  7066. this.DeleteKLineInfo=function(infoName)
  7067. {
  7068. var classInfo=JSKLineInfoMap.GetClassInfo(infoName);
  7069. if (!classInfo)
  7070. {
  7071. console.warn(`[KLineChartContainer::DeleteKLineInfo] can't find infoname=${infoName}`);
  7072. return;
  7073. }
  7074. for(var i=0; i<this.ChartInfo.length; ++i)
  7075. {
  7076. var item=this.ChartInfo[i];
  7077. if (item.ClassName==classInfo.ClassName)
  7078. {
  7079. this.ChartInfo.splice(i,1);
  7080. this.UpdataChartInfo();
  7081. this.Draw();
  7082. break;
  7083. }
  7084. }
  7085. }
  7086. this.SetPolicyInfo = function (aryPolicy, bUpdate)
  7087. {
  7088. if (!aryPolicy || !aryPolicy.length) return;
  7089. var infoItem = JSKLineInfoMap.Get('策略选股');
  7090. if (!infoItem) return;
  7091. var policyInfo = infoItem.Create();
  7092. policyInfo.SetPolicyList(aryPolicy);
  7093. policyInfo.MaxRequestDataCount = this.MaxRequestDataCount;
  7094. this.ChartInfo.push(policyInfo);
  7095. if (bUpdate == true) this.ReqeustKLineInfoData();
  7096. }
  7097. //叠加股票
  7098. this.OverlaySymbol = function (symbol,option)
  7099. {
  7100. for(var i=0; i<this.OverlayChartPaint.length; ++i)
  7101. {
  7102. var item=this.OverlayChartPaint[i];
  7103. if (item.Symbol===symbol)
  7104. {
  7105. console.warn(`[KLineChartContainer::OverlaySymbol] overlay symbol=${symbol} exist.`)
  7106. return false;
  7107. }
  7108. }
  7109. var paint=new ChartOverlayKLine();
  7110. paint.Canvas=this.Canvas;
  7111. paint.ChartBorder=this.Frame.SubFrame[0].Frame.ChartBorder;
  7112. paint.ChartFrame=this.Frame.SubFrame[0].Frame;
  7113. paint.Name="Overlay-KLine";
  7114. paint.DrawType=this.KLineDrawType;
  7115. paint.Symbol=symbol;
  7116. paint.Identify=`Overlay-KLine-${symbol}`;
  7117. if (option && option.Color) paint.Color=option.Color;
  7118. else paint.Color=g_JSChartResource.OverlaySymbol.Color[g_JSChartResource.OverlaySymbol.Random%g_JSChartResource.OverlaySymbol.Color.length];
  7119. paint.SetOption(option);
  7120. ++g_JSChartResource.OverlaySymbol.Random;
  7121. if (this.ChartPaint[0] && this.ChartPaint[0].Data && this.SourceData) paint.MainData=this.ChartPaint[0].Data; //绑定主图数据
  7122. this.OverlayChartPaint.push(paint);
  7123. if (ChartData.IsDayPeriod(this.Period, true)) this.RequestOverlayHistoryData(); //请求日线数据
  7124. else if (ChartData.IsMinutePeriod(this.Period,true)) this.RequestOverlayHistoryMinuteData(); //请求分钟历史数据
  7125. return true;
  7126. }
  7127. this.GetRequestDataCount = function () //K线请求数据个数 (由于可以拖拽下载历史数据,所有原来固定个数的就不能用了)
  7128. {
  7129. var result = { MaxRequestDataCount: this.MaxRequestDataCount, MaxRequestMinuteDayCount: this.MaxRequestMinuteDayCount };
  7130. if (!this.SourceData || !this.SourceData.Data || this.SourceData.Data.length <= 0) return result;
  7131. if (ChartData.IsDayPeriod(this.Period, true))
  7132. {
  7133. var lCount = this.SourceData.Data.length;
  7134. if (lCount > result.MaxRequestDataCount) result.MaxRequestDataCount = lCount;
  7135. }
  7136. else if (ChartData.IsMinutePeriod(this.Period, true))
  7137. {
  7138. var date=null;
  7139. var lCount=0;
  7140. for(var i=0;i<this.SourceData.Data.length; ++i)
  7141. {
  7142. var item=this.SourceData.Data[i];
  7143. if (item.Date!=date) ++lCount;
  7144. date=item.Date;
  7145. }
  7146. if (lCount>result.MaxRequestMinuteDayCount) result.MaxRequestMinuteDayCount=lCount;
  7147. }
  7148. return result;
  7149. }
  7150. this.RequestSingleOverlayHistoryData=function(symbol, dataCount, firstDate, item)
  7151. {
  7152. var self = this;
  7153. item.Status=OVERLAY_STATUS_ID.STATUS_REQUESTDATA_ID;
  7154. if (this.NetworkFilter)
  7155. {
  7156. var obj=
  7157. {
  7158. Name:'KLineChartContainer::RequestOverlayHistoryData', //类名::
  7159. Explain:'叠加股票日K线数据',
  7160. Request:{ Url:self.KLineApiUrl, Data: { symbol: symbol, count: dataCount.MaxRequestDataCount,"first":{ date: firstDate },
  7161. field:["name","symbol","yclose","open","price","high",'vol','amount'] }, Type:'POST' },
  7162. Self:this,
  7163. PreventDefault:false
  7164. };
  7165. this.NetworkFilter(obj, function(data)
  7166. {
  7167. item.Status=OVERLAY_STATUS_ID.STATUS_RECVDATA_ID;
  7168. self.RecvOverlayHistoryData(data,item);
  7169. });
  7170. if (obj.PreventDefault==true) return; //已被上层替换,不调用默认的网络请求
  7171. }
  7172. }
  7173. this.RequestOverlayHistoryData = function ()
  7174. {
  7175. if (!this.OverlayChartPaint.length) return;
  7176. if (!this.SourceData || !this.SourceData.Data) return; //主图数据还没有到完
  7177. var dataCount=this.GetRequestDataCount();
  7178. var firstDate=this.SourceData.Data[0].Date;
  7179. for(var i=0;i<this.OverlayChartPaint.length;++i)
  7180. {
  7181. var item=this.OverlayChartPaint[i];
  7182. if (!item.MainData) continue; //等待主图股票数据未下载完
  7183. if (item.Status!=OVERLAY_STATUS_ID.STATUS_NONE_ID) continue;
  7184. var symbol=item.Symbol;
  7185. if (!symbol) continue;
  7186. this.RequestSingleOverlayHistoryData(symbol, dataCount, firstDate, item);
  7187. }
  7188. }
  7189. this.RecvOverlayHistoryData = function (recvData, paint)
  7190. {
  7191. if (paint.IsDelete) return;
  7192. var data = recvData.data;
  7193. var aryDayData = KLineChartContainer.JsonDataToHistoryData(data);
  7194. //原始叠加数据
  7195. var sourceData = new ChartData();
  7196. sourceData.Data = aryDayData;
  7197. var bindData = new ChartData();
  7198. bindData.Data = aryDayData;
  7199. bindData.Period = this.Period;
  7200. bindData.Right = this.Right;
  7201. if (bindData.Right > 0 && !IsIndexSymbol(data.symbol)) //复权数据 ,指数没有复权)
  7202. {
  7203. var rightData = bindData.GetRightData(bindData.Right, { AlgorithmType: this.RightFormula });
  7204. bindData.Data = rightData;
  7205. }
  7206. var aryOverlayData = this.SourceData.GetOverlayData(bindData.Data); //和主图数据拟合以后的数据
  7207. bindData.Data = aryOverlayData;
  7208. if (ChartData.IsDayPeriod(bindData.Period, false)) //周期数据
  7209. {
  7210. var periodData = bindData.GetPeriodData(bindData.Period);
  7211. bindData.Data = periodData;
  7212. }
  7213. paint.Data = bindData;
  7214. paint.SourceData = sourceData;
  7215. paint.Title = data.name;
  7216. paint.Symbol = data.symbol;
  7217. paint.Status=OVERLAY_STATUS_ID.STATUS_FINISHED_ID;
  7218. this.Frame.SubFrame[0].Frame.YSplitOperator.CoordinateType = 1; //调整为百份比坐标
  7219. this.UpdataDataoffset(); //更新数据偏移
  7220. this.UpdateFrameMaxMin(); //调整坐标最大 最小值
  7221. this.Frame.SetSizeChange(true);
  7222. this.Draw();
  7223. }
  7224. this.RequestSingleHistoryMinuteData=function(symbol, dataCount, firstDate,firstTime, item)
  7225. {
  7226. var self=this;
  7227. item.Status=OVERLAY_STATUS_ID.STATUS_REQUESTDATA_ID;
  7228. if (this.NetworkFilter)
  7229. {
  7230. var obj=
  7231. {
  7232. Name:'KLineChartContainer::RequestOverlayHistoryMinuteData', //类名::
  7233. Explain:'叠加股票分钟K线数据',
  7234. Request:{ Url:self.MinuteKLineApiUrl, Data: { symbol: symbol, count: dataCount.MaxRequestMinuteDayCount,"first":{ date: firstDate, time:firstTime },
  7235. field:["name","symbol","yclose","open","price","high",'vol','amount'] }, Type:'POST' },
  7236. Self:this,
  7237. PreventDefault:false
  7238. };
  7239. this.NetworkFilter(obj, function(data)
  7240. {
  7241. item.Status=OVERLAY_STATUS_ID.STATUS_RECVDATA_ID;
  7242. self.RecvOveralyHistoryMinuteData(data,item);
  7243. });
  7244. if (obj.PreventDefault==true) return; //已被上层替换,不调用默认的网络请求
  7245. }
  7246. }
  7247. this.RequestOverlayHistoryMinuteData=function()
  7248. {
  7249. if (!this.OverlayChartPaint.length) return;
  7250. if (!this.SourceData || !this.SourceData.Data) return; //主图数据还没有到完
  7251. var dataCount=this.GetRequestDataCount();
  7252. var firstDate=this.SourceData.Data[0].Date;
  7253. var firstTime=this.SourceData.Data[0].Time;
  7254. for(var i=0; i<this.OverlayChartPaint.length; ++i)
  7255. {
  7256. var item=this.OverlayChartPaint[i];
  7257. if (!item.MainData) continue; //等待主图股票数据未下载完
  7258. if (item.Status!=OVERLAY_STATUS_ID.STATUS_NONE_ID) continue;
  7259. var symbol=item.Symbol;
  7260. if (!symbol) continue;
  7261. this.RequestSingleHistoryMinuteData(symbol,dataCount,firstDate,firstTime, item );
  7262. }
  7263. }
  7264. this.RecvOveralyHistoryMinuteData=function(recvData,paint)
  7265. {
  7266. if (paint.IsDelete) return;
  7267. var data=recvData.data;
  7268. var aryDayData=KLineChartContainer.JsonDataToMinuteHistoryData(data);
  7269. if (!aryDayData) return;
  7270. //原始叠加数据
  7271. var sourceData=new ChartData();
  7272. sourceData.Data=aryDayData;
  7273. sourceData.DataType=1; //0=日线数据 1=分钟数据
  7274. var bindData=new ChartData();
  7275. bindData.Data=aryDayData;
  7276. bindData.Period=this.Period;
  7277. bindData.Right=this.Right;
  7278. bindData.DataType=1;
  7279. var aryOverlayData=this.SourceData.GetOverlayMinuteData(bindData.Data, this.IsApiPeriod); //和主图数据拟合以后的数据
  7280. bindData.Data=aryOverlayData;
  7281. if (ChartData.IsMinutePeriod(bindData.Period,false) && !this.IsApiPeriod) //周期数据, API周期数据不用计算
  7282. {
  7283. var periodData=bindData.GetPeriodData(bindData.Period);
  7284. bindData.Data=periodData;
  7285. }
  7286. paint.Data=bindData;
  7287. paint.SourceData=sourceData;
  7288. paint.Title=data.name;
  7289. paint.Symbol=data.symbol;
  7290. paint.Status=OVERLAY_STATUS_ID.STATUS_FINISHED_ID; //数据下载完成
  7291. this.Frame.SubFrame[0].Frame.YSplitOperator.CoordinateType=1; //调整为百份比坐标
  7292. this.UpdataDataoffset(); //更新数据偏移
  7293. this.UpdateFrameMaxMin(); //调整坐标最大 最小值
  7294. this.Frame.SetSizeChange(true);
  7295. this.Draw();
  7296. }
  7297. //取消叠加股票
  7298. this.ClearOverlaySymbol = function ()
  7299. {
  7300. for(var i=0; i<this.OverlayChartPaint.length; ++i)
  7301. {
  7302. var item=this.OverlayChartPaint[i];
  7303. item.IsDelete=true;
  7304. }
  7305. this.OverlayChartPaint=[];
  7306. this.Frame.SubFrame[0].Frame.YSplitOperator.CoordinateType = 0; //调整一般坐标
  7307. this.UpdateFrameMaxMin();
  7308. this.Draw();
  7309. }
  7310. //删除一个叠加股票
  7311. this.DeleteOverlaySymbol=function(symbol)
  7312. {
  7313. for(var i=0; i<this.OverlayChartPaint.length; ++i)
  7314. {
  7315. var item=this.OverlayChartPaint[i];
  7316. if (item.Symbol===symbol)
  7317. {
  7318. item.IsDelete=true;
  7319. this.OverlayChartPaint.splice(i,1);
  7320. if (this.OverlayChartPaint.length<=0) this.Frame.SubFrame[0].Frame.YSplitOperator.CoordinateType=0; //调整一般坐标
  7321. this.UpdateFrameMaxMin();
  7322. this.Draw();
  7323. return true;
  7324. }
  7325. }
  7326. console.warn(`[KLineChartContainer::DeleteOverlaySymbol] overlay symbol=${symbol} not exist.`)
  7327. return false;
  7328. }
  7329. //创建画图工具
  7330. this.CreateChartDrawPicture = function (name, option, callback)
  7331. {
  7332. var drawPicture=null;
  7333. var item=IChartDrawPicture.GetDrawPictureByName(name);
  7334. if (item) drawPicture=item.Create();
  7335. if (!drawPicture) return false;
  7336. drawPicture.Canvas=this.Canvas;
  7337. drawPicture.Status=0;
  7338. drawPicture.Symbol=this.Symbol;
  7339. drawPicture.Period=this.Period;
  7340. drawPicture.Right=this.Right;
  7341. drawPicture.Option=this.ChartDrawOption;
  7342. drawPicture.PixelRatio=this.UIElement.PixelRatio;
  7343. if (callback) drawPicture.FinishedCallback=callback; //完成通知上层回调
  7344. if (option) drawPicture.SetOption(option);
  7345. var self=this;
  7346. drawPicture.Update=function() //更新回调函数
  7347. {
  7348. self.DrawDynamicInfo();
  7349. };
  7350. drawPicture.GetActiveDrawPicture=function() { return self.GetActiveDrawPicture(); }
  7351. this.CurrentChartDrawPicture=drawPicture;
  7352. //JSConsole.Chart.Log("[KLineChartContainer::CreateChartDrawPicture] ", name,this.CurrentChartDrawPicture);
  7353. return true;
  7354. }
  7355. //更新信息地雷
  7356. this.UpdataChartInfo = function ()
  7357. {
  7358. //TODO: 根据K线数据日期来做map, 不在K线上的合并到下一个k线日期里面
  7359. var mapInfoData = new Map();
  7360. if (this.Period==0) //日线数据 根据日期
  7361. {
  7362. for (var i in this.ChartInfo)
  7363. {
  7364. var infoData = this.ChartInfo[i].Data;
  7365. for (var j in infoData)
  7366. {
  7367. var item = infoData[j];
  7368. if (mapInfoData.has(item.Date.toString()))
  7369. mapInfoData.get(item.Date.toString()).Data.push(item);
  7370. else
  7371. mapInfoData.set(item.Date.toString(), { Data: new Array(item) });
  7372. }
  7373. }
  7374. }
  7375. else if (ChartData.IsDayPeriod(this.Period,false))
  7376. {
  7377. mapInfoData=new Map();
  7378. var hisData=this.ChartPaint[0].Data;
  7379. if (hisData && hisData.Data && hisData.Data.length>0)
  7380. {
  7381. var fristKItem=hisData.Data[0];
  7382. var aryInfo=[];
  7383. for(var i in this.ChartInfo)
  7384. {
  7385. var infoItem=this.ChartInfo[i];
  7386. for(var j in infoItem.Data)
  7387. {
  7388. var item=infoItem.Data[j];
  7389. if (item.Date>=fristKItem.Date) //在K线范围内的才显示
  7390. aryInfo.push(item);
  7391. }
  7392. }
  7393. aryInfo.sort(function(a,b) { return a.Date-b.Date }); //排序
  7394. for(var i=0;i<hisData.Data.length;)
  7395. {
  7396. var kItem=hisData.Data[i]; //K线数据
  7397. if (aryInfo.length<=0) break;
  7398. var infoItem=aryInfo[0];
  7399. if (kItem.Date<infoItem.Date)
  7400. {
  7401. ++i;
  7402. continue;
  7403. }
  7404. //信息地雷日期<K线上的日期 就是属于这个K线上的
  7405. if (mapInfoData.has(kItem.Date.toString()))
  7406. mapInfoData.get(kItem.Date.toString()).Data.push(infoItem);
  7407. else
  7408. mapInfoData.set(kItem.Date.toString(),{Data:new Array(infoItem)});
  7409. aryInfo.shift();
  7410. //JSConsole.Chart.Log('[KLineChartContainer::UpdataChartInfo]',item);
  7411. }
  7412. }
  7413. }
  7414. var klinePaint = this.ChartPaint[0];
  7415. klinePaint.InfoData = mapInfoData;
  7416. var titlePaint = this.TitlePaint[0];
  7417. if (titlePaint) titlePaint.InfoData = mapInfoData;
  7418. }
  7419. //接收到窗口指标数据 订阅模式
  7420. this.RecvWindowIndex=function(index, data)
  7421. {
  7422. var indexItem=this.WindowIndex[index];
  7423. if (!indexItem) return;
  7424. if (typeof(indexItem.RecvSubscribeData)=="function")
  7425. {
  7426. var hisData=this.ChartPaint[0].Data;
  7427. indexItem.RecvSubscribeData(data,this,index,hisData);
  7428. }
  7429. }
  7430. //更新窗口指标
  7431. this.UpdateWindowIndex = function (index)
  7432. {
  7433. var bindData = new ChartData();
  7434. bindData.Data = this.SourceData.Data;
  7435. bindData.Period = this.Period;
  7436. bindData.Right = this.Right;
  7437. if (this.IsApiPeriod)
  7438. {
  7439. }
  7440. else
  7441. {
  7442. if (bindData.Right > 0) //复权
  7443. {
  7444. var rightData = bindData.GetRightData(bindData.Right, { AlgorithmType: this.RightFormula });
  7445. bindData.Data = rightData;
  7446. }
  7447. if (ChartData.IsDayPeriod(bindData.Period, false) || ChartData.IsMinutePeriod(bindData.Period, false)) //周期数据
  7448. {
  7449. var periodData = bindData.GetPeriodData(bindData.Period);
  7450. bindData.Data = periodData;
  7451. }
  7452. }
  7453. this.WindowIndex[index].BindData(this, index, bindData);
  7454. this.UpdataDataoffset(); //更新数据偏移
  7455. this.UpdateFrameMaxMin(); //调整坐标最大 最小值
  7456. this.Draw();
  7457. }
  7458. //修改参数指标
  7459. this.ChangeWindowIndexParam = function (index) {
  7460. this.WindowIndex[index].Index[0].Param += 1;
  7461. this.WindowIndex[index].Index[1].Param += 1;
  7462. this.UpdateWindowIndex(index);
  7463. }
  7464. this.OnDoubleClick = function (x, y, e)
  7465. {
  7466. var tooltip = new TooltipData();
  7467. for (var i in this.ChartPaint)
  7468. {
  7469. var item = this.ChartPaint[i];
  7470. if (item.GetTooltipData(x, y, tooltip))
  7471. break;
  7472. }
  7473. if (!tooltip.Data) return;
  7474. e.data = { Chart: this, Tooltip: tooltip };
  7475. }
  7476. this.CancelAutoUpdate=function() //关闭停止更新
  7477. {
  7478. if (this.AutoUpdateTimer)
  7479. {
  7480. clearTimeout(this.AutoUpdateTimer);
  7481. this.AutoUpdateTimer = null;
  7482. }
  7483. }
  7484. //数据自动更新
  7485. this.AutoUpdate = function (waitTime) //waitTime 更新时间
  7486. {
  7487. this.CancelAutoUpdate();
  7488. if (!this.IsAutoUpdate) return;
  7489. if (!this.Symbol) return;
  7490. if (this.IsDestroy) return;
  7491. var self = this;
  7492. var marketStatus = MARKET_SUFFIX_NAME.GetMarketStatus(this.Symbol);
  7493. if (marketStatus == 0 || marketStatus == 3) return; //闭市,盘后
  7494. var frequency = this.AutoUpdateFrequency;
  7495. if (marketStatus == 1) //盘前
  7496. {
  7497. this.AutoUpdateTimer=setTimeout(function () { self.AutoUpdate(); }, frequency);
  7498. }
  7499. else if (marketStatus == 2) //盘中
  7500. {
  7501. this.AutoUpdateTimer=setTimeout(function ()
  7502. {
  7503. if (ChartData.IsDayPeriod(self.Period, true))
  7504. {
  7505. self.RequestRealtimeData(); //更新最新行情
  7506. //self.ReqeustKLineInfoData();
  7507. }
  7508. else if (ChartData.IsMinutePeriod(self.Period, true) || ChartData.IsSecondPeriod(self.Period))
  7509. {
  7510. self.RequestMinuteRealtimeData(); //请求分钟数据
  7511. }
  7512. }, frequency);
  7513. }
  7514. }
  7515. this.GetMaxPageSize = function ()
  7516. {
  7517. let width = this.Frame.ChartBorder.GetWidth();
  7518. let barWidth = (ZOOM_SEED[ZOOM_SEED.length - 1][0] + ZOOM_SEED[ZOOM_SEED.length - 1][1]);
  7519. let pageSize = parseInt(width / barWidth) - 8;
  7520. JSConsole.Chart.Log(`[KLineChartContainer::GetMaxPageSize] width=${width} barWidth=${barWidth} pageSize=${pageSize}`);
  7521. return pageSize
  7522. }
  7523. //数据拖拽下载
  7524. this.DragDownloadData = function ()
  7525. {
  7526. var data = null;
  7527. if (!this.Frame.Data) data = this.Frame.Data;
  7528. else data = this.Frame.SubFrame[0].Frame.Data;
  7529. if (!data) return false;
  7530. if (data.DataOffset > 0) return;
  7531. if (ChartData.IsMinutePeriod(this.Period, true) || ChartData.IsSecondPeriod(this.Period)) //下载分钟数据
  7532. {
  7533. JSConsole.Chart.Log(`[KLineChartContainer.DragDownloadData] Minute:[Enable=${this.DragDownload.Minute.Enable}, IsEnd=${this.DragDownload.Minute.IsEnd}, Status=${this.DragDownload.Minute.Status}, Period=${this.Period}]`);
  7534. if (!this.DragDownload.Minute.Enable) return;
  7535. if (this.DragDownload.Minute.IsEnd) return; //全部下载完了
  7536. if (this.DragDownload.Minute.Status != 0) return;
  7537. this.RequestDragMinuteData();
  7538. }
  7539. else if (ChartData.IsDayPeriod(this.Period, true)) // 下载日线
  7540. {
  7541. JSConsole.Chart.Log(`[KLineChartContainer.DragDownloadData] Day:[Enable=${this.DragDownload.Minute.Enable}, IsEnd=${this.DragDownload.Minute.IsEnd}, Status=${this.DragDownload.Minute.Status}]`);
  7542. if (!this.DragDownload.Day.Enable) return;
  7543. if (this.DragDownload.Day.IsEnd) return; //全部下载完了
  7544. if (this.DragDownload.Day.Status != 0) return;
  7545. this.RequestDragDayData();
  7546. }
  7547. }
  7548. this.RequestDragMinuteData = function ()
  7549. {
  7550. var option=
  7551. {
  7552. FuncName:'KLineChartContainer::RequestDragMinuteData',
  7553. FuncExplain:"拖拽分钟|秒K线数据下载",
  7554. RecvFuncName:"RecvDragMinuteData",
  7555. Download:this.DragDownload.Minute,
  7556. Url:this.DragMinuteKLineApiUrl,
  7557. Count:this.MaxRequestMinuteDayCount,
  7558. XShowCount:this.Frame.GetXShowCount(),
  7559. };
  7560. this.RequestPreviousMinuteData(option);
  7561. }
  7562. this.RequestPreviousMinuteData=function(option)
  7563. {
  7564. var funcName=option.FuncName;
  7565. var funcExplain=option.FuncExplain;
  7566. var download=option.Download;
  7567. var url=option.Url;
  7568. var count=option.Count; //请求数据个数
  7569. var self = this;
  7570. this.AutoUpdateEvent(false, funcName); //停止自动更新
  7571. this.CancelAutoUpdate();
  7572. download.Status = 1;
  7573. var firstItem=null;
  7574. if (IFrameSplitOperator.IsNonEmptyArray(this.SourceData.Data))
  7575. firstItem = this.SourceData.Data[0]; //最新的一条数据
  7576. else
  7577. firstItem={Date:null, Time:null};
  7578. var postData =
  7579. {
  7580. "field": ["name", "symbol", "yclose", "open", "price", "high", "low", "vol"],
  7581. "symbol": self.Symbol,
  7582. "enddate": firstItem.Date,
  7583. "endtime": firstItem.Time,
  7584. "count": count,
  7585. "first": { date: firstItem.Date, time: firstItem.Time },
  7586. };
  7587. if (IFrameSplitOperator.IsNonEmptyArray(this.OverlayChartPaint))
  7588. {
  7589. postData.overlay=[];
  7590. for(var i=0;i<this.OverlayChartPaint.length;++i)
  7591. {
  7592. var item=this.OverlayChartPaint[i];
  7593. postData.overlay.push({ symbol:item.Symbol });
  7594. }
  7595. }
  7596. if (this.NetworkFilter)
  7597. {
  7598. var obj =
  7599. {
  7600. Name: funcName, //类名::函数
  7601. Explain: funcExplain,
  7602. Request: { Url: url, Type: 'POST', Data: postData, Period:this.Period, Right:this.Right },
  7603. DragDownload: download,
  7604. Option:option,
  7605. Self: this,
  7606. ZoomData:option.ZoomData,
  7607. PreventDefault: false
  7608. };
  7609. this.NetworkFilter(obj, function (data)
  7610. {
  7611. self.RecvPreviousMinuteData(data, option);
  7612. download.Status = 0;
  7613. self.AutoUpdateEvent(true, funcName); //自动更新
  7614. self.AutoUpdate();
  7615. });
  7616. if (obj.PreventDefault == true) return; //已被上层替换,不调用默认的网络请求
  7617. }
  7618. }
  7619. //分钟K线拖动 !!没有做叠加分钟K线
  7620. this.RecvPreviousMinuteData=function(recvdata, option)
  7621. {
  7622. var download=option.Download;
  7623. var data=recvdata.data;
  7624. var aryDayData = KLineChartContainer.JsonDataToMinuteHistoryData(data);
  7625. if (!aryDayData || aryDayData.length<=0)
  7626. {
  7627. download.IsEnd=true;
  7628. JSConsole.Chart.Log(`[KLineChartContainer.RecvPreviousMinuteData] ${this.Symbol} data end. FuncName=${option.FuncName}`);
  7629. this.Draw();
  7630. return;
  7631. }
  7632. var lastDataCount = this.GetHistoryDataCount(); //保存下上一次的数据个数
  7633. var endIndex=null;
  7634. if (IFrameSplitOperator.IsNonEmptyArray(this.SourceData.Data))
  7635. {
  7636. var firstData=this.SourceData.Data[0];
  7637. for(var i=aryDayData.length-1;i>=0;--i)
  7638. {
  7639. var item=aryDayData[i];
  7640. if (firstData.Date>item.Date || (firstData.Date==item.Date && firstData.Time>item.Time))
  7641. {
  7642. endIndex=i;
  7643. break;
  7644. }
  7645. else if (firstData.Date==item.Date && firstData.Time==item.Time)
  7646. {
  7647. firstData.YClose=item.YClose;
  7648. endIndex=i-1;
  7649. break;
  7650. }
  7651. }
  7652. }
  7653. else
  7654. {
  7655. endIndex=aryDayData.length-1;
  7656. }
  7657. if (endIndex==null && endIndex<0) return;
  7658. for(var i=0;i<aryDayData.length && i<=endIndex;++i) //数据往前插
  7659. {
  7660. var item=aryDayData[i];
  7661. this.SourceData.Data.splice(i,0,item);
  7662. }
  7663. var bindData=new ChartData();
  7664. bindData.Data=this.SourceData.Data;
  7665. bindData.Period=this.Period;
  7666. bindData.Right=this.Right;
  7667. bindData.DataType=this.SourceData.DataType;
  7668. bindData.Symbol=this.Symbol;
  7669. if (!this.IsApiPeriod)
  7670. {
  7671. if (ChartData.IsDayPeriod(bindData.Period, false) || ChartData.IsMinutePeriod(bindData.Period, false)) //周期数据 (0= 日线,4=1分钟线 不需要处理)
  7672. {
  7673. var periodData = bindData.GetPeriodData(bindData.Period);
  7674. bindData.Data = periodData;
  7675. }
  7676. }
  7677. //绑定数据
  7678. this.UpdateMainData(bindData, lastDataCount);
  7679. if (option) //缩放需要调整当前屏的位置
  7680. {
  7681. if (option.ZoomData)
  7682. {
  7683. var zoomData=option.ZoomData;
  7684. var showCount=zoomData.PageSize-zoomData.RightSpaceCount; //一屏显示的数据个数
  7685. bindData.DataOffset= bindData.Data.length-showCount;
  7686. if (bindData.DataOffset<0) bindData.DataOffset=0;
  7687. }
  7688. else if (IFrameSplitOperator.IsNumber(option.DataOffset))
  7689. {
  7690. bindData.DataOffset+=option.DataOffset;
  7691. if (bindData.DataOffset<0) bindData.DataOffset=0;
  7692. }
  7693. }
  7694. this.UpdateOverlayDragMinuteData(data);
  7695. this.BindInstructionIndexData(bindData); //执行指示脚本
  7696. for (var i = 0; i < this.Frame.SubFrame.length; ++i)
  7697. {
  7698. this.BindIndexData(i, bindData);
  7699. }
  7700. //刷新画图
  7701. this.UpdataDataoffset(); //更新数据偏移
  7702. this.UpdatePointByCursorIndex(); //更新十字光标位子
  7703. this.UpdateFrameMaxMin(); //调整坐标最大 最小值
  7704. this.Frame.SetSizeChange(true);
  7705. this.Draw();
  7706. //叠加指标计算
  7707. this.BindAllOverlayIndexData(bindData);
  7708. }
  7709. this.MergeOverlaySymbolMinuteData=function(item, aryOverlayData)
  7710. {
  7711. if (!item.Symbol) false;
  7712. if (!IFrameSplitOperator.IsNonEmptyArray(aryOverlayData)) return false;
  7713. var findData=null;
  7714. for(var i=0;i<aryOverlayData.length;++i) //查找对应的叠加股票数据
  7715. {
  7716. var overlayItem=aryOverlayData[i];
  7717. if (overlayItem.symbol==item.Symbol)
  7718. {
  7719. findData=overlayItem;
  7720. break;
  7721. }
  7722. }
  7723. if (!findData) return false;
  7724. var aryDayData=KLineChartContainer.JsonDataToMinuteHistoryData(findData);
  7725. var sourceData=item.SourceData; //叠加股票的所有数据
  7726. var firstData=sourceData.Data[0];
  7727. var endIndex=null;
  7728. for(var i=aryDayData.length-1;i>=0;--i)
  7729. {
  7730. var itemData=aryDayData[i];
  7731. if (firstData.Date>itemData.Date)
  7732. {
  7733. endIndex=i;
  7734. break;
  7735. }
  7736. else if (firstData.Date==itemData.Date && firstData.Time>itemData.Time)
  7737. {
  7738. endIndex=i;
  7739. break;
  7740. }
  7741. else if (firstData.Date==itemData.Date && firstData.Time==itemData.Time)
  7742. {
  7743. firstData.YClose=itemData.YClose;
  7744. endIndex=i-1;
  7745. break;
  7746. }
  7747. }
  7748. if (endIndex==null && endIndex<0) return false;
  7749. for(var i=0; i<aryDayData.length && i<=endIndex;++i) //数据往前插
  7750. {
  7751. var itemData=aryDayData[i];
  7752. sourceData.Data.splice(i,0,itemData);
  7753. }
  7754. var bindData=new ChartData();
  7755. bindData.Data=sourceData.Data;
  7756. bindData.Period=this.Period;
  7757. bindData.Right=this.Right;
  7758. bindData.DataType=0;
  7759. var aryOverlayData=this.SourceData.GetOverlayMinuteData(bindData.Data, this.IsApiPeriod); //和主图数据拟合以后的数据
  7760. bindData.Data=aryOverlayData;
  7761. if (ChartData.IsMinutePeriod(bindData.Period,false) && !this.IsApiPeriod) //周期数据
  7762. {
  7763. var periodData=bindData.GetPeriodData(bindData.Period);
  7764. bindData.Data=periodData;
  7765. }
  7766. item.Data=bindData;
  7767. return true;
  7768. }
  7769. this.UpdateOverlayDragMinuteData=function(data)
  7770. {
  7771. if (!IFrameSplitOperator.IsNonEmptyArray(this.OverlayChartPaint)) return;
  7772. var aryRecvOverlayData=data.overlay;
  7773. for(var i=0;i<this.OverlayChartPaint.length; ++i)
  7774. {
  7775. var item=this.OverlayChartPaint[i];
  7776. if (!item.Symbol) continue;
  7777. var bUpdate=false;
  7778. if (item.MainData && item.Status==OVERLAY_STATUS_ID.STATUS_FINISHED_ID) //等待主图股票数据未下载完
  7779. {
  7780. bUpdate=this.MergeOverlaySymbolMinuteData(item,aryRecvOverlayData);
  7781. }
  7782. if (!bUpdate) //没有更新数据 手动跟主图数据对齐
  7783. {
  7784. if (item.Data && IFrameSplitOperator.IsNonEmptyArray(item.Data.Data))
  7785. {
  7786. var bindData=item.Data;
  7787. var aryOverlayData=this.SourceData.GetOverlayMinuteData(bindData.Data, this.IsApiPeriod); //和主图数据拟合以后的数据
  7788. bindData.Data=aryOverlayData;
  7789. }
  7790. }
  7791. }
  7792. }
  7793. this.RequestDragDayData = function ()
  7794. {
  7795. var option=
  7796. {
  7797. FuncName:'KLineChartContainer::RequestDragDayData',
  7798. FuncExplain:"拖拽日K数据下载",
  7799. RecvFuncName:"RecvDragDayData",
  7800. Download:this.DragDownload.Day,
  7801. Url:this.DragKLineApiUrl,
  7802. Count:this.MaxRequestDataCount,
  7803. XShowCount:this.Frame.GetXShowCount(),
  7804. };
  7805. this.RequestPreviousDayData(option);
  7806. }
  7807. //请求拖动或缩放的日线历史数据
  7808. this.RequestPreviousDayData=function(option)
  7809. {
  7810. var funcName=option.FuncName;
  7811. var funcExplain=option.FuncExplain;
  7812. var download=option.Download;
  7813. var url=option.Url;
  7814. var count=option.Count; //请求数据个数
  7815. var self = this;
  7816. this.AutoUpdateEvent(false, funcName); //停止自动更新
  7817. this.CancelAutoUpdate();
  7818. var download = this.DragDownload.Day;
  7819. download.Status = 1;
  7820. var firstItem =null;
  7821. if (IFrameSplitOperator.IsNonEmptyArray(this.SourceData.Data))
  7822. firstItem = this.SourceData.Data[0]; //最新的一条数据
  7823. else
  7824. firstItem={Date:null};
  7825. var postData =
  7826. {
  7827. "field": ["name", "symbol", "yclose", "open", "price", "high", "low", "vol"],
  7828. "symbol": self.Symbol,
  7829. "enddate": firstItem.Date,
  7830. "count": count,
  7831. "first": { date: firstItem.Date }
  7832. };
  7833. if (IFrameSplitOperator.IsNonEmptyArray(this.OverlayChartPaint))
  7834. {
  7835. postData.overlay=[];
  7836. for(var i=0;i<this.OverlayChartPaint.length;++i)
  7837. {
  7838. var item=this.OverlayChartPaint[i];
  7839. if (item.Symbol) postData.overlay.push( { symbol:item.Symbol } );
  7840. }
  7841. }
  7842. if (this.NetworkFilter)
  7843. {
  7844. var obj =
  7845. {
  7846. Name: funcName, //类名::函数
  7847. Explain: funcExplain,
  7848. Request: { Url: url, Type: 'POST', Data: postData , Period:this.Period, Right:this.Right },
  7849. DragDownload: download,
  7850. Option:option,
  7851. Self: this,
  7852. ZoomData:option.ZoomData,
  7853. PreventDefault: false
  7854. };
  7855. this.NetworkFilter(obj, function (data)
  7856. {
  7857. self.RecvPreviousDayData(data, option);
  7858. download.Status = 0;
  7859. self.AutoUpdateEvent(true, funcName); //自动更新
  7860. self.AutoUpdate();
  7861. });
  7862. if (obj.PreventDefault == true) return; //已被上层替换,不调用默认的网络请求
  7863. }
  7864. }
  7865. this.RecvPreviousDayData = function (recvdata, option)
  7866. {
  7867. var download=option.Download;
  7868. var data = recvdata.data;
  7869. var aryDayData = KLineChartContainer.JsonDataToHistoryData(data);
  7870. if (!aryDayData || aryDayData.length<=0)
  7871. {
  7872. download.IsEnd=true; //下完了
  7873. JSConsole.Chart.Log(`[KLineChartContainer.RecvPreviousDayData] ${this.Symbol} data end. FuncName=${option.FuncName}`);
  7874. return;
  7875. }
  7876. var lastDataCount = this.GetHistoryDataCount(); //保存下上一次的数据个数
  7877. var endIndex=null;
  7878. if (IFrameSplitOperator.IsNonEmptyArray(this.SourceData.Data))
  7879. {
  7880. var firstData=this.SourceData.Data[0];
  7881. for(var i=aryDayData.length-1;i>=0;--i)
  7882. {
  7883. var item=aryDayData[i];
  7884. if (firstData.Date>item.Date)
  7885. {
  7886. endIndex=i;
  7887. break;
  7888. }
  7889. else if (firstData.Date==item.Date)
  7890. {
  7891. firstData.YClose=item.YClose;
  7892. endIndex=i-1;
  7893. break;
  7894. }
  7895. }
  7896. }
  7897. else
  7898. {
  7899. var firstData={ Date:null };
  7900. endIndex=aryDayData.length-1;
  7901. }
  7902. if (endIndex==null && endIndex<0) return;
  7903. for(var i=0; i<aryDayData.length && i<=endIndex;++i) //数据往前插
  7904. {
  7905. var item=aryDayData[i];
  7906. this.SourceData.Data.splice(i,0,item);
  7907. }
  7908. var bindData = new ChartData();
  7909. bindData.Data = this.SourceData.Data;
  7910. bindData.Period = this.Period;
  7911. bindData.Right = this.Right;
  7912. bindData.DataType = this.SourceData.DataType;
  7913. bindData.Symbol = this.Symbol;
  7914. if (!this.IsApiPeriod)
  7915. {
  7916. if (ChartData.IsDayPeriod(bindData.Period, false) || ChartData.IsMinutePeriod(bindData.Period, false)) //周期数据 (0= 日线,4=1分钟线 不需要处理)
  7917. {
  7918. var periodData = bindData.GetPeriodData(bindData.Period);
  7919. bindData.Data = periodData;
  7920. }
  7921. }
  7922. //绑定数据
  7923. this.UpdateMainData(bindData, lastDataCount);
  7924. if (option) //缩放需要调整当前屏的位置
  7925. {
  7926. if (option.ZoomData)
  7927. {
  7928. var zoomData=option.ZoomData;
  7929. var showCount=zoomData.PageSize-zoomData.RightSpaceCount; //一屏显示的数据个数
  7930. bindData.DataOffset= bindData.Data.length-showCount;
  7931. if (bindData.DataOffset<0) bindData.DataOffset=0;
  7932. }
  7933. else if (IFrameSplitOperator.IsNumber(option.DataOffset))
  7934. {
  7935. bindData.DataOffset+=option.DataOffset;
  7936. if (bindData.DataOffset<0) bindData.DataOffset=0;
  7937. }
  7938. }
  7939. this.UpdateOverlayDragDayData(data);
  7940. this.BindInstructionIndexData(bindData); //执行指示脚本
  7941. for (var i = 0; i < this.Frame.SubFrame.length; ++i)
  7942. {
  7943. this.BindIndexData(i, bindData);
  7944. }
  7945. //刷新画图
  7946. this.UpdataDataoffset(); //更新数据偏移
  7947. this.UpdatePointByCursorIndex(); //更新十字光标位子
  7948. this.UpdateFrameMaxMin(); //调整坐标最大 最小值
  7949. this.Frame.SetSizeChange(true);
  7950. this.Draw();
  7951. //更新信息地雷
  7952. this.ReqeustKLineInfoData( { FunctionName:option.RecvFuncName, StartDate:firstData.Date } );
  7953. //叠加指标计算
  7954. this.BindAllOverlayIndexData(bindData);
  7955. }
  7956. this.MergeOverlaySymbolDayData=function(item, aryOverlayData)
  7957. {
  7958. if (!item.Symbol) return false;
  7959. if (!IFrameSplitOperator.IsNonEmptyArray(aryOverlayData)) return false;
  7960. var findData=null;
  7961. for(var i=0;i<aryOverlayData.length;++i) //查找对应的叠加股票数据
  7962. {
  7963. var overlayItem=aryOverlayData[i];
  7964. if (overlayItem.symbol==item.Symbol)
  7965. {
  7966. findData=overlayItem;
  7967. break;
  7968. }
  7969. }
  7970. if (!findData) false;
  7971. var aryDayData=KLineChartContainer.JsonDataToHistoryData(findData);
  7972. var sourceData=item.SourceData; //叠加股票的所有数据
  7973. var firstData=sourceData.Data[0];
  7974. var endIndex=null;
  7975. for(var i=aryDayData.length-1;i>=0;--i)
  7976. {
  7977. var itemData=aryDayData[i];
  7978. if (firstData.Date>itemData.Date)
  7979. {
  7980. endIndex=i;
  7981. break;
  7982. }
  7983. else if (firstData.Date==itemData.Date)
  7984. {
  7985. firstData.YClose=itemData.YClose;
  7986. endIndex=i-1;
  7987. break;
  7988. }
  7989. }
  7990. if (endIndex==null && endIndex<0) return false;
  7991. for(var i=0; i<aryDayData.length && i<=endIndex;++i) //数据往前插
  7992. {
  7993. var itemData=aryDayData[i];
  7994. sourceData.Data.splice(i,0,itemData);
  7995. }
  7996. var bindData=new ChartData();
  7997. bindData.Data=sourceData.Data;
  7998. bindData.Period=this.Period;
  7999. bindData.Right=this.Right;
  8000. bindData.DataType=0;
  8001. if (bindData.Right>0 && MARKET_SUFFIX_NAME.IsSHSZStockA(findData.symbol) && !this.IsApiPeriod) //复权数据 ,A股才有有复权
  8002. {
  8003. var rightData=bindData.GetRightData(bindData.Right, { AlgorithmType: this.RightFormula });
  8004. bindData.Data=rightData;
  8005. }
  8006. var aryOverlayData=this.SourceData.GetOverlayData(bindData.Data, this.IsApiPeriod); //和主图数据拟合以后的数据
  8007. bindData.Data=aryOverlayData;
  8008. if (ChartData.IsDayPeriod(bindData.Period,false) && !this.IsApiPeriod) //周期数据
  8009. {
  8010. var periodData=bindData.GetPeriodData(bindData.Period);
  8011. bindData.Data=periodData;
  8012. }
  8013. item.Data=bindData;
  8014. return true;
  8015. }
  8016. //更新叠加数据
  8017. this.UpdateOverlayDragDayData=function(data)
  8018. {
  8019. if (!IFrameSplitOperator.IsNonEmptyArray(this.OverlayChartPaint)) return;
  8020. var aryRecvOverlayData=data.overlay;
  8021. for(var i=0;i<this.OverlayChartPaint.length; ++i)
  8022. {
  8023. var item=this.OverlayChartPaint[i];
  8024. if (!item.Symbol) continue;
  8025. var bUpdate=false;
  8026. if (item.MainData && item.Status==OVERLAY_STATUS_ID.STATUS_FINISHED_ID) //等待主图股票数据未下载完
  8027. {
  8028. bUpdate=this.MergeOverlaySymbolDayData(item, aryRecvOverlayData);
  8029. }
  8030. if (!bUpdate) //没有更新数据 手动跟主图数据对齐
  8031. {
  8032. if (item.Data && IFrameSplitOperator.IsNonEmptyArray(item.Data.Data))
  8033. {
  8034. var bindData=item.Data;
  8035. var aryOverlayData=this.SourceData.GetOverlayData(bindData.Data, this.IsApiPeriod); //和主图数据拟合以后的数据
  8036. bindData.Data=aryOverlayData;
  8037. }
  8038. }
  8039. }
  8040. }
  8041. this.SetCustomVerical = function (windowId, data)
  8042. {
  8043. if (!this.Frame) return;
  8044. if (windowId >= this.Frame.SubFrame.length) return;
  8045. var item = this.Frame.SubFrame[windowId];
  8046. if (item.Frame) item.Frame.CustomVerticalInfo = data;
  8047. }
  8048. this.OnSize=function()
  8049. {
  8050. if (!this.Frame) return;
  8051. if (!this.Frame.OnSize) return;
  8052. var obj=this.Frame.OnSize();
  8053. this.Frame.SetSizeChange(true);
  8054. if (obj.Changed)
  8055. {
  8056. this.UpdataDataoffset();
  8057. this.UpdatePointByCursorIndex();
  8058. this.UpdateFrameMaxMin();
  8059. }
  8060. this.Draw();
  8061. }
  8062. this.AddOverlayIndex=function(obj)
  8063. {
  8064. var overlay=this.CreateOverlayWindowsIndex(obj);
  8065. if (!overlay) return;
  8066. var bindData=this.ChartPaint[0].Data;
  8067. this.BindOverlayIndexData(overlay,obj.WindowIndex,bindData);
  8068. this.UpdataDataoffset(); //更新数据偏移
  8069. this.UpdateFrameMaxMin(); //调整坐标最大 最小值
  8070. this.Draw();
  8071. }
  8072. //创建一个叠加指标
  8073. this.CreateOverlayWindowsIndex=function(obj) // {WindowIndex:, IndexName:, Identify:, ShowRightText:, API:}
  8074. {
  8075. let indexName=obj.IndexName;
  8076. let windowIndex=obj.WindowIndex;
  8077. var apiItem=null, indexInfo=null, indexCustom=null;
  8078. if (obj.API)
  8079. {
  8080. apiItem=obj.API;
  8081. }
  8082. else if (obj.Script) //动态执行脚本
  8083. {
  8084. indexInfo={ Script:obj.Script, ID:obj.indexName, Name:obj.indexName};
  8085. if (obj.Name) indexInfo.Name=obj.Name;
  8086. }
  8087. else
  8088. {
  8089. let scriptData = new JSCommonIndexScript.JSIndexScript();
  8090. indexInfo = scriptData.Get(indexName); //系统指标
  8091. if (!indexInfo)
  8092. {
  8093. indexCustom=JSIndexMap.Get(indexName); //定制指标
  8094. if (!indexCustom)
  8095. {
  8096. console.warn(`[KLineChartContainer::CreateOverlayIndex] can not find index[${indexName}]`);
  8097. return null;
  8098. }
  8099. }
  8100. }
  8101. var subFrame=this.Frame.SubFrame[windowIndex];
  8102. subFrame.Interval=this.OverlayIndexFrameWidth;
  8103. var overlayFrame=new OverlayIndexItem();
  8104. if (obj.Identify) overlayFrame.Identify=obj.Identify; //由外部指定id
  8105. var frame= this.CreateOverlayFrame();
  8106. frame.Canvas=this.Canvas;
  8107. frame.MainFrame=subFrame.Frame;
  8108. frame.ChartBorder=subFrame.Frame.ChartBorder;
  8109. if (IFrameSplitOperator.IsBool(obj.IsShareY)) frame.IsShareY=obj.IsShareY;
  8110. if (IFrameSplitOperator.IsBool(obj.IsCalculateYMaxMin)) frame.IsCalculateYMaxMin=obj.IsCalculateYMaxMin; //是否计算Y最大最小值
  8111. if (IFrameSplitOperator.IsNumber(obj.IsShowMainFrame)) frame.IsShowMainFrame=obj.IsShowMainFrame;
  8112. frame.YSplitOperator=new FrameSplitY();
  8113. frame.YSplitOperator.LanguageID=this.LanguageID;
  8114. frame.YSplitOperator.FrameSplitData=this.FrameSplitData.get('double');
  8115. frame.YSplitOperator.Frame=frame;
  8116. frame.YSplitOperator.ChartBorder=frame.ChartBorder;
  8117. frame.YSplitOperator.SplitCount=subFrame.Frame.YSplitOperator.SplitCount;
  8118. frame.YSplitOperator.GetEventCallback=(id)=> { return this.GetEventCallback(id); };
  8119. frame.YSplitOperator.OverlayIdentify=overlayFrame.Identify;
  8120. overlayFrame.Frame=frame;
  8121. if (apiItem)
  8122. {
  8123. var apiIndex=new APIScriptIndex(apiItem.Name,apiItem.Script,apiItem.Args,obj, true);
  8124. apiIndex.OverlayIndex={ IsOverlay:true, Identify:overlayFrame.Identify, WindowIndex:windowIndex, Frame:overlayFrame }; //叠加指标信息
  8125. overlayFrame.Script=apiIndex;
  8126. }
  8127. else if (indexInfo)
  8128. {
  8129. JSIndexScript.ModifyAttribute(indexInfo, obj);
  8130. var scriptIndex=new OverlayScriptIndex(indexInfo.Name,indexInfo.Script,indexInfo.Args,indexInfo); //脚本执行
  8131. scriptIndex.OverlayIndex={ IsOverlay:true, Identify:overlayFrame.Identify, WindowIndex:windowIndex, Frame:overlayFrame }; //叠加指标信息
  8132. overlayFrame.Script=scriptIndex;
  8133. }
  8134. else
  8135. {
  8136. var scriptIndex=indexCustom.Create();
  8137. scriptIndex.OverlayIndex={ IsOverlay:true, Identify:overlayFrame.Identify, WindowIndex:windowIndex, Frame:overlayFrame }; //叠加指标信息
  8138. scriptIndex.Create(this,windowIndex);
  8139. overlayFrame.Script=scriptIndex;
  8140. }
  8141. subFrame.OverlayIndex.push(overlayFrame);
  8142. return overlayFrame;
  8143. }
  8144. this.DeleteOverlayWindowsIndex=function(identify) //删除叠加指标
  8145. {
  8146. if (!this.DeleteOverlayIndex(identify, null)) return;
  8147. this.Frame.ResetXYSplit(true);
  8148. this.Draw();
  8149. }
  8150. this.ChangePriceGap=function(obj)
  8151. {
  8152. if (!obj) return;
  8153. var klineChart=this.ChartPaint[0];
  8154. if (!klineChart) return;
  8155. if (IFrameSplitOperator.IsNumber(obj.Count)) klineChart.PriceGap.Count=obj.Count;
  8156. if (IFrameSplitOperator.IsBool(obj.Enable)) klineChart.PriceGap.Enable=obj.Enable;
  8157. this.Draw();
  8158. }
  8159. this.GetKData=function()
  8160. {
  8161. if (!this.ChartPaint[0]) return null;
  8162. var data=this.ChartPaint[0].Data;
  8163. if (!data) return null;
  8164. return data;
  8165. }
  8166. this.ClickExtendChartButton=function(button, e)
  8167. {
  8168. var event=this.GetEventCallback(JSCHART_EVENT_ID.ON_CLICK_EXTENDCHART_BUTTON);
  8169. if (event && event.Callback)
  8170. {
  8171. var data={ Info:button, PreventDefault:false, e:e }; //PreventDefault 是否阻止内置的点击处理
  8172. event.Callback(event,data,this);
  8173. if (data.PreventDefault) return;
  8174. }
  8175. //筹码按钮
  8176. if (button.ID==JSCHART_BUTTON_ID.CHIP_DEFULT)
  8177. {
  8178. button.Chart.ShowType=0;
  8179. this.Draw();
  8180. }
  8181. else if (button.ID==JSCHART_BUTTON_ID.CHIP_LONG)
  8182. {
  8183. button.Chart.ShowType=1;
  8184. this.Draw();
  8185. }
  8186. else if (button.ID==JSCHART_BUTTON_ID.CHIP_RECENT)
  8187. {
  8188. button.Chart.ShowType=2;
  8189. this.Draw();
  8190. }
  8191. else if (button.ID==JSCHART_BUTTON_ID.CHIP_CLOSE)
  8192. {
  8193. if (this.DeleteStockChipChart) this.DeleteStockChipChart();
  8194. }
  8195. }
  8196. }
  8197. //API 返回数据 转化为array[]
  8198. KLineChartContainer.JsonDataToHistoryData = function (data)
  8199. {
  8200. var list = data.data;
  8201. var aryDayData = new Array();
  8202. if (!list) return aryDayData;
  8203. var upperSymbol = null;
  8204. if (data.symbol) upperSymbol = data.symbol.toUpperCase();
  8205. var isFutures = false; //是否是期货
  8206. isFutures = MARKET_SUFFIX_NAME.IsChinaFutures(upperSymbol);
  8207. var date = 0, yclose = 1, open = 2, high = 3, low = 4, close = 5, vol = 6, amount = 7, position = 8;
  8208. var fclose=9, yfclose=10; //结算价, 前结算价
  8209. var bfactor=11, afactor=12; //前, 后复权因子
  8210. var flowCapital=15; //流通股本
  8211. var colorData=JSCHART_DATA_FIELD_ID.KLINE_COLOR_DATA;
  8212. var extendDataIndex=JSCHART_DATA_FIELD_ID.KLINE_DAY_EXTENDDATA; //k线扩展数据
  8213. for (var i = 0; i < list.length; ++i)
  8214. {
  8215. var item = new HistoryData();
  8216. var jsData = list[i];
  8217. item.Date = jsData[date];
  8218. item.Open = jsData[open];
  8219. item.YClose = jsData[yclose];
  8220. item.Close = jsData[close];
  8221. item.High = jsData[high];
  8222. item.Low = jsData[low];
  8223. item.Vol = jsData[vol]; //原始单位股
  8224. item.Amount = jsData[amount];
  8225. //可选配置
  8226. if (IFrameSplitOperator.IsNumber(jsData[position])) item.Position = jsData[position];//期货持仓
  8227. if (IFrameSplitOperator.IsNumber(jsData[fclose])) item.FClose=jsData[fclose]; //期货结算价
  8228. if (IFrameSplitOperator.IsNumber(jsData[yfclose])) item.YFClose=jsData[yfclose]; //期货前结算价
  8229. if (IFrameSplitOperator.IsNumber(jsData[bfactor])) item.BFactor=jsData[bfactor]; //前复权因子
  8230. if (IFrameSplitOperator.IsNumber(jsData[afactor])) item.AFactor=jsData[afactor]; //后复权因子
  8231. if (IFrameSplitOperator.IsNumber(jsData[flowCapital])) item.FlowCapital=jsData[flowCapital]; //流通股本
  8232. if (!IFrameSplitOperator.IsNumber(item.Open)) continue;
  8233. if (jsData[colorData]) item.ColorData=jsData[colorData];
  8234. if (jsData[extendDataIndex]) item.ExtendData=jsData[extendDataIndex];
  8235. aryDayData.push(item);
  8236. }
  8237. return aryDayData;
  8238. }
  8239. KLineChartContainer.JsonDataToRealtimeData = function (data, symbol)
  8240. {
  8241. if (!data) return null;
  8242. if (!IFrameSplitOperator.IsNonEmptyArray(data.stock)) return null;
  8243. var stock=null;
  8244. for(var i=0;i<data.stock.length;++i)
  8245. {
  8246. var item=data.stock[i];
  8247. if (item && item.symbol==symbol)
  8248. {
  8249. stock=item;
  8250. break;
  8251. }
  8252. }
  8253. if (!stock) return null;
  8254. var upperSymbol = symbol.toUpperCase();
  8255. var isSHSZ = MARKET_SUFFIX_NAME.IsSHSZ(upperSymbol);
  8256. var item = new HistoryData();
  8257. item.Date = stock.date;
  8258. item.Open = stock.open;
  8259. item.YClose = stock.yclose;
  8260. item.High = stock.high;
  8261. item.Low = stock.low;
  8262. item.Vol=stock.vol; //单位股
  8263. item.Amount = stock.amount;
  8264. item.Close = stock.price;
  8265. if (IFrameSplitOperator.IsNumber(stock.position)) item.Position = stock.position; //持仓量
  8266. if (IFrameSplitOperator.IsNumber(stock.bfactor)) item.BFactor=stock.bfactor; //前复权因子
  8267. if (IFrameSplitOperator.IsNumber(stock.afactor)) item.AFactor=stock.afactor; //后复权因子
  8268. if (IFrameSplitOperator.IsNumber(stock.flowCapital)) item.FlowCapital=stock.flowCapital; //流通股本
  8269. if (stock.colordata) item.ColorData=stock.colordata; //自定义颜色
  8270. if (stock.extendData) item.ExtendData=stock.extendData;
  8271. return item;
  8272. }
  8273. //分钟K线叠加数据增量更新v2版本
  8274. KLineChartContainer.JsonDataToMinuteRealtimeDataV2=function(data,symbol)
  8275. {
  8276. if (!data || !data.overlay || !symbol) return null;
  8277. var overlayData=null;
  8278. for(var i=0;i<data.overlay.length;++i) //overlay={ symbol:, name:, data:[] }
  8279. {
  8280. var item=data.overlay[i];
  8281. if (item.symbol==symbol)
  8282. {
  8283. overlayData=item;
  8284. break;
  8285. }
  8286. }
  8287. if (!overlayData) return null;
  8288. var upperSymbol=symbol.toUpperCase();
  8289. var isSHSZ=MARKET_SUFFIX_NAME.IsSHSZ(upperSymbol);
  8290. var isFutures=MARKET_SUFFIX_NAME.IsFutures(upperSymbol); //是否是期货
  8291. var date = 0, yclose = 1, open = 2, high = 3, low = 4, close = 5, vol = 6, amount = 7, time = 8, position=9;
  8292. var orderFlow=JSCHART_DATA_FIELD_ID.KLINE_ORDERFLOW;
  8293. var yClose=null;
  8294. var aryMinuteData=[];
  8295. for (var i = 0; i < overlayData.data.length; ++i)
  8296. {
  8297. var item = new HistoryData();
  8298. var jsData=overlayData.data[i];
  8299. item.Date = jsData[date];
  8300. item.Open = jsData[open];
  8301. item.YClose = jsData[yclose];
  8302. item.Close = jsData[close];
  8303. item.High = jsData[high];
  8304. item.Low = jsData[low];
  8305. item.Vol = jsData[vol]; //股
  8306. item.Amount = jsData[amount];
  8307. item.Time=jsData[time];
  8308. if (IFrameSplitOperator.IsNumber(jsData[position])) item.Position=jsData[position]; //期货持仓
  8309. if (!IFrameSplitOperator.IsNumber(item.YClose))
  8310. {
  8311. if (IFrameSplitOperator.IsNumber(yClose)) item.YClose=yClose;
  8312. }
  8313. if (IFrameSplitOperator.IsNumber(item.Close)) yClose=item.Close;
  8314. if (jsData[orderFlow]) item.OrderFlow=jsData[orderFlow];
  8315. aryMinuteData.push(item);
  8316. }
  8317. return aryMinuteData;
  8318. }
  8319. KLineChartContainer.JsonDataToMinuteRealtimeData = function (data)
  8320. {
  8321. var symbol = data.stock[0].symbol;
  8322. var upperSymbol = symbol.toUpperCase();
  8323. var isSHSZ = MARKET_SUFFIX_NAME.IsSHSZ(upperSymbol);
  8324. var isFutures = MARKET_SUFFIX_NAME.IsChinaFutures(upperSymbol);
  8325. var aryMinuteData = new Array();
  8326. var preClose = data.stock[0].yclose; //前一个数据价格
  8327. var date = data.stock[0].date;
  8328. if (isFutures && data.stock[0].yclearing) preClose = data.stock[0].yclearing; //期货使用昨结算价
  8329. for (var i=0; i<data.stock[0].minute.length; ++i)
  8330. {
  8331. var jsData = data.stock[0].minute[i];
  8332. var item = new HistoryData();
  8333. item.Close = jsData.price;
  8334. item.Open = jsData.open;
  8335. item.High = jsData.high;
  8336. item.Low = jsData.low;
  8337. item.Vol = jsData.vol; //单位股
  8338. item.Amount = jsData.amount;
  8339. if (jsData.date > 0) item.Date = jsData.date;
  8340. else item.Date = date;
  8341. item.Time = jsData.time;
  8342. item.YClose = preClose;
  8343. if (IFrameSplitOperator.IsNumber(jsData.position)) item.Position = jsData.position; //持仓量
  8344. if (!IFrameSplitOperator.IsNumber(item.Close)) //当前没有价格 使用上一个价格填充
  8345. {
  8346. item.Close = preClose;
  8347. item.Open = item.High = item.Low = item.Close;
  8348. }
  8349. //价格是0的 都用空
  8350. if (!IFrameSplitOperator.IsNumber(item.Open)) item.Open = null;
  8351. if (!IFrameSplitOperator.IsNumber(item.Close)) item.Close = null;
  8352. if (!IFrameSplitOperator.IsNumber(item.High)) item.High = null;
  8353. if (!IFrameSplitOperator.IsNumber(item.Low)) item.Low = null;
  8354. //上次价格
  8355. if (IFrameSplitOperator.IsNumber(jsData.price)) preClose = jsData.price;
  8356. aryMinuteData[i] = item;
  8357. }
  8358. return aryMinuteData;
  8359. }
  8360. //API 返回数据 转化为array[]
  8361. KLineChartContainer.JsonDataToMinuteHistoryData = function (data)
  8362. {
  8363. var upperSymbol = null;
  8364. if (data.symbol) upperSymbol = data.symbol.toUpperCase();
  8365. var isSHSZ = false;
  8366. if (upperSymbol) isSHSZ = MARKET_SUFFIX_NAME.IsSHSZ(upperSymbol);
  8367. var isFutures = false; //是否是期货
  8368. if (upperSymbol) isFutures = MARKET_SUFFIX_NAME.IsChinaFutures(upperSymbol);
  8369. var list = data.data;
  8370. var aryDayData = new Array();
  8371. var date = 0, yclose = 1, open = 2, high = 3, low = 4, close = 5, vol = 6, amount = 7, time = 8, position = 9;
  8372. var fclose=10, yfclose=11; //结算价, 前结算价
  8373. var bfactor=12, afactor=13; //前, 后复权因子
  8374. var colorData=JSCHART_DATA_FIELD_ID.KLINE_COLOR_DATA;
  8375. var extendDataIndex=JSCHART_DATA_FIELD_ID.KLINE_MINUTE_EXTENDDATA; //k线扩展数据
  8376. for (var i = 0; i < list.length; ++i)
  8377. {
  8378. var item = new HistoryData();
  8379. var jsData=list[i];
  8380. item.Date = jsData[date];
  8381. item.Open = jsData[open];
  8382. item.YClose = jsData[yclose];
  8383. item.Close = jsData[close];
  8384. item.High = jsData[high];
  8385. item.Low = jsData[low];
  8386. item.Vol = jsData[vol]; //原始单位股
  8387. item.Amount = jsData[amount];
  8388. item.Time = jsData[time];
  8389. if (IFrameSplitOperator.IsNumber(jsData[position])) item.Position = jsData[position]; //期货持仓
  8390. if (IFrameSplitOperator.IsNumber(jsData[fclose])) item.FClose=jsData[fclose]; //期货结算价
  8391. if (IFrameSplitOperator.IsNumber(jsData[yfclose])) item.YFClose=jsData[yfclose]; //期货前结算价
  8392. if (IFrameSplitOperator.IsNumber(jsData[bfactor])) item.BFactor=jsData[bfactor]; //前复权因子
  8393. if (IFrameSplitOperator.IsNumber(jsData[afactor])) item.AFactor=jsData[afactor]; //后复权因子
  8394. if (jsData[colorData]) item.ColorData=jsData[colorData];
  8395. if (jsData[extendDataIndex]) item.ExtendData=jsData[extendDataIndex];
  8396. aryDayData.push(item);
  8397. }
  8398. return aryDayData;
  8399. }
  8400. ///////////////////////////////////////////////////////////////////////////////////////////
  8401. // 走势图
  8402. //
  8403. function MinuteChartContainer(uielement)
  8404. {
  8405. this.newMethod = JSChartContainer; //派生
  8406. this.newMethod(uielement);
  8407. delete this.newMethod;
  8408. this.ClassName = 'MinuteChartContainer';
  8409. this.WindowIndex = new Array();
  8410. this.Symbol;
  8411. this.Name;
  8412. this.SourceData; //原始的历史数据
  8413. this.OverlaySourceData; //叠加的原始数据
  8414. this.IsAutoUpdate = false; //是否自动更新行情数据
  8415. this.AutoUpdateFrequency = 30000; //30秒更新一次数据
  8416. this.AutoUpdateTimer=null; //更新定时器
  8417. this.TradeDate = 0; //行情交易日期
  8418. this.LoadDataSplashTitle = '下载分钟数据';
  8419. this.UpdateUICallback; //数据到达回调
  8420. this.DayCount = 1; //显示几天的数据
  8421. this.DayData; //多日分钟数据
  8422. this.ZoomStepPixel = 50; //放大缩小手势需要的最小像素
  8423. this.MinuteApiUrl = g_JSChartResource.Domain + "/API/Stock";
  8424. this.HistoryMinuteApiUrl = g_JSChartResource.Domain + "/API/StockMinuteData"; //历史分钟数据
  8425. this.DataStatus={ MultiDay:false, LatestDay:false }; //MultiDay=多日 LatestDay:当天
  8426. this.EnableNightDayBG=false; //是否启动夜盘背景色
  8427. //手机拖拽
  8428. this.ontouchstart = function (e)
  8429. {
  8430. if (this.ChartSplashPaint && this.ChartSplashPaint.IsEnableSplash == true) return;
  8431. this.IsPress=false;
  8432. this.IsOnTouch = true;
  8433. this.TouchDrawCount=0;
  8434. if (this.ClickModel) this.ClickModel.PreventHide=false;
  8435. var jsChart = this;
  8436. if (jsChart.DragMode == 0) return;
  8437. if (this.IsPhoneDragging(e))
  8438. {
  8439. if (this.TryClickLock || this.TryClickIndexTitle)
  8440. {
  8441. var touches = this.GetToucheData(e, this.IsForceLandscape);
  8442. var x = touches[0].clientX;
  8443. var y = touches[0].clientY;
  8444. if (this.TryClickLock && this.TryClickLock(x, y)) return;
  8445. if (this.TryClickIndexTitle && this.TryClickIndexTitle(x, y)) return;
  8446. }
  8447. //长按2秒,十字光标
  8448. this.ClearTouchTimer();
  8449. var drag =
  8450. {
  8451. "Click": {},
  8452. "LastMove": {}, //最后移动的位置
  8453. };
  8454. var touches = this.GetToucheData(e, jsChart.IsForceLandscape);
  8455. drag.Click.X = touches[0].clientX;
  8456. drag.Click.Y = touches[0].clientY;
  8457. drag.LastMove.X = touches[0].clientX;
  8458. drag.LastMove.Y = touches[0].clientY;
  8459. this.MouseDrag=drag;
  8460. this.PhoneTouchInfo={ Start:{X:touches[0].clientX, Y:touches[0].clientY }, End:{ X:touches[0].clientX, Y:touches[0].clientY } };
  8461. if (this.SelectChartDrawPicture) this.SelectChartDrawPicture.IsSelected=false;
  8462. this.SelectChartDrawPicture=null;
  8463. if (this.CurrentChartDrawPicture) //画图工具模式
  8464. {
  8465. var drawPicture=this.CurrentChartDrawPicture;
  8466. if (drawPicture.Status==2)
  8467. {
  8468. this.SetChartDrawPictureThirdPoint(drag.Click.X,drag.Click.Y,true);
  8469. }
  8470. else
  8471. {
  8472. this.SetChartDrawPictureFirstPoint(drag.Click.X,drag.Click.Y,true);
  8473. //只有1个点 直接完成
  8474. if (this.FinishChartDrawPicturePoint()) this.DrawDynamicInfo({Corss:false, Tooltip:false});
  8475. }
  8476. return;
  8477. }
  8478. else
  8479. {
  8480. var pt=this.PointAbsoluteToRelative(touches[0].clientX,touches[0].clientY, true);
  8481. var drawPictrueData={ X:pt.X, Y:pt.Y, PixelRatio:this.UIElement.PixelRatio };
  8482. if (this.GetChartDrawPictureByPoint(drawPictrueData))
  8483. {
  8484. if (drawPictrueData.ChartDrawPicture.EnableMove===true)
  8485. drawPictrueData.ChartDrawPicture.Status=20;
  8486. drawPictrueData.ChartDrawPicture.ValueToPoint();
  8487. drawPictrueData.ChartDrawPicture.MovePointIndex=drawPictrueData.PointIndex;
  8488. drawPictrueData.ChartDrawPicture.IsSelected=true;
  8489. this.CurrentChartDrawPicture=drawPictrueData.ChartDrawPicture;
  8490. this.SelectChartDrawPicture=drawPictrueData.ChartDrawPicture;
  8491. let event=this.GetEventCallback(JSCHART_EVENT_ID.ON_CLICK_DRAWPICTURE); //选中画图工具事件
  8492. if (event && event.Callback)
  8493. {
  8494. let sendData={ DrawPicture: drawPictrueData.ChartDrawPicture };
  8495. event.Callback(event,sendData,this);
  8496. }
  8497. this.DrawDynamicInfo();
  8498. return;
  8499. }
  8500. }
  8501. var T_ShowCorssCursor=()=>
  8502. {
  8503. if (this.ChartCorssCursor.IsShow === true) //移动十字光标
  8504. {
  8505. var x = drag.Click.X;
  8506. var y = drag.Click.Y;
  8507. if (jsChart.IsForceLandscape) y = jsChart.UIElement.Height - drag.Click.Y; //强制横屏Y计算
  8508. jsChart.OnMouseMove(x, y, e);
  8509. }
  8510. }
  8511. if (this.EnableZoomIndexWindow)
  8512. {
  8513. this.PhoneDBClick.AddTouchStart(touches[0].clientX, touches[0].clientY, Date.now());
  8514. JSConsole.Chart.Log("[MinuteChartContainer::OnTouchStart] PhoneDBClick ", this.PhoneDBClick);
  8515. }
  8516. if (this.EnableScrollUpDown==true)
  8517. {
  8518. this.TouchTimer=setTimeout(()=>
  8519. {
  8520. this.MouseDrag=null;
  8521. this.IsPress=true;
  8522. T_ShowCorssCursor();
  8523. }, this.PressTime);
  8524. }
  8525. var bStartTimer=true; //长按计时开始
  8526. if (this.EnableClickModel)
  8527. {
  8528. if (this.ClickModel.IsShowCorssCursor==true) bStartTimer=false;
  8529. else bStartTimer= true;
  8530. }
  8531. if (bStartTimer)
  8532. {
  8533. this.ClearTouchTimer();
  8534. this.TouchTimer = setTimeout(()=>{
  8535. jsChart.IsPress=true;
  8536. if (drag.Click.X == drag.LastMove.X && drag.Click.Y == drag.LastMove.Y) //手指没有移动,出现十字光标
  8537. {
  8538. jsChart.MouseDrag = null;
  8539. //移动十字光标
  8540. var x = drag.Click.X;
  8541. var y = drag.Click.Y;
  8542. if (jsChart.EnableClickModel===true) jsChart.ClickModel.IsShowCorssCursor=true;
  8543. jsChart.OnMouseMove(x, y, e);
  8544. }
  8545. }, jsChart.PressTime);
  8546. }
  8547. else if (!this.EnableClickModel)
  8548. {
  8549. if (this.EnableScrollUpDown==false)
  8550. T_ShowCorssCursor();
  8551. else if (this.IsClickShowCorssCursor)
  8552. T_ShowCorssCursor();
  8553. }
  8554. this.TouchEvent({ EventID:JSCHART_EVENT_ID.ON_PHONE_TOUCH, FunctionName:"OnTouchStart"}, e);
  8555. }
  8556. else if (this.IsPhonePinching(e))
  8557. {
  8558. var phonePinch = { "Start": {}, "Last": {} };
  8559. var touches = this.GetToucheData(e, jsChart.IsForceLandscape);
  8560. phonePinch.Start = { "X": touches[0].pageX, "Y": touches[0].pageY, "X2": touches[1].pageX, "Y2": touches[1].pageY };
  8561. phonePinch.Last = { "X": touches[0].pageX, "Y": touches[0].pageY, "X2": touches[1].pageX, "Y2": touches[1].pageY };
  8562. jsChart.PhonePinch = phonePinch;
  8563. }
  8564. }
  8565. this.ontouchmove = function (e)
  8566. {
  8567. if (this.ChartSplashPaint && this.ChartSplashPaint.IsEnableSplash == true) return;
  8568. var jsChart = this;
  8569. var drag = jsChart.MouseDrag;
  8570. var touches = this.GetToucheData(e, jsChart.IsForceLandscape);
  8571. if (this.IsPhoneDragging(e))
  8572. {
  8573. if (drag == null)
  8574. {
  8575. var x = touches[0].clientX;
  8576. var y = touches[0].clientY;
  8577. this.LastMovePoint={ X:x, Y:y };
  8578. if (this.DrawMoveTimer) return;
  8579. this.DrawMoveTimer=setTimeout(()=>
  8580. {
  8581. if (!this.LastMovePoint) return;
  8582. this.OnMouseMove(this.LastMovePoint.X, this.LastMovePoint.Y, e);
  8583. this.DrawMoveTimer=null;
  8584. }, this.DrawMoveWaitTime);
  8585. }
  8586. else
  8587. {
  8588. var moveAngle=this.GetMoveAngle(drag.LastMove,{X:touches[0].clientX, Y:touches[0].clientY});
  8589. var moveSetp=Math.abs(drag.LastMove.X-touches[0].clientX);
  8590. var moveUpDown=Math.abs(drag.LastMove.Y-touches[0].clientY);
  8591. moveSetp=parseInt(moveSetp);
  8592. if (this.CurrentChartDrawPicture && this.CurrentChartDrawPicture.EnableMove===true)
  8593. {
  8594. var drawPicture=this.CurrentChartDrawPicture;
  8595. if (drawPicture.Status==1 || drawPicture.Status==2)
  8596. {
  8597. if(moveSetp<5 && moveUpDown<5) return;
  8598. if(this.SetChartDrawPictureSecondPoint(touches[0].clientX,touches[0].clientY,true))
  8599. {
  8600. this.DrawDynamicInfo();
  8601. }
  8602. }
  8603. else if (drawPicture.Status==3)
  8604. {
  8605. if(this.SetChartDrawPictureThirdPoint(touches[0].clientX,touches[0].clientY,true))
  8606. {
  8607. this.DrawDynamicInfo();
  8608. }
  8609. }
  8610. else if (drawPicture.Status==20) //画图工具移动
  8611. {
  8612. if(moveSetp<5 && moveUpDown<5) return;
  8613. if(this.MoveChartDrawPicture(touches[0].clientX-drag.LastMove.X,touches[0].clientY-drag.LastMove.Y,true))
  8614. {
  8615. this.DrawDynamicInfo();
  8616. }
  8617. }
  8618. drag.LastMove.X=touches[0].clientX;
  8619. drag.LastMove.Y=touches[0].clientY;
  8620. }
  8621. else
  8622. {
  8623. if ( ((moveUpDown>0 && moveSetp<=3) || moveAngle<=this.TouchMoveMinAngle) && this.EnableScrollUpDown==true )
  8624. { //上下滚动
  8625. var event=this.GetEventCallback(JSCHART_EVENT_ID.ON_TOUCH_SCROLL_UP_DOWN);
  8626. var isEnd=true; //是否退出
  8627. if (event && event.Callback)
  8628. {
  8629. var sendData={ DragData:drag, PreventDefault:false };
  8630. event.Callback(event, sendData, this);
  8631. isEnd=(sendData.PreventDefault===false);
  8632. }
  8633. if (isEnd)
  8634. {
  8635. this.ClearTouchTimer();
  8636. return;
  8637. }
  8638. }
  8639. if (drag!=null)
  8640. {
  8641. this.ClearTouchTimer();
  8642. this.MouseDrag=null;
  8643. var x = touches[0].clientX;
  8644. var y = touches[0].clientY;
  8645. this.OnMouseMove(x,y,e);
  8646. }
  8647. }
  8648. }
  8649. }
  8650. else if (this.IsPhonePinching(e))
  8651. {
  8652. var phonePinch = jsChart.PhonePinch;
  8653. if (!phonePinch) return;
  8654. if (this.EnableZoomUpDown && this.EnableZoomUpDown.Touch===false) return;
  8655. var yHeight = Math.abs(touches[0].pageY - touches[1].pageY);
  8656. var yLastHeight = Math.abs(phonePinch.Last.Y - phonePinch.Last.Y2);
  8657. var yStep = yHeight - yLastHeight;
  8658. var xHeight = Math.abs(touches[0].pageX - touches[1].pageX);
  8659. var xLastHeight = Math.abs(phonePinch.Last.X - phonePinch.Last.X2);
  8660. var xStep = xHeight - xLastHeight;
  8661. var minStep=this.ZoomStepPixel;
  8662. if (Math.abs(yStep) < minStep && Math.abs(xStep) < minStep) return;
  8663. if (Math.abs(xStep) > minStep)
  8664. {
  8665. var event=this.GetEventCallback(JSCHART_EVENT_ID.ON_MINUTE_TOUCH_ZOOM)
  8666. if (event && event.Callback)
  8667. {
  8668. var data={ XStep:xStep, YStep:yStep, PreventDefault:false };
  8669. event.Callback(event,data,this);
  8670. if (data.PreventDefault)
  8671. {
  8672. this.PhonePinch=null;
  8673. this.ClearTouchTimer();
  8674. return;
  8675. }
  8676. }
  8677. }
  8678. phonePinch.Last = { "X": touches[0].pageX, "Y": touches[0].pageY, "X2": touches[1].pageX, "Y2": touches[1].pageY };
  8679. }
  8680. if (this.PhoneTouchInfo)
  8681. {
  8682. this.PhoneTouchInfo.End.X=touches[0].clientX;
  8683. this.PhoneTouchInfo.End.Y=touches[0].clientY;
  8684. }
  8685. }
  8686. //创建
  8687. //windowCount 窗口个数
  8688. this.Create = function (windowCount)
  8689. {
  8690. this.UIElement.JSChartContainer = this;
  8691. //创建十字光标
  8692. this.ChartCorssCursor = new ChartCorssCursor();
  8693. this.ChartCorssCursor.Canvas = this.Canvas;
  8694. this.ChartCorssCursor.StringFormatX = new HQMinuteTimeStringFormat();
  8695. this.ChartCorssCursor.StringFormatX.GetEventCallback=(id)=> { return this.GetEventCallback(id); }
  8696. this.ChartCorssCursor.StringFormatY = g_DivTooltipDataForamt.Create("CorssCursor_YStringFormat");
  8697. this.ChartCorssCursor.StringFormatY.GetEventCallback=(id)=> { return this.GetEventCallback(id); }
  8698. this.ChartCorssCursor.StringFormatY.LanguageID = this.LanguageID;
  8699. this.ChartCorssCursor.StringFormatY.HQChart=this;
  8700. this.ChartCorssCursor.GetEventCallback=(id)=> { return this.GetEventCallback(id); }
  8701. this.ChartCorssCursor.HQChart=this;
  8702. //创建等待提示
  8703. this.ChartSplashPaint = new ChartSplashPaint();
  8704. this.ChartSplashPaint.Canvas = this.Canvas;
  8705. this.ChartSplashPaint.SplashTitle = this.LoadDataSplashTitle;
  8706. this.ChartSplashPaint.HQChart=this;
  8707. //创建框架容器
  8708. this.Frame = new HQTradeFrame();
  8709. this.Frame.ChartBorder = new ChartBorder();
  8710. this.Frame.ChartBorder.UIElement = this.UIElement;
  8711. this.Frame.ChartBorder.Top = 25;
  8712. this.Frame.ChartBorder.Left = 50;
  8713. this.Frame.ChartBorder.Bottom = 20;
  8714. this.Frame.Canvas = this.Canvas;
  8715. this.Frame.GetEventCallback=(id)=> { return this.GetEventCallback(id); }
  8716. this.Frame.ZoomStartWindowIndex=2;
  8717. this.ChartCorssCursor.Frame = this.Frame; //十字光标绑定框架
  8718. this.ChartSplashPaint.Frame = this.Frame;
  8719. this.CreateChildWindow(windowCount);
  8720. this.CreateMainKLine();
  8721. //子窗口动态标题
  8722. for (var i=0; i<this.Frame.SubFrame.length; ++i)
  8723. {
  8724. var titlePaint = new DynamicChartTitlePainting();
  8725. if (i==0 || i==1) titlePaint.IsShowMainIndexTitle=false;
  8726. titlePaint.Frame = this.Frame.SubFrame[i].Frame;
  8727. titlePaint.Canvas = this.Canvas;
  8728. titlePaint.LanguageID = this.LanguageID;
  8729. titlePaint.GetEventCallback=(id)=> { return this.GetEventCallback(id); }
  8730. this.TitlePaint.push(titlePaint);
  8731. }
  8732. this.ChartCorssCursor.StringFormatX.Frame = this.Frame.SubFrame[0].Frame;
  8733. this.ChartCorssCursor.StringFormatY.Frame=this.Frame;
  8734. }
  8735. //创建子窗口
  8736. this.CreateChildWindow = function (windowCount)
  8737. {
  8738. var event=this.GetEventCallback(JSCHART_EVENT_ID.ON_CREATE_FRAME);
  8739. for (var i = 0; i < windowCount; ++i)
  8740. {
  8741. var border = new ChartBorder();
  8742. border.UIElement = this.UIElement;
  8743. var frame = new MinuteFrame();
  8744. frame.Canvas = this.Canvas;
  8745. frame.ChartBorder = border;
  8746. frame.Identify=i;
  8747. if (i < 2) frame.ChartBorder.TitleHeight = 0;
  8748. frame.XPointCount = 243;
  8749. frame.GetEventCallback=(id)=> { return this.GetEventCallback(id); }
  8750. frame.GlobalOption=this.GlobalOption;
  8751. frame.HQChart=this;
  8752. frame.CreateLockPaint();
  8753. var DEFAULT_HORIZONTAL = [9, 8, 7, 6, 5, 4, 3, 2, 1];
  8754. frame.HorizontalMax = DEFAULT_HORIZONTAL[0];
  8755. frame.HorizontalMin = DEFAULT_HORIZONTAL[DEFAULT_HORIZONTAL.length - 1];
  8756. if (i == 0)
  8757. {
  8758. frame.YSplitOperator = new FrameSplitMinutePriceY();
  8759. frame.YSplitOperator.FrameSplitData = this.FrameSplitData.get('price');
  8760. frame.YSplitOperator.HQChart=this;
  8761. }
  8762. else
  8763. {
  8764. frame.YSplitOperator = new FrameSplitY();
  8765. frame.YSplitOperator.FrameSplitData = this.FrameSplitData.get('double');
  8766. frame.YSplitOperator.LanguageID = this.LanguageID;
  8767. }
  8768. frame.YSplitOperator.GetEventCallback=(id)=> { return this.GetEventCallback(id); }
  8769. frame.YSplitOperator.Frame = frame;
  8770. frame.YSplitOperator.ChartBorder = border;
  8771. frame.XSplitOperator = new FrameSplitMinuteX();
  8772. frame.XSplitOperator.Frame = frame;
  8773. frame.XSplitOperator.ChartBorder = border;
  8774. frame.XSplitOperator.GetEventCallback=(id)=> { return this.GetEventCallback(id); }
  8775. if (i != windowCount - 1) frame.XSplitOperator.ShowText = false;
  8776. frame.XSplitOperator.Operator();
  8777. for (var j in DEFAULT_HORIZONTAL)
  8778. {
  8779. frame.HorizontalInfo[j] = new CoordinateInfo();
  8780. frame.HorizontalInfo[j].Value = DEFAULT_HORIZONTAL[j];
  8781. if (i == 0 && j == frame.HorizontalMin) continue;
  8782. frame.HorizontalInfo[j].Message[1] = DEFAULT_HORIZONTAL[j].toString();
  8783. frame.HorizontalInfo[j].Font = "14px 微软雅黑";
  8784. }
  8785. var subFrame = new SubFrameItem();
  8786. frame.FrameData.SubFrameItem=subFrame;
  8787. subFrame.Frame = frame;
  8788. if (i == 0) subFrame.Height = 20;
  8789. else subFrame.Height = 10;
  8790. this.Frame.SubFrame[i] = subFrame;
  8791. if (event && event.Callback)
  8792. {
  8793. var sendData={ SubFrame:this.Frame.SubFrame[i], WindowIndex:i };
  8794. event.Callback(event, sendData, this);
  8795. }
  8796. }
  8797. }
  8798. this.CreateSubFrameItem=function(id)
  8799. {
  8800. var border=new ChartBorder();
  8801. border.UIElement=this.UIElement;
  8802. var frame=new MinuteFrame();
  8803. frame.Canvas=this.Canvas;
  8804. frame.ChartBorder=border;
  8805. frame.Identify=id; //窗口序号
  8806. frame.XPointCount=243;
  8807. frame.GetEventCallback=(id)=> { return this.GetEventCallback(id); };
  8808. frame.GlobalOption=this.GlobalOption;
  8809. frame.HQChart=this;
  8810. frame.CreateLockPaint();
  8811. var DEFAULT_HORIZONTAL=[9,8,7,6,5,4,3,2,1];
  8812. frame.HorizontalMax=DEFAULT_HORIZONTAL[0];
  8813. frame.HorizontalMin=DEFAULT_HORIZONTAL[DEFAULT_HORIZONTAL.length-1];
  8814. frame.YSplitOperator=new FrameSplitY();
  8815. frame.YSplitOperator.LanguageID=this.LanguageID;
  8816. frame.YSplitOperator.FrameSplitData=this.FrameSplitData.get('double');
  8817. frame.YSplitOperator.Frame=frame;
  8818. frame.YSplitOperator.ChartBorder=border;
  8819. frame.XSplitOperator=new FrameSplitMinuteX();
  8820. frame.XSplitOperator.Frame=frame;
  8821. frame.XSplitOperator.ChartBorder=border;
  8822. frame.XSplitOperator.ShowText=false;
  8823. frame.XSplitOperator.GetEventCallback=(id)=> { return this.GetEventCallback(id); }
  8824. frame.YSplitOperator.GetEventCallback=(id)=> { return this.GetEventCallback(id); }
  8825. //K线数据绑定
  8826. var xPointCouont=this.Frame.SubFrame[0].Frame.XPointCount;
  8827. frame.XPointCount=xPointCouont;
  8828. frame.Data=this.ChartPaint[0].Data;
  8829. for(var j in DEFAULT_HORIZONTAL)
  8830. {
  8831. frame.HorizontalInfo[j]= new CoordinateInfo();
  8832. frame.HorizontalInfo[j].Value=DEFAULT_HORIZONTAL[j];
  8833. frame.HorizontalInfo[j].Message[1]=DEFAULT_HORIZONTAL[j].toString();
  8834. frame.HorizontalInfo[j].Font="14px 微软雅黑";
  8835. }
  8836. var subFrame=new SubFrameItem();
  8837. subFrame.Frame=frame;
  8838. subFrame.Height=10;
  8839. var event=this.GetEventCallback(JSCHART_EVENT_ID.ON_CREATE_FRAME);
  8840. if (event && event.Callback)
  8841. {
  8842. var sendData={ SubFrame:subFrame, WindowIndex:id };
  8843. event.Callback(event, sendData, this);
  8844. }
  8845. return subFrame;
  8846. }
  8847. this.UpdateXShowText=function()
  8848. {
  8849. var bLastFrame=true;
  8850. for(var i=this.Frame.SubFrame.length-1;i>=0;--i)
  8851. {
  8852. var item=this.Frame.SubFrame[i].Frame;
  8853. var subFrame=this.Frame.SubFrame[i];
  8854. if (bLastFrame)
  8855. {
  8856. item.XSplitOperator.ShowText=true;
  8857. if (subFrame.Height>0) bLastFrame=false;
  8858. }
  8859. else
  8860. {
  8861. item.XSplitOperator.ShowText=false;
  8862. }
  8863. }
  8864. }
  8865. //删除某一个窗口的指标 bCallDestory=是否调用图形销毁函数
  8866. this.DeleteIndexPaint = function (windowIndex, bCallDestroy)
  8867. {
  8868. if (!this.Frame.SubFrame[windowIndex]) return;
  8869. var subFrame=this.Frame.SubFrame[windowIndex].Frame;
  8870. if (!subFrame) return;
  8871. var paint=[];
  8872. for (var i=0;i<this.ChartPaint.length;++i) //踢出当前窗口的指标画法
  8873. {
  8874. let item = this.ChartPaint[i];
  8875. var bFind=(item.ChartFrame.Guid==subFrame.Guid || item.ChartFrame==subFrame);
  8876. if (i == 0 || !bFind)
  8877. {
  8878. paint.push(item);
  8879. }
  8880. else
  8881. {
  8882. if (bCallDestroy===true)
  8883. {
  8884. if (item && item.OnDestroy) item.OnDestroy(); //图形销毁
  8885. }
  8886. }
  8887. }
  8888. //清空指定最大最小值
  8889. subFrame.YSpecificMaxMin = null;
  8890. subFrame.IsLocked = false; //解除上锁
  8891. subFrame.YSplitOperator.SplitType=subFrame.YSplitOperator.DefaultSplitType; //还原Y坐标分割模式
  8892. this.ChartPaint = paint;
  8893. //清空东条标题
  8894. var titleIndex = windowIndex + 1;
  8895. this.TitlePaint[titleIndex].Data = [];
  8896. this.TitlePaint[titleIndex].Title = null;
  8897. }
  8898. this.CreateStockInfo = function () {
  8899. this.ExtendChartPaint[0] = new StockInfoExtendChartPaint();
  8900. this.ExtendChartPaint[0].Canvas = this.Canvas;
  8901. this.ExtendChartPaint[0].ChartBorder = this.Frame.ChartBorder;
  8902. this.ExtendChartPaint[0].ChartFrame = this.Frame;
  8903. this.Frame.ChartBorder.Right = 300;
  8904. }
  8905. //创建主图K线画法
  8906. this.CreateMainKLine = function ()
  8907. {
  8908. //分钟线
  8909. var minuteLine = new ChartMinutePriceLine();
  8910. minuteLine.Canvas = this.Canvas;
  8911. minuteLine.ChartBorder = this.Frame.SubFrame[0].Frame.ChartBorder;
  8912. minuteLine.ChartFrame = this.Frame.SubFrame[0].Frame;
  8913. minuteLine.Name = "Minute-Line";
  8914. minuteLine.Identify="Minute-Line";
  8915. minuteLine.Color = g_JSChartResource.Minute.PriceColor;
  8916. minuteLine.LineWidth=g_JSChartResource.Minute.PriceLineWidth;
  8917. minuteLine.AreaColor = g_JSChartResource.Minute.AreaPriceColor;
  8918. this.ChartPaint[0] = minuteLine;
  8919. //分钟线均线
  8920. var averageLine = new ChartMinutePriceLine();
  8921. averageLine.Canvas = this.Canvas;
  8922. averageLine.ChartBorder = this.Frame.SubFrame[0].Frame.ChartBorder;
  8923. averageLine.ChartFrame = this.Frame.SubFrame[0].Frame;
  8924. averageLine.Name = "Minute-Average-Line";
  8925. averageLine.Identify="Minute-Average-Line";
  8926. averageLine.Color = g_JSChartResource.Minute.AvPriceColor;
  8927. averageLine.IsDrawArea = false;
  8928. this.ChartPaint[1] = averageLine;
  8929. //成交量柱子
  8930. var chartVol = new ChartMinuteVolumBar();
  8931. chartVol.Color = g_JSChartResource.Minute.VolBarColor;
  8932. chartVol.Canvas = this.Canvas;
  8933. chartVol.ChartBorder = this.Frame.SubFrame[1].Frame.ChartBorder;
  8934. chartVol.ChartFrame = this.Frame.SubFrame[1].Frame;
  8935. chartVol.Name = "Minute-Vol-Bar";
  8936. chartVol.Identify="Minute-Vol-Bar";
  8937. this.ChartPaint[2] = chartVol;
  8938. //持仓线
  8939. var chartPosition=new ChartSubLine();
  8940. chartPosition.Color = g_JSChartResource.Minute.PriceColor;
  8941. chartPosition.Canvas = this.Canvas;
  8942. chartPosition.ChartBorder = this.Frame.SubFrame[1].Frame.ChartBorder;
  8943. chartPosition.ChartFrame = this.Frame.SubFrame[1].Frame;
  8944. chartPosition.Name = "Minute-Position-Line";
  8945. chartPosition.Identify = "Minute-Position-Line";
  8946. this.ChartPaint[3] = chartPosition;
  8947. this.TitlePaint[0] = new DynamicMinuteTitlePainting();
  8948. this.TitlePaint[0].Frame = this.Frame.SubFrame[0].Frame;
  8949. this.TitlePaint[0].Canvas = this.Canvas;
  8950. this.TitlePaint[0].LanguageID = this.LanguageID;
  8951. this.TitlePaint[0].HQChart=this;
  8952. }
  8953. //切换成 脚本指标
  8954. this.ChangeScriptIndex = function (windowIndex, indexData)
  8955. {
  8956. this.DeleteIndexPaint(windowIndex, true);
  8957. this.WindowIndex[windowIndex] = new ScriptIndex(indexData.Name, indexData.Script, indexData.Args, indexData); //脚本执行
  8958. var bindData = this.SourceData;
  8959. this.BindIndexData(windowIndex, bindData); //执行脚本
  8960. this.UpdataDataoffset(); //更新数据偏移
  8961. this.UpdateFrameMaxMin(); //调整坐标最大 最小值
  8962. this.Draw();
  8963. }
  8964. //切换api指标
  8965. this.ChangeAPIIndex=function(windowIndex,indexData)
  8966. {
  8967. this.DeleteIndexPaint(windowIndex, true);
  8968. //使用API挂接指标数据 API:{ Name:指标名字, Script:指标脚本可以为空, Args:参数可以为空, Url:指标执行地址 }
  8969. var apiItem=indexData.API;
  8970. this.WindowIndex[windowIndex]=new APIScriptIndex(apiItem.Name,apiItem.Script,apiItem.Args,indexData);
  8971. var bindData=this.ChartPaint[0].Data;
  8972. this.BindIndexData(windowIndex,bindData); //执行脚本
  8973. this.UpdataDataoffset(); //更新数据偏移
  8974. this.UpdateFrameMaxMin(); //调整坐标最大 最小值
  8975. this.Draw();
  8976. }
  8977. this.ChangeIndex = function (windowIndex, indexName, option)
  8978. {
  8979. if (this.Frame.SubFrame.length < 3) return;
  8980. if (option && option.API)
  8981. return this.ChangeAPIIndex(windowIndex,option);
  8982. //查找系统指标
  8983. let scriptData = new JSCommonIndexScript.JSIndexScript();
  8984. let indexInfo = scriptData.Get(indexName);
  8985. if (!indexInfo) return;
  8986. if (windowIndex < 2) windowIndex = 2;
  8987. if (windowIndex >= this.Frame.SubFrame.length) windowIndex = 2;
  8988. if (option) JSIndexScript.ModifyAttribute(indexInfo, option);
  8989. return this.ChangeScriptIndex(windowIndex, indexInfo);
  8990. }
  8991. this.ChangeIndexTemplate=function(option) //切换指标模板 可以设置指标窗口个数 每个窗口的指标, 只能从第3个指标窗口开始设置,前面2个指标窗口固定无法设置
  8992. {
  8993. if (!Array.isArray(option.Windows)) return;
  8994. this.Frame.RestoreIndexWindows();
  8995. var count=option.Windows.length;
  8996. var currentLength=this.Frame.SubFrame.length;
  8997. var startWindowIndex=2;
  8998. count+=startWindowIndex;
  8999. var dayCount=null;
  9000. if (IFrameSplitOperator.IsNumber(option.DayCount) && option.DayCount!=this.DayCount) dayCount= option.DayCount; //天数
  9001. var bRefreshData= (dayCount!=null);
  9002. //清空所有的指标图型
  9003. for(var i=startWindowIndex;i<currentLength;++i)
  9004. {
  9005. this.DeleteIndexPaint(i);
  9006. var frame=this.Frame.SubFrame[i];
  9007. frame.YSpecificMaxMin=null;
  9008. frame.IsLocked=false;
  9009. frame.YSplitScale = null;
  9010. }
  9011. if (currentLength>count)
  9012. {
  9013. var event=this.GetEventCallback(JSCHART_EVENT_ID.ON_DELETE_FRAME);
  9014. for(var i=currentLength-1;i>=count;--i)
  9015. {
  9016. if (event && event.Callback)
  9017. {
  9018. var sendData={ SubFrame:this.Frame.SubFrame[i], WindowIndex:i };
  9019. event.Callback(event, sendData, this);
  9020. }
  9021. }
  9022. this.Frame.SubFrame.splice(count,currentLength-count);
  9023. this.WindowIndex.splice(count,currentLength-count);
  9024. this.TitlePaint.splice(count+1,currentLength-count);
  9025. }
  9026. else
  9027. {
  9028. for(var i=currentLength;i<count;++i) //创建新的指标窗口
  9029. {
  9030. var subFrame=this.CreateSubFrameItem(i);
  9031. this.Frame.SubFrame[i]=subFrame;
  9032. var titlePaint=new DynamicChartTitlePainting();
  9033. titlePaint.Frame=this.Frame.SubFrame[i].Frame;
  9034. titlePaint.Canvas=this.Canvas;
  9035. titlePaint.LanguageID=this.LanguageID;
  9036. titlePaint.GetEventCallback=(id)=> { return this.GetEventCallback(id); }
  9037. titlePaint.SelectedChart=this.SelectedChart;
  9038. this.TitlePaint[i+1]=titlePaint;
  9039. }
  9040. }
  9041. for(var i=0;i<count;++i)
  9042. {
  9043. var windowIndex=i;
  9044. var item=null,frameItem=null;
  9045. if (option.Frame && option.Frame.length>i) frameItem=option.Frame[windowIndex];
  9046. if (windowIndex>=startWindowIndex) item=option.Windows[windowIndex-startWindowIndex];
  9047. var titleIndex=windowIndex+1;
  9048. this.TitlePaint[titleIndex].Data=[];
  9049. this.TitlePaint[titleIndex].Title=null;
  9050. if (item)
  9051. {
  9052. if (item.Script) //自定义指标脚本
  9053. {
  9054. this.WindowIndex[windowIndex]=new ScriptIndex(item.Name,item.Script,item.Args,item); //脚本执行
  9055. }
  9056. else if (item.API) //后台指标
  9057. {
  9058. var apiItem=item.API;
  9059. this.WindowIndex[windowIndex]=new APIScriptIndex(apiItem.Name,apiItem.Script,apiItem.Args,item);
  9060. }
  9061. else
  9062. {
  9063. var indexID=item.Index;
  9064. var indexItem=JSIndexMap.Get(indexID);
  9065. if (indexItem)
  9066. {
  9067. this.WindowIndex[windowIndex]=indexItem.Create();
  9068. this.CreateWindowIndex(windowIndex);
  9069. }
  9070. else
  9071. {
  9072. var systemScript = new JSIndexScript();
  9073. var indexInfo = systemScript.Get(indexID);
  9074. if (indexInfo)
  9075. {
  9076. JSIndexScript.ModifyAttribute(indexInfo, item)
  9077. this.WindowIndex[windowIndex]=new ScriptIndex(indexInfo.Name,indexInfo.Script, indexInfo.Args,indexInfo); //脚本执行
  9078. }
  9079. }
  9080. }
  9081. }
  9082. this.SetSubFrameAttribute(this.Frame.SubFrame[windowIndex], item, frameItem);
  9083. }
  9084. //清空叠加指标
  9085. for(var i=0;i<this.Frame.SubFrame.length;++i)
  9086. {
  9087. this.DeleteWindowsOverlayIndex(i);
  9088. }
  9089. //最后一个显示X轴坐标
  9090. for(var i=0;i<this.Frame.SubFrame.length;++i)
  9091. {
  9092. var item=this.Frame.SubFrame[i].Frame;
  9093. if (i==this.Frame.SubFrame.length-1) item.XSplitOperator.ShowText=true;
  9094. else item.XSplitOperator.ShowText=false;
  9095. }
  9096. //叠加指标
  9097. var aryOverlayIndex=[];
  9098. if (IFrameSplitOperator.IsNonEmptyArray(option.OverlayIndex))
  9099. {
  9100. for(var i=0;i<option.OverlayIndex.length;++i)
  9101. {
  9102. var item=option.OverlayIndex[i];
  9103. if (item.Index) item.IndexName=item.Index;
  9104. if (item.Windows>=0) item.WindowIndex=item.Windows;
  9105. var overlay=this.CreateOverlayWindowsIndex(item);
  9106. if (!overlay) continue;
  9107. aryOverlayIndex.push({ WindowsIndex:item.WindowIndex, Overlay:overlay });
  9108. }
  9109. }
  9110. this.Frame.SetSizeChange(true);
  9111. if (!bRefreshData)
  9112. {
  9113. var bindData=this.SourceData;
  9114. for(var i=0;i<count;++i)
  9115. {
  9116. this.BindIndexData(i,bindData);
  9117. }
  9118. for(var i=0;i<aryOverlayIndex.length;++i)
  9119. {
  9120. var item=aryOverlayIndex[i];
  9121. this.BindOverlayIndexData(item.Overlay,item.WindowsIndex,bindData);
  9122. }
  9123. this.UpdataDataoffset(); //更新数据偏移
  9124. if (this.UpdateXShowText) this.UpdateXShowText();
  9125. this.ResetFrameXYSplit();
  9126. this.UpdateFrameMaxMin(); //调整坐标最大 最小值
  9127. this.Draw();
  9128. }
  9129. else
  9130. {
  9131. //this.Frame.SetSizeChange(true);
  9132. if (dayCount!=null) this.ChangeDayCount(dayCount);
  9133. }
  9134. }
  9135. //设置指标窗口个数
  9136. this.ChangeIndexWindowCount=function(count, option)
  9137. {
  9138. if (count<2) return; //1,2个窗口固定的不能动
  9139. if (this.Frame.SubFrame.length==count) return;
  9140. var currentLength=this.Frame.SubFrame.length;
  9141. if (currentLength>count)
  9142. {
  9143. var event=this.GetEventCallback(JSCHART_EVENT_ID.ON_DELETE_FRAME);
  9144. for(var i=currentLength-1;i>=count;--i)
  9145. {
  9146. this.DeleteIndexPaint(i);
  9147. //this.DeleteChartPaintExtend({WindowIndex:i});
  9148. var item=this.Frame.SubFrame[i].Frame;
  9149. if (event && event.Callback)
  9150. {
  9151. var sendData={ SubFrame:this.Frame.SubFrame[i], WindowIndex:i };
  9152. event.Callback(event, sendData, this);
  9153. }
  9154. }
  9155. this.Frame.SubFrame.splice(count,currentLength-count);
  9156. this.WindowIndex.splice(count,currentLength-count);
  9157. this.TitlePaint.splice(count+1,currentLength-count);
  9158. }
  9159. else
  9160. {
  9161. //创建新的指标窗口
  9162. var mainFrame=this.Frame.SubFrame[0].Frame;
  9163. for(var i=currentLength;i<count;++i)
  9164. {
  9165. var subFrame=this.CreateSubFrameItem(i, mainFrame);
  9166. this.Frame.SubFrame[i]=subFrame;
  9167. var titlePaint=new DynamicChartTitlePainting();
  9168. titlePaint.Frame=this.Frame.SubFrame[i].Frame;
  9169. titlePaint.Canvas=this.Canvas;
  9170. titlePaint.LanguageID=this.LanguageID;
  9171. titlePaint.GetEventCallback=(id)=> { return this.GetEventCallback(id); }
  9172. titlePaint.SelectedChart=this.SelectedChart;
  9173. titlePaint.MainTitlePaint=this.TitlePaint[0];
  9174. titlePaint.HQChart=this;
  9175. this.TitlePaint[i+1]=titlePaint;
  9176. }
  9177. //创建指标
  9178. const indexName=[{Index:"RSI"},{Index:"MACD"},{Index:"DMA"},{Index:"DMI"},{Index:"KDJ"},{Index:"WR"} ];
  9179. let scriptData = new JSIndexScript();
  9180. for(var i=currentLength;i<count;++i)
  9181. {
  9182. var item=indexName[i%indexName.length];
  9183. var indexInfo = scriptData.Get(item.Index);
  9184. JSIndexScript.ModifyAttribute(indexInfo,item);
  9185. this.WindowIndex[i] = new ScriptIndex(indexInfo.Name, indexInfo.Script, indexInfo.Args,indexInfo); //脚本执行
  9186. var bindData=this.SourceData;
  9187. this.BindIndexData(i,bindData); //执行脚本
  9188. }
  9189. //最后一个显示X轴坐标
  9190. for(var i=0;i<this.Frame.SubFrame.length;++i)
  9191. {
  9192. var item=this.Frame.SubFrame[i].Frame;
  9193. if (i==this.Frame.SubFrame.length-1) item.XSplitOperator.ShowText=true;
  9194. else item.XSplitOperator.ShowText=false;
  9195. }
  9196. this.UpdataDataoffset(); //更新数据偏移
  9197. }
  9198. this.UpdateXShowText();
  9199. this.SetSizeChange(true);
  9200. this.ResetFrameXYSplit();
  9201. this.UpdateFrameMaxMin(); //调整坐标最大 最小值
  9202. this.Draw();
  9203. }
  9204. this.RemoveIndexWindow=function(id)
  9205. {
  9206. JSConsole.Chart.Log('[MinuteChartContainer::RemoveIndexWindow] remove id', id);
  9207. if (id<2) return;
  9208. if (!this.Frame.SubFrame) return;
  9209. if (id>=this.Frame.SubFrame.length) return;
  9210. var delFrame=this.Frame.SubFrame[id].Frame;
  9211. this.DeleteIndexPaint(id, true);
  9212. var event=this.GetEventCallback(JSCHART_EVENT_ID.ON_DELETE_FRAME);
  9213. if (event && event.Callback)
  9214. {
  9215. var sendData={ SubFrame:this.Frame.SubFrame[id], WindowIndex:id };
  9216. event.Callback(event, sendData, this);
  9217. }
  9218. this.Frame.SubFrame.splice(id,1);
  9219. this.WindowIndex.splice(id,1);
  9220. this.TitlePaint.splice(id+1,1); //删除对应的动态标题
  9221. for(var i=0;i<this.Frame.SubFrame.length;++i)
  9222. {
  9223. var item=this.Frame.SubFrame[i].Frame;
  9224. if (i==this.Frame.SubFrame.length-1) item.XSplitOperator.ShowText=true;
  9225. else item.XSplitOperator.ShowText=false;
  9226. item.Identify=i;
  9227. }
  9228. this.Frame.SetSizeChange(true);
  9229. this.UpdateFrameMaxMin();
  9230. this.ResetFrameXYSplit();
  9231. this.Draw();
  9232. }
  9233. this.ClearIndexPaint=function()
  9234. {
  9235. if (this.Frame && this.Frame.SubFrame)
  9236. {
  9237. for(var i=2;i<this.Frame.SubFrame.length;++i)
  9238. {
  9239. if (i>=2) this.DeleteIndexPaint(i, true);
  9240. }
  9241. }
  9242. }
  9243. this.ResetDataStatus=function()
  9244. {
  9245. this.DataStatus.MultiDay=false;
  9246. this.DataStatus.LatestDay=false;
  9247. }
  9248. //切换股票代码
  9249. this.ChangeSymbol = function (symbol)
  9250. {
  9251. this.Symbol = symbol;
  9252. this.CancelAutoUpdate(); //先停止定时器
  9253. this.ChartSplashPaint.SetTitle(this.LoadDataSplashTitle);
  9254. this.ChartSplashPaint.EnableSplash(true);
  9255. this.ResetDataStatus();
  9256. this.ClearIndexPaint();
  9257. this.ResetOverlaySymbolStatus();
  9258. this.Frame.ClearYCoordinateMaxMin();
  9259. this.ClearGlobalOption();
  9260. this.RequestData();
  9261. }
  9262. this.ChangeDayCount = function (count)
  9263. {
  9264. if (count < 0 || count > 10) return;
  9265. this.DayCount = count;
  9266. this.CancelAutoUpdate(); //先停止定时器
  9267. this.ResetDataStatus();
  9268. this.ClearIndexPaint();
  9269. this.ResetOverlaySymbolStatus();
  9270. this.Frame.ClearYCoordinateMaxMin();
  9271. this.ClearGlobalOption();
  9272. this.RequestData();
  9273. }
  9274. //叠加股票 只支持日线数据
  9275. this.OverlaySymbol = function (symbol,option)
  9276. {
  9277. var arySymbol=null;
  9278. if (IFrameSplitOperator.IsString(symbol)) arySymbol=[symbol];
  9279. else if (Array.isArray(symbol)) arySymbol=symbol;
  9280. if (!IFrameSplitOperator.IsNonEmptyArray(arySymbol)) return false;
  9281. var aryNewSymbol=[];
  9282. for(var i=0, j=0;i<arySymbol.length;++i)
  9283. {
  9284. var strSymbol=arySymbol[i];
  9285. var bFind=false;
  9286. for(j=0;j<this.OverlayChartPaint.length; ++j)
  9287. {
  9288. var item=this.OverlayChartPaint[j];
  9289. if (item.Symbol==strSymbol)
  9290. {
  9291. bFind=true;
  9292. console.warn(`[MinuteChartContainer::OverlaySymbol] overlay symbol=${strSymbol} exist.`);
  9293. break;
  9294. }
  9295. }
  9296. if (!bFind) aryNewSymbol.push(strSymbol);
  9297. }
  9298. if (!IFrameSplitOperator.IsNonEmptyArray(aryNewSymbol)) return true;
  9299. for(var i=0;i<aryNewSymbol.length;++i)
  9300. {
  9301. var strSymbol=aryNewSymbol[i];
  9302. var paint=new ChartOverlayMinutePriceLine();
  9303. paint.Canvas=this.Canvas;
  9304. paint.ChartBorder=this.Frame.SubFrame[0].Frame.ChartBorder;
  9305. paint.ChartFrame=this.Frame.SubFrame[0].Frame;
  9306. paint.Name="Overlay-Minute";
  9307. paint.Symbol=strSymbol;
  9308. paint.Identify=`Overlay-Minute-${strSymbol}`;
  9309. if (option && option.Color) paint.Color=option.Color; //外部设置颜色
  9310. else paint.Color=g_JSChartResource.OverlaySymbol.Color[g_JSChartResource.OverlaySymbol.Random%g_JSChartResource.OverlaySymbol.Color.length];
  9311. ++g_JSChartResource.OverlaySymbol.Random;
  9312. paint.MainData=this.SourceData; //绑定主图数据
  9313. if (paint.SetOption) paint.SetOption(option);
  9314. this.OverlayChartPaint.push(paint);
  9315. }
  9316. if (this.DayCount <= 1) this.RequestOverlayMinuteData(); //请求数据
  9317. else this.RequestOverlayHistoryMinuteData();
  9318. return true;
  9319. }
  9320. //删除一个叠加股票
  9321. this.DeleteOverlaySymbol=function(symbol)
  9322. {
  9323. for(var i=0;i<this.OverlayChartPaint.length; ++i)
  9324. {
  9325. var item=this.OverlayChartPaint[i];
  9326. if (item.Symbol===symbol)
  9327. {
  9328. item.IsDelete=true;
  9329. this.OverlayChartPaint.splice(i,1);
  9330. this.UpdateFrameMaxMin();
  9331. this.Draw();
  9332. return true;
  9333. }
  9334. }
  9335. console.warn(`[MinuteChartContainer::DeleteOverlaySymbol] overlay symbol=${symbol} not exist.`)
  9336. return false;
  9337. }
  9338. //取消叠加股票
  9339. this.ClearOverlaySymbol=function()
  9340. {
  9341. for(var i=0; i<this.OverlayChartPaint.length; ++i)
  9342. {
  9343. var item=this.OverlayChartPaint[i];
  9344. item.IsDelete=true;
  9345. }
  9346. this.OverlayChartPaint=[];
  9347. this.Frame.SubFrame[0].Frame.YSplitOperator.OverlayChartPaint=this.OverlayChartPaint;
  9348. this.TitlePaint[0].OverlayChartPaint=this.OverlayChartPaint; //绑定叠加
  9349. this.UpdateFrameMaxMin();
  9350. this.Draw();
  9351. }
  9352. this.TryClickLock = function (x, y)
  9353. {
  9354. for (var i=0; i<this.Frame.SubFrame.length; ++i)
  9355. {
  9356. var item = this.Frame.SubFrame[i];
  9357. if (!item.Frame.IsLocked) continue;
  9358. if (!item.Frame.LockPaint) continue;
  9359. var tooltip = new TooltipData();
  9360. if (!item.Frame.LockPaint.GetTooltipData(x, y, tooltip)) continue;
  9361. tooltip.HQChart = this;
  9362. if (tooltip.Data.Callback) tooltip.Data.Callback(tooltip);
  9363. return true;
  9364. }
  9365. return false;
  9366. }
  9367. this.RequestData = function ()
  9368. {
  9369. if (this.DayCount <= 1) this.RequestMinuteData();
  9370. else this.RequestHistoryMinuteData(); //请求数据
  9371. }
  9372. this.RecvMinuteDataEvent = function (option)
  9373. {
  9374. if (!this.mapEvent.has(JSCHART_EVENT_ID.RECV_MINUTE_DATA)) return;
  9375. var event = this.mapEvent.get(JSCHART_EVENT_ID.RECV_MINUTE_DATA);
  9376. var data = { MinuteData: this.SourceData, Stock: { Symbol: this.Symbol, Name: this.Name }, Option:option, DataStatus:this.DataStatus }
  9377. event.Callback(event, data, this);
  9378. }
  9379. this.RequestHistoryMinuteData = function () //请求历史分钟数据
  9380. {
  9381. var self = this;
  9382. this.ChartSplashPaint.SetTitle(this.LoadDataSplashTitle);
  9383. this.ChartSplashPaint.EnableSplash(true);
  9384. this.Draw();
  9385. if (this.NetworkFilter)
  9386. {
  9387. var obj =
  9388. {
  9389. Name: 'MinuteChartContainer::RequestHistoryMinuteData', //类名::
  9390. Explain: '多日分时数据',
  9391. Request: { Url: self.HistoryMinuteApiUrl, Data: { daycount: self.DayCount, symbol: self.Symbol }, Type: 'POST' },
  9392. Self: this,
  9393. PreventDefault: false
  9394. };
  9395. this.NetworkFilter(obj, function (data) {
  9396. self.ChartSplashPaint.EnableSplash(false);
  9397. self.RecvHistoryMinuteData(data);
  9398. });
  9399. if (obj.PreventDefault == true) return; //已被上层替换,不调用默认的网络请求
  9400. }
  9401. JSNetwork.HttpRequest({
  9402. url: self.HistoryMinuteApiUrl,
  9403. data:
  9404. {
  9405. "symbol": self.Symbol,
  9406. "daycount": self.DayCount
  9407. },
  9408. method: "post",
  9409. dataType: "json",
  9410. success: function (data) {
  9411. self.ChartSplashPaint.EnableSplash(false);
  9412. self.RecvHistoryMinuteData(data);
  9413. }
  9414. });
  9415. }
  9416. this.RecvHistoryMinuteData = function (recvdata)
  9417. {
  9418. var data = recvdata.data;
  9419. if (data.code!=0)
  9420. {
  9421. JSConsole.Chart.Log('[MinuteChartContainer::RecvHistoryMinuteData] failed.',data);
  9422. return;
  9423. }
  9424. this.DayData = MinuteChartContainer.JsonDataToMinuteDataArray(data);;
  9425. this.Symbol = data.symbol;
  9426. this.Name = data.name;
  9427. this.DataStatus.MultiDay=true;
  9428. if (IFrameSplitOperator.IsNonEmptyArray(this.DayData))
  9429. {
  9430. this.CaclutateLimitPrice(this.DayData[0].YClose, data.data[0].limitprice); //计算涨停价格
  9431. }
  9432. this.UpdateHistoryMinuteUI();
  9433. this.RecvMinuteDataEvent({FunctionName:"RecvHistoryMinuteData"} );
  9434. this.RequestOverlayHistoryMinuteData();
  9435. this.BindAllOverlayIndexData(this.SourceData);
  9436. if (typeof (this.UpdateUICallback) == 'function') this.UpdateUICallback('RecvHistoryMinuteData', this);
  9437. this.AutoUpdate();
  9438. }
  9439. this.CaclutateLimitPrice=function(yClose, limitData)
  9440. {
  9441. this.LimitPrice=null;
  9442. //var limitData=data.stock[0].limitprice;
  9443. if (limitData && limitData.max>0 && limitData.min>0) //API里带涨停价格 直接使用
  9444. {
  9445. this.LimitPrice={ Max:limitData.max, Min:limitData.min };
  9446. return;
  9447. }
  9448. var range=MARKET_SUFFIX_NAME.GetLimitPriceRange(this.Symbol, this.Name); //通过规则获取涨停价格
  9449. if (!range)
  9450. {
  9451. JSConsole.Chart.Log(`[MinuteChartContainer::CaclutateLimitPrice] ${this.Symbol} no limit price.`)
  9452. return;
  9453. }
  9454. //var yClose=data.stock[0].yclose;
  9455. if (yClose<=0) return;
  9456. this.LimitPrice={ Max:yClose*(1+range.Max), Min:yClose*(1+range.Min) };
  9457. JSConsole.Chart.Log(`[MinuteChartContainer::CaclutateLimitPrice] ${this.Symbol} yClose:${yClose} max:${this.LimitPrice.Max} min:${this.LimitPrice.Min}`);
  9458. this.LimitPrice.Max=parseFloat(this.LimitPrice.Max.toFixed(2));
  9459. this.LimitPrice.Min=parseFloat(this.LimitPrice.Min.toFixed(2));
  9460. JSConsole.Chart.Log(`[MinuteChartContainer::CaclutateLimitPrice] ${this.Symbol} tofixed(2) max:${this.LimitPrice.Max} min:${this.LimitPrice.Min}`);
  9461. }
  9462. this.UpdateHistoryMinuteUI = function ()
  9463. {
  9464. var allMinuteData = this.HistoryMinuteDataToArray(this.DayData);
  9465. //原始数据
  9466. var sourceData = new ChartData();
  9467. sourceData.Data = allMinuteData;
  9468. this.SourceData = sourceData;
  9469. this.TradeDate = this.DayData[0].Date;
  9470. this.Frame.SetDayCount(this.DayData.length);
  9471. var upperSymbol=this.Symbol.toUpperCase();
  9472. var yClose=this.DayData[0].YClose;
  9473. var isFutures=MARKET_SUFFIX_NAME.IsFutures(upperSymbol);
  9474. if (IFrameSplitOperator.IsNumber(this.DayData[0].YClearing) && isFutures) yClose=this.DayData[0].YClearing; //期货使用前结算价
  9475. this.BindMainData(sourceData, yClose);
  9476. //if (MARKET_SUFFIX_NAME.IsChinaFutures(this.Symbol)) this.ChartPaint[1].Data = null; //期货均线暂时不用
  9477. if (this.Frame.SubFrame.length > 2)
  9478. {
  9479. var bindData = new ChartData();
  9480. bindData.Data = allMinuteData;
  9481. for (var i = 2; i < this.Frame.SubFrame.length; ++i)
  9482. {
  9483. this.BindIndexData(i, bindData);
  9484. }
  9485. }
  9486. for (let i in this.Frame.SubFrame)
  9487. {
  9488. var item = this.Frame.SubFrame[i];
  9489. item.Frame.XSplitOperator.Symbol = this.Symbol;
  9490. item.Frame.XSplitOperator.DayCount = this.DayData.length;
  9491. item.Frame.XSplitOperator.DayData = this.DayData;
  9492. item.Frame.XSplitOperator.Operator(); //调整X轴个数
  9493. item.Frame.YSplitOperator.Symbol = this.Symbol;
  9494. }
  9495. this.ChartCorssCursor.StringFormatY.Symbol = this.Symbol;
  9496. this.ChartCorssCursor.StringFormatX.Symbol = this.Symbol;
  9497. this.TitlePaint[0].IsShowDate = true;
  9498. this.UpdateFrameMaxMin(); //调整坐标最大 最小值
  9499. this.Frame.SetSizeChange(true);
  9500. this.Draw();
  9501. }
  9502. this.HistoryMinuteDataToArray = function (data) //把多日分钟数据转化为单数组
  9503. {
  9504. var result = [];
  9505. for (var i = data.length - 1; i >= 0; --i) {
  9506. var item = data[i];
  9507. for (var j in item.Data) {
  9508. result.push(item.Data[j]);
  9509. }
  9510. }
  9511. return result;
  9512. }
  9513. this.UpdateLatestMinuteData = function (data, date) //更新最新交易日的分钟数据
  9514. {
  9515. for (var i in this.DayData) {
  9516. var item = this.DayData[i];
  9517. if (item.Date === date) {
  9518. item.Data = data;
  9519. break;
  9520. }
  9521. }
  9522. }
  9523. //请求分钟数据
  9524. this.RequestMinuteData = function ()
  9525. {
  9526. var self = this;
  9527. var fields =
  9528. [
  9529. "name", "symbol",
  9530. "yclose", "open", "price", "high", "low",
  9531. "vol", "amount",
  9532. "date", "time",
  9533. "minute", "minutecount"
  9534. ];
  9535. var upperSymbol = this.Symbol.toUpperCase();
  9536. if (MARKET_SUFFIX_NAME.IsChinaFutures(upperSymbol)) //期货的需要加上结算价
  9537. {
  9538. fields.push("clearing");
  9539. fields.push("yclearing");
  9540. }
  9541. if (this.NetworkFilter)
  9542. {
  9543. var obj =
  9544. {
  9545. Name: 'MinuteChartContainer::RequestMinuteData', //类名::函数名
  9546. Explain: '最新分时数据',
  9547. Request: { Url: self.MinuteApiUrl, Data: { field: fields, symbol: [self.Symbol] }, Type: 'POST' },
  9548. Self: this,
  9549. PreventDefault: false
  9550. };
  9551. this.NetworkFilter(obj, function (data)
  9552. {
  9553. self.ChartSplashPaint.EnableSplash(false);
  9554. self.RecvMinuteData(data);
  9555. });
  9556. if (obj.PreventDefault == true) return; //已被上层替换,不调用默认的网络请求
  9557. }
  9558. JSNetwork.HttpRequest({
  9559. url: this.MinuteApiUrl,
  9560. data:
  9561. {
  9562. "field": fields,
  9563. "symbol": [this.Symbol],
  9564. "start": -1
  9565. },
  9566. method: "post",
  9567. dataType: "json",
  9568. success: function (data) {
  9569. self.ChartSplashPaint.EnableSplash(false);
  9570. self.RecvMinuteData(data);
  9571. }
  9572. });
  9573. }
  9574. this.RecvMinuteData = function (data)
  9575. {
  9576. if (data.data && data.data.dataType===1) //增量更新数据模式
  9577. {
  9578. this.RecvUpdateMinuteData(data.data);
  9579. return;
  9580. }
  9581. var aryMinuteData = MinuteChartContainer.JsonDataToMinuteData(data.data);
  9582. var bFirstData=(this.DataStatus.LatestDay==false); //首条单日数据
  9583. this.DataStatus.LatestDay=true;
  9584. this.DataStatus.LatestDate=data.data.stock[0].date; //保存下最后一天的日期
  9585. if (this.DayCount > 1) //多日走势图
  9586. {
  9587. this.UpdateLatestMinuteData(aryMinuteData, data.data.stock[0].date);
  9588. this.UpdateHistoryMinuteUI();
  9589. this.RecvMinuteDataEvent({FunctionName:"RecvMinuteData"} );
  9590. this.RequestOverlayMinuteData(); //更新最新叠加数据
  9591. this.BindAllOverlayIndexData(this.SourceData);
  9592. //if (typeof (this.UpdateUICallback) == 'function') this.UpdateUICallback('RecvMinuteData', this);
  9593. this.AutoUpdate();
  9594. return;
  9595. }
  9596. if (this.IsOnTouch==true) //正在操作中不更新数据
  9597. {
  9598. if (this.SourceData && IFrameSplitOperator.IsNonEmptyArray(this.SourceData.Data))
  9599. {
  9600. this.AutoUpdate();
  9601. return;
  9602. }
  9603. }
  9604. //原始数据
  9605. var sourceData = new ChartData();
  9606. sourceData.Data = aryMinuteData;
  9607. this.SourceData = sourceData;
  9608. this.UpdateMinuteUI(data.data.stock[0], {FunctionName:"RecvMinuteData", Day:{ IsFirstData:bFirstData} });
  9609. if (data.AutoUpdate===false)
  9610. {
  9611. }
  9612. else
  9613. {
  9614. this.AutoUpdate();
  9615. }
  9616. }
  9617. this.UpdateMinuteUI=function(stockData, eventData)
  9618. {
  9619. this.TradeDate = stockData.date;
  9620. this.Frame.SetDayCount(1); //单日数据
  9621. this.Symbol = stockData.symbol;
  9622. this.Name = stockData.name;
  9623. var yClose = stockData.yclose;
  9624. var upperSymbol = this.Symbol.toUpperCase();
  9625. var isFutures = MARKET_SUFFIX_NAME.IsFutures(upperSymbol);
  9626. if (stockData.yclearing && isFutures) yClose = stockData.yclearing; //期货使用前结算价
  9627. this.CaclutateLimitPrice(yClose, stockData.limitprice); //计算涨停价格
  9628. var extendData = { High: stockData.high, Low: stockData.low };
  9629. this.BindMainData(this.SourceData, yClose, extendData);
  9630. for (let i=0;i<this.Frame.SubFrame.length;++i) //把股票代码设置到X轴刻度类里
  9631. {
  9632. var item = this.Frame.SubFrame[i];
  9633. item.Frame.XSplitOperator.Symbol = this.Symbol;
  9634. item.Frame.XSplitOperator.DayCount = 1;
  9635. item.Frame.XSplitOperator.Operator(); //调整X轴个数
  9636. item.Frame.YSplitOperator.Symbol = this.Symbol;
  9637. }
  9638. //计算指标
  9639. if (this.Frame.SubFrame.length > 2)
  9640. {
  9641. var bindData = new ChartData();
  9642. bindData.Data = this.SourceData.Data;
  9643. for (var i = 2; i < this.Frame.SubFrame.length; ++i)
  9644. {
  9645. this.BindIndexData(i, bindData);
  9646. }
  9647. }
  9648. this.ChartCorssCursor.StringFormatY.Symbol = this.Symbol;
  9649. this.ChartCorssCursor.StringFormatX.Symbol = this.Symbol;
  9650. var chartInfo = this.GetChartMinuteInfo();
  9651. if (chartInfo) chartInfo.SourceData = this.SourceData; //数据绑定到信息地雷上
  9652. this.RecvMinuteDataEvent(eventData);
  9653. this.RequestMinuteInfoData();
  9654. this.RequestOverlayMinuteData();//请求叠加数据 (主数据下载完再下载)
  9655. this.UpdateFrameMaxMin(); //调整坐标最大 最小值
  9656. this.Frame.SetSizeChange(true);
  9657. this.Draw();
  9658. this.BindAllOverlayIndexData(this.SourceData);
  9659. }
  9660. this.RecvUpdateMinuteData=function(data)
  9661. {
  9662. var minuteData=MinuteChartContainer.JsonDataToUpdateMinuteData(data);
  9663. if (this.DayCount > 1) //多日走势图
  9664. {
  9665. this.UpdateLatestMinuteDataV2(minuteData);
  9666. this.UpdateHistoryMinuteUI();
  9667. this.RecvMinuteDataEvent({FunctionName:"RecvUpdateMinuteData"});
  9668. this.RequestOverlayMinuteData(); //更新最新叠加数据
  9669. this.BindAllOverlayIndexData(this.SourceData);
  9670. if (typeof (this.UpdateUICallback) == 'function') this.UpdateUICallback('RecvMinuteData', this);
  9671. this.AutoUpdate();
  9672. return;
  9673. }
  9674. this.UpdateLatestMinuteDataV2(minuteData);
  9675. this.UpdateMinuteUI(data.data.stock[0], {FunctionName:"RecvUpdateMinuteData"});
  9676. if (data.AutoUpdate===false) //不执行自动更新
  9677. {
  9678. }
  9679. else
  9680. {
  9681. this.AutoUpdate();
  9682. }
  9683. }
  9684. //更新最新的几条数据
  9685. this.UpdateLatestMinuteDataV2=function(minuteData)
  9686. {
  9687. if (this.DayCount>1)
  9688. {
  9689. if (!this.DayData) return;
  9690. var findItem=null;
  9691. for(var i=0; i<this.DayData.length; ++i)
  9692. {
  9693. var item=this.DayData[i];
  9694. if (item.Date===date)
  9695. {
  9696. findItem=item;
  9697. break;
  9698. }
  9699. }
  9700. if (!findItem) return;
  9701. var findIndex=-1;
  9702. var firstItem=minuteData.Data[0];
  9703. for(var i=0;i<findItem.Data.length;++i)
  9704. {
  9705. var item=findItem.Data[i];
  9706. if (item.Date==firstItem.Date && item.Time==firstItem.Time)
  9707. {
  9708. findIndex=i;
  9709. break;
  9710. }
  9711. }
  9712. if (findIndex<0) findIndex=findItem.Data.length;
  9713. for(var i=0, j=findIndex; i<minuteData.Data.length; ++i, ++j)
  9714. {
  9715. var item=minuteData.Data[i];
  9716. findItem.Data[j]=item;
  9717. }
  9718. }
  9719. else
  9720. {
  9721. if (!this.SourceData) return;
  9722. var findIndex=-1;
  9723. var firstItem=minuteData.Data[0];
  9724. for(var i=0;i<this.SourceData.Data.length;++i)
  9725. {
  9726. var item=this.SourceData.Data[i];
  9727. if (item.Date==firstItem.Date && item.Time==firstItem.Time)
  9728. {
  9729. findIndex=i;
  9730. break;
  9731. }
  9732. }
  9733. if (findIndex<0) findIndex=this.SourceData.Data.length;
  9734. for(var i=0, j=findIndex; i<minuteData.Data.length; ++i, ++j)
  9735. {
  9736. var item=minuteData.Data[i];
  9737. this.SourceData.Data[j]=item;
  9738. }
  9739. }
  9740. }
  9741. //请求叠加数据 (主数据下载完再下载))
  9742. this.RequestOverlayMinuteData = function ()
  9743. {
  9744. var self = this;
  9745. var date=this.TradeDate; //最后一个交易日期
  9746. for(var i=0; i<this.OverlayChartPaint.length; ++i)
  9747. {
  9748. var item=this.OverlayChartPaint[i];
  9749. if (!item.MainData) continue;
  9750. if (item.Status!=OVERLAY_STATUS_ID.STATUS_NONE_ID) continue;
  9751. var symbol=item.Symbol;
  9752. if (!symbol) continue;
  9753. this.RequestSingleOverlayMinuteData(symbol, date, item);
  9754. }
  9755. }
  9756. this.RequestSingleOverlayMinuteData=function(symbol, date, item)
  9757. {
  9758. var self = this;
  9759. item.Status=OVERLAY_STATUS_ID.STATUS_REQUESTDATA_ID;
  9760. if (this.NetworkFilter)
  9761. {
  9762. var obj=
  9763. {
  9764. Name:'MinuteChartContainer::RequestOverlayMinuteData', //类名::函数名
  9765. Explain:'叠加股票最新分时数据',
  9766. Request:{ Url:this.HistoryMinuteApiUrl, Data:{days:[date], symbol:symbol}, Type:'POST' },
  9767. Self:this,
  9768. PreventDefault:false
  9769. };
  9770. this.NetworkFilter(obj, function(data)
  9771. {
  9772. item.Status=OVERLAY_STATUS_ID.STATUS_RECVDATA_ID;
  9773. self.RecvOverlayMinuteData(data,item);
  9774. });
  9775. if (obj.PreventDefault==true) return; //已被上层替换,不调用默认的网络请求
  9776. }
  9777. //请求数据
  9778. JSNetwork.HttpRequest({
  9779. url: this.HistoryMinuteApiUrl,
  9780. data:
  9781. {
  9782. "symbol":symbol,
  9783. "days": [date],
  9784. },
  9785. type:"post",
  9786. dataType: "json",
  9787. async:true,
  9788. success: function (data)
  9789. {
  9790. item.Status=OVERLAY_STATUS_ID.STATUS_RECVDATA_ID;
  9791. //self.RecvMultiOverlayMinuteData([data]);
  9792. self.RecvOverlayMinuteData(data,item);
  9793. }
  9794. });
  9795. }
  9796. this.RecvOverlayMinuteData = function (recvData, paint, option)
  9797. {
  9798. var data = recvData.data;
  9799. var aryMinuteData = MinuteChartContainer.JsonDataToMinuteDataArray(data);
  9800. var sourceData = null;
  9801. var yClose;
  9802. if (this.DayCount > 1) //多日数据
  9803. {
  9804. if (aryMinuteData.length <= 0) return;
  9805. var minuteData = aryMinuteData[0];
  9806. for (var i in this.OverlaySourceData)
  9807. {
  9808. var item = this.OverlaySourceData[i];
  9809. if (item.Date == minuteData.Date)
  9810. {
  9811. this.OverlaySourceData[i] = minuteData;
  9812. var allMinuteData = this.HistoryMinuteDataToArray(this.OverlaySourceData);
  9813. var sourceData = new ChartData();
  9814. sourceData.Data = allMinuteData;
  9815. yClose = minuteData.YClose;
  9816. break;
  9817. }
  9818. }
  9819. if (sourceData == null) return;
  9820. }
  9821. else
  9822. {
  9823. if (aryMinuteData.length > 0) sourceData = aryMinuteData[0];
  9824. else sourceData = new ChartData();
  9825. yClose = sourceData.YClose;
  9826. }
  9827. paint.Data=sourceData;
  9828. paint.Title=data.name;
  9829. paint.Symbol=data.symbol;
  9830. paint.YClose=yClose;
  9831. paint.Status=OVERLAY_STATUS_ID.STATUS_FINISHED_ID;
  9832. var bRedraw=true;
  9833. if (option && option.Redraw==false) bRedraw=false;
  9834. if (bRedraw)
  9835. {
  9836. this.UpdateFrameMaxMin(); //调整坐标最大 最小值
  9837. this.Frame.SetSizeChange(true);
  9838. this.Draw();
  9839. }
  9840. }
  9841. this.RequestOverlayHistoryMinuteData = function ()
  9842. {
  9843. if (!IFrameSplitOperator.IsNonEmptyArray(this.DayData)) return;
  9844. var self = this;
  9845. var days=[];
  9846. for(var i=0; i<this.DayData.length; ++i)
  9847. {
  9848. var item=this.DayData[i];
  9849. days.push(item.Date);
  9850. }
  9851. if (days.length<=0) return;
  9852. for(var i=0; i<this.OverlayChartPaint.length; ++i)
  9853. {
  9854. var item=this.OverlayChartPaint[i]
  9855. var symbol=item.Symbol;
  9856. if (!symbol) continue;
  9857. if (item.Status!=OVERLAY_STATUS_ID.STATUS_NONE_ID) continue;
  9858. this.RequestSingleOverlayHistoryMinuteData(symbol, days, item);
  9859. }
  9860. }
  9861. this.RequestSingleOverlayHistoryMinuteData=function(symbol, days, item)
  9862. {
  9863. var self = this;
  9864. item.Status=OVERLAY_STATUS_ID.STATUS_REQUESTDATA_ID;
  9865. if (this.NetworkFilter)
  9866. {
  9867. var obj=
  9868. {
  9869. Name:'MinuteChartContainer::RequestOverlayHistoryMinuteData', //类名::函数名
  9870. Explain:'叠加股票多日分时数据',
  9871. Request:{ Url:self.HistoryMinuteApiUrl, Data:{days:days, symbol:symbol}, Type:'POST' },
  9872. Self:this,
  9873. PreventDefault:false
  9874. };
  9875. this.NetworkFilter(obj, function(data)
  9876. {
  9877. item.Status=OVERLAY_STATUS_ID.STATUS_RECVDATA_ID;
  9878. self.RecvOverlayHistoryMinuteData(data,item);
  9879. });
  9880. if (obj.PreventDefault==true) return; //已被上层替换,不调用默认的网络请求
  9881. }
  9882. JSNetwork.HttpRequest({
  9883. url: self.HistoryMinuteApiUrl,
  9884. data:{ "symbol": symbol, "days": days },
  9885. type:"post",
  9886. dataType: "json",
  9887. async:true,
  9888. success: function (data)
  9889. {
  9890. item.Status=OVERLAY_STATUS_ID.STATUS_RECVDATA_ID;
  9891. self.RecvOverlayHistoryMinuteData(data,item);
  9892. }
  9893. });
  9894. }
  9895. this.RecvOverlayHistoryMinuteData = function (recvData, paint) //叠加历史的分钟数据
  9896. {
  9897. var data = recvData.data;
  9898. if (!IFrameSplitOperator.IsNonEmptyArray(this.DayData)) return;
  9899. var dayData=MinuteChartContainer.JsonDataToMinuteDataArray(data);
  9900. if (!IFrameSplitOperator.IsNonEmptyArray(dayData)) return;
  9901. var overlayDayData = [];
  9902. for (var i in this.DayData)
  9903. {
  9904. var item = this.DayData[i];
  9905. var bFind = false;
  9906. for (var j in dayData)
  9907. {
  9908. if (item.Date == dayData[j].Date)
  9909. {
  9910. overlayDayData.push(dayData[i]);
  9911. bFind = true;
  9912. break;
  9913. }
  9914. }
  9915. if (!bFind) //当天不存在叠加数据, 存空
  9916. {
  9917. var empytData = new ChartData();
  9918. empytData.Date=item.Date;
  9919. empytData.Data.length=item.Data.length;
  9920. overlayDayData.push(empytData);
  9921. }
  9922. }
  9923. paint.SourceData=overlayDayData;
  9924. var allMinuteData = this.HistoryMinuteDataToArray(overlayDayData);
  9925. var yClose=overlayDayData[0].YClose; //取最近一个交易日前收盘最为中轴线
  9926. //原始数据
  9927. var sourceData = new ChartData();
  9928. sourceData.Data = allMinuteData;
  9929. paint.Data=sourceData;
  9930. paint.Title=data.name;
  9931. paint.Symbol=data.symbol;
  9932. paint.YClose=yClose;
  9933. paint.Status=OVERLAY_STATUS_ID.STATUS_FINISHED_ID;
  9934. this.UpdateFrameMaxMin(); //调整坐标最大 最小值
  9935. this.Frame.SetSizeChange(true);
  9936. this.Draw();
  9937. }
  9938. this.CancelAutoUpdate = function () //关闭停止更新
  9939. {
  9940. if (this.AutoUpdateTimer)
  9941. {
  9942. clearTimeout(this.AutoUpdateTimer);
  9943. this.AutoUpdateTimer = null;
  9944. }
  9945. }
  9946. //数据自动更新
  9947. this.AutoUpdate = function ()
  9948. {
  9949. this.CancelAutoUpdate();
  9950. if (!this.IsAutoUpdate) return;
  9951. if (!this.Symbol) return;
  9952. if (this.IsDestroy) return;
  9953. var self = this;
  9954. var marketStatus = MARKET_SUFFIX_NAME.GetMarketStatus(this.Symbol);
  9955. if (marketStatus == 0 || marketStatus == 3) return; //闭市,盘后
  9956. var frequency = this.AutoUpdateFrequency;
  9957. if (marketStatus == 1) //盘前
  9958. {
  9959. this.AutoUpdateTimer=setTimeout(function () { self.AutoUpdate(); }, frequency);
  9960. }
  9961. else if (marketStatus == 2) //盘中
  9962. {
  9963. this.AutoUpdateTimer=setTimeout(function ()
  9964. {
  9965. //self.ResetOverlaySymbolStatus();
  9966. self.RequestMinuteData();
  9967. }, frequency);
  9968. }
  9969. }
  9970. this.StopAutoUpdate = function ()
  9971. {
  9972. this.CancelAutoUpdate();
  9973. this.IsAutoUpdate = false;
  9974. }
  9975. this.BindIndexData = function (windowIndex, hisData)
  9976. {
  9977. if (!this.WindowIndex[windowIndex]) return;
  9978. if (typeof (this.WindowIndex[windowIndex].RequestData) == "function") //数据需要另外下载的.
  9979. {
  9980. this.WindowIndex[windowIndex].RequestData(this, windowIndex, hisData);
  9981. return;
  9982. }
  9983. if (typeof (this.WindowIndex[windowIndex].ExecuteScript) == 'function')
  9984. {
  9985. this.WindowIndex[windowIndex].ExecuteScript(this, windowIndex, hisData);
  9986. return;
  9987. }
  9988. this.WindowIndex[windowIndex].BindData(this, windowIndex, hisData);
  9989. }
  9990. this.BindMainData = function (minuteData, yClose, extendData) //绑定分钟数据
  9991. {
  9992. //分钟数据
  9993. var bindData = new ChartData();
  9994. bindData.Data = minuteData.GetClose();
  9995. this.ChartPaint[0].Data = bindData;
  9996. this.ChartPaint[0].Source=minuteData;
  9997. this.ChartPaint[0].YClose = yClose;
  9998. this.ChartPaint[0].NotSupportMessage = null;
  9999. this.Frame.SubFrame[0].Frame.YSplitOperator.YClose = yClose;
  10000. this.Frame.SubFrame[0].Frame.YSplitOperator.Data = bindData;
  10001. this.Frame.Data=this.ChartPaint[0].Data;
  10002. this.Frame.SourceData=minuteData;
  10003. for(var i=0; i<this.Frame.SubFrame.length; ++i)
  10004. {
  10005. var item=this.Frame.SubFrame[i].Frame;
  10006. item.Data=minuteData; //每个子窗口都绑定下数据
  10007. }
  10008. //均线
  10009. bindData = new ChartData();
  10010. bindData.Data = minuteData.GetMinuteAvPrice();
  10011. this.ChartPaint[1].Data = bindData;
  10012. var upperSymbol=this.Symbol.toUpperCase();
  10013. if (MARKET_SUFFIX_NAME.IsForeignExchange(upperSymbol)) //外汇没有均线
  10014. this.ChartPaint[1].Data=null;
  10015. else if (MARKET_SUFFIX_NAME.IsShowAvPrice && !MARKET_SUFFIX_NAME.IsShowAvPrice(upperSymbol)) //外部控制是否显示均线
  10016. this.ChartPaint[1].Data=null;
  10017. this.Frame.SubFrame[0].Frame.YSplitOperator.AverageData = bindData;
  10018. this.Frame.SubFrame[0].Frame.YSplitOperator.OverlayChartPaint = this.OverlayChartPaint;
  10019. this.Frame.SubFrame[0].Frame.YSplitOperator.LimitPrice=this.LimitPrice;
  10020. if (extendData)
  10021. {
  10022. this.Frame.SubFrame[0].Frame.YSplitOperator.High = extendData.High;
  10023. this.Frame.SubFrame[0].Frame.YSplitOperator.Low = extendData.Low;
  10024. }
  10025. //成交量
  10026. this.ChartPaint[2].Data = minuteData;
  10027. this.ChartPaint[2].YClose = yClose;
  10028. this.ChartPaint[2].Symbol=this.Symbol;
  10029. var upperSymbol=this.Symbol.toUpperCase();
  10030. var bFutures=MARKET_SUFFIX_NAME.IsChinaFutures(upperSymbol);
  10031. var bSHO = MARKET_SUFFIX_NAME.IsSHO(upperSymbol);
  10032. var bSZO = MARKET_SUFFIX_NAME.IsSZO(upperSymbol); //深证股票期权
  10033. if (bFutures || bSHO || bSZO)
  10034. {
  10035. this.ChartPaint[3].Data.Data = minuteData.GetPosition();
  10036. }
  10037. else
  10038. {
  10039. this.ChartPaint[3].Data.Data=null;
  10040. }
  10041. this.TitlePaint[0].Data = this.SourceData; //动态标题
  10042. this.TitlePaint[0].Symbol = this.Symbol;
  10043. this.TitlePaint[0].Name = this.Name;
  10044. this.TitlePaint[0].YClose = yClose;
  10045. if (this.ChartCorssCursor)
  10046. {
  10047. if (this.ChartCorssCursor.StringFormatY)
  10048. {
  10049. this.ChartCorssCursor.StringFormatY.YClose=yClose;
  10050. this.ChartCorssCursor.StringFormatX.Data=this.ChartPaint[0].Data; //十字光标
  10051. }
  10052. }
  10053. if (this.ExtendChartPaint[0])
  10054. {
  10055. this.ExtendChartPaint[0].Symbol = this.Symbol;
  10056. this.ExtendChartPaint[0].Name = this.Name;
  10057. }
  10058. //叠加股票
  10059. for(var i=0; i<this.OverlayChartPaint.length; ++i)
  10060. {
  10061. var item=this.OverlayChartPaint[i];
  10062. item.MainData=minuteData; //绑定主图数据
  10063. }
  10064. }
  10065. //添加叠加指标
  10066. this.AddOverlayIndex=function(obj)
  10067. {
  10068. var overlay=this.CreateOverlayWindowsIndex(obj);
  10069. if (!overlay) return;
  10070. var bindData=this.SourceData;
  10071. this.BindOverlayIndexData(overlay,obj.WindowIndex,bindData);
  10072. this.UpdataDataoffset(); //更新数据偏移
  10073. this.UpdateFrameMaxMin(); //调整坐标最大 最小值
  10074. this.Draw();
  10075. }
  10076. //创建一个叠加指标
  10077. this.CreateOverlayWindowsIndex=function(obj) //{WindowIndex:, IndexName:, Identify:, ShowRightText:, API:}
  10078. {
  10079. let indexName=obj.IndexName;
  10080. let windowIndex=obj.WindowIndex;
  10081. var apiItem=null, indexInfo=null, indexCustom=null;
  10082. if (obj.API)
  10083. {
  10084. apiItem=obj.API;
  10085. }
  10086. else if (obj.Script) //动态执行脚本
  10087. {
  10088. indexInfo={ Script:obj.Script, ID:obj.indexName, Name:obj.indexName};
  10089. if (obj.Name) indexInfo.Name=obj.Name;
  10090. }
  10091. else
  10092. {
  10093. let scriptData = new JSCommonIndexScript.JSIndexScript();
  10094. indexInfo = scriptData.Get(indexName); //系统指标
  10095. if (!indexInfo)
  10096. {
  10097. indexCustom=JSIndexMap.Get(indexName); //定制指标
  10098. if (!indexCustom)
  10099. {
  10100. console.warn(`[MinuteChartContainer::CreateOverlayIndex] can not find index[${indexName}]`);
  10101. return null;
  10102. }
  10103. }
  10104. }
  10105. var subFrame=this.Frame.SubFrame[windowIndex];
  10106. subFrame.Interval=this.OverlayIndexFrameWidth;
  10107. var overlayFrame=new OverlayIndexItem();
  10108. if (obj.Identify) overlayFrame.Identify=obj.Identify; //由外部指定id
  10109. var frame=this.CreateOverlayFrame();
  10110. frame.Canvas=this.Canvas;
  10111. frame.MainFrame=subFrame.Frame;
  10112. frame.ChartBorder=subFrame.Frame.ChartBorder;
  10113. frame.GlobalOption=this.GlobalOption;
  10114. if (IFrameSplitOperator.IsBool(obj.ShowRightText)) frame.IsShow=obj.ShowRightText;
  10115. if (IFrameSplitOperator.IsBool(obj.IsShareY)) frame.IsShareY=true;
  10116. if (IFrameSplitOperator.IsBool(obj.IsCalculateYMaxMin)) frame.IsCalculateYMaxMin=obj.IsCalculateYMaxMin; //是否计算Y最大最小值
  10117. if (IFrameSplitOperator.IsNumber(obj.IsShowMainFrame)) frame.IsShowMainFrame=obj.IsShowMainFrame;
  10118. frame.YSplitOperator=new FrameSplitY();
  10119. frame.YSplitOperator.LanguageID=this.LanguageID;
  10120. frame.YSplitOperator.FrameSplitData=this.FrameSplitData.get('double');
  10121. frame.YSplitOperator.Frame=frame;
  10122. frame.YSplitOperator.ChartBorder=frame.ChartBorder;
  10123. frame.YSplitOperator.SplitCount=subFrame.Frame.YSplitOperator.SplitCount;
  10124. frame.YSplitOperator.GetEventCallback=(id)=> { return this.GetEventCallback(id); };
  10125. frame.YSplitOperator.HQChart=this;
  10126. frame.YSplitOperator.OverlayIdentify=overlayFrame.Identify;
  10127. if (obj.Frame)
  10128. {
  10129. var item=obj.Frame;
  10130. if (item.Custom) frame.YSplitOperator.Custom=item.Custom;
  10131. }
  10132. overlayFrame.Frame=frame;
  10133. if (apiItem)
  10134. {
  10135. var apiIndex=new APIScriptIndex(apiItem.Name,apiItem.Script,apiItem.Args,obj, true);
  10136. apiIndex.OverlayIndex={ IsOverlay:true, Identify:overlayFrame.Identify, WindowIndex:windowIndex, Frame:overlayFrame }; //叠加指标信息
  10137. overlayFrame.Script=apiIndex;
  10138. }
  10139. else if (indexInfo)
  10140. {
  10141. let indexData = indexInfo;
  10142. if (obj.Args) indexData.Args=obj.Args; //外部可以设置参数
  10143. var scriptIndex=new OverlayScriptIndex(indexData.Name,indexData.Script,indexData.Args,indexData); //脚本执行
  10144. scriptIndex.OverlayIndex={ IsOverlay:true, Identify:overlayFrame.Identify, WindowIndex:windowIndex, Frame:overlayFrame }; //叠加指标信息
  10145. overlayFrame.Script=scriptIndex;
  10146. }
  10147. else
  10148. {
  10149. var scriptIndex=indexCustom.Create();
  10150. scriptIndex.OverlayIndex={ IsOverlay:true, Identify:overlayFrame.Identify, WindowIndex:windowIndex, Frame:overlayFrame }; //叠加指标信息
  10151. scriptIndex.Create(this,windowIndex);
  10152. overlayFrame.Script=scriptIndex;
  10153. }
  10154. subFrame.OverlayIndex.push(overlayFrame);
  10155. return overlayFrame;
  10156. }
  10157. //获取子窗口的所有画法
  10158. this.GetChartPaint = function (windowIndex)
  10159. {
  10160. var paint = new Array();
  10161. for (var i in this.ChartPaint)
  10162. {
  10163. if (i < 3) continue; //分钟 均线 成交量 3个线不能改
  10164. var item = this.ChartPaint[i];
  10165. if (item.ChartFrame == this.Frame.SubFrame[windowIndex].Frame)
  10166. paint.push(item);
  10167. }
  10168. return paint;
  10169. }
  10170. //创建指定窗口指标
  10171. this.CreateWindowIndex = function (windowIndex)
  10172. {
  10173. this.WindowIndex[windowIndex].Create(this, windowIndex);
  10174. }
  10175. this.CreateExtendChart = function (name, option) //创建扩展图形
  10176. {
  10177. var chart;
  10178. switch (name)
  10179. {
  10180. case 'MinuteTooltip':
  10181. if (option.Create && typeof(option.Create)=='function') chart=option.Create();
  10182. else chart = new MinuteTooltipPaint();
  10183. chart.Canvas = this.Canvas;
  10184. chart.ChartBorder = this.Frame.ChartBorder;
  10185. chart.ChartFrame = this.Frame;
  10186. chart.HQChart = this;
  10187. option.LanguageID = this.LanguageID;
  10188. chart.SetOption(option);
  10189. this.ExtendChartPaint.push(chart);
  10190. return chart;
  10191. case "BackgroundPaint":
  10192. case '背景图':
  10193. chart = new BackgroundPaint();
  10194. chart.Canvas = this.Canvas;
  10195. chart.ChartBorder = this.Frame.ChartBorder;
  10196. chart.ChartFrame = this.Frame;
  10197. chart.HQChart = this;
  10198. chart.SetOption(option);
  10199. this.ExtendChartPaint.push(chart);
  10200. return chart;
  10201. default:
  10202. chart=g_ExtendChartPaintFactory.Create(name);
  10203. if (!chart) return null;
  10204. chart.Canvas=this.Canvas;
  10205. chart.ChartBorder=this.Frame.ChartBorder;
  10206. chart.ChartFrame=this.Frame;
  10207. chart.HQChart=this;
  10208. chart.SetOption(option);
  10209. this.ExtendChartPaint.push(chart);
  10210. return chart;
  10211. }
  10212. }
  10213. this.SetMinuteInfo = function (aryInfo, bUpdate)
  10214. {
  10215. this.ChartInfo = []; //先清空
  10216. for (var i in aryInfo)
  10217. {
  10218. var infoItem = JSMinuteInfoMap.Get(aryInfo[i]);
  10219. if (!infoItem) continue;
  10220. var item = infoItem.Create();
  10221. this.ChartInfo.push(item);
  10222. }
  10223. if (bUpdate == true) this.RequestMinuteInfoData();
  10224. }
  10225. this.GetChartMinuteInfo = function ()
  10226. {
  10227. return this.ChartInfoPaint;
  10228. }
  10229. this.CreateMinuteInfo = function (option) //在Create()以后 在调用
  10230. {
  10231. var chart = new ChartMinuteInfo();
  10232. chart.Canvas = this.Canvas;
  10233. chart.ChartBorder = this.Frame.SubFrame[0].Frame.ChartBorder;
  10234. chart.ChartFrame = this.Frame.SubFrame[0].Frame;
  10235. chart.ChartMinutePrice = this.ChartPaint[0];
  10236. if (option && chart.SetOption) chart.SetOption(option);
  10237. this.ChartInfoPaint = chart;
  10238. return chart;
  10239. }
  10240. //信息地雷数据请求
  10241. this.RequestMinuteInfoData = function ()
  10242. {
  10243. if (this.ChartInfo.length <= 0) return;
  10244. var chart = this.GetChartMinuteInfo();
  10245. if (!chart) chart = this.CreateMinuteInfo(null); //不存在就创建
  10246. chart.SourceData = this.SourceData;
  10247. //信息地雷信息
  10248. for (var i in this.ChartInfo) {
  10249. this.ChartInfo[i].RequestData(this);
  10250. }
  10251. }
  10252. //更新信息地雷
  10253. this.UpdataChartInfo = function ()
  10254. {
  10255. var chart = this.GetChartMinuteInfo();
  10256. if (!chart) return;
  10257. var infoMap = new Map();
  10258. for (var i in this.ChartInfo)
  10259. {
  10260. var infoData = this.ChartInfo[i].Data;
  10261. for (var j in infoData)
  10262. {
  10263. var item = infoData[j];
  10264. var dateTime = `${item.Date} ${item.Time}`;
  10265. if (infoMap.has(dateTime)) infoMap.get(dateTime).Data.push(item);
  10266. else infoMap.set(dateTime, { Data: new Array(item) });
  10267. }
  10268. }
  10269. chart.Data = infoMap;
  10270. }
  10271. this.TryClickIndexTitle=function(x,y)
  10272. {
  10273. for(var i=0; i<this.TitlePaint.length; ++i)
  10274. {
  10275. var item=this.TitlePaint[i];
  10276. if (!item.IsClickTitle) continue;
  10277. if (!item.IsClickTitle(x,y)) continue;
  10278. var data={ Point:{X:x, Y:y}, Title:item.Title, FrameID:item.Frame.Identify };
  10279. JSConsole.Chart.Log('[MinuteChartContainer::TryClickIndexTitle] click title ', data);
  10280. var event=this.GetEvent(JSCHART_EVENT_ID.ON_CLICK_INDEXTITLE);
  10281. if (event && event.Callback) event.Callback(event,data,this);
  10282. return true;
  10283. }
  10284. return false;
  10285. }
  10286. //接收到窗口指标数据 订阅模式
  10287. this.RecvWindowIndex=function(index, data)
  10288. {
  10289. if (index<2) return;
  10290. var indexItem=this.WindowIndex[index];
  10291. if (!indexItem) return;
  10292. if (typeof(indexItem.RecvSubscribeData)=="function")
  10293. {
  10294. var bindData=this.SourceData;
  10295. indexItem.RecvSubscribeData(data,this,index,bindData);
  10296. }
  10297. }
  10298. this.UpdateWindowIndex=function(index)
  10299. {
  10300. if (index<2) return;
  10301. var bindData=this.SourceData;
  10302. this.BindIndexData(index,bindData)
  10303. this.UpdataDataoffset(); //更新数据偏移
  10304. this.UpdateFrameMaxMin(); //调整坐标最大 最小值
  10305. this.Draw();
  10306. }
  10307. this.CreateChartDrawPicture=function(name, option, callback)
  10308. {
  10309. var drawPicture=null;
  10310. var item=IChartDrawPicture.GetDrawPictureByName(name);
  10311. if (item) drawPicture=item.Create();
  10312. if (!drawPicture) return false;
  10313. drawPicture.Canvas=this.Canvas;
  10314. drawPicture.Status=0;
  10315. drawPicture.Symbol=this.Symbol;
  10316. drawPicture.Period=888888888;
  10317. drawPicture.Option=this.ChartDrawOption;
  10318. drawPicture.PixelRatio=this.UIElement.PixelRatio;
  10319. if (callback) drawPicture.FinishedCallback=callback; //完成通知上层回调
  10320. if (option) drawPicture.SetOption(option);
  10321. var self=this;
  10322. drawPicture.Update=function() //更新回调函数
  10323. {
  10324. self.DrawDynamicInfo();
  10325. };
  10326. drawPicture.GetActiveDrawPicture=function() { return self.GetActiveDrawPicture(); }
  10327. this.CurrentChartDrawPicture=drawPicture;
  10328. JSConsole.Chart.Log("[MinuteChartContainer::CreateChartDrawPicture] ", name,this.CurrentChartDrawPicture);
  10329. return true;
  10330. }
  10331. this.GetKData=function()
  10332. {
  10333. if (!this.SourceData) return null;
  10334. var data=this.SourceData;
  10335. if (!data) return null;
  10336. return data;
  10337. }
  10338. }
  10339. //API 返回数据 转化为array[]
  10340. MinuteChartContainer.JsonDataToMinuteData = function (data)
  10341. {
  10342. var upperSymbol = data.stock[0].symbol.toUpperCase();
  10343. var isSHSZ = MARKET_SUFFIX_NAME.IsSHSZ(upperSymbol);
  10344. var isFutures = MARKET_SUFFIX_NAME.IsFutures(upperSymbol);
  10345. var isSHO = MARKET_SUFFIX_NAME.IsSHO(upperSymbol); //上海股票期权
  10346. var isSZO = MARKET_SUFFIX_NAME.IsSZO(upperSymbol); //深证股票期权
  10347. var preClose = data.stock[0].yclose; //前一个数据价格
  10348. var preAvPrice = data.stock[0].yclose; //前一个均价
  10349. var yClose = data.stock[0].yclose;
  10350. var yClearing=data.stock[0].yclearing;
  10351. if (isFutures && data.stock[0].yclearing) preClose = preAvPrice =yClearing ; //期货使用昨结算价
  10352. var date = data.stock[0].date;
  10353. var aryMinuteData = new Array();
  10354. for (var i in data.stock[0].minute)
  10355. {
  10356. var jsData = data.stock[0].minute[i];
  10357. var item = new MinuteData();
  10358. if (jsData.price) preClose = jsData.price;
  10359. if (jsData.avprice) preAvPrice = jsData.avprice;
  10360. item.YClearing=yClearing;
  10361. item.YClose=yClose;
  10362. item.Close = jsData.price;
  10363. item.Open = jsData.open;
  10364. item.High = jsData.high;
  10365. item.Low = jsData.low;
  10366. item.Vol = jsData.vol;
  10367. item.Amount = jsData.amount;
  10368. item.Increase = jsData.increase;
  10369. item.Risefall = jsData.risefall;
  10370. item.AvPrice = jsData.avprice;
  10371. if (!item.Close) //当前没有价格 使用上一个价格填充
  10372. {
  10373. item.Close = preClose;
  10374. item.Open = item.High = item.Low = item.Close;
  10375. }
  10376. if (!item.AvPrice) item.AvPrice = preAvPrice;
  10377. if (jsData.date > 0) date = jsData.date; //分钟数据中有日期 优先使用
  10378. item.DateTime = date.toString() + " " + jsData.time.toString();
  10379. item.Date = date;
  10380. item.Time = jsData.time;
  10381. if (isFutures || isSHO || isSZO) item.Position = jsData.position; //期货 期权有持仓
  10382. if (yClose && item.Close) item.Increase = (item.Close - yClose) / yClose * 100; //涨幅 (最新价格-昨收)/昨收*100
  10383. if (isFutures && yClearing && item.Close) item.Increase = (item.Close - yClearing) / yClearing * 100; //涨幅 (最新价格-昨结算价)/昨结算价*100
  10384. if (jsData.ExtendData) item.ExtendData=jsData.ExtendData; //扩展数据
  10385. aryMinuteData[i] = item;
  10386. }
  10387. return aryMinuteData;
  10388. }
  10389. //多日日线数据API 转化成array[];
  10390. MinuteChartContainer.JsonDataToMinuteDataArray = function (data)
  10391. {
  10392. var upperSymbol = data.symbol.toUpperCase();
  10393. var isSHSZ = MARKET_SUFFIX_NAME.IsSHSZ(upperSymbol);
  10394. var isFutures = MARKET_SUFFIX_NAME.IsFutures(upperSymbol);
  10395. var isSHO = MARKET_SUFFIX_NAME.IsSHO(upperSymbol); //上海股票期权
  10396. var isSZO = MARKET_SUFFIX_NAME.IsSZO(upperSymbol); //深证股票期权
  10397. var result = [];
  10398. var extendDataIndex=JSCHART_DATA_FIELD_ID.MINUTE_MULTI_DAY_EXTENDDATA; //扩展数据序号
  10399. for (var i=0; i<data.data.length; ++i)
  10400. {
  10401. var minuteData = [];
  10402. var dayData = data.data[i];
  10403. var date = dayData.date;
  10404. var yClose = dayData.yclose; //前收盘 计算涨幅
  10405. var preClose = yClose; //前一个数据价格
  10406. var yClearing=dayData.yclearing; //昨结算价
  10407. var preAvPrice=null; //前一个均价
  10408. for (var j=0;j<dayData.minute.length; ++j)
  10409. {
  10410. var jsData = dayData.minute[j];
  10411. if (jsData[2]) preClose = jsData[2]; //保存上一个收盘数据
  10412. var item = new MinuteData();
  10413. item.YClose=yClose;
  10414. item.YClearing=yClearing;
  10415. item.Close = jsData[2];
  10416. item.Open = jsData[1];
  10417. item.High = jsData[3];
  10418. item.Low = jsData[4];
  10419. item.Increase = null;
  10420. item.Vol = jsData[5];
  10421. item.Amount = jsData[6];
  10422. if (7 < jsData.length && jsData[7] > 0)
  10423. {
  10424. item.AvPrice = jsData[7]; //均价
  10425. preAvPrice = jsData[7];
  10426. }
  10427. if (!item.Close) //当前没有价格 使用上一个价格填充
  10428. {
  10429. item.Close = preClose;
  10430. item.Open = item.High = item.Low = item.Close;
  10431. }
  10432. if (!item.AvPrice && preAvPrice) item.AvPrice = preAvPrice;
  10433. if (item.Close && yClose) item.Increase = (item.Close - yClose) / yClose * 100;
  10434. if (isFutures && item.Close && yClearing) item.Increase = (item.Close - yClearing) / yClearing * 100;
  10435. item.DateTime = date.toString() + " " + jsData[0].toString();
  10436. item.Date = date;
  10437. item.Time = jsData[0];
  10438. if (8<jsData.length && jsData[8]>0)
  10439. {
  10440. item.Date=jsData[8]; //日期
  10441. item.DateTime=item.Date.toString()+" "+jsData[0].toString();
  10442. }
  10443. if ((isFutures || isSHO || isSZO) && 9 < jsData.length) item.Position = jsData[9]; //持仓
  10444. else if (IFrameSplitOperator.IsNumber(jsData[9])) item.Position=jsData[9];
  10445. if (j == 0 )
  10446. {
  10447. //if (isSHSZ) item.DateTime = date.toString() + " 0925";//第1个数据 写死9:25
  10448. item.IsFristData = true;
  10449. }
  10450. if (jsData[extendDataIndex]) item.ExtendData=jsData[extendDataIndex];
  10451. minuteData[j] = item;
  10452. }
  10453. var newData = new ChartData();
  10454. newData.Data = minuteData;
  10455. newData.YClose = yClose;
  10456. newData.Close = dayData.close;
  10457. newData.Date = date;
  10458. if (IFrameSplitOperator.IsNumber(yClearing)) newData.YClearing=yClearing;
  10459. result.push(newData);
  10460. }
  10461. return result;
  10462. }
  10463. //分钟增量数据 stock: [ { date:, yclose:, yclearing: , minute:[ [],]} 0=日期 1=时间 2=开 3=高 4=低 5=收 6=均价 7=量 8=金额 9=涨幅 10=涨跌 11=领先指标 ]
  10464. MinuteChartContainer.JsonDataToUpdateMinuteData=function(data)
  10465. {
  10466. if (!data || !data.stock) return null;
  10467. var stock=data.stock[0];
  10468. if (!IFrameSplitOperator.IsNumber(stock.date)) return null;
  10469. var symbol=data.stock[0].symbol;
  10470. var upperSymbol=symbol.toUpperCase();
  10471. var isSHSZ=MARKET_SUFFIX_NAME.IsSHSZ(upperSymbol);
  10472. var isFutures=MARKET_SUFFIX_NAME.IsFutures(upperSymbol); //国内期货, 纽约期货交易所
  10473. var minuteData={ Date:stock.date, Data:[] , Symbol:symbol, Name:stock.name };
  10474. var extendDataIndex=JSCHART_DATA_FIELD_ID.MINUTE_DAY_EXTENDDATA; //扩展数据序号
  10475. if (IFrameSplitOperator.IsNumber(stock.high)) minuteData.High=stock.high;
  10476. if (IFrameSplitOperator.IsNumber(stock.low)) minuteData.Low=stock.low;
  10477. if (IFrameSplitOperator.IsNumber(stock.yclose)) minuteData.YClose=stock.yclose;
  10478. if (IFrameSplitOperator.IsNumber(stock.YClearing)) minuteData.YClearing=stock.yclearing;
  10479. if (IFrameSplitOperator.IsNumber(stock.high)) minuteData.High=stock.high;
  10480. if (IFrameSplitOperator.IsNumber(stock.low)) minuteData.Low=stock.low;
  10481. if (IFrameSplitOperator.IsNumber(stock.yclose)) minuteData.YClose=stock.yclose;
  10482. if (IFrameSplitOperator.IsNumber(stock.YClearing)) minuteData.YClearing=stock.yclearing;
  10483. if (!IFrameSplitOperator.IsNonEmptyArray(stock.minute)) return minuteData;
  10484. for(var i=0;i<stock.minute.length;++i)
  10485. {
  10486. var jsData=stock.minute[i];
  10487. var item=new MinuteData();
  10488. item.YClearing=minuteData.YClearing;
  10489. item.YClose=minuteData.YClose;
  10490. item.Date=jsData[0];
  10491. item.Time=jsData[1];
  10492. item.Open=jsData[2];
  10493. item.High=jsData[3];
  10494. item.Low=jsData[4];
  10495. item.Close=jsData[5];
  10496. item.AvPrice=jsData[6];
  10497. item.Vol=jsData[7];
  10498. item.Amount=jsData[8];
  10499. if (IFrameSplitOperator.IsNumber(jsData[9])) item.Increase=jsData[9];
  10500. if (IFrameSplitOperator.IsNumber(jsData[10])) item.Risefall=jsData[10];
  10501. if (IFrameSplitOperator.IsNumber(jsData[11])) item.Lead=jsData[11];
  10502. if (jsData[extendDataIndex]) item.ExtendData=jsData[extendDataIndex];
  10503. item.DateTime=item.Date.toString()+" "+item.Time.toString();
  10504. if (IFrameSplitOperator.IsNumber(minuteData.YClose) && item.Close)
  10505. item.Increase=(item.Close-minuteData.YClose)/minuteData.YClose*100; //涨幅 (最新价格-昨收)/昨收*100;
  10506. if (isFutures && minuteData.YClearing && item.Close)
  10507. item.Increase=(item.Close-minuteData.YClearing)/minuteData.YClearing*100; //涨幅 (最新价格-昨结算价)/昨结算价*100;
  10508. minuteData.Data.push(item);
  10509. }
  10510. return minuteData;
  10511. }
  10512. /////////////////////////////////////////////////////////////////////////////
  10513. // 自定义指数
  10514. //
  10515. function CustomKLineChartContainer(uielement) {
  10516. this.newMethod = KLineChartContainer; //派生
  10517. this.newMethod(uielement);
  10518. delete this.newMethod;
  10519. this.ClassName = 'CustomKLineChartContainer';
  10520. this.ChangeRight = null; //没有复权设置
  10521. this.LoadDataSplashTitle = '计算指数数据';
  10522. this.CustomKLineApiUrl = g_JSChartResource.Domain + "/API/IndexCalculate"; //自定义指数计算地址
  10523. this.CustomStock; //成分
  10524. this.QueryDate = { Start: 20180101, End: 20180627 }; //计算时间区间
  10525. this.RequestHistoryData = function () {
  10526. var self = this;
  10527. this.ChartSplashPaint.SetTitle(this.LoadDataSplashTitle);
  10528. this.ChartSplashPaint.EnableSplash(true);
  10529. this.Draw();
  10530. JSNetwork.HttpRequest({
  10531. url: this.CustomKLineApiUrl,
  10532. data:
  10533. {
  10534. "stock": self.CustomStock,
  10535. "Name": self.Symbol,
  10536. "date": { "startdate": self.QueryDate.Start, "enddate": self.QueryDate.End }
  10537. },
  10538. method: 'POST',
  10539. dataType: "json",
  10540. async: true,
  10541. success: function (data) {
  10542. self.ChartSplashPaint.EnableSplash(false);
  10543. self.RecvHistoryData(data);
  10544. }
  10545. });
  10546. }
  10547. this.RecvHistoryData = function (recvData)
  10548. {
  10549. var data = recvData.data;
  10550. var aryDayData = KLineChartContainer.JsonDataToHistoryData(data);
  10551. //原始数据
  10552. var sourceData = new ChartData();
  10553. sourceData.Data = aryDayData;
  10554. sourceData.DataType = 0; //0=日线数据 1=分钟数据
  10555. sourceData.Symbol = data.symbol;
  10556. //显示的数据
  10557. var bindData = new ChartData();
  10558. bindData.Data = aryDayData;
  10559. bindData.Right = 0; //指数没有复权
  10560. bindData.Period = this.Period;
  10561. bindData.DataType = 0;
  10562. bindData.Symbol = data.symbol;
  10563. if (ChartData.IsDayPeriod(this.Period, false)) //周期数据
  10564. {
  10565. var periodData = sourceData.GetPeriodData(bindData.Period);
  10566. bindData.Data = periodData;
  10567. }
  10568. //绑定数据
  10569. this.SourceData = sourceData;
  10570. this.Name = data.name;
  10571. this.BindMainData(bindData, this.PageSize);
  10572. for (var i = 0; i < this.Frame.SubFrame.length; ++i)
  10573. {
  10574. this.BindIndexData(i, bindData);
  10575. }
  10576. //this.BindIndexData(0,hisData);
  10577. //this.BindIndexData(1,hisData);
  10578. //this.BindIndexData(2,hisData);
  10579. //刷新画图
  10580. this.UpdataDataoffset(); //更新数据偏移
  10581. this.UpdatePointByCursorIndex(); //更新十字光标位子
  10582. this.UpdateFrameMaxMin(); //调整坐标最大 最小值
  10583. this.Frame.SetSizeChange(true);
  10584. this.Draw();
  10585. if (typeof (this.UpdateUICallback) == 'function') this.UpdateUICallback('RecvHistoryData', this);
  10586. }
  10587. }
  10588. ////////////////////////////////////////////////////////////////////////////////
  10589. // K线横屏显示
  10590. //
  10591. function KLineChartHScreenContainer(uielement)
  10592. {
  10593. this.newMethod = KLineChartContainer; //派生
  10594. this.newMethod(uielement);
  10595. delete this.newMethod;
  10596. this.ClassName = 'KLineChartHScreenContainer';
  10597. this.OnMouseMove = function (x, y, e)
  10598. {
  10599. this.LastPoint.X = x;
  10600. this.LastPoint.Y = y;
  10601. this.CursorIndex = this.Frame.GetXData(y);
  10602. this.DrawDynamicInfo();
  10603. }
  10604. //手机拖拽
  10605. this.ontouchstart = function (e)
  10606. {
  10607. if (this.ChartSplashPaint && this.ChartSplashPaint.IsEnableSplash == true) return;
  10608. var jsChart = this;
  10609. if (jsChart.DragMode == 0) return;
  10610. this.IsPress=false;
  10611. this.IsOnTouch = true;
  10612. this.PhonePinch = null;
  10613. this.TouchDrawCount=0;
  10614. if (this.IsPhoneDragging(e))
  10615. {
  10616. var touches = this.GetToucheData(e);
  10617. var pt={ X:touches[0].clientX, Y:touches[0].clientY};
  10618. if (this.TryPhoneClickButton(pt.X, pt.Y, e)) return;
  10619. //长按2秒,十字光标
  10620. if (this.TouchTimer != null) clearTimeout(this.TouchTimer);
  10621. var bStartTimer=true;
  10622. if (this.EnableClickModel && this.ClickModel.IsShowCorssCursor==true) bStartTimer=false;
  10623. var drag = { "Click": {}, "LastMove": {}, };//最后移动的位置
  10624. var touches = this.GetToucheData(e);
  10625. drag.Click.X = touches[0].clientX;
  10626. drag.Click.Y = touches[0].clientY;
  10627. drag.LastMove.X = touches[0].clientX;
  10628. drag.LastMove.Y = touches[0].clientY;
  10629. this.MouseDrag = drag;
  10630. this.PhoneTouchInfo={ Start:{X:touches[0].clientX, Y:touches[0].clientY }, End:{ X:touches[0].clientX, Y:touches[0].clientY } };
  10631. if (this.SelectChartDrawPicture) this.SelectChartDrawPicture.IsSelected=false;
  10632. this.SelectChartDrawPicture=null;
  10633. if (this.CurrentChartDrawPicture) //画图工具模式
  10634. {
  10635. var drawPicture=this.CurrentChartDrawPicture;
  10636. if (drawPicture.Status==2)
  10637. this.SetChartDrawPictureThirdPoint(drag.Click.X,drag.Click.Y,true);
  10638. else
  10639. {
  10640. this.SetChartDrawPictureFirstPoint(drag.Click.X,drag.Click.Y,true);
  10641. //只有1个点 直接完成
  10642. if (this.FinishChartDrawPicturePoint()) this.DrawDynamicInfo({Corss:false, Tooltip:false});
  10643. }
  10644. return;
  10645. }
  10646. else
  10647. {
  10648. var drawPictrueData={X:touches[0].clientX, Y:touches[0].clientY, PixelRatio:this.UIElement.PixelRatio };
  10649. if (this.GetChartDrawPictureByPoint(drawPictrueData))
  10650. {
  10651. drawPictrueData.ChartDrawPicture.Status=20;
  10652. drawPictrueData.ChartDrawPicture.ValueToPoint();
  10653. drawPictrueData.ChartDrawPicture.MovePointIndex=drawPictrueData.PointIndex;
  10654. drawPictrueData.ChartDrawPicture.IsSelected=true;
  10655. this.CurrentChartDrawPicture=drawPictrueData.ChartDrawPicture;
  10656. this.SelectChartDrawPicture=drawPictrueData.ChartDrawPicture;
  10657. let event=this.GetEventCallback(JSCHART_EVENT_ID.ON_CLICK_DRAWPICTURE); //选中画图工具事件
  10658. if (event && event.Callback)
  10659. {
  10660. let sendData={ DrawPicture: drawPictrueData.ChartDrawPicture };
  10661. event.Callback(event,sendData,this);
  10662. }
  10663. this.DrawDynamicInfo();
  10664. return;
  10665. }
  10666. }
  10667. if (bStartTimer)
  10668. {
  10669. //长按2秒,十字光标
  10670. this.TouchTimer = setTimeout(function () {
  10671. jsChart.IsPress=true;
  10672. if (drag.Click.X == drag.LastMove.X && drag.Click.Y == drag.LastMove.Y) //手指没有移动,出现十字光标
  10673. {
  10674. var mouseDrag = jsChart.MouseDrag;
  10675. jsChart.MouseDrag = null;
  10676. //移动十字光标
  10677. var x = drag.Click.X;
  10678. var y = drag.Click.Y;
  10679. if (jsChart.EnableClickModel===true) jsChart.ClickModel.IsShowCorssCursor=true;
  10680. jsChart.OnMouseMove(x, y, e);
  10681. }
  10682. }, jsChart.PressTime);
  10683. }
  10684. if (this.EnableClickModel)
  10685. {
  10686. //if (this.ClickModel.IsShowCorssCursor===true) this.MoveCorssCursor(drag.Click,e)
  10687. }
  10688. else if (jsChart.IsClickShowCorssCursor)
  10689. {
  10690. var x = drag.Click.X;
  10691. var y = drag.Click.Y;
  10692. jsChart.OnMouseMove(x, y, e,true);
  10693. }
  10694. }
  10695. else if (this.IsPhonePinching(e))
  10696. {
  10697. var phonePinch = { "Start": {}, "Last": {}};
  10698. var touches = this.GetToucheData(e);
  10699. phonePinch.Start = { "X": touches[0].pageX, "Y": touches[0].pageY, "X2": touches[1].pageX, "Y2": touches[1].pageY };
  10700. phonePinch.Last = { "X": touches[0].pageX, "Y": touches[0].pageY, "X2": touches[1].pageX, "Y2": touches[1].pageY };
  10701. this.PhonePinch = phonePinch;
  10702. this.SelectChartDrawPicture=null;
  10703. }
  10704. this.TouchEvent({ EventID:JSCHART_EVENT_ID.ON_PHONE_TOUCH, FunctionName:"OnTouchStart"}, e);
  10705. }
  10706. this.ontouchmove = function (e)
  10707. {
  10708. if (this.ChartSplashPaint && this.ChartSplashPaint.IsEnableSplash == true) return;
  10709. var jsChart = this;
  10710. var touches = this.GetToucheData(e);
  10711. if (this.IsPhoneDragging(e))
  10712. {
  10713. var drag = jsChart.MouseDrag;
  10714. if (drag == null)
  10715. {
  10716. var x = touches[0].clientX;
  10717. var y = touches[0].clientY;
  10718. jsChart.OnMouseMove(x, y, e);
  10719. }
  10720. else
  10721. {
  10722. var moveSetp = Math.abs(drag.LastMove.Y - touches[0].clientY);
  10723. var moveUpDown=Math.abs(drag.LastMove.X-touches[0].clientX);
  10724. moveSetp = parseInt(moveSetp);
  10725. var isMoveCorssCursor=false; //是否移动十字光标
  10726. if (this.EnableClickModel)
  10727. {
  10728. if (this.ClickModel.IsShowCorssCursor===true) isMoveCorssCursor=true;
  10729. else isMoveCorssCursor=false;
  10730. }
  10731. if (this.CurrentChartDrawPicture)
  10732. {
  10733. var drawPicture=this.CurrentChartDrawPicture;
  10734. if (drawPicture.Status==1 || drawPicture.Status==2)
  10735. {
  10736. if(moveSetp<5 && moveUpDown<5) return;
  10737. if(this.SetChartDrawPictureSecondPoint(touches[0].clientX,touches[0].clientY))
  10738. {
  10739. this.DrawDynamicInfo();
  10740. }
  10741. }
  10742. else if (drawPicture.Status==3)
  10743. {
  10744. if(this.SetChartDrawPictureThirdPoint(touches[0].clientX,touches[0].clientY))
  10745. {
  10746. this.DrawDynamicInfo();
  10747. }
  10748. }
  10749. else if (drawPicture.Status==20) //画图工具移动
  10750. {
  10751. if(moveSetp<5 && moveUpDown<5) return;
  10752. if(this.MoveChartDrawPicture(touches[0].clientX-drag.LastMove.X,touches[0].clientY-drag.LastMove.Y))
  10753. {
  10754. this.DrawDynamicInfo();
  10755. }
  10756. }
  10757. drag.LastMove.X=touches[0].clientX;
  10758. drag.LastMove.Y=touches[0].clientY;
  10759. }
  10760. else if (isMoveCorssCursor)
  10761. {
  10762. jsChart.MouseDrag=null;
  10763. jsChart.MoveCorssCursor(drag.Click,e); //移动十字光标
  10764. }
  10765. else if (jsChart.DragMode == 1) //数据左右拖拽
  10766. {
  10767. if (moveSetp < 5) return;
  10768. var isLeft = true;
  10769. if (drag.LastMove.Y < touches[0].clientY) isLeft = false;//右移数据
  10770. if (jsChart.DataMove(moveSetp, isLeft))
  10771. {
  10772. jsChart.UpdataDataoffset();
  10773. jsChart.UpdatePointByCursorIndex();
  10774. jsChart.UpdateFrameMaxMin();
  10775. jsChart.ResetFrameXYSplit();
  10776. jsChart.Draw();
  10777. }
  10778. else
  10779. {
  10780. if (jsChart.DragDownloadData) jsChart.DragDownloadData();
  10781. }
  10782. drag.LastMove.X = touches[0].clientX;
  10783. drag.LastMove.Y = touches[0].clientY;
  10784. }
  10785. }
  10786. if (this.PhoneTouchInfo)
  10787. {
  10788. this.PhoneTouchInfo.End.X=touches[0].clientX;
  10789. this.PhoneTouchInfo.End.Y=touches[0].clientY;
  10790. }
  10791. }
  10792. else if (this.IsPhonePinching(e))
  10793. {
  10794. var phonePinch = jsChart.PhonePinch;
  10795. if (!phonePinch) return;
  10796. if (this.EnableZoomUpDown && this.EnableZoomUpDown.Touch===false) return;
  10797. var yHeight = Math.abs(touches[0].pageX - touches[1].pageX);
  10798. var yLastHeight = Math.abs(phonePinch.Last.X - phonePinch.Last.X2);
  10799. var yStep = yHeight - yLastHeight;
  10800. if (Math.abs(yStep) < 5) return;
  10801. if (yStep > 0) //放大
  10802. {
  10803. var cursorIndex = {};
  10804. cursorIndex.Index = parseInt(Math.abs(jsChart.CursorIndex - 0.5).toFixed(0));
  10805. if (!jsChart.Frame.ZoomUp(cursorIndex)) return;
  10806. jsChart.CursorIndex = cursorIndex.Index;
  10807. jsChart.UpdatePointByCursorIndex();
  10808. jsChart.UpdataDataoffset();
  10809. jsChart.UpdateFrameMaxMin();
  10810. jsChart.ResetFrameXYSplit();
  10811. jsChart.Draw();
  10812. }
  10813. else //缩小
  10814. {
  10815. var cursorIndex = {};
  10816. cursorIndex.Index = parseInt(Math.abs(jsChart.CursorIndex - 0.5).toFixed(0));
  10817. if (!jsChart.Frame.ZoomDown(cursorIndex)) return;
  10818. jsChart.CursorIndex = cursorIndex.Index;
  10819. jsChart.UpdataDataoffset();
  10820. jsChart.UpdatePointByCursorIndex();
  10821. jsChart.UpdateFrameMaxMin();
  10822. jsChart.ResetFrameXYSplit();
  10823. jsChart.Draw();
  10824. }
  10825. phonePinch.Last = { "X": touches[0].pageX, "Y": touches[0].pageY, "X2": touches[1].pageX, "Y2": touches[1].pageY };
  10826. }
  10827. }
  10828. uielement.onmousedown = function (e) //鼠标拖拽
  10829. {
  10830. if (!this.JSChartContainer) return;
  10831. if (this.JSChartContainer.DragMode == 0) return;
  10832. if (this.JSChartContainer.TryClickLock) {
  10833. var x = e.clientX - this.getBoundingClientRect().left;
  10834. var y = e.clientY - this.getBoundingClientRect().top;
  10835. if (this.JSChartContainer.TryClickLock(x, y)) return;
  10836. }
  10837. var drag =
  10838. {
  10839. "Click": {},
  10840. "LastMove": {}, //最后移动的位置
  10841. };
  10842. drag.Click.X = e.clientX;
  10843. drag.Click.Y = e.clientY;
  10844. drag.LastMove.X = e.clientX;
  10845. drag.LastMove.Y = e.clientY;
  10846. this.JSChartContainer.MouseDrag = drag;
  10847. document.JSChartContainer = this.JSChartContainer;
  10848. this.JSChartContainer.SelectChartDrawPicture = null;
  10849. uielement.ondblclick = function (e) {
  10850. var x = e.clientX - this.getBoundingClientRect().left;
  10851. var y = e.clientY - this.getBoundingClientRect().top;
  10852. if (this.JSChartContainer)
  10853. this.JSChartContainer.OnDoubleClick(x, y, e);
  10854. }
  10855. document.onmousemove = function (e) {
  10856. if (!this.JSChartContainer) return;
  10857. //加载数据中,禁用鼠标事件
  10858. if (this.JSChartContainer.ChartSplashPaint && this.JSChartContainer.ChartSplashPaint.IsEnableSplash == true) return;
  10859. var drag = this.JSChartContainer.MouseDrag;
  10860. if (!drag) return;
  10861. var moveSetp = Math.abs(drag.LastMove.Y - e.clientY);
  10862. if (this.JSChartContainer.DragMode == 1) //数据左右拖拽
  10863. {
  10864. if (moveSetp < 5) return;
  10865. var isLeft = true;
  10866. if (drag.LastMove.Y < e.clientY) isLeft = false;//右移数据
  10867. if (this.JSChartContainer.DataMove(moveSetp, isLeft)) {
  10868. this.JSChartContainer.UpdataDataoffset();
  10869. this.JSChartContainer.UpdatePointByCursorIndex();
  10870. this.JSChartContainer.UpdateFrameMaxMin();
  10871. this.JSChartContainer.ResetFrameXYSplit();
  10872. this.JSChartContainer.Draw();
  10873. }
  10874. drag.LastMove.X = e.clientX;
  10875. drag.LastMove.Y = e.clientY;
  10876. }
  10877. };
  10878. document.onmouseup = function (e) {
  10879. //清空事件
  10880. document.onmousemove = null;
  10881. document.onmouseup = null;
  10882. //清空数据
  10883. this.JSChartContainer.MouseDrag = null;
  10884. this.JSChartContainer.CurrentChartDrawPicture = null;
  10885. this.JSChartContainer = null;
  10886. }
  10887. }
  10888. //创建 windowCount 窗口个数
  10889. this.Create = function (windowCount)
  10890. {
  10891. this.UIElement.JSChartContainer = this;
  10892. //创建十字光标
  10893. this.ChartCorssCursor = new ChartCorssCursor();
  10894. this.ChartCorssCursor.Canvas = this.Canvas;
  10895. this.ChartCorssCursor.StringFormatX = g_DivTooltipDataForamt.Create("CorssCursor_XStringFormat");
  10896. this.ChartCorssCursor.StringFormatX.LanguageID=this.LanguageID;
  10897. this.ChartCorssCursor.StringFormatY = g_DivTooltipDataForamt.Create("CorssCursor_YStringFormat");
  10898. this.ChartCorssCursor.StringFormatY.LanguageID=this.LanguageID;
  10899. this.ChartCorssCursor.GetEventCallback=(id)=> { return this.GetEventCallback(id); }
  10900. //创建等待提示
  10901. this.ChartSplashPaint = new ChartSplashPaint();
  10902. this.ChartSplashPaint.Canvas = this.Canvas;
  10903. this.ChartSplashPaint.HQChart=this;
  10904. //创建框架容器
  10905. this.Frame = new HQTradeHScreenFrame();
  10906. this.Frame.ChartBorder = new ChartBorder();
  10907. this.Frame.ChartBorder.UIElement = this.UIElement;
  10908. this.Frame.ChartBorder.Top = 30;
  10909. this.Frame.ChartBorder.Left = 5;
  10910. this.Frame.ChartBorder.Bottom = 20;
  10911. this.Frame.Canvas = this.Canvas;
  10912. this.ChartCorssCursor.Frame = this.Frame; //十字光标绑定框架
  10913. this.ChartSplashPaint.Frame = this.Frame;
  10914. this.CreateChildWindow(windowCount);
  10915. this.CreateMainKLine();
  10916. //子窗口动态标题
  10917. for (var i in this.Frame.SubFrame)
  10918. {
  10919. var titlePaint = new DynamicChartTitlePainting();
  10920. titlePaint.Frame = this.Frame.SubFrame[i].Frame;
  10921. titlePaint.Canvas = this.Canvas;
  10922. titlePaint.GetEventCallback=(id)=> { return this.GetEventCallback(id); }
  10923. this.TitlePaint.push(titlePaint);
  10924. }
  10925. }
  10926. //创建子窗口
  10927. this.CreateChildWindow = function (windowCount)
  10928. {
  10929. for (var i = 0; i < windowCount; ++i)
  10930. {
  10931. var border = new ChartBorder();
  10932. border.UIElement = this.UIElement;
  10933. var frame = new KLineHScreenFrame();
  10934. frame.Canvas = this.Canvas;
  10935. frame.ChartBorder = border;
  10936. frame.Identify = i; //窗口序号
  10937. frame.RightSpaceCount = this.RightSpaceCount; //右边
  10938. frame.GetEventCallback=(id)=> { return this.GetEventCallback(id); };
  10939. frame.GlobalOption=this.GlobalOption;
  10940. frame.CreateLockPaint();
  10941. frame.HorizontalMax = 20;
  10942. frame.HorizontalMin = 10;
  10943. if (i == 0)
  10944. {
  10945. frame.YSplitOperator = new FrameSplitKLinePriceY();
  10946. frame.YSplitOperator.FrameSplitData = this.FrameSplitData.get('price');
  10947. frame.YSplitOperator.FrameSplitData2 = this.FrameSplitData.get('double');
  10948. //主图上下间距
  10949. border.TopSpace = 12;
  10950. border.BottomSpace = 12;
  10951. }
  10952. else
  10953. {
  10954. frame.YSplitOperator = new FrameSplitY();
  10955. frame.YSplitOperator.FrameSplitData = this.FrameSplitData.get('double');
  10956. //frame.IsLocked = true;
  10957. }
  10958. frame.YSplitOperator.Frame = frame;
  10959. frame.YSplitOperator.GetEventCallback=(id)=> { return this.GetEventCallback(id); }
  10960. frame.YSplitOperator.ChartBorder = border;
  10961. frame.XSplitOperator = new FrameSplitKLineX();
  10962. frame.XSplitOperator.Frame = frame;
  10963. frame.XSplitOperator.ChartBorder = border;
  10964. frame.XSplitOperator.GetEventCallback =(id)=> { return this.GetEventCallback(id); }
  10965. if (i != windowCount - 1) frame.XSplitOperator.ShowText = false;
  10966. for (var j = frame.HorizontalMin; j <= frame.HorizontalMax; j += 1)
  10967. {
  10968. frame.HorizontalInfo[j] = new CoordinateInfo();
  10969. frame.HorizontalInfo[j].Value = j;
  10970. if (i == 0 && j == frame.HorizontalMin) continue;
  10971. frame.HorizontalInfo[j].Message[1] = j.toString();
  10972. frame.HorizontalInfo[j].Font = "14px 微软雅黑";
  10973. }
  10974. var subFrame = new SubFrameItem();
  10975. frame.FrameData.SubFrameItem=subFrame;
  10976. subFrame.Frame = frame;
  10977. if (i == 0)
  10978. subFrame.Height = 20;
  10979. else
  10980. subFrame.Height = 10;
  10981. this.Frame.SubFrame[i] = subFrame;
  10982. }
  10983. }
  10984. this.CreateStockChipPhone=function(option)
  10985. {
  10986. var chart=new StockChipPhone();
  10987. chart.Canvas=this.Canvas;
  10988. chart.ChartBorder=this.Frame.ChartBorder;
  10989. chart.ChartFrame=this.Frame;
  10990. chart.HQChart=this;
  10991. chart.Left=this.Frame.ChartBorder.Bottom; //左边间距使用当前框架间距
  10992. chart.SetOption(option);
  10993. this.ExtendChartPaint.push(chart);
  10994. this.Frame.ChartBorder.Bottom+=chart.Width; //创建筹码需要增加右边的间距
  10995. this.GlobalOption.RightHorizontal.Show=false;
  10996. return chart;
  10997. }
  10998. this.DeleteStockChipChart=function()
  10999. {
  11000. var stockChip=this.GetStockChipChart();
  11001. if (!stockChip) return;
  11002. var chipWidth=stockChip.Chart.Width;
  11003. this.DeleteExtendChart(stockChip);
  11004. this.Frame.ChartBorder.Bottom-=chipWidth;
  11005. if (stockChip.Chart.ClassName=="StockChipPhone")
  11006. {
  11007. this.GlobalOption.RightHorizontal.Show=true;
  11008. this.Frame.ResetXYSplit();
  11009. }
  11010. this.SetSizeChange(true);
  11011. this.Draw();
  11012. }
  11013. }
  11014. ////////////////////////////////////////////////////////////////////////////////
  11015. // 走势图横屏显示
  11016. //
  11017. function MinuteChartHScreenContainer(uielement)
  11018. {
  11019. this.newMethod = MinuteChartContainer; //派生
  11020. this.newMethod(uielement);
  11021. delete this.newMethod;
  11022. this.ClassName = 'MinuteChartHScreenContainer';
  11023. this.OnMouseMove = function (x, y, e) {
  11024. this.LastPoint.X = x;
  11025. this.LastPoint.Y = y;
  11026. this.CursorIndex = this.Frame.GetXData(y);
  11027. this.DrawDynamicInfo();
  11028. }
  11029. //创建 windowCount 窗口个数
  11030. this.Create = function (windowCount)
  11031. {
  11032. this.UIElement.JSChartContainer = this;
  11033. //创建十字光标
  11034. this.ChartCorssCursor = new ChartCorssCursor();
  11035. this.ChartCorssCursor.Canvas = this.Canvas;
  11036. this.ChartCorssCursor.StringFormatX = new HQMinuteTimeStringFormat();
  11037. this.ChartCorssCursor.StringFormatY = new HQPriceStringFormat();
  11038. this.ChartCorssCursor.GetEventCallback=(id)=> { return this.GetEventCallback(id); }
  11039. this.ChartCorssCursor.HQChart=this;
  11040. //创建等待提示
  11041. this.ChartSplashPaint = new ChartSplashPaint();
  11042. this.ChartSplashPaint.Canvas = this.Canvas;
  11043. this.ChartSplashPaint.SplashTitle = this.LoadDataSplashTitle;
  11044. //创建框架容器
  11045. this.Frame = new HQTradeHScreenFrame();
  11046. this.Frame.ChartBorder = new ChartBorder();
  11047. this.Frame.ChartBorder.UIElement = this.UIElement;
  11048. this.Frame.ChartBorder.Top = 25;
  11049. this.Frame.ChartBorder.Left = 50;
  11050. this.Frame.ChartBorder.Bottom = 20;
  11051. this.Frame.Canvas = this.Canvas;
  11052. this.ChartCorssCursor.Frame = this.Frame; //十字光标绑定框架
  11053. this.ChartSplashPaint.Frame = this.Frame;
  11054. this.CreateChildWindow(windowCount);
  11055. this.CreateMainKLine();
  11056. //子窗口动态标题
  11057. for (var i in this.Frame.SubFrame)
  11058. {
  11059. var titlePaint = new DynamicChartTitlePainting();
  11060. titlePaint.Frame = this.Frame.SubFrame[i].Frame;
  11061. titlePaint.Canvas = this.Canvas;
  11062. titlePaint.GetEventCallback=(id)=> { return this.GetEventCallback(id); }
  11063. this.TitlePaint.push(titlePaint);
  11064. }
  11065. this.ChartCorssCursor.StringFormatX.Frame = this.Frame.SubFrame[0].Frame;
  11066. }
  11067. //创建子窗口
  11068. this.CreateChildWindow = function (windowCount)
  11069. {
  11070. for (var i = 0; i < windowCount; ++i)
  11071. {
  11072. var border = new ChartBorder();
  11073. border.UIElement = this.UIElement;
  11074. var frame = new MinuteHScreenFrame();
  11075. frame.Canvas = this.Canvas;
  11076. frame.ChartBorder = border;
  11077. if (i < 2) frame.ChartBorder.TitleHeight = 0;
  11078. frame.XPointCount = 243;
  11079. frame.Identify=i;
  11080. frame.HQChart=this;
  11081. frame.GetEventCallback=(id)=> { return this.GetEventCallback(id); }
  11082. frame.GlobalOption=this.GlobalOption;
  11083. frame.CreateLockPaint();
  11084. var DEFAULT_HORIZONTAL = [9, 8, 7, 6, 5, 4, 3, 2, 1];
  11085. frame.HorizontalMax = DEFAULT_HORIZONTAL[0];
  11086. frame.HorizontalMin = DEFAULT_HORIZONTAL[DEFAULT_HORIZONTAL.length - 1];
  11087. if (i == 0)
  11088. {
  11089. frame.YSplitOperator = new FrameSplitMinutePriceY();
  11090. frame.YSplitOperator.FrameSplitData = this.FrameSplitData.get('price');
  11091. }
  11092. else
  11093. {
  11094. frame.YSplitOperator = new FrameSplitY();
  11095. frame.YSplitOperator.FrameSplitData = this.FrameSplitData.get('double');
  11096. }
  11097. frame.YSplitOperator.GetEventCallback=(id)=> { return this.GetEventCallback(id); }
  11098. frame.YSplitOperator.Frame = frame;
  11099. frame.YSplitOperator.ChartBorder = border;
  11100. frame.XSplitOperator = new FrameSplitMinuteX();
  11101. frame.XSplitOperator.Frame = frame;
  11102. frame.XSplitOperator.ChartBorder = border;
  11103. frame.XSplitOperator.GetEventCallback=(id)=> { return this.GetEventCallback(id); }
  11104. if (i != windowCount - 1) frame.XSplitOperator.ShowText = false;
  11105. frame.XSplitOperator.Operator();
  11106. for (var j in DEFAULT_HORIZONTAL)
  11107. {
  11108. frame.HorizontalInfo[j] = new CoordinateInfo();
  11109. frame.HorizontalInfo[j].Value = DEFAULT_HORIZONTAL[j];
  11110. if (i == 0 && j == frame.HorizontalMin) continue;
  11111. frame.HorizontalInfo[j].Message[1] = DEFAULT_HORIZONTAL[j].toString();
  11112. frame.HorizontalInfo[j].Font = "14px 微软雅黑";
  11113. }
  11114. var subFrame = new SubFrameItem();
  11115. frame.FrameData.SubFrameItem=subFrame;
  11116. subFrame.Frame = frame;
  11117. if (i == 0)
  11118. subFrame.Height = 20;
  11119. else
  11120. subFrame.Height = 10;
  11121. this.Frame.SubFrame[i] = subFrame;
  11122. }
  11123. }
  11124. }
  11125. ////////////////////////////////////////////////////////////////////////////////
  11126. // K线训练,包含横屏
  11127. //
  11128. function KLineTrainChartContainer(uielement, bHScreen)
  11129. {
  11130. if (bHScreen === true)
  11131. {
  11132. this.newMethod = KLineChartHScreenContainer; //派生
  11133. this.newMethod(uielement);
  11134. delete this.newMethod;
  11135. }
  11136. else
  11137. {
  11138. this.newMethod = KLineChartContainer; //派生
  11139. this.newMethod(uielement);
  11140. delete this.newMethod;
  11141. }
  11142. this.ClassName2 = 'KLineTrainChartContainer';
  11143. this.BuySellPaint; //买卖点画法
  11144. this.TrainDataCount = 300; //训练数据个数
  11145. this.AutoRunTimer = null; //K线自动前进定时器
  11146. this.BuySellData = []; //模拟买卖数据 {Buy:{Price:价格,Date:日期,Time:时间} , Sell:{Price:价格,Date:日期,Time:时间}
  11147. this.TrainDataIndex; //当前训练的数据索引
  11148. this.TrainCallback; //训练回调 (K线每前进一次就调用一次)
  11149. this.DragMode = 1;
  11150. this.TrainStartEnd = {};
  11151. this.KLineSourceData; //原始K线数据 对应 SourceData
  11152. this.TrainInfo = { Start: {}, End: {} }; // Index:数据索引, Date:日期 Time:时间
  11153. this.CreateBuySellPaint = function () //在主窗口建立以后 创建买卖点
  11154. {
  11155. var chart = new ChartBuySell();
  11156. chart.Canvas = this.Canvas;
  11157. chart.ChartBorder = this.Frame.SubFrame[0].Frame.ChartBorder;
  11158. chart.ChartFrame = this.Frame.SubFrame[0].Frame;
  11159. chart.Name = "KLine-Train-BuySell";
  11160. this.ChartPaintEx[0] = chart;
  11161. }
  11162. this.GetKDataIndexByDateTime = function (kData, dateTime)
  11163. {
  11164. if (!dateTime || !kData) return -1;
  11165. for (var i=0; i<kData.length; ++i)
  11166. {
  11167. var item = kData[i];
  11168. if (ChartData.IsMinutePeriod(this.Period, true))
  11169. {
  11170. if (IFrameSplitOperator.IsNumber(this.TrainStartDate.Time))
  11171. {
  11172. if (item.Date >= this.TrainStartDate.Date && item.Time >= this.TrainStartDate.Time)
  11173. return i;
  11174. }
  11175. else
  11176. {
  11177. if (item.Date >= this.TrainStartDate.Date)
  11178. return i;
  11179. }
  11180. }
  11181. else if (ChartData.IsDayPeriod(this.Period, true) || ChartData.IsTickPeriod(this.Period))
  11182. {
  11183. if (item.Date >= this.TrainStartDate.Date)
  11184. return i;
  11185. }
  11186. }
  11187. return -1;
  11188. }
  11189. this.AfterBindMainData = function (funcName)
  11190. {
  11191. if (!this.ChartPaintEx[0]) this.CreateBuySellPaint();
  11192. var hisData = this.ChartPaint[0].Data;
  11193. this.ChartPaintEx[0].Data = hisData;
  11194. var showItem = hisData.Data[hisData.Data.length - 1];
  11195. //最后一个显示数据
  11196. this.TrainInfo.LastShowData = showItem;
  11197. //最后一个原始数据
  11198. this.TrainInfo.LastData = this.SourceData.Data[this.SourceData.Data.length - 1];
  11199. if (funcName != 'Update')
  11200. this.UpdateTrainUICallback("开始");
  11201. }
  11202. this.BeforeBindMainData = function (funcName)
  11203. {
  11204. if (funcName == "Update") return;
  11205. //全量数据 需要过滤
  11206. this.KLineSourceData = new ChartData();
  11207. this.KLineSourceData.Data = this.SourceData.Data.slice(0);
  11208. var count = this.SourceData.Data.length;
  11209. var lEnd = count - this.TrainDataCount - 20;
  11210. var findIndex = this.GetKDataIndexByDateTime(this.SourceData.Data, this.TrainStartDate);
  11211. if (findIndex >= 0)
  11212. {
  11213. lEnd = findIndex + 1;
  11214. if (count - lEnd < this.TrainDataCount) this.TrainDataCount = count - lEnd;
  11215. }
  11216. //训练起始日期
  11217. var index = lEnd - 1;
  11218. var kItem = this.SourceData.Data[index];
  11219. this.TrainInfo.Start.Index = index;
  11220. this.TrainInfo.Start.Date = kItem.Date;
  11221. this.TrainInfo.Start.Time = kItem.Time;
  11222. //训练结束日期
  11223. this.TrainInfo.End.Index = index;
  11224. this.TrainInfo.End.Date = kItem.Date;
  11225. this.TrainInfo.End.Time = kItem.Time;
  11226. //最后一个数据
  11227. this.TrainInfo.LastData = kItem;
  11228. //修改数据个数
  11229. this.SourceData.Data.length = lEnd;
  11230. }
  11231. this.Run = function (option)
  11232. {
  11233. if (this.AutoRunTimer) return;
  11234. if (this.TrainDataCount <= 0) return;
  11235. var self = this;
  11236. this.AutoRunTimer = setInterval(function () {
  11237. if (!self.MoveNextKLineData(option)) clearInterval(self.AutoRunTimer);
  11238. }, 1000);
  11239. }
  11240. this.MoveNextKLineData = function (option) //{PageSize:, Step:}
  11241. {
  11242. if (this.TrainDataCount <= 0) return false;
  11243. var step = 1, moveStep=0;
  11244. if (option && option.Step > 1) step = option.Step;
  11245. for (var i = 0; i < step; ++i)
  11246. {
  11247. var index = this.TrainInfo.End.Index + 1;
  11248. if (index >= this.KLineSourceData.Data.length) break;
  11249. var kItem = this.KLineSourceData.Data[index];
  11250. this.SourceData.Data.push(kItem);
  11251. this.TrainInfo.End.Index = index;
  11252. this.TrainInfo.End.Date = kItem.Date;
  11253. this.TrainInfo.End.Time = kItem.Time;
  11254. --this.TrainDataCount;
  11255. ++moveStep;
  11256. if (this.TrainDataCount <= 0) break;
  11257. }
  11258. if (moveStep == 0) return false;
  11259. //使用当前页数据个数移动K线
  11260. var pageSize = this.Frame.GetCurrentPageSize();
  11261. if (IFrameSplitOperator.IsNumber(pageSize))
  11262. this.PageSize = pageSize - this.RightSpaceCount;
  11263. this.Update();
  11264. if (this.TrainDataCount <= 0)
  11265. {
  11266. this.FinishTrainData();
  11267. this.UpdateTrainUICallback("结束");
  11268. return false;
  11269. }
  11270. this.UpdateTrainUICallback("训练中");
  11271. return true;
  11272. }
  11273. this.UpdateTrainUICallback = function (description)
  11274. {
  11275. //新的监听事件
  11276. if (!this.mapEvent.has(JSCHART_EVENT_ID.RECV_TRAIN_MOVE_STEP)) return;
  11277. var item = this.mapEvent.get(JSCHART_EVENT_ID.RECV_TRAIN_MOVE_STEP);
  11278. if (!item.Callback) return;
  11279. var data =
  11280. {
  11281. TrainDataCount: this.TrainDataCount,
  11282. BuySellData: this.BuySellData,
  11283. KLine:
  11284. {
  11285. Start: { Index: this.TrainInfo.Start.Index, Date: this.TrainInfo.Start.Date },
  11286. End: { Index: this.TrainInfo.End.Index, Date: this.TrainInfo.End.Date }
  11287. },
  11288. LastData: this.TrainInfo.LastData,
  11289. LastShowData: this.TrainInfo.LastShowData
  11290. };
  11291. if (IFrameSplitOperator.IsNumber(this.TrainInfo.Start.Time)) data.KLine.Start.Time = this.TrainInfo.Start.Time;
  11292. if (IFrameSplitOperator.IsNumber(this.TrainInfo.End.Time)) data.KLine.End.Time = this.TrainInfo.End.Time;
  11293. if (description) data.Description = description
  11294. if (this.TrainDataCount <= 0)
  11295. {
  11296. data.Symbol = this.Symbol;
  11297. data.Name = this.Name;
  11298. }
  11299. item.Callback(item, data, this);
  11300. }
  11301. this.FinishTrainData = function ()
  11302. {
  11303. }
  11304. this.Stop = function ()
  11305. {
  11306. if (this.AutoRunTimer != null) clearInterval(this.AutoRunTimer);
  11307. this.AutoRunTimer = null;
  11308. }
  11309. this.BuyOrSell = function (obj, bDraw) //{ Price:价格, Vol:数量, Op: 买/卖 0=buy 1=sell, ID:单号 } bDraw是否立即绘制图标
  11310. {
  11311. var kItem = this.TrainInfo.LastShowData;
  11312. if (!kItem) return false;
  11313. var buySellPaint = this.ChartPaintEx[0];
  11314. if (!buySellPaint) return false;
  11315. var hisData = this.ChartPaint[0].Data;
  11316. if (!hisData || hisData.Data.length <= 0) return false;
  11317. var index = hisData.Data.length - 1; //数据索引
  11318. var buyItem = { Date: this.TrainInfo.End.Date, Time: this.TrainInfo.End.Time, Price: obj.Price, Vol: obj.Vol, Op: 0, ID: obj.ID };
  11319. if (obj.Op == 1) buyItem.Op = 1;
  11320. var key = index;
  11321. buyItem.Key = key;
  11322. this.BuySellData.push(buyItem);
  11323. buySellPaint.AddTradeItem(buyItem);
  11324. if (bDraw == true) this.Draw();
  11325. }
  11326. this.RestartTrain = function (option) // { Symbol:, Period:周期, Right:复权, Train:{ DataCount:, DateTime: } }
  11327. {
  11328. JSConsole.Chart.Log('[KLineTrainChartContainer::RestartTrain] option ', option);
  11329. this.TrainInfo = { Start: {}, End: {} };
  11330. this.BuySellData = [];
  11331. this.KLineSourceData = null;
  11332. var buySellPaint = this.ChartPaintEx[0];
  11333. if (buySellPaint)
  11334. {
  11335. buySellPaint.Data = null;
  11336. buySellPaint.ClearTradeData();
  11337. }
  11338. if (option.Symbol) this.Symbol = option.Symbol;
  11339. if (IFrameSplitOperator.IsNumber(option.Period)) this.Period = option.Period;
  11340. if (IFrameSplitOperator.IsNumber(option.Right)) this.Right = option.Right;
  11341. if (option.Train)
  11342. {
  11343. if (option.Train.DataCount > 1) this.TrainDataCount = option.Train.DataCount;
  11344. if (option.Train.DateTime) this.TrainStartDate = option.Train.DateTime;
  11345. }
  11346. var symbol = this.Symbol;
  11347. this.ChangeSymbol(symbol);
  11348. }
  11349. }
  11350. ///////////////////////////////////////////////////////////////////////////////////
  11351. // 简单的K线图, 只计算一次
  11352. //
  11353. //////////////////////////////////////////////////////////////////////////////////
  11354. function KLineTrainSimpleChartContainer(uielement, bHScreen)
  11355. {
  11356. this.newMethod=KLineTrainChartContainer; //派生
  11357. this.newMethod(uielement, bHScreen);
  11358. delete this.newMethod;
  11359. this.IsHScreen=bHScreen;
  11360. this.IsZoomLockRight=true;
  11361. this.RightSpaceCount=0;
  11362. this.RecvFlowCapitalData=function(data)
  11363. {
  11364. this.Super_RecvFlowCapitalData(data);
  11365. }
  11366. this.BeforeBindMainData=function(funcName)
  11367. {
  11368. }
  11369. this.UpdateLastDataIcon=function()
  11370. {
  11371. if (!this.ChartPaintEx[0]) return;
  11372. var chart=this.ChartPaintEx[0];
  11373. chart.LastDataIndex=this.TrainInfo.End.Index;
  11374. }
  11375. this.AfterBindMainData=function(funcName)
  11376. {
  11377. if (!this.ChartPaintEx[0])
  11378. {
  11379. this.CreateBuySellPaint();
  11380. this.ChartPaintEx[0].LastDataDrawType=1;
  11381. }
  11382. if (funcName!="Update")
  11383. {
  11384. var hisData=this.ChartOperator_Temp_GetHistroyData();
  11385. if (!hisData) return false;
  11386. var count=hisData.Data.length;
  11387. var lEnd=count-this.TrainDataCount-20;
  11388. var xPointcount=this.Frame.SubFrame[0].Frame.XPointCount;
  11389. var findIndex=this.GetKDataIndexByDateTime(hisData.Data, this.TrainStartDate);
  11390. if (findIndex>=0)
  11391. {
  11392. lEnd=findIndex+1;
  11393. if (count-lEnd<this.TrainDataCount) this.TrainDataCount=count-lEnd;
  11394. }
  11395. var xOffset=lEnd-xPointcount;
  11396. hisData.DataOffset=xOffset;
  11397. var index=lEnd-1;
  11398. var kItem=hisData.Data[index];
  11399. //最后一个显示数据
  11400. this.TrainInfo.LastShowData=kItem;
  11401. this.TrainInfo.LastData = kItem;
  11402. //训练起始日期
  11403. this.TrainInfo.Start.Index=index;
  11404. this.TrainInfo.Start.Date=kItem.Date;
  11405. this.TrainInfo.Start.Time=kItem.Time;
  11406. //训练结束日期
  11407. this.TrainInfo.End.Index=index;
  11408. this.TrainInfo.End.Date=kItem.Date;
  11409. this.TrainInfo.End.Time=kItem.Time;
  11410. this.UpdateLastDataIcon();
  11411. this.UpdateTrainUICallback("开始");
  11412. }
  11413. }
  11414. this.Super_UpdataDataoffset=this.UpdataDataoffset;
  11415. this.UpdataDataoffset=function()
  11416. {
  11417. this.Super_UpdataDataoffset();
  11418. var hisData=this.ChartPaint[0].Data;
  11419. this.ChartPaintEx[0].Data=hisData;
  11420. }
  11421. this.MoveNextKLineData=function(option) //{PageSize:, Step:}
  11422. {
  11423. if (this.TrainDataCount<=0) return false;
  11424. var hisData=this.ChartOperator_Temp_GetHistroyData();
  11425. if (!hisData) return false;
  11426. var step=1;
  11427. if (option && option.Step>1) step=option.Step;
  11428. var count=hisData.Data.length;
  11429. var moveStep=0;
  11430. for(var i=0; i<step; ++i)
  11431. {
  11432. var index=this.TrainInfo.End.Index+1;
  11433. if (index>=count) break;
  11434. var kItem=hisData.Data[index];
  11435. this.TrainInfo.End.Index=index;
  11436. this.TrainInfo.End.Date=kItem.Date;
  11437. this.TrainInfo.End.Time=kItem.Time;
  11438. --this.TrainDataCount;
  11439. ++moveStep;
  11440. if (this.TrainDataCount<=0) break;
  11441. }
  11442. if (moveStep==0) return false;
  11443. //最后一个显示数据
  11444. this.TrainInfo.LastShowData=kItem;
  11445. this.TrainInfo.LastData = kItem;
  11446. //调整x轴索引位置
  11447. var lEnd=this.TrainInfo.End.Index;
  11448. var xPointcount=this.Frame.SubFrame[0].Frame.XPointCount;
  11449. var xOffset=lEnd-xPointcount+1;
  11450. hisData.DataOffset=xOffset;
  11451. this.UpdateLastDataIcon();
  11452. this.UpdataDataoffset();
  11453. this.UpdateFrameMaxMin();
  11454. this.Draw();
  11455. if (this.TrainDataCount<=0)
  11456. {
  11457. this.FinishTrainData();
  11458. this.UpdateTrainUICallback("结束");
  11459. return false;
  11460. }
  11461. this.UpdateTrainUICallback("训练中");
  11462. return true;
  11463. }
  11464. this.BuyOrSell=function(obj, bDraw) //{ Price:价格, Vol:数量, Op: 买/卖 0=buy 1=sell, ID:单号 } bDraw是否立即绘制图标
  11465. {
  11466. var kItem=this.TrainInfo.LastShowData;
  11467. if (!kItem) return false;
  11468. var buySellPaint=this.ChartPaintEx[0];
  11469. if (!buySellPaint) return false;
  11470. var hisData=this.ChartPaint[0].Data;
  11471. if (!hisData || hisData.Data.length<=0) return false;
  11472. var index=this.TrainInfo.End.Index; //数据索引
  11473. var buyItem={ Date:this.TrainInfo.End.Date, Time:this.TrainInfo.End.Time, Price:obj.Price, Vol:obj.Vol, Op:0, ID:obj.ID };
  11474. if (obj.Op==1) buyItem.Op=1;
  11475. var key=index;
  11476. buyItem.Key=key;
  11477. this.BuySellData.push(buyItem);
  11478. buySellPaint.AddTradeItem(buyItem);
  11479. if (bDraw==true) this.Draw();
  11480. }
  11481. this.DataMove=function(step,isLeft)
  11482. {
  11483. step=parseInt(step/this.StepPixel);
  11484. if (step<=0) return false;
  11485. var data = this.ChartOperator_Temp_GetHistroyData();
  11486. if (!data) return false;
  11487. var xPointcount = 0;
  11488. if (this.Frame.XPointCount) xPointcount = this.Frame.XPointCount;
  11489. else xPointcount = this.Frame.SubFrame[0].Frame.XPointCount;
  11490. if (!xPointcount) return false;
  11491. if (isLeft) //-->
  11492. {
  11493. if (this.RightSpaceCount > 0)
  11494. {
  11495. //TODO: not support
  11496. if (xPointcount + data.DataOffset >= data.Data.length + this.RightSpaceCount - 1) return false;
  11497. data.DataOffset += step;
  11498. if (data.DataOffset + xPointcount >= data.Data.length + this.RightSpaceCount)
  11499. data.DataOffset = data.Data.length - (xPointcount - this.RightSpaceCount);
  11500. }
  11501. else
  11502. {
  11503. var end=this.TrainInfo.End.Index+1;
  11504. if (xPointcount + data.DataOffset >= end) return false;
  11505. data.DataOffset += step;
  11506. if (data.DataOffset + xPointcount >= end)
  11507. data.DataOffset = end - xPointcount;
  11508. }
  11509. return true;
  11510. }
  11511. else //<--
  11512. {
  11513. if (data.DataOffset <= 0) return false;
  11514. data.DataOffset -= step;
  11515. if (data.DataOffset < 0) data.DataOffset = 0;
  11516. return true;
  11517. }
  11518. }
  11519. //获取最后一个数据的相对于当前屏的索引
  11520. this.GetLastDataIndex=function()
  11521. {
  11522. if (!this.ChartPaint[0] || !this.ChartPaint[0].Data || !this.ChartPaint[0].Data.Data) return null;
  11523. var hisData=this.ChartPaint[0].Data;
  11524. var dataCount=this.TrainInfo.End.Index+1
  11525. if (dataCount>0) return (dataCount-1)-hisData.DataOffset;
  11526. return null;
  11527. }
  11528. }
  11529. /////////////////////////////////////////////////////////////////////////////////
  11530. // 深度图
  11531. //
  11532. function DepthChartContainer(uielement)
  11533. {
  11534. this.newMethod=JSChartContainer; //派生
  11535. this.newMethod(uielement);
  11536. delete this.newMethod;
  11537. this.ClassName="DepthChartContainer";
  11538. this.Symbol;
  11539. //数据
  11540. this.MapAsk=new Map();
  11541. this.MapBid=new Map();
  11542. this.IsAutoUpdate=false; //是否自动更新行情数据
  11543. this.AutoUpdateFrequency=30000; //30秒更新一次数据
  11544. this.AutoUpdateTimer=null;
  11545. this.DefaultZoom=0.8; //默认显示80%的盘口 (0 - 1)
  11546. this.MaxVolRate=1.1;
  11547. this.Create=function(option)
  11548. {
  11549. this.UIElement.JSChartContainer=this;
  11550. //创建十字光标
  11551. this.ChartCorssCursor=new DepthChartCorssCursor();
  11552. this.ChartCorssCursor.Canvas=this.Canvas;
  11553. this.ChartCorssCursor.HQChart=this;
  11554. //this.ChartCorssCursor.StringFormatX=g_DivTooltipDataForamt.Create("CorssCursor_XStringFormat");
  11555. //this.ChartCorssCursor.StringFormatX.LanguageID=this.LanguageID;
  11556. //this.ChartCorssCursor.StringFormatY=g_DivTooltipDataForamt.Create("CorssCursor_YStringFormat");
  11557. //this.ChartCorssCursor.StringFormatY.LanguageID=this.LanguageID;
  11558. //创建等待提示
  11559. this.ChartSplashPaint = new ChartSplashPaint();
  11560. this.ChartSplashPaint.Canvas = this.Canvas;
  11561. this.ChartSplashPaint.SplashTitle = this.LoadDataSplashTitle;
  11562. //创建框架
  11563. this.Frame=new DepthChartFrame();
  11564. this.Frame.ChartBorder=new ChartBorder();
  11565. this.Frame.ChartBorder.UIElement=this.UIElement;
  11566. this.Frame.ChartBorder.Top=30;
  11567. this.Frame.ChartBorder.Left=5;
  11568. this.Frame.ChartBorder.Bottom=20;
  11569. this.Frame.ChartBorder.TitleHeight=0;
  11570. this.Frame.Canvas=this.Canvas;
  11571. this.Frame.Identify=0;
  11572. var ySplitOper=new FrameSplitY();
  11573. ySplitOper.FrameSplitData=this.FrameSplitData.get('double');
  11574. ySplitOper.LanguageID=this.LanguageID;
  11575. ySplitOper.Frame=this.Frame;
  11576. ySplitOper.SplitCount=5;
  11577. ySplitOper.IgnoreYValue=[0];
  11578. ySplitOper.LineType=3;
  11579. ySplitOper.ChartBorder=this.Frame.ChartBorder;
  11580. ySplitOper.GetEventCallback=(id)=> { return this.GetEventCallback(id); }
  11581. this.Frame.YSplitOperator=ySplitOper;
  11582. var xSplitOper=new FrameSplitXDepth();
  11583. xSplitOper.Frame=this.Frame;;
  11584. xSplitOper.ChartBorder=this.Frame.ChartBorder;;
  11585. xSplitOper.LanguageID=this.LanguageID;
  11586. xSplitOper.LineType=3;
  11587. xSplitOper.GetEventCallback=(id)=> { return this.GetEventCallback(id); };
  11588. this.Frame.XSplitOperator=xSplitOper
  11589. if (this.ChartCorssCursor) this.ChartCorssCursor.Frame=this.Frame; //十字光标绑定框架
  11590. this.ChartSplashPaint.Frame = this.Frame;
  11591. var chartItem=new ChartOrderbookDepth();
  11592. chartItem.Canvas=this.Canvas;
  11593. chartItem.ChartBorder=this.Frame.ChartBorder;
  11594. chartItem.ChartFrame=this.Frame;
  11595. chartItem.Name="深度图"
  11596. this.ChartPaint.push(chartItem);
  11597. }
  11598. this.ontouchstart=function(e)
  11599. {
  11600. this.IsOnTouch=true;
  11601. this.TouchDrawCount=0;
  11602. this.PhonePinch=null;
  11603. var isSingleTouch=this.IsSingleTouch(e);
  11604. if (this.EnableScrollUpDown==false || !isSingleTouch) //多点触屏
  11605. {
  11606. }
  11607. if (this.IsPhoneDragging(e))
  11608. {
  11609. var drag=
  11610. {
  11611. "Click":{},
  11612. "LastMove":{} //最后移动的位置
  11613. };
  11614. var touches=this.GetToucheData(e,this.IsForceLandscape);
  11615. drag.Click.X=touches[0].clientX;
  11616. drag.Click.Y=touches[0].clientY;
  11617. drag.LastMove.X=touches[0].clientX;
  11618. drag.LastMove.Y=touches[0].clientY;
  11619. this.MouseDrag=drag;
  11620. var x = drag.Click.X;
  11621. var y = drag.Click.Y;
  11622. this.OnMouseMove(x, y, e);
  11623. }
  11624. else if (this.IsPhonePinching(e))
  11625. {
  11626. var phonePinch=
  11627. {
  11628. "Start":{},
  11629. "Last":{}
  11630. };
  11631. var touches=this.GetToucheData(e,this.IsForceLandscape);
  11632. phonePinch.Start={"X":touches[0].pageX,"Y":touches[0].pageY,"X2":touches[1].pageX,"Y2":touches[1].pageY};
  11633. phonePinch.Last={"X":touches[0].pageX,"Y":touches[0].pageY,"X2":touches[1].pageX,"Y2":touches[1].pageY};
  11634. this.PhonePinch=phonePinch;
  11635. }
  11636. }
  11637. this.ontouchmove=function(e)
  11638. {
  11639. var touches=this.GetToucheData(e,false);
  11640. if (this.IsPhoneDragging(e))
  11641. {
  11642. var drag=this.MouseDrag;
  11643. if (drag==null)
  11644. {
  11645. var x = touches[0].clientX;
  11646. var y = touches[0].clientY;
  11647. this.OnMouseMove(x,y,e);
  11648. }
  11649. else
  11650. {
  11651. this.MouseDrag=null;
  11652. var x = touches[0].clientX;
  11653. var y = touches[0].clientY;
  11654. this.OnMouseMove(x,y,e);
  11655. }
  11656. }
  11657. else if (this.IsPhonePinching(e))
  11658. {
  11659. var phonePinch=this.PhonePinch;
  11660. if (!phonePinch) return;
  11661. if (this.EnableZoomUpDown && this.EnableZoomUpDown.Touch===false) return;
  11662. var yHeight = Math.abs(touches[0].pageY - touches[1].pageY);
  11663. var yLastHeight = Math.abs(phonePinch.Last.Y - phonePinch.Last.Y2);
  11664. var yStep = yHeight - yLastHeight;
  11665. var xHeight = Math.abs(touches[0].pageX - touches[1].pageX);
  11666. var xLastHeight = Math.abs(phonePinch.Last.X - phonePinch.Last.X2);
  11667. var xStep = xHeight - xLastHeight;
  11668. var minStep=this.ZoomStepPixel;
  11669. if (Math.abs(yStep) <minStep && Math.abs(xStep) < minStep) return;
  11670. var step = yStep;
  11671. if (Math.abs(yStep) < minStep) step = xStep;
  11672. if (step>0) //放大
  11673. {
  11674. if (!this.Frame.ZoomUp()) return;
  11675. this.UpdateFrameMaxMin();
  11676. this.Draw();
  11677. }
  11678. else //缩小
  11679. {
  11680. if (!this.Frame.ZoomDown()) return;
  11681. this.UpdateFrameMaxMin();
  11682. this.Draw();
  11683. }
  11684. phonePinch.Last={"X":touches[0].pageX,"Y":touches[0].pageY,"X2":touches[1].pageX,"Y2":touches[1].pageY};
  11685. }
  11686. }
  11687. this.ontouchend=function(e)
  11688. {
  11689. JSConsole.Chart.Log('[DepthChartContainer::OnTouchEnd]',e);
  11690. this.IsOnTouch = false;
  11691. this.Draw();
  11692. this.TouchDrawCount=0;
  11693. }
  11694. this.OnMouseMove = function (x, y, e, bFullDraw)
  11695. {
  11696. var lastY = this.LastPoint.Y;
  11697. this.LastPoint.X = x;
  11698. this.LastPoint.Y = y;
  11699. this.FullDraw();
  11700. }
  11701. this.ChangeSymbol=function(symbol)
  11702. {
  11703. this.CancelAutoUpdate(); //先停止定时器
  11704. this.Symbol=symbol;
  11705. this.MapBid=new Map();
  11706. this.MapAsk=new Map();
  11707. this.Frame.VerticalRange.Differ=null;
  11708. this.ChartSplashPaint.SetTitle(this.LoadDataSplashTitle);
  11709. this.ChartSplashPaint.EnableSplash(true);
  11710. this.Draw();
  11711. this.RequestDepthData();
  11712. }
  11713. this.RequestDepthData=function() //全量历史数据
  11714. {
  11715. var self=this;
  11716. if (this.NetworkFilter)
  11717. {
  11718. var obj=
  11719. {
  11720. Name:'DepthChartContainer::RequestDepthData', //类名::
  11721. Explain:'深度图数据',
  11722. Request:{ Data: { symbol:self.Symbol } },
  11723. Self:this,
  11724. PreventDefault:false
  11725. };
  11726. this.NetworkFilter(obj, function(data)
  11727. {
  11728. self.ChartSplashPaint.EnableSplash(false);
  11729. self.RecvDepthData(data);
  11730. self.AutoUpdate();
  11731. });
  11732. if (obj.PreventDefault==true) return; //已被上层替换,不调用默认的网络请求
  11733. }
  11734. }
  11735. this.RecvDepthData=function(data)
  11736. {
  11737. this.UpdateAskAndBid(data);
  11738. var aryAsk=Array.from(this.MapAsk.values()); //卖 右边
  11739. aryAsk.sort((a,b)=> { return a.Price-b.Price; });
  11740. var sumVol=0;
  11741. for(var i in aryAsk)
  11742. {
  11743. var item=aryAsk[i];
  11744. sumVol+=item.Vol;
  11745. aryAsk[i]={Price:item.Price, Vol:sumVol };
  11746. }
  11747. var aryBid=Array.from(this.MapBid.values()); //买 左边
  11748. aryBid.sort((a,b)=> { return b.Price-a.Price; });
  11749. var sumVol=0;
  11750. for(var i in aryBid)
  11751. {
  11752. var item=aryBid[i];
  11753. sumVol+=item.Vol;
  11754. aryBid[i]={Price:item.Price, Vol:sumVol };
  11755. }
  11756. var drawData={ Asks:aryAsk, Bids:aryBid };
  11757. var chart=this.ChartPaint[0];
  11758. chart.Data=drawData;
  11759. this.Frame.XSplitOperator.Symbol=this.Symbol;
  11760. this.ChartCorssCursor.Data=drawData;
  11761. this.ChartCorssCursor.Symbol=this.Symbol;
  11762. this.UpdateFramePriceList();
  11763. this.UpdateFrameMaxMin();
  11764. this.Draw();
  11765. }
  11766. this.UpdateAskAndBid=function(data) //更新数据
  11767. {
  11768. if(data.datatype=="snapshot") //全量数据
  11769. {
  11770. this.MapBid=new Map();
  11771. this.MapAsk=new Map();
  11772. }
  11773. for(var i in data.asks)
  11774. {
  11775. var item=data.asks[i];
  11776. var price=parseFloat(item[0]);
  11777. var vol=parseFloat(item[1]);
  11778. if (this.MapAsk.has(price))
  11779. {
  11780. var value=this.MapAsk.get(price);
  11781. if (vol<=0) this.MapAsk.delete(price);
  11782. else value.Vol=vol;
  11783. }
  11784. else
  11785. {
  11786. if (vol>0) this.MapAsk.set(price, { Price:price, Vol:vol});
  11787. }
  11788. }
  11789. for(var i in data.bids)
  11790. {
  11791. var item=data.bids[i];
  11792. var price=parseFloat(item[0]);
  11793. var vol=parseFloat(item[1]);
  11794. if (this.MapBid.has(price))
  11795. {
  11796. var value=this.MapBid.get(price);
  11797. if (vol<=0) this.MapBid.delete(price);
  11798. else value.Vol=vol;
  11799. }
  11800. else
  11801. {
  11802. if (vol>0) this.MapBid.set(price, { Price:price, Vol:vol});
  11803. }
  11804. }
  11805. }
  11806. this.UpdateFramePriceList=function()
  11807. {
  11808. var aryAskPrice=Array.from(this.MapAsk.keys());
  11809. var aryBidPrice=Array.from(this.MapBid.keys());
  11810. aryAskPrice.sort((a,b)=> { return a-b; });
  11811. aryBidPrice.sort((a,b)=> { return a-b; });
  11812. if (aryAskPrice.length>1 && aryBidPrice.length>1)
  11813. {
  11814. var askMin=aryAskPrice[0], askMax=aryAskPrice[aryAskPrice.length-1];
  11815. var bidMin=aryBidPrice[0], bidMax=aryBidPrice[aryBidPrice.length-1];
  11816. var askDifference=askMax-askMin; //卖差值
  11817. var bidDifference=bidMax-bidMin; //买差值
  11818. var difference=Math.max(askDifference, bidDifference); //取最大的差值,2边调整
  11819. var ask={Min:askMin, Max:askMin+difference};
  11820. var bid={Max:bidMax, Min:bidMax-difference};
  11821. var range={ Max:ask.Max, Min:bid.Min };
  11822. }
  11823. this.Frame.SetPriceList(aryAskPrice,aryBidPrice);
  11824. var xRange=this.Frame.VerticalRange;
  11825. xRange.Max=range.Max;
  11826. xRange.Center=range.Min+(range.Max-range.Min)/2;
  11827. xRange.Min=range.Min;
  11828. xRange.MaxDiffer=difference; //差值
  11829. xRange.Ask=ask;
  11830. xRange.Bid=bid;
  11831. if (!IFrameSplitOperator.IsNumber(xRange.Differ))
  11832. xRange.Differ=difference*this.DefaultZoom;
  11833. xRange.Min=xRange.Center-xRange.Differ;
  11834. xRange.Max=xRange.Center+xRange.Differ;
  11835. }
  11836. this.UpdateFrameMaxMin=function()
  11837. {
  11838. var range=this.ChartPaint[0].GetMaxMin();
  11839. this.Frame.HorizontalMax=range.Max*this.MaxVolRate;
  11840. this.Frame.HorizontalMin=0;
  11841. this.Frame.XYSplit=true;
  11842. }
  11843. this.CancelAutoUpdate=function() //关闭停止更新
  11844. {
  11845. if (this.AutoUpdateTimer)
  11846. {
  11847. clearTimeout(this.AutoUpdateTimer);
  11848. this.AutoUpdateTimer = null;
  11849. }
  11850. }
  11851. this.StopAutoUpdate=function()
  11852. {
  11853. this.CancelAutoUpdate();
  11854. if (!this.IsAutoUpdate) return;
  11855. this.IsAutoUpdate=false;
  11856. }
  11857. this.AutoUpdate=function() //数据自动更新
  11858. {
  11859. this.CancelAutoUpdate();
  11860. if (!this.IsAutoUpdate) return;
  11861. if (!this.Symbol) return;
  11862. if (this.IsDestroy) return;
  11863. var self = this;
  11864. var marketStatus=MARKET_SUFFIX_NAME.GetMarketStatus(this.Symbol);
  11865. if (marketStatus==0 || marketStatus==3) return; //闭市,盘后
  11866. var frequency=this.AutoUpdateFrequency;
  11867. if (marketStatus==1) //盘前
  11868. {
  11869. this.AutoUpdateTimer=setTimeout(function()
  11870. {
  11871. self.AutoUpdate();
  11872. },frequency);
  11873. }
  11874. else if (marketStatus==2) //盘中
  11875. {
  11876. this.AutoUpdateTimer=setTimeout(function()
  11877. {
  11878. self.RequestDepthData();
  11879. },frequency);
  11880. }
  11881. }
  11882. }
  11883. //是否是指数代码
  11884. function IsIndexSymbol(symbol) {
  11885. var upperSymbol = symbol.toUpperCase();
  11886. if (upperSymbol.indexOf('.SH') > 0) {
  11887. upperSymbol = upperSymbol.replace('.SH', '');
  11888. if (upperSymbol.charAt(0) == '0' && parseInt(upperSymbol) <= 3000) return true;
  11889. }
  11890. else if (upperSymbol.indexOf('.SZ') > 0) {
  11891. upperSymbol = upperSymbol.replace('.SZ', '');
  11892. if (upperSymbol.charAt(0) == '3' && upperSymbol.charAt(1) == '9') return true;
  11893. }
  11894. else if (upperSymbol.indexOf('.CI') > 0) //自定义指数
  11895. {
  11896. return true;
  11897. }
  11898. return false;
  11899. }
  11900. //导出统一使用JSCommon命名空间名
  11901. var JSCommon=
  11902. {
  11903. JSCanvasElement: JSCanvasElement,
  11904. JSNetwork:JSNetwork,
  11905. JSChart: JSChart,
  11906. Guid: Guid,
  11907. IFrameSplitOperator: IFrameSplitOperator,
  11908. ChartData: ChartData,
  11909. DataPlus: DataPlus,
  11910. KLineTooltipPaint: KLineTooltipPaint,
  11911. MARKET_SUFFIX_NAME: MARKET_SUFFIX_NAME,
  11912. JSCommonCoordinateData:JSCommonCoordinateData,
  11913. FrameSplitKLineX:FrameSplitKLineX,
  11914. FrameSplitKLinePriceY:FrameSplitKLinePriceY,
  11915. JSCHART_EVENT_ID:JSCHART_EVENT_ID,
  11916. JSCHART_DATA_FIELD_ID:JSCHART_DATA_FIELD_ID,
  11917. JSCHART_OPERATOR_ID:JSCHART_OPERATOR_ID,
  11918. };
  11919. export
  11920. {
  11921. JSCommon
  11922. };
  11923. /*
  11924. module.exports =
  11925. {
  11926. JSCommon:
  11927. {
  11928. JSCanvasElement: JSCanvasElement,
  11929. JSChart: JSChart,
  11930. Guid: Guid,
  11931. IFrameSplitOperator: IFrameSplitOperator,
  11932. ChartData: ChartData,
  11933. DataPlus: DataPlus,
  11934. KLineTooltipPaint: KLineTooltipPaint,
  11935. MARKET_SUFFIX_NAME: MARKET_SUFFIX_NAME,
  11936. JSCommonCoordinateData:JSCommonCoordinateData,
  11937. FrameSplitKLineX:FrameSplitKLineX,
  11938. FrameSplitKLinePriceY:FrameSplitKLinePriceY,
  11939. JSCHART_EVENT_ID:JSCHART_EVENT_ID
  11940. },
  11941. };
  11942. */