umychart.wechat.3.0.js 494 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568756975707571757275737574757575767577757875797580758175827583758475857586758775887589759075917592759375947595759675977598759976007601760276037604760576067607760876097610761176127613761476157616761776187619762076217622762376247625762676277628762976307631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700770177027703770477057706770777087709771077117712771377147715771677177718771977207721772277237724772577267727772877297730773177327733773477357736773777387739774077417742774377447745774677477748774977507751775277537754775577567757775877597760776177627763776477657766776777687769777077717772777377747775777677777778777977807781778277837784778577867787778877897790779177927793779477957796779777987799780078017802780378047805780678077808780978107811781278137814781578167817781878197820782178227823782478257826782778287829783078317832783378347835783678377838783978407841784278437844784578467847784878497850785178527853785478557856785778587859786078617862786378647865786678677868786978707871787278737874787578767877787878797880788178827883788478857886788778887889789078917892789378947895789678977898789979007901790279037904790579067907790879097910791179127913791479157916791779187919792079217922792379247925792679277928792979307931793279337934793579367937793879397940794179427943794479457946794779487949795079517952795379547955795679577958795979607961796279637964796579667967796879697970797179727973797479757976797779787979798079817982798379847985798679877988798979907991799279937994799579967997799879998000800180028003800480058006800780088009801080118012801380148015801680178018801980208021802280238024802580268027802880298030803180328033803480358036803780388039804080418042804380448045804680478048804980508051805280538054805580568057805880598060806180628063806480658066806780688069807080718072807380748075807680778078807980808081808280838084808580868087808880898090809180928093809480958096809780988099810081018102810381048105810681078108810981108111811281138114811581168117811881198120812181228123812481258126812781288129813081318132813381348135813681378138813981408141814281438144814581468147814881498150815181528153815481558156815781588159816081618162816381648165816681678168816981708171817281738174817581768177817881798180818181828183818481858186818781888189819081918192819381948195819681978198819982008201820282038204820582068207820882098210821182128213821482158216821782188219822082218222822382248225822682278228822982308231823282338234823582368237823882398240824182428243824482458246824782488249825082518252825382548255825682578258825982608261826282638264826582668267826882698270827182728273827482758276827782788279828082818282828382848285828682878288828982908291829282938294829582968297829882998300830183028303830483058306830783088309831083118312831383148315831683178318831983208321832283238324832583268327832883298330833183328333833483358336833783388339834083418342834383448345834683478348834983508351835283538354835583568357835883598360836183628363836483658366836783688369837083718372837383748375837683778378837983808381838283838384838583868387838883898390839183928393839483958396839783988399840084018402840384048405840684078408840984108411841284138414841584168417841884198420842184228423842484258426842784288429843084318432843384348435843684378438843984408441844284438444844584468447844884498450845184528453845484558456845784588459846084618462846384648465846684678468846984708471847284738474847584768477847884798480848184828483848484858486848784888489849084918492849384948495849684978498849985008501850285038504850585068507850885098510851185128513851485158516851785188519852085218522852385248525852685278528852985308531853285338534853585368537853885398540854185428543854485458546854785488549855085518552855385548555855685578558855985608561856285638564856585668567856885698570857185728573857485758576857785788579858085818582858385848585858685878588858985908591859285938594859585968597859885998600860186028603860486058606860786088609861086118612861386148615861686178618861986208621862286238624862586268627862886298630863186328633863486358636863786388639864086418642864386448645864686478648864986508651865286538654865586568657865886598660866186628663866486658666866786688669867086718672867386748675867686778678867986808681868286838684868586868687868886898690869186928693869486958696869786988699870087018702870387048705870687078708870987108711871287138714871587168717871887198720872187228723872487258726872787288729873087318732873387348735873687378738873987408741874287438744874587468747874887498750875187528753875487558756875787588759876087618762876387648765876687678768876987708771877287738774877587768777877887798780878187828783878487858786878787888789879087918792879387948795879687978798879988008801880288038804880588068807880888098810881188128813881488158816881788188819882088218822882388248825882688278828882988308831883288338834883588368837883888398840884188428843884488458846884788488849885088518852885388548855885688578858885988608861886288638864886588668867886888698870887188728873887488758876887788788879888088818882888388848885888688878888888988908891889288938894889588968897889888998900890189028903890489058906890789088909891089118912891389148915891689178918891989208921892289238924892589268927892889298930893189328933893489358936893789388939894089418942894389448945894689478948894989508951895289538954895589568957895889598960896189628963896489658966896789688969897089718972897389748975897689778978897989808981898289838984898589868987898889898990899189928993899489958996899789988999900090019002900390049005900690079008900990109011901290139014901590169017901890199020902190229023902490259026902790289029903090319032903390349035903690379038903990409041904290439044904590469047904890499050905190529053905490559056905790589059906090619062906390649065906690679068906990709071907290739074907590769077907890799080908190829083908490859086908790889089909090919092909390949095909690979098909991009101910291039104910591069107910891099110911191129113911491159116911791189119912091219122912391249125912691279128912991309131913291339134913591369137913891399140914191429143914491459146914791489149915091519152915391549155915691579158915991609161916291639164916591669167916891699170917191729173917491759176917791789179918091819182918391849185918691879188918991909191919291939194919591969197919891999200920192029203920492059206920792089209921092119212921392149215921692179218921992209221922292239224922592269227922892299230923192329233923492359236923792389239924092419242924392449245924692479248924992509251925292539254925592569257925892599260926192629263926492659266926792689269927092719272927392749275927692779278927992809281928292839284928592869287928892899290929192929293929492959296929792989299930093019302930393049305930693079308930993109311931293139314931593169317931893199320932193229323932493259326932793289329933093319332933393349335933693379338933993409341934293439344934593469347934893499350935193529353935493559356935793589359936093619362936393649365936693679368936993709371937293739374937593769377937893799380938193829383938493859386938793889389939093919392939393949395939693979398939994009401940294039404940594069407940894099410941194129413941494159416941794189419942094219422942394249425942694279428942994309431943294339434943594369437943894399440944194429443944494459446944794489449945094519452945394549455945694579458945994609461946294639464946594669467946894699470947194729473947494759476947794789479948094819482948394849485948694879488948994909491949294939494949594969497949894999500950195029503950495059506950795089509951095119512951395149515951695179518951995209521952295239524952595269527952895299530953195329533953495359536953795389539954095419542954395449545954695479548954995509551955295539554955595569557955895599560956195629563956495659566956795689569957095719572957395749575957695779578957995809581958295839584958595869587958895899590959195929593959495959596959795989599960096019602960396049605960696079608960996109611961296139614961596169617961896199620962196229623962496259626962796289629963096319632963396349635963696379638963996409641964296439644964596469647964896499650965196529653965496559656965796589659966096619662966396649665966696679668966996709671967296739674967596769677967896799680968196829683968496859686968796889689969096919692969396949695969696979698969997009701970297039704970597069707970897099710971197129713971497159716971797189719972097219722972397249725972697279728972997309731973297339734973597369737973897399740974197429743974497459746974797489749975097519752975397549755975697579758975997609761976297639764976597669767976897699770977197729773977497759776977797789779978097819782978397849785978697879788978997909791979297939794979597969797979897999800980198029803980498059806980798089809981098119812981398149815981698179818981998209821982298239824982598269827982898299830983198329833983498359836983798389839984098419842984398449845984698479848984998509851985298539854985598569857985898599860986198629863986498659866986798689869987098719872987398749875987698779878987998809881988298839884988598869887988898899890989198929893989498959896989798989899990099019902990399049905990699079908990999109911991299139914991599169917991899199920992199229923992499259926992799289929993099319932993399349935993699379938993999409941994299439944994599469947994899499950995199529953995499559956995799589959996099619962996399649965996699679968996999709971997299739974997599769977997899799980998199829983998499859986998799889989999099919992999399949995999699979998999910000100011000210003100041000510006100071000810009100101001110012100131001410015100161001710018100191002010021100221002310024100251002610027100281002910030100311003210033100341003510036100371003810039100401004110042100431004410045100461004710048100491005010051100521005310054100551005610057100581005910060100611006210063100641006510066100671006810069100701007110072100731007410075100761007710078100791008010081100821008310084100851008610087100881008910090100911009210093100941009510096100971009810099101001010110102101031010410105101061010710108101091011010111101121011310114101151011610117101181011910120101211012210123101241012510126101271012810129101301013110132101331013410135101361013710138101391014010141101421014310144101451014610147101481014910150101511015210153101541015510156101571015810159101601016110162101631016410165101661016710168101691017010171101721017310174101751017610177101781017910180101811018210183101841018510186101871018810189101901019110192101931019410195101961019710198101991020010201102021020310204102051020610207102081020910210102111021210213102141021510216102171021810219102201022110222102231022410225102261022710228102291023010231102321023310234102351023610237102381023910240102411024210243102441024510246102471024810249102501025110252102531025410255102561025710258102591026010261102621026310264102651026610267102681026910270102711027210273102741027510276102771027810279102801028110282102831028410285102861028710288102891029010291102921029310294102951029610297102981029910300103011030210303103041030510306103071030810309103101031110312103131031410315103161031710318103191032010321103221032310324103251032610327103281032910330103311033210333103341033510336103371033810339103401034110342103431034410345103461034710348103491035010351103521035310354103551035610357103581035910360103611036210363103641036510366103671036810369103701037110372103731037410375103761037710378103791038010381103821038310384103851038610387103881038910390103911039210393103941039510396103971039810399104001040110402104031040410405104061040710408104091041010411104121041310414104151041610417104181041910420104211042210423104241042510426104271042810429104301043110432104331043410435104361043710438104391044010441104421044310444104451044610447104481044910450104511045210453104541045510456104571045810459104601046110462104631046410465104661046710468104691047010471104721047310474104751047610477104781047910480104811048210483104841048510486104871048810489104901049110492104931049410495104961049710498104991050010501105021050310504105051050610507105081050910510105111051210513105141051510516105171051810519105201052110522105231052410525105261052710528105291053010531105321053310534105351053610537105381053910540105411054210543105441054510546105471054810549105501055110552105531055410555105561055710558105591056010561105621056310564105651056610567105681056910570105711057210573105741057510576105771057810579105801058110582105831058410585105861058710588105891059010591105921059310594105951059610597105981059910600106011060210603106041060510606106071060810609106101061110612106131061410615106161061710618106191062010621106221062310624106251062610627106281062910630106311063210633106341063510636106371063810639106401064110642106431064410645106461064710648106491065010651106521065310654106551065610657106581065910660106611066210663106641066510666106671066810669106701067110672106731067410675106761067710678106791068010681106821068310684106851068610687106881068910690106911069210693106941069510696106971069810699107001070110702107031070410705107061070710708107091071010711107121071310714107151071610717107181071910720107211072210723107241072510726107271072810729107301073110732107331073410735107361073710738107391074010741107421074310744107451074610747107481074910750107511075210753107541075510756107571075810759107601076110762107631076410765107661076710768107691077010771107721077310774107751077610777107781077910780107811078210783107841078510786107871078810789107901079110792107931079410795107961079710798107991080010801108021080310804108051080610807108081080910810108111081210813108141081510816108171081810819108201082110822108231082410825108261082710828108291083010831108321083310834108351083610837108381083910840108411084210843108441084510846108471084810849108501085110852108531085410855108561085710858108591086010861108621086310864108651086610867108681086910870108711087210873108741087510876108771087810879108801088110882108831088410885108861088710888108891089010891108921089310894108951089610897108981089910900109011090210903109041090510906109071090810909109101091110912109131091410915109161091710918109191092010921109221092310924109251092610927109281092910930109311093210933109341093510936109371093810939109401094110942109431094410945109461094710948109491095010951109521095310954109551095610957109581095910960109611096210963109641096510966109671096810969109701097110972109731097410975109761097710978109791098010981109821098310984109851098610987109881098910990109911099210993109941099510996109971099810999110001100111002110031100411005110061100711008110091101011011110121101311014110151101611017110181101911020110211102211023110241102511026110271102811029110301103111032110331103411035110361103711038110391104011041110421104311044110451104611047110481104911050110511105211053110541105511056110571105811059110601106111062110631106411065110661106711068110691107011071110721107311074110751107611077110781107911080110811108211083110841108511086110871108811089110901109111092110931109411095110961109711098110991110011101111021110311104111051110611107111081110911110111111111211113111141111511116111171111811119111201112111122111231112411125111261112711128111291113011131111321113311134111351113611137111381113911140111411114211143111441114511146111471114811149111501115111152111531115411155111561115711158111591116011161111621116311164111651116611167111681116911170111711117211173111741117511176111771117811179111801118111182111831118411185111861118711188111891119011191111921119311194111951119611197111981119911200112011120211203112041120511206112071120811209112101121111212112131121411215112161121711218112191122011221112221122311224112251122611227112281122911230112311123211233112341123511236112371123811239112401124111242112431124411245112461124711248112491125011251112521125311254112551125611257112581125911260112611126211263112641126511266112671126811269112701127111272112731127411275112761127711278112791128011281112821128311284112851128611287112881128911290112911129211293112941129511296112971129811299113001130111302113031130411305113061130711308113091131011311113121131311314113151131611317113181131911320113211132211323113241132511326113271132811329113301133111332113331133411335113361133711338113391134011341113421134311344113451134611347113481134911350113511135211353113541135511356113571135811359113601136111362113631136411365113661136711368113691137011371113721137311374113751137611377113781137911380113811138211383113841138511386113871138811389113901139111392113931139411395113961139711398113991140011401114021140311404114051140611407114081140911410114111141211413114141141511416114171141811419114201142111422114231142411425114261142711428114291143011431114321143311434114351143611437114381143911440114411144211443114441144511446114471144811449114501145111452114531145411455114561145711458114591146011461114621146311464114651146611467114681146911470114711147211473114741147511476114771147811479114801148111482114831148411485114861148711488114891149011491114921149311494114951149611497114981149911500115011150211503115041150511506115071150811509115101151111512115131151411515115161151711518115191152011521115221152311524115251152611527115281152911530115311153211533115341153511536115371153811539115401154111542115431154411545115461154711548115491155011551115521155311554115551155611557115581155911560115611156211563115641156511566115671156811569115701157111572115731157411575115761157711578115791158011581115821158311584115851158611587115881158911590115911159211593115941159511596115971159811599116001160111602116031160411605116061160711608116091161011611116121161311614116151161611617116181161911620116211162211623116241162511626116271162811629116301163111632116331163411635116361163711638116391164011641116421164311644116451164611647116481164911650116511165211653116541165511656116571165811659116601166111662116631166411665116661166711668116691167011671116721167311674116751167611677116781167911680116811168211683116841168511686116871168811689116901169111692116931169411695116961169711698116991170011701117021170311704117051170611707117081170911710117111171211713117141171511716117171171811719117201172111722117231172411725117261172711728117291173011731117321173311734117351173611737117381173911740117411174211743117441174511746117471174811749117501175111752117531175411755117561175711758117591176011761117621176311764117651176611767117681176911770117711177211773117741177511776117771177811779117801178111782117831178411785117861178711788117891179011791117921179311794117951179611797117981179911800118011180211803118041180511806118071180811809118101181111812118131181411815118161181711818118191182011821118221182311824118251182611827118281182911830118311183211833118341183511836118371183811839118401184111842118431184411845118461184711848118491185011851118521185311854118551185611857118581185911860118611186211863118641186511866118671186811869118701187111872118731187411875118761187711878118791188011881118821188311884118851188611887118881188911890118911189211893118941189511896118971189811899119001190111902119031190411905119061190711908119091191011911119121191311914119151191611917119181191911920119211192211923119241192511926119271192811929119301193111932119331193411935119361193711938119391194011941119421194311944119451194611947119481194911950119511195211953119541195511956119571195811959119601196111962119631196411965119661196711968119691197011971119721197311974119751197611977119781197911980119811198211983119841198511986119871198811989119901199111992119931199411995119961199711998119991200012001120021200312004120051200612007120081200912010120111201212013120141201512016120171201812019120201202112022120231202412025120261202712028120291203012031120321203312034120351203612037120381203912040120411204212043120441204512046120471204812049120501205112052120531205412055120561205712058120591206012061120621206312064120651206612067120681206912070120711207212073120741207512076120771207812079120801208112082120831208412085120861208712088120891209012091120921209312094120951209612097120981209912100121011210212103121041210512106121071210812109121101211112112121131211412115121161211712118121191212012121121221212312124121251212612127121281212912130121311213212133121341213512136121371213812139121401214112142121431214412145121461214712148121491215012151121521215312154121551215612157121581215912160121611216212163121641216512166121671216812169121701217112172121731217412175121761217712178121791218012181121821218312184121851218612187121881218912190121911219212193121941219512196121971219812199122001220112202122031220412205122061220712208122091221012211122121221312214122151221612217122181221912220122211222212223122241222512226122271222812229122301223112232122331223412235122361223712238122391224012241122421224312244122451224612247122481224912250122511225212253122541225512256122571225812259122601226112262122631226412265122661226712268122691227012271122721227312274122751227612277122781227912280122811228212283122841228512286122871228812289122901229112292122931229412295122961229712298122991230012301123021230312304123051230612307123081230912310123111231212313123141231512316123171231812319123201232112322123231232412325123261232712328123291233012331123321233312334123351233612337123381233912340123411234212343123441234512346123471234812349123501235112352123531235412355123561235712358123591236012361123621236312364123651236612367123681236912370123711237212373123741237512376123771237812379123801238112382123831238412385123861238712388123891239012391123921239312394123951239612397123981239912400124011240212403124041240512406124071240812409124101241112412124131241412415124161241712418124191242012421124221242312424124251242612427124281242912430124311243212433124341243512436124371243812439124401244112442124431244412445124461244712448124491245012451124521245312454124551245612457124581245912460124611246212463124641246512466124671246812469124701247112472124731247412475124761247712478124791248012481124821248312484124851248612487124881248912490124911249212493124941249512496124971249812499125001250112502125031250412505125061250712508125091251012511125121251312514125151251612517125181251912520125211252212523125241252512526125271252812529125301253112532125331253412535125361253712538125391254012541125421254312544125451254612547125481254912550125511255212553125541255512556125571255812559125601256112562125631256412565125661256712568125691257012571125721257312574125751257612577125781257912580125811258212583125841258512586125871258812589125901259112592125931259412595125961259712598125991260012601126021260312604126051260612607126081260912610126111261212613126141261512616126171261812619126201262112622126231262412625126261262712628126291263012631126321263312634126351263612637126381263912640126411264212643126441264512646126471264812649126501265112652126531265412655126561265712658126591266012661126621266312664126651266612667126681266912670126711267212673126741267512676126771267812679126801268112682126831268412685126861268712688126891269012691126921269312694126951269612697126981269912700127011270212703127041270512706127071270812709127101271112712127131271412715127161271712718127191272012721127221272312724127251272612727127281272912730127311273212733127341273512736127371273812739127401274112742127431274412745127461274712748127491275012751127521275312754127551275612757127581275912760127611276212763127641276512766127671276812769127701277112772127731277412775127761277712778127791278012781127821278312784127851278612787127881278912790127911279212793127941279512796127971279812799128001280112802128031280412805128061280712808128091281012811128121281312814128151281612817128181281912820128211282212823128241282512826128271282812829128301283112832128331283412835128361283712838128391284012841128421284312844128451284612847128481284912850128511285212853128541285512856128571285812859128601286112862128631286412865128661286712868128691287012871128721287312874128751287612877128781287912880128811288212883128841288512886128871288812889128901289112892128931289412895128961289712898128991290012901129021290312904129051290612907129081290912910129111291212913129141291512916129171291812919129201292112922129231292412925129261292712928129291293012931129321293312934129351293612937129381293912940129411294212943129441294512946129471294812949129501295112952129531295412955129561295712958129591296012961129621296312964129651296612967129681296912970129711297212973129741297512976129771297812979129801298112982129831298412985129861298712988129891299012991129921299312994129951299612997129981299913000130011300213003130041300513006130071300813009130101301113012130131301413015130161301713018130191302013021130221302313024130251302613027130281302913030130311303213033130341303513036130371303813039130401304113042130431304413045130461304713048130491305013051130521305313054130551305613057130581305913060130611306213063130641306513066130671306813069130701307113072130731307413075130761307713078130791308013081130821308313084130851308613087130881308913090130911309213093130941309513096130971309813099131001310113102131031310413105131061310713108131091311013111131121311313114131151311613117131181311913120131211312213123131241312513126131271312813129131301313113132131331313413135131361313713138131391314013141131421314313144131451314613147131481314913150131511315213153131541315513156131571315813159131601316113162131631316413165131661316713168131691317013171131721317313174131751317613177131781317913180131811318213183131841318513186131871318813189131901319113192131931319413195131961319713198131991320013201132021320313204132051320613207132081320913210132111321213213132141321513216132171321813219132201322113222132231322413225132261322713228132291323013231132321323313234132351323613237132381323913240132411324213243132441324513246132471324813249132501325113252132531325413255132561325713258132591326013261132621326313264132651326613267132681326913270132711327213273132741327513276132771327813279132801328113282132831328413285132861328713288132891329013291132921329313294132951329613297132981329913300133011330213303133041330513306133071330813309133101331113312133131331413315133161331713318133191332013321133221332313324133251332613327133281332913330133311333213333133341333513336133371333813339133401334113342133431334413345133461334713348133491335013351133521335313354133551335613357133581335913360133611336213363133641336513366133671336813369133701337113372133731337413375133761337713378133791338013381133821338313384133851338613387133881338913390133911339213393133941339513396133971339813399134001340113402134031340413405134061340713408134091341013411134121341313414134151341613417134181341913420134211342213423134241342513426134271342813429134301343113432134331343413435134361343713438134391344013441134421344313444134451344613447134481344913450134511345213453134541345513456134571345813459134601346113462134631346413465134661346713468134691347013471134721347313474134751347613477134781347913480134811348213483134841348513486134871348813489134901349113492134931349413495134961349713498134991350013501135021350313504135051350613507135081350913510135111351213513135141351513516135171351813519135201352113522135231352413525135261352713528135291353013531135321353313534135351353613537135381353913540135411354213543135441354513546135471354813549135501355113552135531355413555135561355713558135591356013561135621356313564135651356613567135681356913570135711357213573135741357513576135771357813579135801358113582135831358413585135861358713588135891359013591135921359313594135951359613597135981359913600136011360213603136041360513606136071360813609136101361113612136131361413615136161361713618136191362013621136221362313624136251362613627136281362913630136311363213633136341363513636136371363813639136401364113642136431364413645136461364713648136491365013651136521365313654136551365613657136581365913660136611366213663136641366513666136671366813669136701367113672136731367413675136761367713678136791368013681136821368313684136851368613687136881368913690136911369213693136941369513696136971369813699137001370113702137031370413705137061370713708137091371013711137121371313714137151371613717137181371913720137211372213723137241372513726137271372813729137301373113732137331373413735137361373713738137391374013741137421374313744137451374613747137481374913750137511375213753137541375513756137571375813759137601376113762137631376413765137661376713768137691377013771137721377313774137751377613777137781377913780137811378213783137841378513786137871378813789137901379113792137931379413795137961379713798137991380013801138021380313804138051380613807138081380913810138111381213813138141381513816138171381813819138201382113822138231382413825138261382713828138291383013831138321383313834138351383613837138381383913840138411384213843138441384513846138471384813849138501385113852138531385413855138561385713858138591386013861138621386313864138651386613867138681386913870138711387213873138741387513876138771387813879138801388113882138831388413885138861388713888138891389013891138921389313894138951389613897138981389913900139011390213903139041390513906139071390813909139101391113912139131391413915139161391713918139191392013921139221392313924139251392613927139281392913930139311393213933139341393513936139371393813939139401394113942139431394413945139461394713948139491395013951139521395313954139551395613957139581395913960139611396213963139641396513966139671396813969139701397113972139731397413975139761397713978139791398013981139821398313984139851398613987139881398913990139911399213993139941399513996139971399813999140001400114002140031400414005140061400714008140091401014011140121401314014140151401614017140181401914020140211402214023140241402514026140271402814029140301403114032140331403414035140361403714038140391404014041140421404314044140451404614047140481404914050140511405214053140541405514056140571405814059140601406114062140631406414065140661406714068140691407014071140721407314074140751407614077140781407914080140811408214083140841408514086140871408814089140901409114092140931409414095140961409714098140991410014101141021410314104141051410614107141081410914110141111411214113141141411514116141171411814119141201412114122141231412414125141261412714128141291413014131141321413314134141351413614137141381413914140141411414214143141441414514146141471414814149141501415114152141531415414155141561415714158141591416014161141621416314164141651416614167141681416914170141711417214173141741417514176141771417814179141801418114182141831418414185141861418714188141891419014191141921419314194141951419614197141981419914200142011420214203142041420514206142071420814209142101421114212142131421414215142161421714218142191422014221142221422314224142251422614227142281422914230142311423214233142341423514236142371423814239142401424114242142431424414245142461424714248
  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. //行情数据结构体 及涉及到的行情算法(复权,周期等)
  11. import {
  12. JSCommon_ChartData as ChartData, JSCommon_HistoryData as HistoryData,
  13. JSCommon_SingleData as SingleData, JSCommon_MinuteData as MinuteData,
  14. JSCommon_CUSTOM_DAY_PERIOD_START as CUSTOM_DAY_PERIOD_START,
  15. JSCommon_CUSTOM_DAY_PERIOD_END as CUSTOM_DAY_PERIOD_END,
  16. JSCommon_CUSTOM_MINUTE_PERIOD_START as CUSTOM_MINUTE_PERIOD_START,
  17. JSCommon_CUSTOM_MINUTE_PERIOD_END as CUSTOM_MINUTE_PERIOD_END,
  18. JSCommon_CUSTOM_SECOND_PERIOD_START as CUSTOM_SECOND_PERIOD_START,
  19. JSCommon_CUSTOM_SECOND_PERIOD_END as CUSTOM_SECOND_PERIOD_END,
  20. JSCommon_Rect as Rect,
  21. JSCommon_DataPlus as DataPlus,
  22. JSCommon_JSCHART_EVENT_ID as JSCHART_EVENT_ID,
  23. JSCommon_PhoneDBClick as PhoneDBClick,
  24. } from "./umychart.data.wechat.js";
  25. import {
  26. JSCommon_JSKLineInfoMap as JSKLineInfoMap,
  27. JSCommon_KLINE_INFO_TYPE as KLINE_INFO_TYPE,
  28. JSCommon_JSMinuteInfoMap as JSMinuteInfoMap,
  29. } from "./umychart.klineinfo.wechat.js";
  30. import
  31. {
  32. JSCommonCoordinateData as JSCommonCoordinateData,
  33. JSCommonCoordinateData_MARKET_SUFFIX_NAME as MARKET_SUFFIX_NAME ,
  34. JSCommonCoordinateData_Global_FuturesTimeData as g_FuturesTimeData,
  35. JSCommonCoordinateData_Global_NYMEXTimeData as g_NYMEXTimeData,
  36. JSCommonCoordinateData_Global_COMEXTimeData as g_COMEXTimeData,
  37. JSCommonCoordinateData_Global_NYBOTTimeData as g_NYBOTTimeData,
  38. JSCommonCoordinateData_Global_LMETimeData as g_LMETimeData,
  39. JSCommonCoordinateData_Global_CBOTTimeData as g_CBOTTimeData,
  40. } from "./umychart.coordinatedata.wechat.js";
  41. import { JSCommonComplier } from "./umychart.complier.wechat.js"; //通达信编译器
  42. import { JSCommonIndexScript } from "./umychart.index.data.wechat.js"; //系统指标定义
  43. import { JSCommon_HQIndexFormula as HQIndexFormula } from "./umychart.hqIndexformula.wechat.js"; //通达信编译器
  44. //图形库
  45. import {
  46. JSCommonChartPaint_IChartPainting as IChartPainting,
  47. JSCommonChartPaint_ChartSingleText as ChartSingleText,
  48. JSCommonChartPaint_ChartKLine as ChartKLine,
  49. JSCommonChartPaint_ChartLine as ChartLine,
  50. JSCommonChartPaint_ChartSubLine as ChartSubLine,
  51. JSCommonChartPaint_ChartPointDot as ChartPointDot,
  52. JSCommonChartPaint_ChartStick as ChartStick,
  53. JSCommonChartPaint_ChartLineStick as ChartLineStick,
  54. JSCommonChartPaint_ChartStickLine as ChartStickLine,
  55. JSCommonChartPaint_ChartOverlayKLine as ChartOverlayKLine,
  56. JSCommonChartPaint_ChartMinuteInfo as ChartMinuteInfo,
  57. JSCommonChartPaint_ChartRectangle as ChartRectangle,
  58. JSCommonChartPaint_ChartMultiText as ChartMultiText,
  59. JSCommonChartPaint_ChartMultiLine as ChartMultiLine,
  60. JSCommonChartPaint_ChartMultiBar as ChartMultiBar,
  61. JSCommonChartPaint_ChartPie as ChartPie,
  62. JSCommonChartPaint_ChartCircle as ChartCircle,
  63. JSCommonChartPaint_ChartChinaMap as ChartChinaMap,
  64. JSCommonChartPaint_ChartRadar as ChartRadar,
  65. JSCommonChartPaint_ChartCorssCursor as ChartCorssCursor,
  66. JSCommonChartPaint_ChartBuySell as ChartBuySell,
  67. JSCommonChartPaint_ChartMACD as ChartMACD,
  68. JSCommonChartPaint_ChartSplashPaint as ChartSplashPaint,
  69. JSCommonChartPaint_ChartBackground as ChartBackground,
  70. JSCommonChartPaint_ChartMinuteVolumBar as ChartMinuteVolumBar,
  71. JSCommonChartPaint_ChartMultiHtmlDom as ChartMultiHtmlDom,
  72. JSCommonChartPaint_ChartLock as ChartLock,
  73. JSCommonChartPaint_ChartVolStick as ChartVolStick,
  74. JSCommonChartPaint_ChartBand as ChartBand,
  75. JSCommonChartPaint_DepthChartCorssCursor as DepthChartCorssCursor,
  76. JSCommonChartPaint_ChartOrderbookDepth as ChartOrderbookDepth,
  77. JSCommonChartPaint_ChartMinutePriceLine as ChartMinutePriceLine,
  78. JSCommonChartPaint_ChartText as ChartText ,
  79. JSCommonChartPaint_ChartStraightArea as ChartStraightArea,
  80. } from "./umychart.chartpaint.wechat.js";
  81. //扩展画法图形库
  82. import {
  83. JSCommonExtendChartPaint_IExtendChartPainting as IExtendChartPainting,
  84. JSCommonExtendChartPaint_KLineTooltipPaint as KLineTooltipPaint,
  85. JSCommonExtendChartPaint_BarragePaint as BarragePaint,
  86. JSCommonExtendChartPaint_MinuteTooltipPaint as MinuteTooltipPaint,
  87. JSCommonExtendChartPaint_BackgroundPaint as BackgroundPaint,
  88. } from "./umychart.extendchart.wechat.js";
  89. import {
  90. JSCommonIndex_IndexInfo as IndexInfo,
  91. JSCommonIndex_BaseIndex as BaseIndex,
  92. JSCommonIndex_ScriptIndex as ScriptIndex,
  93. } from './umychart.index.wechat.js'
  94. import{
  95. JSCommonResource_Global_JSChartResource as g_JSChartResource,
  96. JSCommonResource_JSCHART_LANGUAGE_ID as JSCHART_LANGUAGE_ID,
  97. JSCommonResource_Global_JSChartLocalization as g_JSChartLocalization,
  98. } from './umychart.resource.wechat.js'
  99. import { JSCommonUniApp } from './umychart.uniapp.canvas.helper.js'
  100. import
  101. {
  102. JSCommonSplit_CoordinateInfo as CoordinateInfo,
  103. JSCommonSplit_IFrameSplitOperator as IFrameSplitOperator,
  104. JSCommonSplit_FrameSplitKLinePriceY as FrameSplitKLinePriceY,
  105. JSCommonSplit_FrameSplitY as FrameSplitY,
  106. JSCommonSplit_FrameSplitKLineX as FrameSplitKLineX,
  107. JSCommonSplit_FrameSplitMinutePriceY as FrameSplitMinutePriceY,
  108. JSCommonSplit_FrameSplitMinuteX as FrameSplitMinuteX,
  109. JSCommonSplit_FrameSplitXData as FrameSplitXData,
  110. JSCommonSplit_SplitData as SplitData,
  111. JSCommonSplit_PriceSplitData as PriceSplitData,
  112. JSCommonSplit_FrameSplitXDepth as FrameSplitXDepth,
  113. JSCommonFormat_IChangeStringFormat as IChangeStringFormat,
  114. JSCommonFormat_HQPriceStringFormat as HQPriceStringFormat,
  115. JSCommonFormat_HQDateStringFormat as HQDateStringFormat,
  116. JSCommonFormat_HQMinuteTimeStringFormat as HQMinuteTimeStringFormat,
  117. JSCommonFormat_Global_DataFormat as g_DivTooltipDataForamt,
  118. } from './umychart.framesplit.wechat.js'
  119. import
  120. {
  121. JSCommonChartTitle_IChartTitlePainting as IChartTitlePainting,
  122. JSCommonChartTitle_DynamicKLineTitlePainting as DynamicKLineTitlePainting,
  123. JSCommonChartTitle_DynamicMinuteTitlePainting as DynamicMinuteTitlePainting,
  124. JSCommonChartTitle_DynamicChartTitlePainting as DynamicChartTitlePainting,
  125. JSCommonChartTitle_DynamicTitleData as DynamicTitleData,
  126. JSCommonChartTitle_STRING_FORMAT_TYPE as STRING_FORMAT_TYPE,
  127. } from './umychart.charttitle.wechat.js'
  128. function JSCanvasElement()
  129. {
  130. this.Height;
  131. this.Width;
  132. this.ID;
  133. this.WebGLCanvas;
  134. this.IsUniApp=false;
  135. this.CanvasNode=null;
  136. this.ComponentObject=null; //在自定义组件下,当前组件实例的this,表示在这个自定义组件下查找拥有 canvas-id 的 canvas ,如果省略则不在任何自定义组件内查找
  137. //获取画布
  138. this.GetContext = function ()
  139. {
  140. var canvas;
  141. if (this.CanvasNode && this.CanvasNode.node)
  142. {
  143. const width = this.CanvasNode.width;
  144. const height = this.CanvasNode.height;
  145. var node = this.CanvasNode.node;
  146. node._height = height;
  147. node._width = width;
  148. JSConsole.Chart.Log("[JSCanvasElement::GetContext] create by getContext('2d')");
  149. canvas = node.getContext('2d');
  150. const dpr = wx.getSystemInfoSync().pixelRatio;
  151. node.width = width * dpr;
  152. node.height = height * dpr;
  153. canvas.restore();
  154. canvas.save();
  155. canvas.scale(dpr, dpr);
  156. canvas.draw = (bDraw, callback) => { if (callback) callback(); };
  157. canvas.DomNode = node;
  158. }
  159. else
  160. {
  161. if (this.ComponentObject) //小程序自定义组件
  162. canvas=wx.createCanvasContext(this.ID,this.ComponentObject);
  163. else
  164. canvas=wx.createCanvasContext(this.ID);
  165. }
  166. if (this.IsUniApp)
  167. {
  168. JSConsole.Chart.Log('[JSCanvasElement::GetContext] measureText() => JSUniAppCanvasHelper.MeasureText()');
  169. canvas.measureText = function (text) //uniapp 计算宽度需要自己计算
  170. {
  171. var width = JSCommonUniApp.JSUniAppCanvasHelper.MeasureText(text, canvas);
  172. return { width: width };
  173. }
  174. canvas.fillText_backup=canvas.fillText; //uniapp fillText 填了最大长度就会失真, 所以去掉
  175. canvas.fillText=function(text,x,y,maxWidth)
  176. {
  177. canvas.fillText_backup(text,x,y);
  178. }
  179. }
  180. return canvas;
  181. }
  182. this.GetWebGLCanvas=function(id)
  183. {
  184. var self=this;
  185. const query = wx.createSelectorQuery();
  186. query.select(id).node().exec((res) => {
  187. JSConsole.Chart.Log('[JSCanvasElement::GetWebGLCanvas] res ', res)
  188. self.WebGLCanvas = res[0].node;
  189. })
  190. }
  191. }
  192. function JSChart(element)
  193. {
  194. this.JSChartContainer; //画图控件
  195. this.CanvasElement = element;
  196. this.AddEventCallback = function (obj) //事件回调 {event:事件id, callback:回调函数}
  197. {
  198. if (this.JSChartContainer && typeof (this.JSChartContainer.AddEventCallback) == 'function')
  199. {
  200. JSConsole.Chart.Log('[JSChart:AddEventCallback] ', obj);
  201. this.JSChartContainer.AddEventCallback(obj);
  202. }
  203. }
  204. this.OnSize = function (option)
  205. {
  206. if (option)
  207. {
  208. if (IFrameSplitOperator.IsNumber(option.Width)) this.CanvasElement.Width=option.Width;
  209. if (IFrameSplitOperator.IsNumber(option.Height)) this.CanvasElement.Height=option.Height;
  210. }
  211. if (option && option.Redraw==false) return;
  212. if (this.JSChartContainer)
  213. {
  214. if (option && option.Type==1 && this.JSChartContainer.OnSize)
  215. {
  216. this.JSChartContainer.OnSize();
  217. }
  218. else
  219. {
  220. if (this.JSChartContainer.Frame) this.JSChartContainer.Frame.SetSizeChage(true);
  221. this.JSChartContainer.Draw();
  222. }
  223. }
  224. }
  225. //历史K线图
  226. this.CreateKLineChartContainer = function (option)
  227. {
  228. var chart = null;
  229. if (option.Type === "历史K线图横屏") chart = new KLineChartHScreenContainer(this.CanvasElement);
  230. else chart = new KLineChartContainer(this.CanvasElement);
  231. if (option.NetworkFilter) chart.NetworkFilter = option.NetworkFilter;
  232. if (option.KLine) //k线图的属性设置
  233. {
  234. if (option.KLine.DragMode >= 0) chart.DragMode = option.KLine.DragMode;
  235. if (option.KLine.Right >= 0) chart.Right = option.KLine.Right;
  236. if (option.KLine.Period >= 0) chart.Period = option.KLine.Period;
  237. if (option.KLine.MaxReqeustDataCount > 0) chart.MaxReqeustDataCount = option.KLine.MaxReqeustDataCount;
  238. if (option.KLine.Info && option.KLine.Info.length > 0) chart.SetKLineInfo(option.KLine.Info, false);
  239. if (option.KLine.Policy && option.KLine.Policy.length > 0) chart.SetPolicyInfo(option.KLine.Policy, false);
  240. if (option.KLine.KLineDoubleClick == false) chart.MinuteDialog = this.MinuteDialog = null;
  241. if (option.KLine.MaxRequestMinuteDayCount > 0) chart.MaxRequestMinuteDayCount = option.KLine.MaxRequestMinuteDayCount;
  242. if (option.KLine.DrawType) chart.KLineDrawType = option.KLine.DrawType;
  243. if (option.KLine.RightSpaceCount >= 0) chart.RightSpaceCount = option.KLine.RightSpaceCount;
  244. if (option.KLine.DataWidth>=1) chart.KLineSize={ DataWidth:option.KLine.DataWidth };
  245. }
  246. if (IFrameSplitOperator.IsString(option.SplashTitle)) chart.LoadDataSplashTitle = option.SplashTitle; //设置提示信息内容
  247. if (IFrameSplitOperator.IsBool(option.EnableZoomIndexWindow)) chart.EnableZoomIndexWindow=option.EnableZoomIndexWindow; //双击缩放附图
  248. if (!option.Windows || option.Windows.length <= 0) return null;
  249. if (option.Language)
  250. {
  251. if (option.Language === 'CN') chart.LanguageID = JSCHART_LANGUAGE_ID.LANGUAGE_CHINESE_ID;
  252. else if (option.Language === 'EN') chart.LanguageID = JSCHART_LANGUAGE_ID.LANGUAGE_ENGLISH_ID;
  253. }
  254. if (option.SourceDatatLimit) chart.SetSourceDatatLimit(option.SourceDatatLimit);
  255. if (option.EnableZoomUpDown) chart.EnableZoomUpDown=option.EnableZoomUpDown;
  256. if (option.ZoomStepPixel>0) chart.ZoomStepPixel=option.ZoomStepPixel;
  257. if (IFrameSplitOperator.IsNumber(option.DrawMoveWaitTime)) chart.DrawMoveWaitTime=option.DrawMoveWaitTime;
  258. //创建子窗口
  259. chart.Create(option.Windows.length);
  260. if (option.Border)
  261. {
  262. var item=option.Border;
  263. if (!isNaN(option.Border.Left)) chart.Frame.ChartBorder.Left = option.Border.Left;
  264. if (!isNaN(option.Border.Right)) chart.Frame.ChartBorder.Right = option.Border.Right;
  265. if (!isNaN(option.Border.Top)) chart.Frame.ChartBorder.Top = option.Border.Top;
  266. if (!isNaN(option.Border.Bottom)) chart.Frame.ChartBorder.Bottom = option.Border.Bottom;
  267. if (item.AutoLeft) chart.Frame.AutoLeftBorder=item.AutoLeft;
  268. if (item.AutoRight) chart.Frame.AutoRightBorder=item.AutoRight;
  269. }
  270. if (option.KLine)
  271. {
  272. if (option.KLine.PageSize > 0)
  273. {
  274. let maxPageSize = chart.GetMaxPageSize();
  275. if (maxPageSize < option.KLine.PageSize) chart.PageSize = maxPageSize;
  276. else chart.PageSize = option.KLine.PageSize;
  277. }
  278. if (option.KLine.InfoDrawType) chart.ChartPaint[0].InfoDrawType = option.KLine.InfoDrawType;
  279. }
  280. if (option.DragDownload)
  281. {
  282. if (option.DragDownload.Day && option.DragDownload.Day.Enable == true) chart.DragDownload.Day.Enable = true;
  283. if (option.DragDownload.Minute && option.DragDownload.Minute.Enable == true) chart.DragDownload.Minute.Enable = true;
  284. }
  285. if (option.IsApiPeriod == true) chart.IsApiPeriod = option.IsApiPeriod;
  286. if (option.CorssCursorTouchEnd == true) chart.CorssCursorTouchEnd = option.CorssCursorTouchEnd;
  287. if (option.IsClickShowCorssCursor == true) chart.IsClickShowCorssCursor = option.IsClickShowCorssCursor;
  288. if (option.IsFullDraw == true) chart.IsFullDraw = option.IsFullDraw;
  289. if (option.CorssCursorInfo)
  290. {
  291. var item=option.CorssCursorInfo;
  292. if (!isNaN(option.CorssCursorInfo.Left)) chart.ChartCorssCursor.ShowTextMode.Left = option.CorssCursorInfo.Left;
  293. if (!isNaN(option.CorssCursorInfo.Right)) chart.ChartCorssCursor.ShowTextMode.Right = option.CorssCursorInfo.Right;
  294. if (!isNaN(option.CorssCursorInfo.Bottom)) chart.ChartCorssCursor.ShowTextMode.Bottom = option.CorssCursorInfo.Bottom;
  295. if (option.CorssCursorInfo.IsShowCorss === false) chart.ChartCorssCursor.IsShowCorss = option.CorssCursorInfo.IsShowCorss;
  296. if (option.CorssCursorInfo.IsShowClose == true) chart.ChartCorssCursor.IsShowClose = option.CorssCursorInfo.IsShowClose; //Y轴显示收盘价
  297. if (IFrameSplitOperator.IsNumber(option.CorssCursorInfo.HPenType)) chart.ChartCorssCursor.HPenType = option.CorssCursorInfo.HPenType;
  298. if (option.CorssCursorInfo.VPenType > 0) chart.ChartCorssCursor.VPenType = option.CorssCursorInfo.VPenType;
  299. if (IFrameSplitOperator.IsNumber(item.DateFormatType)) chart.ChartCorssCursor.StringFormatX.DateFormatType=item.DateFormatType;
  300. }
  301. if (typeof (option.UpdateUICallback) == 'function') //数据到达回调
  302. chart.UpdateUICallback = option.UpdateUICallback;
  303. if (option.Frame)
  304. {
  305. for (var i in option.Frame)
  306. {
  307. var item = option.Frame[i];
  308. if (!chart.Frame.SubFrame[i]) continue;
  309. if (item.SplitCount) chart.Frame.SubFrame[i].Frame.YSplitOperator.SplitCount = item.SplitCount;
  310. if (item.StringFormat) chart.Frame.SubFrame[i].Frame.YSplitOperator.StringFormat = item.StringFormat;
  311. if (!isNaN(item.Height)) chart.Frame.SubFrame[i].Height = item.Height;
  312. if (item.IsShowBorder == false) chart.Frame.SubFrame[i].Frame.IsShowBorder = item.IsShowBorder;
  313. if (item.IsShowXLine == false) chart.Frame.SubFrame[i].Frame.IsShowXLine = item.IsShowXLine;
  314. if (item.IsShowYLine==false) chart.Frame.SubFrame[i].Frame.IsShowYLine=item.IsShowYLine;
  315. if (item.XMessageAlign == 'bottom') chart.Frame.SubFrame[i].Frame.XMessageAlign = item.XMessageAlign;
  316. if (item.IsShowTitle == false) chart.Frame.SubFrame[i].Frame.IsShowTitle = false;
  317. if (IFrameSplitOperator.IsBool(item.IsShowIndexTitle)) chart.Frame.SubFrame[i].Frame.IsShowTitle=item.IsShowIndexTitle;
  318. if (item.UpdateTitleUICallback && chart.Frame.SubFrame[i].Frame.TitlePaint) chart.Frame.SubFrame[i].Frame.TitlePaint.UpdateUICallback = item.UpdateTitleUICallback;
  319. if (item.IsShowLeftText === false || item.IsShowLeftText === true) chart.Frame.SubFrame[i].Frame.IsShowYText[0] = item.IsShowLeftText; //显示左边刻度
  320. if (item.IsShowRightText === false || item.IsShowRightText === true) chart.Frame.SubFrame[i].Frame.IsShowYText[1] = item.IsShowRightText; //显示右边刻度
  321. if (item.TopSpace >= 0) chart.Frame.SubFrame[i].Frame.ChartBorder.TopSpace = item.TopSpace;
  322. if (item.BottomSpace >= 0) chart.Frame.SubFrame[i].Frame.ChartBorder.BottomSpace = item.BottomSpace;
  323. if (item.Custom) chart.Frame.SubFrame[i].Frame.YSplitOperator.Custom = item.Custom;
  324. if (IFrameSplitOperator.IsNumber(item.SplitType)) chart.Frame.SubFrame[i].Frame.YSplitOperator.SplitType = item.SplitType;
  325. if (IFrameSplitOperator.IsNumber(item.FloatPrecision)) chart.Frame.SubFrame[i].Frame.YSplitOperator.FloatPrecision = item.FloatPrecision; //强制指定小数位数(主图有效)
  326. if (IFrameSplitOperator.IsNumber(item.BorderLine)) chart.Frame.SubFrame[i].Frame.BorderLine=item.BorderLine;
  327. if (IFrameSplitOperator.IsNumber(item.YTextBaseline)) chart.Frame.SubFrame[i].Frame.YTextBaseline=item.YTextBaseline;
  328. }
  329. }
  330. if (option.KLine)
  331. {
  332. if (option.KLine.ShowKLine == false) chart.ChartPaint[0].IsShow = false;
  333. if (option.KLine.IsShowMaxMinPrice == false) chart.ChartPaint[0].IsShowMaxMinPrice = false;
  334. }
  335. if (option.KLineTitle)
  336. {
  337. if (option.KLineTitle.IsShowName == false) chart.TitlePaint[0].IsShowName = false;
  338. if (option.KLineTitle.IsShowSettingInfo == false) chart.TitlePaint[0].IsShowSettingInfo = false;
  339. if (option.KLineTitle.IsShow == false) chart.TitlePaint[0].IsShow = false;
  340. if (option.KLineTitle.UpdateUICallback) chart.TitlePaint[0].UpdateUICallback = option.KLineTitle.UpdateUICallback
  341. if (option.KLineTitle.LineCount > 1) chart.TitlePaint[0].LineCount = option.KLineTitle.LineCount;
  342. }
  343. //叠加股票 只支持叠加1个股票
  344. for (var i in option.Overlay)
  345. {
  346. var item = option.Overlay[i];
  347. if (item.Symbol)
  348. {
  349. chart.OverlayChartPaint[0].Symbol = item.Symbol;
  350. if (item.Color) chart.OverlayChartPaint[0].Color=item.Color;
  351. chart.OverlayChartPaint[0].SetOption(item);
  352. break;
  353. }
  354. }
  355. if (option.ExtendChart) //创建扩展画法
  356. {
  357. for (var i in option.ExtendChart)
  358. {
  359. var item = option.ExtendChart[i];
  360. chart.CreateExtendChart(item.Name, item);
  361. }
  362. }
  363. let scriptData = new JSCommonIndexScript.JSIndexScript(); //系统指标
  364. if (option.ColorIndex) //五彩K线
  365. {
  366. var item = option.ColorIndex;
  367. let indexInfo = scriptData.Get(item.Index);
  368. if (indexInfo) chart.ColorIndex = new ScriptIndex(indexInfo.Name, indexInfo.Script, indexInfo.Args, indexInfo); //脚本执行
  369. }
  370. if (option.TradeIndex) //交易指标
  371. {
  372. var item = option.TradeIndex;
  373. let indexInfo = scriptData.Get(item.Index);
  374. if (indexInfo) chart.TradeIndex = new ScriptIndex(indexInfo.Name, indexInfo.Script, indexInfo.Args, indexInfo); //脚本执行
  375. }
  376. for (var i in option.Windows) //创建子窗口的指标
  377. {
  378. var item = option.Windows[i];
  379. if (item.Script)
  380. {
  381. chart.WindowIndex[i] = new ScriptIndex(item.Name, item.Script, item.Args, item); //脚本执行
  382. }
  383. else if (item.API) //使用API挂接指标数据 API:{ Name:指标名字, Script:指标脚本可以为空, Args:参数可以为空, Url:指标执行地址 }
  384. {
  385. var apiItem = item.API;
  386. chart.WindowIndex[i] = new APIScriptIndex(apiItem.Name, apiItem.Script, apiItem.Args, item);
  387. }
  388. else
  389. {
  390. var indexItem = JSIndexMap.Get(item.Index); //自定义指标
  391. if (indexItem)
  392. {
  393. chart.WindowIndex[i] = indexItem.Create();
  394. chart.CreateWindowIndex(i);
  395. }
  396. else //系统指标里查找
  397. {
  398. let indexInfo = scriptData.Get(item.Index);
  399. if (!indexInfo) continue;
  400. if (item.Lock) indexInfo.Lock = item.Lock;
  401. indexInfo.ID = item.Index;
  402. var args = indexInfo.Args;
  403. if (item.Args) args = item.Args;
  404. chart.WindowIndex[i] = new ScriptIndex(indexInfo.Name, indexInfo.Script, args, indexInfo); //脚本执行
  405. if (item.StringFormat > 0) chart.WindowIndex[i].StringFormat = item.StringFormat;
  406. if (item.FloatPrecision >= 0) chart.WindowIndex[i].FloatPrecision = item.FloatPrecision;
  407. }
  408. }
  409. if (item.Modify != null) chart.Frame.SubFrame[i].Frame.ModifyIndex = item.Modify;
  410. if (item.Change != null) chart.Frame.SubFrame[i].Frame.ChangeIndex = item.Change;
  411. if (item.IsDrawTitleBG==true) chart.Frame.SubFrame[i].Frame.IsDrawTitleBG=item.IsDrawTitleBG;
  412. if (typeof (item.UpdateUICallback) == 'function') chart.WindowIndex[i].UpdateUICallback = item.UpdateUICallback;
  413. if (!isNaN(item.TitleHeight)) chart.Frame.SubFrame[i].Frame.ChartBorder.TitleHeight = item.TitleHeight;
  414. if (item.IsShowIndexName == false) chart.Frame.SubFrame[i].Frame.IsShowIndexName = false;
  415. if (item.IndexParamSpace >= 0) chart.Frame.SubFrame[i].Frame.IndexParamSpace = item.IndexParamSpace;
  416. }
  417. return chart;
  418. }
  419. //自定义指数历史K线图
  420. this.CreateCustomKLineChartContainer = function (option) {
  421. var chart = new CustomKLineChartContainer(this.CanvasElement);
  422. if (option.KLine) //k线图的属性设置
  423. {
  424. if (option.KLine.DragMode >= 0) chart.DragMode = option.KLine.DragMode;
  425. if (option.KLine.Right >= 0) chart.Right = option.KLine.Right;
  426. if (option.KLine.Period >= 0) chart.Period = option.KLine.Period;
  427. if (option.KLine.MaxReqeustDataCount > 0) chart.MaxReqeustDataCount = option.KLine.MaxReqeustDataCount;
  428. if (option.KLine.Info && option.KLine.Info.length > 0) chart.SetKLineInfo(option.KLine.Info, false);
  429. if (option.KLine.KLineDoubleClick == false) chart.MinuteDialog = this.MinuteDialog = null;
  430. if (option.KLine.PageSize > 0) chart.PageSize = option.KLine.PageSize;
  431. if (option.KLine.IsShowTooltip == false) chart.IsShowTooltip = false;
  432. }
  433. if (option.CustomStock) chart.CustomStock = option.CustomStock;
  434. if (option.QueryDate) chart.QueryDate = option.QueryDate;
  435. if (typeof (option.UpdateUICallback) == 'function') chart.UpdateUICallback = option.UpdateUICallback;
  436. if (!option.Windows || option.Windows.length <= 0) return null;
  437. //创建子窗口
  438. chart.Create(option.Windows.length);
  439. if (option.Border) {
  440. if (!isNaN(option.Border.Left)) chart.Frame.ChartBorder.Left = option.Border.Left;
  441. if (!isNaN(option.Border.Right)) chart.Frame.ChartBorder.Right = option.Border.Right;
  442. if (!isNaN(option.Border.Top)) chart.Frame.ChartBorder.Top = option.Border.Top;
  443. if (!isNaN(option.Border.Bottom)) chart.Frame.ChartBorder.Bottom = option.Border.Bottom;
  444. }
  445. if (option.IsShowCorssCursorInfo == false) //取消显示十字光标刻度信息
  446. {
  447. chart.ChartCorssCursor.IsShowText = option.IsShowCorssCursorInfo;
  448. }
  449. if (option.Frame) {
  450. for (var i in option.Frame) {
  451. var item = option.Frame[i];
  452. if (item.SplitCount) chart.Frame.SubFrame[i].Frame.YSplitOperator.SplitCount = item.SplitCount;
  453. if (item.StringFormat) chart.Frame.SubFrame[i].Frame.YSplitOperator.StringFormat = item.StringFormat;
  454. if (item.XMessageAlign == 'bottom') chart.Frame.SubFrame[i].Frame.XMessageAlign = item.XMessageAlign;
  455. }
  456. }
  457. if (option.KLineTitle) {
  458. if (option.KLineTitle.IsShowName == false) chart.TitlePaint[0].IsShowName = false;
  459. if (option.KLineTitle.IsShowSettingInfo == false) chart.TitlePaint[0].IsShowSettingInfo = false;
  460. }
  461. //创建子窗口的指标
  462. let scriptData = new JSCommonIndexScript.JSIndexScript();
  463. for (var i in option.Windows) {
  464. var item = option.Windows[i];
  465. if (item.Script) {
  466. chart.WindowIndex[i] = new ScriptIndex(item.Name, item.Script, item.Args, item); //脚本执行
  467. }
  468. else {
  469. var indexItem = JSIndexMap.Get(item.Index);
  470. if (indexItem) {
  471. chart.WindowIndex[i] = indexItem.Create();
  472. chart.CreateWindowIndex(i);
  473. }
  474. else //系统指标里查找
  475. {
  476. let indexInfo = scriptData.Get(item.Index);
  477. if (!indexInfo) continue;
  478. if (item.Lock) indexInfo.Lock = item.Lock;
  479. chart.WindowIndex[i] = new ScriptIndex(indexInfo.Name, indexInfo.Script, indexInfo.Args, indexInfo); //脚本执行
  480. }
  481. }
  482. if (item.Modify != null)
  483. chart.Frame.SubFrame[i].Frame.ModifyIndex = item.Modify;
  484. if (item.Change != null)
  485. chart.Frame.SubFrame[i].Frame.ChangeIndex = item.Change;
  486. if (!isNaN(item.TitleHeight)) chart.Frame.SubFrame[i].Frame.ChartBorder.TitleHeight = item.TitleHeight;
  487. }
  488. return chart;
  489. }
  490. //分钟走势图
  491. this.CreateMinuteChartContainer = function (option)
  492. {
  493. var chart = null;
  494. if (option.Type === "分钟走势图横屏") chart = new MinuteChartHScreenContainer(this.CanvasElement);
  495. else chart = new MinuteChartContainer(this.CanvasElement);
  496. if (option.NetworkFilter) chart.NetworkFilter = option.NetworkFilter;
  497. var windowsCount = 2;
  498. if (option.Windows && option.Windows.length > 0) windowsCount += option.Windows.length; //指标窗口从第3个窗口开始
  499. if (option.EnableScrollUpDown==true) chart.EnableScrollUpDown=option.EnableScrollUpDown;
  500. if (option.Info && option.Info.length > 0) chart.SetMinuteInfo(option.Info, false);
  501. if (IFrameSplitOperator.IsString(option.SplashTitle)) chart.LoadDataSplashTitle = option.SplashTitle; //设置提示信息内容
  502. if (IFrameSplitOperator.IsBool(option.EnableZoomIndexWindow)) chart.EnableZoomIndexWindow=option.EnableZoomIndexWindow; //双击缩放附图
  503. if (IFrameSplitOperator.IsNumber(option.DrawMoveWaitTime)) chart.DrawMoveWaitTime=option.DrawMoveWaitTime;
  504. if (option.Language)
  505. {
  506. if (option.Language === 'CN') chart.LanguageID = JSCHART_LANGUAGE_ID.LANGUAGE_CHINESE_ID;
  507. else if (option.Language === 'EN') chart.LanguageID = JSCHART_LANGUAGE_ID.LANGUAGE_ENGLISH_ID;
  508. }
  509. chart.Create(windowsCount); //创建子窗口
  510. if (option.CorssCursorTouchEnd == true) chart.CorssCursorTouchEnd = option.CorssCursorTouchEnd;
  511. if (option.IsFullDraw == true) chart.IsFullDraw = option.IsFullDraw;
  512. if (option.CorssCursorInfo) //十字光标设置
  513. {
  514. if (!isNaN(option.CorssCursorInfo.Left)) chart.ChartCorssCursor.ShowTextMode.Left = option.CorssCursorInfo.Left;
  515. if (!isNaN(option.CorssCursorInfo.Right)) chart.ChartCorssCursor.ShowTextMode.Right = option.CorssCursorInfo.Right;
  516. if (!isNaN(option.CorssCursorInfo.Bottom)) chart.ChartCorssCursor.ShowTextMode.Bottom = option.CorssCursorInfo.Bottom;
  517. if (option.CorssCursorInfo.IsShowCorss === false) chart.ChartCorssCursor.IsShowCorss = option.CorssCursorInfo.IsShowCorss;
  518. if (IFrameSplitOperator.IsBool(option.CorssCursorInfo.IsFixXLastTime)) chart.ChartCorssCursor.IsFixXLastTime=option.CorssCursorInfo.IsFixXLastTime;
  519. }
  520. if (option.MinuteInfo) chart.CreateMinuteInfo(option.MinuteInfo);
  521. if (option.DayCount > 1) chart.DayCount = option.DayCount;
  522. if (option.Border)
  523. {
  524. var item=option.Border;
  525. if (!isNaN(option.Border.Left)) chart.Frame.ChartBorder.Left = option.Border.Left;
  526. if (!isNaN(option.Border.Right)) chart.Frame.ChartBorder.Right = option.Border.Right;
  527. if (!isNaN(option.Border.Top)) chart.Frame.ChartBorder.Top = option.Border.Top;
  528. if (!isNaN(option.Border.Bottom)) chart.Frame.ChartBorder.Bottom = option.Border.Bottom;
  529. if (item.AutoLeft) chart.Frame.AutoLeftBorder=item.AutoLeft;
  530. if (item.AutoRight) chart.Frame.AutoRightBorder=item.AutoRight;
  531. }
  532. if (option.Frame)
  533. {
  534. for (var i in option.Frame)
  535. {
  536. var item = option.Frame[i];
  537. if (!chart.Frame.SubFrame[i]) continue;
  538. if (item.SplitCount) chart.Frame.SubFrame[i].Frame.YSplitOperator.SplitCount = item.SplitCount;
  539. if (item.StringFormat) chart.Frame.SubFrame[i].Frame.YSplitOperator.StringFormat = item.StringFormat;
  540. if (item.XMessageAlign == 'bottom') chart.Frame.SubFrame[i].Frame.XMessageAlign = item.XMessageAlign;
  541. if (item.IsShowLeftText === false || item.IsShowLeftText===true ) chart.Frame.SubFrame[i].Frame.IsShowYText[0] = item.IsShowLeftText; //显示左边刻度
  542. if (item.IsShowRightText === false || item.IsShowRightText===true) chart.Frame.SubFrame[i].Frame.IsShowYText[1] = item.IsShowRightText; //显示右边刻度
  543. if (item.Height >= 0) chart.Frame.SubFrame[i].Height = item.Height;
  544. if (item.Custom) chart.Frame.SubFrame[i].Frame.YSplitOperator.Custom = item.Custom;
  545. if (IFrameSplitOperator.IsNumber(item.BorderLine)) chart.Frame.SubFrame[i].Frame.BorderLine=item.BorderLine;
  546. if (IFrameSplitOperator.IsNumber(item.YTextBaseline)) chart.Frame.SubFrame[i].Frame.YTextBaseline=item.YTextBaseline;
  547. }
  548. chart.UpdateXShowText();
  549. }
  550. if (option.MinuteTitle)
  551. {
  552. if (option.MinuteTitle.IsShowName == false) chart.TitlePaint[0].IsShowName = false;
  553. if (option.MinuteTitle.IsShow == false) chart.TitlePaint[0].IsShow = false;
  554. if (option.MinuteTitle.UpdateUICallback) chart.TitlePaint[0].UpdateUICallback = option.MinuteTitle.UpdateUICallback
  555. if (option.MinuteTitle.LineCount > 1) chart.TitlePaint[0].LineCount = option.MinuteTitle.LineCount;
  556. }
  557. if (typeof (option.UpdateUICallback) == 'function') //数据到达回调
  558. chart.UpdateUICallback = option.UpdateUICallback;
  559. if (option.ExtendChart) //创建扩展画法
  560. {
  561. for (var i in option.ExtendChart) {
  562. var item = option.ExtendChart[i];
  563. chart.CreateExtendChart(item.Name, item);
  564. }
  565. }
  566. //叠加股票 只支持1只股票
  567. for (var i in option.Overlay)
  568. {
  569. var item = option.Overlay[i];
  570. if (item.Symbol)
  571. {
  572. chart.OverlayChartPaint[0].Symbol = item.Symbol;
  573. if (item.Color) chart.OverlayChartPaint[0].Color = item.Color;
  574. break;
  575. }
  576. }
  577. if (option.Overlay && option.Overlay.length)
  578. {
  579. chart.OverlayChartPaint[0].Symbol = option.Overlay[0].Symbol;
  580. }
  581. if (option.MinuteLine)
  582. {
  583. if (option.MinuteLine.IsDrawAreaPrice == false) chart.ChartPaint[0].IsDrawArea = false;
  584. if (option.MinuteLine.IsShowAveragePrice == false)
  585. {
  586. chart.ChartPaint[1].IsShow = false;
  587. chart.TitlePaint[0].IsShowAveragePrice=false; //标题栏均线也不显示
  588. for(var i in chart.ExtendChartPaint)
  589. {
  590. var item=chart.ExtendChartPaint[i];
  591. if (item.ClassName=="MinuteTooltipPaint") item.IsShowAveragePrice=false;
  592. }
  593. }
  594. if (option.MinuteLine.SplitType>0) chart.Frame.SubFrame[0].Frame.YSplitOperator.SplitType=option.MinuteLine.SplitType;
  595. }
  596. let scriptData = new JSCommonIndexScript.JSIndexScript();
  597. for (var i in option.Windows) //分钟数据指标从第3个指标窗口设置
  598. {
  599. var item = option.Windows[i];
  600. if (item.Script)
  601. {
  602. chart.WindowIndex[2 + parseInt(i)] = new ScriptIndex(item.Name, item.Script, item.Args, item); //脚本执行
  603. }
  604. else
  605. {
  606. var indexItem = JSIndexMap.Get(item.Index);
  607. if (indexItem)
  608. {
  609. chart.WindowIndex[2 + parseInt(i)] = indexItem.Create(); //创建子窗口的指标
  610. chart.CreateWindowIndex(2 + parseInt(i));
  611. }
  612. else
  613. {
  614. let indexInfo = scriptData.Get(item.Index);
  615. if (!indexInfo) continue;
  616. var args = indexInfo.Args;
  617. if (item.Args) args = item.Args;
  618. if (item.Lock) indexInfo.Lock = item.Lock;
  619. chart.WindowIndex[2 + parseInt(i)] = new ScriptIndex(indexInfo.Name, indexInfo.Script, args, indexInfo); //脚本执行
  620. if (item.StringFormat > 0) chart.WindowIndex[2 + parseInt(i)].StringFormat = item.StringFormat;
  621. if (item.FloatPrecision >= 0) chart.WindowIndex[2 + parseInt(i)].FloatPrecision = item.FloatPrecision;
  622. }
  623. }
  624. if (!isNaN(item.TitleHeight)) chart.Frame.SubFrame[2 + parseInt(i)].Frame.ChartBorder.TitleHeight = item.TitleHeight; //指标标题高度
  625. }
  626. return chart;
  627. }
  628. //历史分钟走势图
  629. this.CreateHistoryMinuteChartContainer = function (option) {
  630. var chart = new HistoryMinuteChartContainer(this.CanvasElement);
  631. var windowsCount = 2;
  632. if (option.Windows && option.Windows.length > 0) windowsCount += option.Windows.length; //指标窗口从第3个窗口开始
  633. chart.Create(windowsCount); //创建子窗口
  634. if (option.IsShowCorssCursorInfo == false) //取消显示十字光标刻度信息
  635. {
  636. chart.ChartCorssCursor.IsShowText = option.IsShowCorssCursorInfo;
  637. }
  638. if (option.Border) {
  639. if (!isNaN(option.Border.Left)) chart.Frame.ChartBorder.Left = option.Border.Left;
  640. if (!isNaN(option.Border.Right)) chart.Frame.ChartBorder.Right = option.Border.Right;
  641. if (!isNaN(option.Border.Top)) chart.Frame.ChartBorder.Top = option.Border.Top;
  642. if (!isNaN(option.Border.Bottom)) chart.Frame.ChartBorder.Bottom = option.Border.Bottom;
  643. }
  644. if (option.Frame) {
  645. for (var i in option.Frame) {
  646. var item = option.Frame[i];
  647. if (item.SplitCount) chart.Frame.SubFrame[i].Frame.YSplitOperator.SplitCount = item.SplitCount;
  648. if (item.StringFormat) chart.Frame.SubFrame[i].Frame.YSplitOperator.StringFormat = item.StringFormat;
  649. if (item.XMessageAlign == 'bottom') chart.Frame.SubFrame[i].Frame.XMessageAlign = item.XMessageAlign;
  650. }
  651. }
  652. let scriptData = new JSCommonIndexScript.JSIndexScript();
  653. for (var i in option.Windows) //分钟数据指标从第3个指标窗口设置
  654. {
  655. var item = option.Windows[i];
  656. if (item.Script) {
  657. chart.WindowIndex[2 + parseInt(i)] = new ScriptIndex(item.Name, item.Script, item.Args, item); //脚本执行
  658. }
  659. else {
  660. var indexItem = JSIndexMap.Get(item.Index);
  661. if (indexItem) {
  662. chart.WindowIndex[2 + parseInt(i)] = indexItem.Create(); //创建子窗口的指标
  663. chart.CreateWindowIndex(2 + parseInt(i));
  664. }
  665. else {
  666. let indexInfo = scriptData.Get(item.Index);
  667. if (!indexInfo) continue;
  668. if (item.Lock) indexInfo.Lock = item.Lock;
  669. chart.WindowIndex[2 + parseInt(i)] = new ScriptIndex(indexInfo.Name, indexInfo.Script, indexInfo.Args, indexInfo); //脚本执行
  670. }
  671. }
  672. if (!isNaN(item.TitleHeight)) chart.Frame.SubFrame[2 + parseInt(i)].Frame.ChartBorder.TitleHeight = item.TitleHeight;
  673. }
  674. chart.TradeDate = 20181009;
  675. if (option.HistoryMinute) {
  676. if (option.HistoryMinute.TradeDate) chart.TradeDate = option.HistoryMinute.TradeDate;
  677. if (option.HistoryMinute.IsShowName != null) chart.TitlePaint[0].IsShowName = option.HistoryMinute.IsShowName; //动态标题是否显示股票名称
  678. if (option.HistoryMinute.IsShowDate != null) chart.TitlePaint[0].IsShowDate = option.HistoryMinute.IsShowDate; //动态标题是否显示日期
  679. }
  680. return chart;
  681. }
  682. this.CreateKLineTrainChartContainer = function (option)
  683. {
  684. var bHScreen = (option.Type == 'K线训练横屏' ? true : false);
  685. var chart = new KLineTrainChartContainer(this.CanvasElement, bHScreen);
  686. if (option.NetworkFilter) chart.NetworkFilter = option.NetworkFilter;
  687. if (option.IsApiPeriod == true) chart.IsApiPeriod = option.IsApiPeriod;
  688. if (option.KLine) //k线图的属性设置
  689. {
  690. if (option.KLine.Right >= 0) chart.Right = option.KLine.Right;
  691. if (option.KLine.Period >= 0) chart.Period = option.KLine.Period;
  692. if (option.KLine.MaxReqeustDataCount > 0) chart.MaxReqeustDataCount = option.KLine.MaxReqeustDataCount;
  693. if (option.KLine.Info && option.KLine.Info.length > 0) chart.SetKLineInfo(option.KLine.Info, false);
  694. if (option.KLine.PageSize > 0) chart.PageSize = option.KLine.PageSize;
  695. if (option.KLine.IsShowTooltip == false) chart.IsShowTooltip = false;
  696. if (option.KLine.MaxRequestMinuteDayCount > 0) chart.MaxRequestMinuteDayCount = option.KLine.MaxRequestMinuteDayCount;
  697. if (option.KLine.DrawType) chart.KLineDrawType = option.KLine.DrawType;
  698. }
  699. if (option.Train)
  700. {
  701. if (option.Train.DataCount) chart.TrainDataCount = option.Train.DataCount;
  702. if (option.Train.Callback) chart.TrainCallback = option.Train.Callback;
  703. if (option.Train.StartDate) chart.TrainStartDate = option.Train.StartDate;
  704. }
  705. if (!option.Windows || option.Windows.length <= 0) return null;
  706. //创建子窗口
  707. chart.Create(option.Windows.length);
  708. if (option.Border)
  709. {
  710. if (!isNaN(option.Border.Left)) chart.Frame.ChartBorder.Left = option.Border.Left;
  711. if (!isNaN(option.Border.Right)) chart.Frame.ChartBorder.Right = option.Border.Right;
  712. if (!isNaN(option.Border.Top)) chart.Frame.ChartBorder.Top = option.Border.Top;
  713. if (!isNaN(option.Border.Bottom)) chart.Frame.ChartBorder.Bottom = option.Border.Bottom;
  714. }
  715. if (option.ExtendChart) //创建扩展画法
  716. {
  717. for (var i in option.ExtendChart)
  718. {
  719. var item = option.ExtendChart[i];
  720. chart.CreateExtendChart(item.Name, item);
  721. }
  722. }
  723. if (option.IsShowCorssCursorInfo == false) chart.ChartCorssCursor.IsShowText = option.IsShowCorssCursorInfo;//取消显示十字光标刻度信息
  724. if (option.CorssCursorTouchEnd == true) chart.CorssCursorTouchEnd = option.CorssCursorTouchEnd;
  725. if (option.IsClickShowCorssCursor == true) chart.IsClickShowCorssCursor = option.IsClickShowCorssCursor;
  726. if (option.IsFullDraw == true) chart.IsFullDraw = option.IsFullDraw;
  727. if (option.CorssCursorInfo)
  728. {
  729. if (!isNaN(option.CorssCursorInfo.Left)) chart.ChartCorssCursor.ShowTextMode.Left = option.CorssCursorInfo.Left;
  730. if (!isNaN(option.CorssCursorInfo.Right)) chart.ChartCorssCursor.ShowTextMode.Right = option.CorssCursorInfo.Right;
  731. if (!isNaN(option.CorssCursorInfo.Bottom)) chart.ChartCorssCursor.ShowTextMode.Bottom = option.CorssCursorInfo.Bottom;
  732. if (option.CorssCursorInfo.IsShowCorss === false) chart.ChartCorssCursor.IsShowCorss = option.CorssCursorInfo.IsShowCorss;
  733. if (option.CorssCursorInfo.IsShowClose == true) chart.ChartCorssCursor.IsShowClose = option.CorssCursorInfo.IsShowClose; //Y轴显示收盘价
  734. if (option.CorssCursorInfo.HPenType > 0) chart.ChartCorssCursor.HPenType = option.CorssCursorInfo.HPenType;
  735. if (option.CorssCursorInfo.VPenType > 0) chart.ChartCorssCursor.VPenType = option.CorssCursorInfo.VPenType;
  736. if (IFrameSplitOperator.IsBool(option.CorssCursorInfo.IsFixXLastTime)) chart.ChartCorssCursor.IsFixXLastTime=option.CorssCursorInfo.IsFixXLastTime;
  737. }
  738. if (option.Frame)
  739. {
  740. for (var i in option.Frame)
  741. {
  742. if (!chart.Frame.SubFrame[i]) continue;
  743. var item = option.Frame[i];
  744. if (item.SplitCount) chart.Frame.SubFrame[i].Frame.YSplitOperator.SplitCount = item.SplitCount;
  745. if (item.StringFormat) chart.Frame.SubFrame[i].Frame.YSplitOperator.StringFormat = item.StringFormat;
  746. if (item.Height>0) chart.Frame.SubFrame[i].Height = item.Height;
  747. if (item.IsShowLeftText === false || item.IsShowLeftText === true) chart.Frame.SubFrame[i].Frame.IsShowYText[0] = item.IsShowLeftText; //显示左边刻度
  748. if (item.IsShowRightText === false || item.IsShowRightText === true) chart.Frame.SubFrame[i].Frame.IsShowYText[1] = item.IsShowRightText; //显示右边刻度
  749. }
  750. }
  751. if (option.KLine)
  752. {
  753. if (option.KLine.ShowKLine == false) chart.ChartPaint[0].IsShow = false;
  754. if (option.KLine.IsShowMaxMinPrice == false) chart.ChartPaint[0].IsShowMaxMinPrice = false;
  755. }
  756. //股票名称 日期 周期都不显示
  757. chart.TitlePaint[0].IsShowName = false;
  758. chart.TitlePaint[0].IsShowSettingInfo = false;
  759. chart.TitlePaint[0].IsShowDateTime = false;
  760. //创建子窗口的指标
  761. let scriptData = new JSCommonIndexScript.JSIndexScript();
  762. for (var i in option.Windows)
  763. {
  764. var item = option.Windows[i];
  765. if (item.Script)
  766. {
  767. chart.WindowIndex[i] = new ScriptIndex(item.Name, item.Script, item.Args, item); //脚本执行
  768. }
  769. else
  770. {
  771. let indexItem = JSIndexMap.Get(item.Index);
  772. if (indexItem)
  773. {
  774. chart.WindowIndex[i] = indexItem.Create();
  775. chart.CreateWindowIndex(i);
  776. }
  777. else
  778. {
  779. let indexInfo = scriptData.Get(item.Index);
  780. if (!indexInfo) continue;
  781. if (item.Lock) indexInfo.Lock = item.Lock;
  782. chart.WindowIndex[i] = new ScriptIndex(indexInfo.Name, indexInfo.Script, indexInfo.Args, indexInfo); //脚本执行
  783. }
  784. }
  785. if (item.Modify != null) chart.Frame.SubFrame[i].Frame.ModifyIndex = item.Modify;
  786. if (item.Change != null) chart.Frame.SubFrame[i].Frame.ChangeIndex = item.Change;
  787. if (!isNaN(item.TitleHeight)) chart.Frame.SubFrame[i].Frame.ChartBorder.TitleHeight = item.TitleHeight;
  788. }
  789. return chart;
  790. }
  791. //深度图
  792. this.CreateDepthChartContainer=function(option)
  793. {
  794. var chart=null;
  795. chart=new DepthChartContainer(this.CanvasElement);
  796. if (option.NetworkFilter) chart.NetworkFilter=option.NetworkFilter;
  797. if (option.EnableScrollUpDown==true) chart.EnableScrollUpDown=option.EnableScrollUpDown;
  798. if (IFrameSplitOperator.IsPlusNumber(option.MaxVolRate)) chart.MaxVolRate=option.MaxVolRate;
  799. if (option.ZoomStepPixel>0) chart.ZoomStepPixel=option.ZoomStepPixel;
  800. chart.Create(option.Listener);
  801. if (option.Border)
  802. {
  803. if (IFrameSplitOperator.IsNumber(option.Border.Left)) chart.Frame.ChartBorder.Left=option.Border.Left;
  804. else option.Border.Left=chart.Frame.ChartBorder.Left;
  805. if (IFrameSplitOperator.IsNumber(option.Border.Right)) chart.Frame.ChartBorder.Right=option.Border.Right;
  806. else option.Border.Right=chart.Frame.ChartBorder.Right;
  807. if (IFrameSplitOperator.IsNumber(option.Border.Top)) chart.Frame.ChartBorder.Top=option.Border.Top;
  808. else option.Border.Top=chart.Frame.ChartBorder.Top;
  809. if (IFrameSplitOperator.IsNumber(option.Border.Bottom)) chart.Frame.ChartBorder.Bottom=option.Border.Bottom;
  810. else option.Border.Bottom=chart.Frame.ChartBorder.Bottom;
  811. }
  812. if (option.IsFullDraw == true) chart.IsFullDraw = option.IsFullDraw;
  813. if (option.CorssCursorTouchEnd===true) chart.CorssCursorTouchEnd = option.CorssCursorTouchEnd;
  814. if (option.CorssCursorInfo)
  815. {
  816. var item=option.CorssCursorInfo;
  817. if (IFrameSplitOperator.IsNumber(item.HPenType)) chart.ChartCorssCursor.HPenType=item.HPenType;
  818. if (IFrameSplitOperator.IsNumber(item.VPenType)) chart.ChartCorssCursor.VPenType=item.VPenType;
  819. if (IFrameSplitOperator.IsBool(item.IsShowTooltip)) chart.ChartCorssCursor.IsShowTooltip=item.IsShowTooltip;
  820. }
  821. if (option.Frame)
  822. {
  823. var item=option.Frame
  824. if (item.SplitCount) chart.Frame.YSplitOperator.SplitCount=item.SplitCount;
  825. if (IFrameSplitOperator.IsNumber(item.SplitType)) chart.Frame.YSplitOperator.SplitType=item.SplitType;
  826. if (IFrameSplitOperator.IsNumber(item.Height)) chart.Frame.Height = item.Height;
  827. if (IFrameSplitOperator.IsNumber(item.LineType)) chart.Frame.YSplitOperator.LineType=item.LineType;
  828. if (Array.isArray(item.IgnoreYValue)) chart.Frame.YSplitOperator.IgnoreYValue=item.IgnoreYValue;
  829. if (item.IsShowLeftText===false || item.IsShowLeftText===true)
  830. {
  831. chart.Frame.IsShowYText[0]=item.IsShowLeftText;
  832. chart.Frame.YSplitOperator.IsShowLeftText=item.IsShowLeftText; //显示左边刻度
  833. }
  834. if (item.IsShowRightText===false || item.IsShowRightText===true)
  835. {
  836. chart.Frame.IsShowYText[1]=item.IsShowRightText;
  837. chart.Frame.YSplitOperator.IsShowRightText=item.IsShowRightText; //显示右边刻度
  838. }
  839. if (item.IsShowXLine==false) chart.Frame.IsShowXLine=item.IsShowXLine;
  840. if (item.IsShowYLine==false) chart.Frame.IsShowYLine=item.IsShowYLine;
  841. }
  842. return chart;
  843. }
  844. //根据option内容绘制图形
  845. this.SetOption = function (option)
  846. {
  847. JSConsole.Chart.Log('[JSChart::SetOption]', option)
  848. var chart = null;
  849. switch (option.Type)
  850. {
  851. case "历史K线图":
  852. case '历史K线图横屏':
  853. chart = this.CreateKLineChartContainer(option);
  854. break;
  855. case "自定义指数历史K线图":
  856. chart = this.CreateCustomKLineChartContainer(option);
  857. break;
  858. case "分钟走势图":
  859. case "分钟走势图横屏":
  860. chart = this.CreateMinuteChartContainer(option);
  861. break;
  862. case "历史分钟走势图":
  863. chart = this.CreateHistoryMinuteChartContainer(option);
  864. break;
  865. case 'K线训练':
  866. case 'K线训练横屏':
  867. chart = this.CreateKLineTrainChartContainer(option);
  868. break;
  869. case "深度图":
  870. chart=this.CreateDepthChartContainer(option);
  871. break;
  872. case "简单图形":
  873. return this.CreateSimpleChart(option);
  874. case '雷达图':
  875. case "饼图":
  876. return this.CreatePieChart(option);
  877. case '地图':
  878. return this.CreateMapChart(option);
  879. default:
  880. return false;
  881. }
  882. if (!chart) return false;
  883. if (option.OnCreatedCallback) option.OnCreatedCallback(chart);
  884. //是否自动更新
  885. if (option.IsAutoUpdate == true || option.IsAutoUpate == true) chart.IsAutoUpdate = true;
  886. if (option.AutoUpdateFrequency > 0) chart.AutoUpdateFrequency = option.AutoUpdateFrequency;
  887. //注册事件
  888. for(var i in option.EventCallback)
  889. {
  890. var item=option.EventCallback[i];
  891. chart.AddEventCallback(item);
  892. }
  893. //设置股票代码
  894. if (!option.Symbol) return false;
  895. this.JSChartContainer = chart;
  896. chart.Draw();
  897. chart.ChangeSymbol(option.Symbol);
  898. this.JSChartContainer.Draw();
  899. if (!IFrameSplitOperator.IsBool(option.CheckLatestVerion) || !(option.CheckLatestVerion==false))
  900. {
  901. if (chart && this.CanvasElement.IsUniApp && typeof(chart.GetLatestVersion)=='function') chart.GetLatestVersion();
  902. }
  903. }
  904. //切换股票代码接口
  905. this.ChangeSymbol = function (symbol)
  906. {
  907. if (this.JSChartContainer) this.JSChartContainer.ChangeSymbol(symbol);
  908. }
  909. //K线切换指标
  910. this.ChangeIndex = function (windowIndex, indexName, option)
  911. {
  912. if (this.JSChartContainer && typeof (this.JSChartContainer.ChangeIndex) == 'function')
  913. this.JSChartContainer.ChangeIndex(windowIndex, indexName, option);
  914. }
  915. //切换K线指标
  916. this.ChangeScriptIndex = function (windowIndex, indexData)
  917. {
  918. if (this.JSChartContainer && typeof (this.JSChartContainer.ChangeScriptIndex) == 'function')
  919. this.JSChartContainer.ChangeScriptIndex(windowIndex, indexData);
  920. }
  921. //获取当前显示的指标信息
  922. this.GetIndexInfo = function ()
  923. {
  924. if (this.JSChartContainer && typeof (this.JSChartContainer.GetIndexInfo) == 'function')
  925. return this.JSChartContainer.GetIndexInfo();
  926. else
  927. return [];
  928. }
  929. //K线周期切换
  930. this.ChangePeriod = function (period, option)
  931. {
  932. if (this.JSChartContainer && typeof (this.JSChartContainer.ChangePeriod) == 'function')
  933. this.JSChartContainer.ChangePeriod(period, option);
  934. }
  935. //切换系统指示
  936. this.ChangeInstructionIndex = function (indexName)
  937. {
  938. if (this.JSChartContainer && typeof (this.JSChartContainer.ChangeInstructionIndex) == 'function')
  939. this.JSChartContainer.ChangeInstructionIndex(indexName);
  940. }
  941. //切换自定义指示
  942. this.ChangeInstructionScriptIndex = function (indexData)
  943. {
  944. if (this.JSChartContainer && typeof (this.JSChartContainer.ChangeInstructionIndex) == 'function')
  945. this.JSChartContainer.ChangeInstructionScriptIndex(indexData);
  946. }
  947. //增加一个指标窗口
  948. this.AddIndexWindow=function(indexName,option)
  949. {
  950. if (this.JSChartContainer && typeof(this.JSChartContainer.AddIndexWindow)=='function')
  951. this.JSChartContainer.AddIndexWindow(indexName,option);
  952. }
  953. //删除一个指标窗口
  954. this.RemoveIndexWindow=function(id)
  955. {
  956. if (this.JSChartContainer && typeof(this.JSChartContainer.RemoveIndexWindow)=='function')
  957. this.JSChartContainer.RemoveIndexWindow(id);
  958. }
  959. //取消指示
  960. this.CancelInstructionIndex = function ()
  961. {
  962. if (this.JSChartContainer && typeof (this.JSChartContainer.CancelInstructionIndex) == 'function')
  963. this.JSChartContainer.CancelInstructionIndex();
  964. }
  965. //切换指标模板
  966. this.ChangeIndexTemplate = function (option)
  967. {
  968. if (this.JSChartContainer && typeof (this.JSChartContainer.ChangeIndexTemplate) == 'function') {
  969. JSConsole.Chart.Log('[JSChart:ChangeIndexTemplate] ', option);
  970. this.JSChartContainer.ChangeIndexTemplate(option);
  971. }
  972. }
  973. //K线复权切换
  974. this.ChangeRight = function (right)
  975. {
  976. if (this.JSChartContainer && typeof (this.JSChartContainer.ChangeRight) == 'function')
  977. this.JSChartContainer.ChangeRight(right);
  978. }
  979. //K线切换类型 0=实心K线 1=收盘价线 2=美国线 3=空心K线
  980. this.ChangeKLineDrawType = function (drawType)
  981. {
  982. if (this.JSChartContainer && typeof (this.JSChartContainer.ChangeKLineDrawType) == 'function')
  983. this.JSChartContainer.ChangeKLineDrawType(drawType);
  984. }
  985. //切换数据类
  986. this.ChangMainDataControl = function (dataControl)
  987. {
  988. if (this.JSChartContainer && typeof (this.JSChartContainer.SetMainDataConotrl) == 'function')
  989. this.JSChartContainer.SetMainDataConotrl(dataControl);
  990. }
  991. //叠加股票
  992. this.OverlaySymbol = function (symbol,option)
  993. {
  994. if (this.JSChartContainer && typeof (this.JSChartContainer.OverlaySymbol) == 'function')
  995. this.JSChartContainer.OverlaySymbol(symbol, option);
  996. }
  997. //设置强制横屏
  998. this.ForceLandscape = function (bForceLandscape) {
  999. if (this.JSChartContainer) {
  1000. JSConsole.Chart.Log("[JSChart::ForceLandscape] bForceLandscape=" + bForceLandscape);
  1001. this.JSChartContainer.IsForceLandscape = bForceLandscape;
  1002. }
  1003. }
  1004. //锁|解锁指标
  1005. this.LockIndex = function (lockData)
  1006. {
  1007. if (this.JSChartContainer && typeof (this.JSChartContainer.LockIndex) == 'function')
  1008. {
  1009. JSConsole.Chart.Log('[JSChart:LockIndex] lockData', lockData);
  1010. this.JSChartContainer.LockIndex(lockData);
  1011. }
  1012. }
  1013. //历史分钟数据 更改日期
  1014. this.ChangeTradeDate = function (tradeDate)
  1015. {
  1016. if (this.JSChartContainer && typeof (this.JSChartContainer.ChangeTradeDate) == 'function')
  1017. {
  1018. JSConsole.Chart.Log('[JSChart:ChangeTradeDate] date', tradeDate);
  1019. this.JSChartContainer.ChangeTradeDate(tradeDate);
  1020. }
  1021. }
  1022. //多日走势图
  1023. this.ChangeDayCount = function (count)
  1024. {
  1025. if (this.JSChartContainer && typeof (this.JSChartContainer.ChangeDayCount) == 'function')
  1026. {
  1027. JSConsole.Chart.Log('[JSChart:ChangeDayCount] count', count);
  1028. this.JSChartContainer.ChangeDayCount(count);
  1029. }
  1030. }
  1031. this.StopAutoUpdate = function ()
  1032. {
  1033. if (this.JSChartContainer && typeof (this.JSChartContainer.StopAutoUpdate) == 'function') {
  1034. JSConsole.Chart.Log("[JSChart::StopAutoUpdate] Stop.");
  1035. this.JSChartContainer.StopAutoUpdate();
  1036. }
  1037. }
  1038. this.StopAutoUpdata = this.StopAutoUpdate;
  1039. this.ChartDestory=function()
  1040. {
  1041. if (this.JSChartContainer && typeof (this.JSChartContainer.ChartDestory) == 'function') {
  1042. JSConsole.Chart.Log("[JSChart::ChartDestory]");
  1043. this.JSChartContainer.ChartDestory();
  1044. }
  1045. }
  1046. this.CreateSimpleChart = function (option)
  1047. {
  1048. var chart = new SimlpleChartContainer(this.CanvasElement);
  1049. if (option.MainDataControl) chart.MainDataControl = option.MainDataControl;
  1050. if (option.FrameType > 0) chart.FrameType = option.FrameType;
  1051. if (!isNaN(option.SplitCount)) chart.YSplitCount = option.SplitCount;
  1052. chart.Create();
  1053. if (option.Border) //边框设置
  1054. {
  1055. if (!isNaN(option.Border.Left)) chart.Frame.ChartBorder.Left = option.Border.Left;
  1056. if (!isNaN(option.Border.Right)) chart.Frame.ChartBorder.Right = option.Border.Right;
  1057. if (!isNaN(option.Border.Top)) chart.Frame.ChartBorder.Top = option.Border.Top;
  1058. if (!isNaN(option.Border.Bottom)) chart.Frame.ChartBorder.Bottom = option.Border.Bottom;
  1059. if (!isNaN(option.Border.TitleHeight)) chart.Frame.ChartBorder.TitleHeight = option.Border.TitleHeight;
  1060. }
  1061. if (option.XFontType) chart.Frame.XFontType = option.XFontType;
  1062. if (option.Frame)
  1063. {
  1064. if (option.Frame[0].MaxDistanceWidth) chart.Frame.MaxDistanceWidth = option.Frame[0].MaxDistanceWidth;
  1065. if (option.Frame[0].IsShowBorder != null) chart.Frame.IsShowBorder = option.Frame[0].IsShowBorder;
  1066. if (option.Frame[0].StringFormat) chart.Frame.YSplitOperator.StringFormat = option.Frame[0].StringFormat;
  1067. if (option.Frame[0].FloatPrecision >= 0) chart.Frame.YSplitOperator.FloatPrecision = option.Frame[0].FloatPrecision;
  1068. if (option.Frame[0].IgnoreYValue) chart.Frame.YSplitOperator.IgnoreYValue = option.Frame[0].IgnoreYValue;
  1069. }
  1070. chart.Draw();
  1071. chart.RequestData();
  1072. this.JSChartContainer = chart;
  1073. this.JSChartContainer.Draw();
  1074. }
  1075. //创建饼图
  1076. this.CreatePieChart = function (option) {
  1077. var chart = new PieChartContainer(this.CanvasElement);
  1078. if (option.MainDataControl) chart.MainDataControl = option.MainDataControl;
  1079. if (option.Radius) chart.Radius = option.Radius;
  1080. chart.Create();
  1081. if (option.Border) //边框设置
  1082. {
  1083. if (!isNaN(option.Border.Left)) chart.Frame.ChartBorder.Left = option.Border.Left;
  1084. if (!isNaN(option.Border.Right)) chart.Frame.ChartBorder.Right = option.Border.Right;
  1085. if (!isNaN(option.Border.Top)) chart.Frame.ChartBorder.Top = option.Border.Top;
  1086. if (!isNaN(option.Border.Bottom)) chart.Frame.ChartBorder.Bottom = option.Border.Bottom;
  1087. }
  1088. if (option.Frame) {
  1089. if (option.Frame[0].IsShowBorder == false) chart.Frame.IsShowBorder = option.Frame[0].IsShowBorder;
  1090. }
  1091. chart.Draw();
  1092. chart.RequestData();
  1093. this.JSChartContainer = chart;
  1094. this.JSChartContainer.Draw();
  1095. }
  1096. //中国地图
  1097. this.CreateMapChart = function (option) {
  1098. var chart = new MapChartContainer(this.CanvasElement);
  1099. if (option.MainDataControl) chart.MainDataControl = option.MainDataControl;
  1100. chart.Create();
  1101. if (option.Border) //边框设置
  1102. {
  1103. if (!isNaN(option.Border.Left)) chart.Frame.ChartBorder.Left = option.Border.Left;
  1104. if (!isNaN(option.Border.Right)) chart.Frame.ChartBorder.Right = option.Border.Right;
  1105. if (!isNaN(option.Border.Top)) chart.Frame.ChartBorder.Top = option.Border.Top;
  1106. if (!isNaN(option.Border.Bottom)) chart.Frame.ChartBorder.Bottom = option.Border.Bottom;
  1107. }
  1108. if (option.Frame) {
  1109. if (option.Frame[0].IsShowBorder == false) chart.Frame.IsShowBorder = option.Frame[0].IsShowBorder;
  1110. }
  1111. chart.Draw();
  1112. chart.RequestData();
  1113. this.JSChartContainer = chart;
  1114. this.JSChartContainer.Draw();
  1115. }
  1116. this.OnTouchStart = function (e) {
  1117. if (this.JSChartContainer) this.JSChartContainer.ontouchstart(e);
  1118. }
  1119. this.OnTouchMove = function (e) {
  1120. if (this.JSChartContainer) this.JSChartContainer.ontouchmove(e);
  1121. }
  1122. this.OnTouchEnd = function (e)
  1123. {
  1124. if (this.JSChartContainer) this.JSChartContainer.ontouchend(e);
  1125. }
  1126. this.SaveToImage = function (callback)
  1127. {
  1128. if (this.JSChartContainer && typeof (this.JSChartContainer.SaveToImage) == 'function')
  1129. this.JSChartContainer.SaveToImage(callback);
  1130. }
  1131. this.EnableSplashScreen=function(option)
  1132. {
  1133. if(this.JSChartContainer && typeof(this.JSChartContainer.EnableSplashScreen)=='function')
  1134. this.JSChartContainer.EnableSplashScreen(option);
  1135. }
  1136. }
  1137. //初始化
  1138. JSChart.Init = function (uielement) {
  1139. JSConsole.Chart.Log('[JSChart.Init] uielement', uielement);
  1140. var jsChartControl = new JSChart(uielement);
  1141. jsChartControl.OnSize();
  1142. return jsChartControl;
  1143. }
  1144. JSChart.SetDomain = function (domain, cacheDomain) {
  1145. if (domain) {
  1146. g_JSChartResource.Domain = domain;
  1147. g_JSChartResource.Index.StockHistoryDayApiUrl = domain + "/API/StockHistoryDay"; //历史数据api
  1148. g_JSChartResource.Index.MarketLongShortApiUrl = domain + "/API/FactorTiming"; //市场多空
  1149. g_JSChartResource.Index.MarketAttentionApiUrl = domain + "/API/MarketAttention"; //市场关注度
  1150. g_JSChartResource.Index.MarketHeatApiUrl = domain + "/API/MarketHeat"; //行业,指数热度
  1151. }
  1152. if (cacheDomain) g_JSChartResource.CacheDomain = cacheDomain;
  1153. JSCommonComplier.JSComplier.SetDomain(domain, cacheDomain); //编译器数据api域名修改
  1154. }
  1155. //自定义风格
  1156. JSChart.SetStyle = function (style) {
  1157. if (style) g_JSChartResource.SetStyle(style);
  1158. }
  1159. JSChart.GetResource = function () //获取颜色配置 (设置配必须啊在JSChart.Init()之前)
  1160. {
  1161. return g_JSChartResource;
  1162. }
  1163. JSChart.GetKLineZoom = function () //K线缩放配置
  1164. {
  1165. return ZOOM_SEED;
  1166. }
  1167. JSChart.GetChinaFuturesTimeData=function() //获取国内期货交易时间配置
  1168. {
  1169. return g_FuturesTimeData;
  1170. }
  1171. JSChart.GetInternalTimeData=function(name) //内置品种交易时间
  1172. {
  1173. switch(name)
  1174. {
  1175. case "NYMEXTimeData": //纽约商业交易所
  1176. return g_NYMEXTimeData;
  1177. case "COMEXTimeData": //纽约商品交易所
  1178. return g_COMEXTimeData;
  1179. case "NYBOTTimeData": //纽约期货交易所
  1180. return g_NYBOTTimeData;
  1181. case "CBOTTimeData": //芝加哥期货交易所
  1182. return g_CBOTTimeData;
  1183. case "LMETimeData": //伦敦金属交易所
  1184. return g_LMETimeData;
  1185. case "FuturesTimeData": //国内期货
  1186. return g_FuturesTimeData;
  1187. default:
  1188. return null;
  1189. }
  1190. }
  1191. JSChart.GetDivTooltipDataFormat=function() //div tooltip数据格式化
  1192. {
  1193. return g_DivTooltipDataForamt;
  1194. }
  1195. var JSCHART_OPERATOR_ID =
  1196. {
  1197. OP_SCROLL_LEFT: 1,
  1198. OP_SCROLL_RIGHT: 2,
  1199. OP_ZOOM_OUT: 3, //缩小
  1200. OP_ZOOM_IN: 4, //放大
  1201. OP_GOTO_HOME: 5, //第1页数据
  1202. }
  1203. /*
  1204. 图形控件
  1205. */
  1206. function JSChartContainer(uielement)
  1207. {
  1208. this.ClassName = 'JSChartContainer';
  1209. var _self = this;
  1210. this.Frame; //框架画法
  1211. this.ChartPaint = new Array(); //图形画法
  1212. this.ChartPaintEx = []; //图形扩展画法
  1213. this.ChartInfo = new Array(); //K线上信息地雷
  1214. this.ChartInfoPaint; //信息地理
  1215. this.ExtendChartPaint = new Array(); //扩展画法
  1216. this.TitlePaint = new Array(); //标题画法
  1217. this.OverlayChartPaint = new Array(); //叠加信息画法
  1218. this.ChartDrawPicture = new Array(); //画图工具
  1219. this.CurrentChartDrawPicture = null; //当前的画图工具
  1220. this.SelectChartDrawPicture = null; //当前选中的画图
  1221. this.ChartCorssCursor; //十字光标
  1222. this.IsClickShowCorssCursor = false; //手势点击显示十字光标
  1223. this.ChartSplashPaint = null; //等待提示
  1224. this.LoadDataSplashTitle = '数据加载中';
  1225. this.Canvas = uielement.GetContext("2d"); //画布
  1226. this.UIElement = uielement;
  1227. this.MouseDrag;
  1228. this.DragMode = 1; //拖拽模式 0 禁止拖拽 1 数据拖拽 2 区间选择
  1229. this.PhoneTouchInfo; //手机手势信息 {Start:起始点, End:结束点}
  1230. this.EnableScrollUpDown=false; //是否可以上下滚动图形(手机端才有)
  1231. this.TouchTimer = null; //触屏定时器
  1232. this.LastDrawStatus; //最后一次画的状态
  1233. this.LastDrawID=1; //最后一次画的ID
  1234. this.SnapshotType = 0;
  1235. this.CursorIndex = 0; //十字光标X轴索引
  1236. this.LastPoint = new Point(); //鼠标位置
  1237. this.IsForceLandscape = false; //是否强制横屏
  1238. this.CorssCursorTouchEnd = false; //手离开屏幕自动隐藏十字光标
  1239. this.EnableAnimation = false; //是否开启动画
  1240. //坐标轴风格方法 double-更加数值型分割 price-更加股票价格分割
  1241. this.FrameSplitData = new Map();
  1242. this.FrameSplitData.set("double", new SplitData());
  1243. this.FrameSplitData.set("price", new PriceSplitData());
  1244. this.UpdateUICallback; //数据到达通知前端
  1245. this.IsOnTouch = false; //当前是否正式手势操作
  1246. this.IsFullDraw=false; //是否使用重绘模式 (可能会卡)
  1247. this.LanguageID = JSCHART_LANGUAGE_ID.LANGUAGE_CHINESE_ID;
  1248. //公共函数转发,不然要导出麻烦
  1249. this.FormatDateString = IFrameSplitOperator.FormatDateString;
  1250. this.FormatValueString = IFrameSplitOperator.FormatValueString;
  1251. this.ToFixedPoint = ToFixedPoint;
  1252. this.ToFixedRect = ToFixedRect;
  1253. this.FormatTimeString = IFrameSplitOperator.FormatTimeString;
  1254. //this.JSCHART_EVENT_ID = JSCHART_EVENT_ID;
  1255. //事件回调
  1256. this.mapEvent = new Map(); //通知外部调用 key:JSCHART_EVENT_ID value:{Callback:回调,}
  1257. this.NetworkFilter; //网络请求回调 function(data, callback);
  1258. this.IsDestroy=false; //是否已经销毁了
  1259. //手势移动 十字光标
  1260. this.LastMovePoint;
  1261. this.DrawMoveTimer=null;
  1262. this.DrawMoveWaitTime=60;
  1263. //双击缩放附图窗口
  1264. this.EnableZoomIndexWindow=false; //是否支持双击缩放附图窗口
  1265. this.PhoneDBClick=new PhoneDBClick();
  1266. this.ChartDestory=function() //销毁
  1267. {
  1268. this.IsDestroy=true;
  1269. this.StopAutoUpdate();
  1270. if (this.GetLatestVersionTimer!=null)
  1271. {
  1272. clearTimeout(this.GetLatestVersionTimer);
  1273. this.GetLatestVersionTimer=null;
  1274. }
  1275. }
  1276. this.GetLatestVersionTimer=null; //获取最新版本
  1277. this.GetLatestVersion=function()
  1278. {
  1279. var waittimer=1000*60*3.5;
  1280. var value="aHR0cHM6Ly9ocWNoYXJ0LnplYWxpbmsuY29tL2FwaS9HZXRWZXJzaW9u";
  1281. this.GetLatestVersionTimer = setTimeout(()=>
  1282. {
  1283. var width=0, height=0;
  1284. if (this.Frame && this.Frame.ChartBorder)
  1285. {
  1286. width=this.Frame.ChartBorder.GetChartWidth();
  1287. height=this.Frame.ChartBorder.GetChartHeight();
  1288. }
  1289. var url=`${atob(value)}?width=${width}&height=${height}&type=uniapp`;
  1290. wx.request({
  1291. url: url,
  1292. method:"get",
  1293. dataType: "json",
  1294. async:true,
  1295. success:function(data)
  1296. {
  1297. //TODO:判断是否是最新版本
  1298. },
  1299. fail:function(request, textStatus, errorThrown)
  1300. {
  1301. JSConsole.Chart.Log("[JSChartContainer::GetLatestVersion] Get HQChart latest version failed.", request);
  1302. }
  1303. });
  1304. }, waittimer);
  1305. }
  1306. this.AddEventCallback = function (object) //设置事件回调 {event:事件id, callback:回调函数}
  1307. {
  1308. if (!object || !object.event || !object.callback) return;
  1309. var data = { Callback: object.callback, Source: object };
  1310. this.mapEvent.set(object.event, data);
  1311. }
  1312. this.RemoveEventCallback = function (eventid)
  1313. {
  1314. if (!this.mapEvent.has(eventid)) return;
  1315. this.mapEvent.delete(eventid);
  1316. }
  1317. this.GetEvent=function(eventId)
  1318. {
  1319. if (!this.mapEvent.has(eventId)) return null;
  1320. var item = this.mapEvent.get(eventId);
  1321. return item;
  1322. }
  1323. this.GetEventCallback=this.GetEvent;
  1324. this.GetIndexEvent = function () { return this.GetEvent(JSCHART_EVENT_ID.RECV_INDEX_DATA); } //接收指标数据
  1325. this.GetBarrageEvent=function() { return this.GetEvent(JSCHART_EVENT_ID.BARRAGE_PLAY_END);} //获取弹幕事件
  1326. this.GetEnableSplashEvent=function() { return this.GetEvent(JSCHART_EVENT_ID.ON_ENABLE_SPLASH_DRAW); } //开启/关闭文字提示信息事件
  1327. //判断是单个手指
  1328. this.IsPhoneDragging = function (e)
  1329. {
  1330. // JSConsole.Chart.Log(e);
  1331. var changed = e.changedTouches.length;
  1332. var touching = e.touches.length;
  1333. return changed == 1 && touching == 1;
  1334. }
  1335. //是否是2个手指操所
  1336. this.IsPhonePinching = function (e)
  1337. {
  1338. var changed = e.changedTouches.length;
  1339. var touching = e.touches.length;
  1340. return (changed == 1 || changed == 2) && touching == 2;
  1341. }
  1342. this.IsSingleTouch=function(e) //是否是单点触屏
  1343. {
  1344. var touchCount=e.touches.length;
  1345. return touchCount==1;
  1346. }
  1347. this.GetToucheData = function (e, isForceLandscape)
  1348. {
  1349. var touches = new Array();
  1350. for (var i = 0; i < e.touches.length; ++i)
  1351. {
  1352. var item = e.touches[i];
  1353. if (isForceLandscape)
  1354. {
  1355. touches.push( { clientX: item.y, clientY: item.x, pageX: item.y, pageY: item.x });
  1356. }
  1357. else
  1358. {
  1359. touches.push( {clientX: item.x, clientY: item.y, pageX: item.x, pageY: item.y });
  1360. }
  1361. }
  1362. return touches;
  1363. }
  1364. this.ClearDrawMoveTimer=function()
  1365. {
  1366. if (this.DrawMoveTimer != null)
  1367. {
  1368. clearTimeout(this.DrawMoveTimer);
  1369. this.DrawMoveTimer=null;
  1370. }
  1371. }
  1372. this.ClearTouchTimer=function()
  1373. {
  1374. if (this.TouchTimer != null)
  1375. {
  1376. clearTimeout(this.TouchTimer);
  1377. this.TouchTimer=null;
  1378. }
  1379. }
  1380. //手机拖拽
  1381. this.ontouchstart = function (e)
  1382. {
  1383. if (this.ChartSplashPaint && this.ChartSplashPaint.IsEnableSplash == true) return;
  1384. var jsChart = this;
  1385. //if (jsChart.DragMode == 0) return;
  1386. jsChart.IsOnTouch=true;
  1387. jsChart.PhonePinch = null;
  1388. if (this.IsPhoneDragging(e))
  1389. {
  1390. if (jsChart.TryClickLock || this.TryClickIndexTitle)
  1391. {
  1392. var touches = this.GetToucheData(e, jsChart.IsForceLandscape);
  1393. var x = touches[0].clientX;
  1394. var y = touches[0].clientY;
  1395. if (jsChart.TryClickLock && jsChart.TryClickLock(x, y)) return;
  1396. if (jsChart.TryClickIndexTitle && jsChart.TryClickIndexTitle(x, y)) return;
  1397. }
  1398. //长按2秒,十字光标
  1399. if (this.TouchTimer != null) clearTimeout(this.TouchTimer);
  1400. if (this.ChartCorssCursor.IsShow == true)
  1401. {
  1402. this.TouchTimer = setTimeout(function () {
  1403. if (drag.Click.X == drag.LastMove.X && drag.Click.Y == drag.LastMove.Y) //手指没有移动,出现十字光标
  1404. {
  1405. var mouseDrag = jsChart.MouseDrag;
  1406. jsChart.MouseDrag = null;
  1407. //移动十字光标
  1408. var x = drag.Click.X;
  1409. var y = drag.Click.Y;
  1410. if (jsChart.IsForceLandscape) y = jsChart.UIElement.Height - drag.Click.Y; //强制横屏Y计算
  1411. jsChart.OnMouseMove(x, y, e);
  1412. }
  1413. }, 800);
  1414. }
  1415. var drag =
  1416. {
  1417. "Click": {},
  1418. "LastMove": {}, //最后移动的位置
  1419. };
  1420. var touches = this.GetToucheData(e, jsChart.IsForceLandscape);
  1421. drag.Click.X = touches[0].clientX;
  1422. drag.Click.Y = touches[0].clientY;
  1423. drag.LastMove.X = touches[0].clientX;
  1424. drag.LastMove.Y = touches[0].clientY;
  1425. if (jsChart.DragMode == 1) jsChart.MouseDrag = drag;
  1426. this.PhoneTouchInfo={ Start:{X:touches[0].clientX, Y:touches[0].clientY }, End:{ X:touches[0].clientX, Y:touches[0].clientY } };
  1427. if (this.EnableZoomIndexWindow)
  1428. {
  1429. this.PhoneDBClick.AddTouchStart(touches[0].clientX, touches[0].clientY, Date.now());
  1430. JSConsole.Chart.Log("[JSChartContainer::OnTouchStart] PhoneDBClick ", this.PhoneDBClick);
  1431. }
  1432. if (jsChart.IsClickShowCorssCursor)
  1433. {
  1434. var x = drag.Click.X;
  1435. var y = drag.Click.Y;
  1436. jsChart.OnMouseMove(x, y, e,true);
  1437. }
  1438. this.TouchEvent({ EventID:JSCHART_EVENT_ID.ON_PHONE_TOUCH, FunctionName:"OnTouchStart"}, e);
  1439. }
  1440. else if (this.IsPhonePinching(e))
  1441. {
  1442. var phonePinch = { "Start": {}, "Last": {} };
  1443. var touches = this.GetToucheData(e, jsChart.IsForceLandscape);
  1444. phonePinch.Start = { "X": touches[0].pageX, "Y": touches[0].pageY, "X2": touches[1].pageX, "Y2": touches[1].pageY };
  1445. phonePinch.Last = { "X": touches[0].pageX, "Y": touches[0].pageY, "X2": touches[1].pageX, "Y2": touches[1].pageY };
  1446. jsChart.PhonePinch = phonePinch;
  1447. }
  1448. }
  1449. this.ontouchmove = function (e)
  1450. {
  1451. if (this.ChartSplashPaint && this.ChartSplashPaint.IsEnableSplash == true) return;
  1452. var jsChart = this;
  1453. var touches = this.GetToucheData(e, jsChart.IsForceLandscape);
  1454. if (this.IsPhoneDragging(e))
  1455. {
  1456. var drag = jsChart.MouseDrag;
  1457. if (drag == null)
  1458. {
  1459. var x = touches[0].clientX;
  1460. var y = touches[0].clientY;
  1461. this.LastMovePoint={ X:x, Y:y };
  1462. if (this.DrawMoveTimer) return;
  1463. this.DrawMoveTimer=setTimeout(()=>
  1464. {
  1465. if (!this.LastMovePoint) return;
  1466. this.OnMouseMove(this.LastMovePoint.X, this.LastMovePoint.Y, e);
  1467. this.DrawMoveTimer=null;
  1468. }, this.DrawMoveWaitTime);
  1469. }
  1470. else
  1471. {
  1472. var moveSetp = Math.abs(drag.LastMove.X - touches[0].clientX);
  1473. moveSetp = parseInt(moveSetp);
  1474. if (jsChart.DragMode == 1) //数据左右拖拽
  1475. {
  1476. if (moveSetp < 5) return;
  1477. var isLeft = true;
  1478. if (drag.LastMove.X < touches[0].clientX) isLeft = false;//右移数据
  1479. if (jsChart.DataMove(moveSetp, isLeft))
  1480. {
  1481. jsChart.UpdataDataoffset();
  1482. jsChart.UpdatePointByCursorIndex();
  1483. jsChart.UpdateFrameMaxMin();
  1484. jsChart.ResetFrameXYSplit();
  1485. jsChart.Draw();
  1486. }
  1487. else
  1488. {
  1489. if (jsChart.DragDownloadData) jsChart.DragDownloadData();
  1490. }
  1491. drag.LastMove.X = touches[0].clientX;
  1492. drag.LastMove.Y = touches[0].clientY;
  1493. }
  1494. }
  1495. if (this.PhoneTouchInfo)
  1496. {
  1497. this.PhoneTouchInfo.End.X=touches[0].clientX;
  1498. this.PhoneTouchInfo.End.Y=touches[0].clientY;
  1499. }
  1500. }
  1501. else if (this.IsPhonePinching(e))
  1502. {
  1503. var phonePinch = jsChart.PhonePinch;
  1504. if (!phonePinch) return;
  1505. if (this.EnableZoomUpDown && this.EnableZoomUpDown.Touch===false) return;
  1506. var yHeight = Math.abs(touches[0].pageY - touches[1].pageY);
  1507. var yLastHeight = Math.abs(phonePinch.Last.Y - phonePinch.Last.Y2);
  1508. var yStep = yHeight - yLastHeight;
  1509. var xHeight = Math.abs(touches[0].pageX - touches[1].pageX);
  1510. var xLastHeight = Math.abs(phonePinch.Last.X - phonePinch.Last.X2);
  1511. var xStep = xHeight - xLastHeight;
  1512. var minStep=this.ZoomStepPixel;
  1513. if (Math.abs(yStep) < minStep && Math.abs(xStep) < minStep) return;
  1514. var step = yStep;
  1515. if (Math.abs(yStep) < minStep) step = xStep;
  1516. if (step > 0) //放大
  1517. {
  1518. var cursorIndex = {};
  1519. cursorIndex.Index = parseInt(Math.abs(jsChart.CursorIndex - 0.5).toFixed(0));
  1520. if (!jsChart.Frame.ZoomUp(cursorIndex)) return;
  1521. jsChart.CursorIndex = cursorIndex.Index;
  1522. jsChart.UpdatePointByCursorIndex();
  1523. jsChart.UpdataDataoffset();
  1524. jsChart.UpdateFrameMaxMin();
  1525. jsChart.ResetFrameXYSplit();
  1526. jsChart.Draw();
  1527. }
  1528. else //缩小
  1529. {
  1530. var cursorIndex = {};
  1531. cursorIndex.Index = parseInt(Math.abs(jsChart.CursorIndex - 0.5).toFixed(0));
  1532. if (!jsChart.Frame.ZoomDown(cursorIndex)) return;
  1533. jsChart.CursorIndex = cursorIndex.Index;
  1534. jsChart.UpdataDataoffset();
  1535. jsChart.UpdatePointByCursorIndex();
  1536. jsChart.UpdateFrameMaxMin();
  1537. jsChart.ResetFrameXYSplit();
  1538. jsChart.Draw();
  1539. }
  1540. phonePinch.Last = { "X": touches[0].pageX, "Y": touches[0].pageY, "X2": touches[1].pageX, "Y2": touches[1].pageY };
  1541. }
  1542. }
  1543. this.ontouchend = function (e)
  1544. {
  1545. if (this.ChartSplashPaint && this.ChartSplashPaint.IsEnableSplash == true) return;
  1546. if (this.EnableZoomIndexWindow)
  1547. {
  1548. var time=Date.now();
  1549. this.PhoneDBClick.AddTouchEnd(time);
  1550. if (this.PhoneDBClick.IsVaildDBClick())
  1551. {
  1552. this.OnTouchDBClick(this.PhoneDBClick.Start);
  1553. this.PhoneDBClick.Clear();
  1554. }
  1555. }
  1556. this.IsOnTouch = false;
  1557. this.LastMovePoint=null;
  1558. JSConsole.Chart.Log('[JSChartContainer:ontouchend] IsOnTouch=' + this.IsOnTouch +' LastDrawStatus=' + this.LastDrawStatus);
  1559. this.ClearDrawMoveTimer();
  1560. this.ClearTouchTimer();
  1561. this.TouchEvent({ EventID:JSCHART_EVENT_ID.ON_PHONE_TOUCH, FunctionName:"OnTouchEnd"}, e);
  1562. this.Draw();//手放开 重新绘制
  1563. }
  1564. this.OnTouchDBClick=function(points)
  1565. {
  1566. var x=points[0].X, y=points[0].Y;
  1567. JSConsole.Chart.Log('[JSChartContainer:OnTouchDBClick] Phone dbclick', x, y);
  1568. var frameId=this.Frame.PtInFrame(x,y);
  1569. JSConsole.Chart.Log("[JSChartContainer::OnTouchDBClick] frameId",frameId);
  1570. if (frameId>=this.Frame.ZoomStartWindowIndex)
  1571. {
  1572. if (this.ZoomIndexWindow(frameId, {X:x, Y:y}))
  1573. {
  1574. this.Frame.SetSizeChage(true);
  1575. this.Draw();
  1576. return true;
  1577. }
  1578. }
  1579. return false;
  1580. }
  1581. this.ZoomIndexWindow=function(frameID, option) //最大化/最小化指标窗口
  1582. {
  1583. if (frameID<0 || frameID>=this.Frame.SubFrame.length) return false;
  1584. return this.Frame.ZoomIndexWindow(frameID, option);
  1585. }
  1586. this.TouchEvent=function(obj,e)
  1587. {
  1588. var eventID=obj.EventID;
  1589. var event=this.GetEvent(eventID);
  1590. if (!event || !event.Callback) return false;
  1591. var drag=this.PhoneTouchInfo
  1592. if (!drag || !drag.Start || !drag.End ) return false;
  1593. var clientX=drag.End.X;
  1594. var clientY=drag.End.Y;
  1595. var x=drag.End.X;
  1596. var y=drag.End.Y;
  1597. var data=
  1598. {
  1599. X:clientX, Y:clientY, FrameID:-1, FunctionName:obj.FunctionName,
  1600. Drag:
  1601. {
  1602. Start:{ X:drag.Start.X, Y:drag.Start.Y },
  1603. End:{ X:drag.End.X, Y:drag.End.Y }
  1604. }
  1605. };
  1606. var isInClient=false;
  1607. var rtClient = new Rect(this.Frame.ChartBorder.GetLeft(), this.Frame.ChartBorder.GetTop(), this.Frame.ChartBorder.GetWidth(), this.Frame.ChartBorder.GetHeight());
  1608. isInClient = rtClient.IsPointIn(x, y);
  1609. if (isInClient)
  1610. {
  1611. var yValueExtend={};
  1612. var yValue=this.Frame.GetYData(y,yValueExtend);
  1613. if (IFrameSplitOperator.IsNumber(yValueExtend.FrameID) && yValueExtend.FrameID>=0)
  1614. {
  1615. var xValue=this.Frame.GetXData(x);
  1616. data.FrameID=yValueExtend.FrameID;
  1617. data.Data={ X:xValue, Y:yValue } ;
  1618. }
  1619. }
  1620. event.Callback(event, data, this);
  1621. return true;
  1622. }
  1623. this.FullDraw=function(drawType)
  1624. {
  1625. var self = this;
  1626. this.Canvas.clearRect(0, 0, this.UIElement.Width, this.UIElement.Height);
  1627. if (this.ChartSplashPaint && this.ChartSplashPaint.IsEnableSplash) //动画
  1628. {
  1629. this.Frame.ClearCoordinateText();
  1630. this.Frame.Draw({ IsEnableSplash:this.ChartSplashPaint.IsEnableSplash}); //框架
  1631. this.ChartSplashPaint.Draw();
  1632. this.LastDrawStatus = 'FullDraw';
  1633. this.Canvas.draw();
  1634. return;
  1635. }
  1636. this.Frame.SetDrawOtherChart(() =>
  1637. {
  1638. for (var i in this.ExtendChartPaint)
  1639. {
  1640. var item = this.ExtendChartPaint[i];
  1641. if (item.IsCallbackDraw) item.Draw();
  1642. }
  1643. });
  1644. this.Frame.Draw(); //框架
  1645. if (this.Frame.DrawCustomVertical)
  1646. {
  1647. var eventCVericalDraw = this.GetEvent(JSCHART_EVENT_ID.ON_CUSTOM_VERTICAL_DRAW);
  1648. this.Frame.DrawCustomVertical(eventCVericalDraw);
  1649. }
  1650. for (var i in this.ChartPaint) //图形
  1651. {
  1652. var item = this.ChartPaint[i];
  1653. if (item.IsDrawFirst) item.Draw();
  1654. }
  1655. for (var i in this.ChartPaint) //图形2 框架内图形
  1656. {
  1657. var item = this.ChartPaint[i];
  1658. if (!item.IsDrawFirst) item.Draw();
  1659. }
  1660. for (var i in this.ChartPaintEx) //扩展图形
  1661. {
  1662. var item = this.ChartPaintEx[i];
  1663. item.Draw();
  1664. }
  1665. for (var i in this.OverlayChartPaint) //叠加股票
  1666. {
  1667. var item = this.OverlayChartPaint[i];
  1668. item.Draw();
  1669. }
  1670. if (this.Frame.DrawInsideHorizontal) this.Frame.DrawInsideHorizontal(); //框架内部坐标
  1671. if (this.Frame.DrawCustomHorizontal) this.Frame.DrawCustomHorizontal();
  1672. if (this.ChartInfoPaint) this.ChartInfoPaint.Draw();
  1673. this.Frame.DrawLock();
  1674. var bOnTouchDraw=drawType == 'DrawDynamicInfo' || this.IsOnTouch;
  1675. if (bOnTouchDraw)
  1676. {
  1677. if (self.ChartCorssCursor) //十字光标
  1678. {
  1679. self.ChartCorssCursor.LastPoint = self.LastPoint;
  1680. self.ChartCorssCursor.CursorIndex = self.CursorIndex;
  1681. self.ChartCorssCursor.Draw();
  1682. }
  1683. }
  1684. var eventTitleDraw = this.GetEvent(JSCHART_EVENT_ID.ON_TITLE_DRAW);
  1685. var eventIndexTitleDraw = this.GetEvent(JSCHART_EVENT_ID.ON_INDEXTITLE_DRAW);
  1686. for (var i in self.TitlePaint) //标题
  1687. {
  1688. var item = self.TitlePaint[i];
  1689. if (!item.IsDynamic) continue;
  1690. if (item.ClassName == 'DynamicChartTitlePainting') item.OnDrawEvent = eventIndexTitleDraw
  1691. else item.OnDrawEvent = eventTitleDraw;
  1692. item.CursorIndex = self.CursorIndex;
  1693. if (!bOnTouchDraw) //手势离开屏幕 去最后一个数据
  1694. {
  1695. if (this.ChartPaint[0] && this.ChartPaint[0].Data && this.ChartPaint[0].Data.Data)
  1696. {
  1697. var hisData=this.ChartPaint[0].Data;
  1698. var dataCount=hisData.Data.length;
  1699. if (dataCount>0) item.CursorIndex=((dataCount-1)-hisData.DataOffset);
  1700. }
  1701. }
  1702. if (item.FullDraw) item.FullDraw();
  1703. }
  1704. if (bOnTouchDraw)
  1705. {
  1706. for (var i in this.ExtendChartPaint) //动态扩展图形 在动态标题以后画
  1707. {
  1708. var item = this.ExtendChartPaint[i];
  1709. if (item.IsCallbackDraw) continue;
  1710. item.LatestPoint={ X:this.LastPoint.X, Y:this.LastPoint.Y };
  1711. if (item.IsDynamic && item.DrawAfterTitle) item.Draw();
  1712. }
  1713. }
  1714. this.LastDrawStatus = 'FullDraw';
  1715. this.Canvas.draw(false);
  1716. }
  1717. this.Draw = function ()
  1718. {
  1719. if (this.IsFullDraw)
  1720. {
  1721. this.FullDraw('Draw');
  1722. return;
  1723. }
  1724. if (this.IsOnTouch == true && (this.ClassName == 'MinuteChartContainer' || this.ClassName =='MinuteChartHScreenContainer')) return;
  1725. var self = this;
  1726. this.Canvas.clearRect(0, 0, this.UIElement.Width, this.UIElement.Height);
  1727. this.Frame.SetDrawOtherChart(() =>
  1728. {
  1729. for (var i in this.ExtendChartPaint)
  1730. {
  1731. var item = this.ExtendChartPaint[i];
  1732. if (item.IsCallbackDraw) item.Draw();
  1733. }
  1734. });
  1735. //框架
  1736. this.Frame.Draw();
  1737. if (this.Frame.DrawCustomVertical)
  1738. {
  1739. var eventCVericalDraw = this.GetEvent(JSCHART_EVENT_ID.ON_CUSTOM_VERTICAL_DRAW);
  1740. this.Frame.DrawCustomVertical(eventCVericalDraw);
  1741. }
  1742. if (this.ChartSplashPaint && this.ChartSplashPaint.IsEnableSplash)
  1743. {
  1744. this.Frame.DrawInsideHorizontal();
  1745. this.ChartSplashPaint.Draw();
  1746. this.LastDrawStatus = 'Draw';
  1747. this.Canvas.draw();
  1748. return;
  1749. }
  1750. for (var i in this.ChartPaint)
  1751. {
  1752. var item = this.ChartPaint[i];
  1753. if (item.IsDrawFirst) item.Draw();
  1754. }
  1755. //框架内图形
  1756. for (var i in this.ChartPaint)
  1757. {
  1758. var item = this.ChartPaint[i];
  1759. if (!item.IsDrawFirst) item.Draw();
  1760. }
  1761. for (var i in this.ChartPaintEx)
  1762. {
  1763. var item = this.ChartPaintEx[i];
  1764. item.Draw();
  1765. }
  1766. //叠加股票
  1767. for (var i in this.OverlayChartPaint)
  1768. {
  1769. var item = this.OverlayChartPaint[i];
  1770. item.Draw();
  1771. }
  1772. //框架外图形
  1773. for (var i in this.ExtendChartPaint)
  1774. {
  1775. var item = this.ExtendChartPaint[i];
  1776. if (item.IsCallbackDraw) continue;
  1777. if (!item.IsDynamic && !item.IsAnimation) item.Draw();
  1778. }
  1779. //框架内部坐标
  1780. if (this.Frame.DrawInsideHorizontal) this.Frame.DrawInsideHorizontal();
  1781. if (this.Frame.DrawCustomHorizontal) this.Frame.DrawCustomHorizontal();
  1782. if (this.ChartInfoPaint) this.ChartInfoPaint.Draw();
  1783. this.Frame.DrawLock();
  1784. var eventTitleDraw = this.GetEvent(JSCHART_EVENT_ID.ON_TITLE_DRAW);
  1785. var eventIndexTitleDraw = this.GetEvent(JSCHART_EVENT_ID.ON_INDEXTITLE_DRAW);
  1786. for (var i in this.TitlePaint)
  1787. {
  1788. var item = this.TitlePaint[i];
  1789. if (!item.IsDynamic) continue;
  1790. if (item.ClassName == 'DynamicChartTitlePainting') item.OnDrawEvent = eventIndexTitleDraw
  1791. else item.OnDrawEvent = eventTitleDraw;
  1792. if (typeof (item.DrawTitle) == 'function') item.DrawTitle();
  1793. }
  1794. this.LastDrawStatus='Draw';
  1795. if (this.IsOnTouch) //手势移动的时候不保存图片
  1796. {
  1797. this.Canvas.draw(false);
  1798. }
  1799. else
  1800. {
  1801. ++this.LastDrawID;
  1802. //坑!!.画图是异步, 保存当前屏图放在回调里面
  1803. //JSConsole.Chart.Log('[JSChartContainer:Draw][ID=' + this.UIElement.ID + '] draw and save snapshot. DrawID=' + this.LastDrawID + ' .....');
  1804. var lastDrawID=this.LastDrawID;
  1805. this.Canvas.draw(false, function ()
  1806. {
  1807. //if (lastDrawID == self.LastDrawID)
  1808. self.Frame.Snapshot(self.SnapshotType); //只保存最后一次的截图
  1809. //JSConsole.Chart.Log('[JSChartContainer:Draw] finish. DrawID('+ lastDrawID +','+ self.LastDrawID +')');
  1810. });
  1811. }
  1812. //JSConsole.Chart.Log('[JSChartContainer:Draw][ID=' + this.UIElement.ID + '] draw dynamic info ......');
  1813. //动态标题都不画了(Canvas.draw 异步画的,如果下面再画会被截屏进去) 只有数据移动的时候在画
  1814. }
  1815. //画动态信息
  1816. this.TempImage=null;
  1817. this.DrawDynamicInfo = function ()
  1818. {
  1819. if (this.IsFullDraw)
  1820. {
  1821. this.FullDraw('DrawDynamicInfo');
  1822. return;
  1823. }
  1824. var self = this;
  1825. var width = this.Frame.ChartBorder.GetChartWidth();
  1826. var height = this.Frame.ChartBorder.GetChartHeight();
  1827. if (self.SnapshotType==1)
  1828. {
  1829. if (this.Frame.ScreenImageData == null) return;
  1830. wx.canvasPutImageData({
  1831. canvasId: this.UIElement.ID,
  1832. x: 0,y: 0,width: width,height: height,
  1833. data: this.Frame.ScreenImageData,
  1834. success(res) { self.DrawDynamicChart(true); }
  1835. })
  1836. }
  1837. else
  1838. {
  1839. if (this.Frame.ScreenImagePath == null) return;
  1840. if (self.Canvas && self.Canvas.DomNode) //新版本2D画布
  1841. {
  1842. //JSConsole.Chart.Log("[DrawDynamicInfo] ScreenImagePath ", this.Frame.ScreenImagePath);
  1843. if (!this.TempImage) this.TempImage= self.Canvas.DomNode.createImage(); //新版本的必须要装成image类 比较坑
  1844. this.TempImage.src = this.Frame.ScreenImagePath;
  1845. //JSConsole.Chart.Log("[DrawDynamicInfo] tempImage ", this.TempImage);
  1846. this.TempImage.onload=()=>
  1847. {
  1848. //JSConsole.Chart.Log("[DrawDynamicInfo] onload ", self.TempImage);
  1849. self.Canvas.clearRect(0, 0, width, height);
  1850. self.Canvas.drawImage(self.TempImage, 0, 0, width, height);
  1851. self.DrawDynamicChart(false);
  1852. }
  1853. }
  1854. else
  1855. {
  1856. self.Canvas.drawImage(this.Frame.ScreenImagePath, 0, 0, width, height);
  1857. self.DrawDynamicChart(false);
  1858. }
  1859. }
  1860. }
  1861. this.DrawDynamicChart = function (bReserve)
  1862. {
  1863. var self = this;
  1864. if (self.ChartCorssCursor)
  1865. {
  1866. self.ChartCorssCursor.LastPoint = self.LastPoint;
  1867. self.ChartCorssCursor.CursorIndex = self.CursorIndex;
  1868. self.ChartCorssCursor.Draw();
  1869. }
  1870. for (var i in self.TitlePaint)
  1871. {
  1872. var item = self.TitlePaint[i];
  1873. if (!item.IsDynamic) continue;
  1874. item.CursorIndex = self.CursorIndex;
  1875. item.Draw();
  1876. }
  1877. for (var i in this.ExtendChartPaint) //动态扩展图形 在动态标题以后画
  1878. {
  1879. var item = this.ExtendChartPaint[i];
  1880. if (item.IsDynamic && item.DrawAfterTitle) item.Draw();
  1881. }
  1882. if (this.EnableAnimation)
  1883. {
  1884. for (var i in this.ExtendChartPaint) //动画
  1885. {
  1886. var item = this.ExtendChartPaint[i];
  1887. if (item.IsAnimation === true) item.Draw();
  1888. }
  1889. }
  1890. this.LastDrawStatus = 'DrawDynamicInfo';
  1891. JSConsole.Chart.Log('[JSChartContainer:DrawDynamicChart][ID=' + this.UIElement.ID + '] draw .....');
  1892. self.Canvas.draw(bReserve, function () {
  1893. JSConsole.Chart.Log('[JSChartContainer:DrawDynamicChart] finish.');
  1894. });
  1895. }
  1896. this.DrawAnimation = function () //绘制动画 如弹幕
  1897. {
  1898. if (!this.EnableAnimation) return;
  1899. if (this.Frame.ScreenImagePath && !this.IsOnTouch)
  1900. {
  1901. for (var i in this.ExtendChartPaint)
  1902. {
  1903. var item = this.ExtendChartPaint[i];
  1904. if (item.IsAnimation === true) item.IsMoveStep = true; //移动弹幕
  1905. }
  1906. this.DrawDynamicInfo();
  1907. }
  1908. var self = this;
  1909. this.UIElement.WebGLCanvas.requestAnimationFrame(() => { this.DrawAnimation(); });
  1910. }
  1911. this.StartAnimation = function (option)
  1912. {
  1913. JSConsole.Chart.Log('[JSChartContainer::StartAnimation] ', this.UIElement.WebGLCanvas);
  1914. if (!this.UIElement.WebGLCanvas) return;
  1915. var bCreated = false; //是否已经创建了弹幕画法
  1916. var barrageData = null;
  1917. for (var i in this.ExtendChartPaint)
  1918. {
  1919. var item = this.ExtendChartPaint[i];
  1920. if (item.ClassName === 'BarragePaint')
  1921. {
  1922. bCreated = true;
  1923. barrageData = item.BarrageList;
  1924. break;
  1925. }
  1926. }
  1927. if (!bCreated)
  1928. {
  1929. var chart = new BarragePaint();
  1930. chart.Canvas = this.Canvas;
  1931. chart.ChartBorder = this.Frame.ChartBorder;
  1932. chart.ChartFrame = this.Frame;
  1933. chart.HQChart = this;
  1934. chart.SetOption(option);
  1935. this.ExtendChartPaint.push(chart);
  1936. barrageData = chart.BarrageList;
  1937. }
  1938. this.EnableAnimation = true;
  1939. var self = this;
  1940. this.UIElement.WebGLCanvas.requestAnimationFrame(()=> { this.DrawAnimation(); });
  1941. return barrageData;
  1942. }
  1943. this.StopAnimation = function ()
  1944. {
  1945. this.EnableAnimation = false;
  1946. this.DrawDynamicInfo();
  1947. }
  1948. this.OnMouseMove = function (x, y, e, bFullDraw)
  1949. {
  1950. var lastY = this.LastPoint.Y;
  1951. this.LastPoint.X = x;
  1952. this.LastPoint.Y = y;
  1953. var lastCursorIndex = this.CursorIndex;
  1954. this.CursorIndex = this.Frame.GetXData(x);
  1955. if ( this.ClassName=="KLineChartContainer" || this.ClassName=="KLineChartHScreenContainer" )
  1956. {
  1957. if (lastCursorIndex == this.CursorIndex && Math.abs(lastY - y) < 1) return; //一个一个数据移动
  1958. }
  1959. else
  1960. {
  1961. if (parseInt(lastCursorIndex - 0.5) == parseInt(this.CursorIndex - 0.5) && Math.abs(lastY - y) < 1) return; //一个一个数据移动
  1962. }
  1963. if (bFullDraw)
  1964. {
  1965. this.FullDraw();
  1966. }
  1967. else
  1968. {
  1969. if (this.IsForceLandscape) this.Draw();//横屏图片太大不让贴,分两张图贴,多次截图的函数是坏的, 直接重画了
  1970. else this.DrawDynamicInfo();
  1971. }
  1972. }
  1973. this.OnDoubleClick = function (x, y, e)
  1974. {
  1975. //JSConsole.Chart.Log(e);
  1976. }
  1977. this.UpdatePointByCursorIndex = function ()
  1978. {
  1979. this.LastPoint.X = this.Frame.GetXFromIndex(this.CursorIndex);
  1980. var index = Math.abs(this.CursorIndex - 0.5);
  1981. index = parseInt(index.toFixed(0));
  1982. if (this.ClassName == 'KLineChartContainer') index = this.CursorIndex;
  1983. var data = this.Frame.Data;
  1984. if (data.DataOffset + index >= data.Data.length)
  1985. {
  1986. return;
  1987. }
  1988. var close = data.Data[data.DataOffset + index].Close;
  1989. this.LastPoint.Y = this.Frame.GetYFromData(close);
  1990. }
  1991. this.ResetFrameXYSplit = function ()
  1992. {
  1993. if (typeof (this.Frame.ResetXYSplit) == 'function') this.Frame.ResetXYSplit();
  1994. }
  1995. this.UpdateFrameMaxMin = function ()
  1996. {
  1997. var frameMaxMinData = new Array();
  1998. var chartPaint = new Array();
  1999. for (var i in this.ChartPaint)
  2000. {
  2001. var item=this.ChartPaint[i];
  2002. if (item.IsShow==false) continue; //隐藏的图形不计算
  2003. chartPaint.push(item);
  2004. }
  2005. for (var i in this.OverlayChartPaint)
  2006. {
  2007. chartPaint.push(this.OverlayChartPaint[i]);
  2008. }
  2009. for (var i in chartPaint)
  2010. {
  2011. var paint = chartPaint[i];
  2012. var range = paint.GetMaxMin();
  2013. if (range == null || range.Max == null || range.Min == null) continue;
  2014. var frameItem = null;
  2015. for (var j in frameMaxMinData)
  2016. {
  2017. if (frameMaxMinData[j].Frame == paint.ChartFrame)
  2018. {
  2019. frameItem = frameMaxMinData[j];
  2020. break;
  2021. }
  2022. }
  2023. if (frameItem)
  2024. {
  2025. if (frameItem.Range.Max < range.Max) frameItem.Range.Max = range.Max;
  2026. if (frameItem.Range.Min > range.Min) frameItem.Range.Min = range.Min;
  2027. }
  2028. else
  2029. {
  2030. frameItem = {};
  2031. frameItem.Frame = paint.ChartFrame;
  2032. frameItem.Range = range;
  2033. frameMaxMinData.push(frameItem);
  2034. }
  2035. }
  2036. for (var i in frameMaxMinData)
  2037. {
  2038. var item = frameMaxMinData[i];
  2039. if (!item.Frame || !item.Range) continue;
  2040. if (item.Range.Max == null || item.Range.Min == null) continue;
  2041. if (item.Frame.YSpecificMaxMin)
  2042. {
  2043. item.Frame.HorizontalMax = item.Frame.YSpecificMaxMin.Max;
  2044. item.Frame.HorizontalMin = item.Frame.YSpecificMaxMin.Min;
  2045. }
  2046. else
  2047. {
  2048. item.Frame.HorizontalMax = item.Range.Max;
  2049. item.Frame.HorizontalMin = item.Range.Min;
  2050. }
  2051. item.Frame.XYSplit = true;
  2052. }
  2053. }
  2054. this.DataMoveLeft = function () {
  2055. var data = null;
  2056. if (!this.Frame.Data) data = this.Frame.Data;
  2057. else data = this.Frame.SubFrame[0].Frame.Data;
  2058. if (!data) return false;
  2059. if (data.DataOffset <= 0) return false;
  2060. --data.DataOffset;
  2061. return true;
  2062. }
  2063. this.DataMoveRight = function () {
  2064. var data = null;
  2065. if (!this.Frame.Data) data = this.Frame.Data;
  2066. else data = this.Frame.SubFrame[0].Frame.Data;
  2067. if (!data) return false;
  2068. var xPointcount = 0;
  2069. if (this.Frame.XPointCount) xPointcount = this.Frame.XPointCount;
  2070. else xPointcount = this.Frame.SubFrame[0].Frame.XPointCount;
  2071. if (!xPointcount) return false;
  2072. if (xPointcount + data.DataOffset >= data.Data.length) return false;
  2073. ++data.DataOffset;
  2074. return true;
  2075. }
  2076. this.UpdataDataoffset = function () {
  2077. var data = null;
  2078. if (this.Frame.Data)
  2079. data = this.Frame.Data;
  2080. else
  2081. data = this.Frame.SubFrame[0].Frame.Data;
  2082. if (!data) return;
  2083. for (var i in this.ChartPaint) {
  2084. var item = this.ChartPaint[i];
  2085. if (!item.Data) continue;
  2086. item.Data.DataOffset = data.DataOffset;
  2087. }
  2088. for (var i in this.OverlayChartPaint) {
  2089. var item = this.OverlayChartPaint[i];
  2090. if (!item.Data) continue;
  2091. item.Data.DataOffset = data.DataOffset;
  2092. }
  2093. }
  2094. this.DataMove = function (step, isLeft)
  2095. {
  2096. step=parseInt(step/this.StepPixel);
  2097. if (step<=0) return false;
  2098. var data = null;
  2099. if (!this.Frame.Data) data = this.Frame.Data;
  2100. else data = this.Frame.SubFrame[0].Frame.Data;
  2101. if (!data) return false;
  2102. var xPointcount = 0;
  2103. if (this.Frame.XPointCount) xPointcount = this.Frame.XPointCount;
  2104. else xPointcount = this.Frame.SubFrame[0].Frame.XPointCount;
  2105. if (!xPointcount) return false;
  2106. if (isLeft) //-->
  2107. {
  2108. if (this.RightSpaceCount > 0)
  2109. {
  2110. if (xPointcount + data.DataOffset >= data.Data.length + this.RightSpaceCount - 1) return false;
  2111. data.DataOffset += step;
  2112. if (data.DataOffset + xPointcount >= data.Data.length + this.RightSpaceCount)
  2113. data.DataOffset = data.Data.length - (xPointcount - this.RightSpaceCount);
  2114. }
  2115. else
  2116. {
  2117. if (xPointcount + data.DataOffset >= data.Data.length) return false;
  2118. data.DataOffset += step;
  2119. if (data.DataOffset + xPointcount >= data.Data.length)
  2120. data.DataOffset = data.Data.length - xPointcount;
  2121. }
  2122. return true;
  2123. }
  2124. else //<--
  2125. {
  2126. if (data.DataOffset <= 0) return false;
  2127. data.DataOffset -= step;
  2128. if (data.DataOffset < 0) data.DataOffset = 0;
  2129. return true;
  2130. }
  2131. }
  2132. //获取鼠标在当前子窗口id
  2133. this.GetSubFrameIndex = function (x, y) {
  2134. if (!this.Frame.SubFrame || this.Frame.SubFrame.length <= 0) return -1;
  2135. for (var i in this.Frame.SubFrame) {
  2136. var frame = this.Frame.SubFrame[i].Frame;
  2137. var left = frame.ChartBorder.GetLeft();
  2138. var top = frame.ChartBorder.GetTop();
  2139. var height = frame.ChartBorder.GetHeight();
  2140. var width = frame.ChartBorder.GetWidth();
  2141. this.Canvas.rect(left, top, width, height);
  2142. if (this.Canvas.isPointInPath(x, y)) return parseInt(i);
  2143. }
  2144. return 0;
  2145. }
  2146. //根据X坐标获取数据索引
  2147. this.GetDataIndexByPoint = function (x) {
  2148. var frame = this.Frame;
  2149. if (this.Frame.SubFrame && this.Frame.SubFrame.length > 0) frame = this.Frame.SubFrame[0].Frame;
  2150. var data = null;
  2151. if (this.Frame.Data)
  2152. data = this.Frame.Data;
  2153. else
  2154. data = this.Frame.SubFrame[0].Frame.Data;
  2155. if (!data || !frame) return;
  2156. var index = parseInt(frame.GetXData(x));
  2157. //JSConsole.Chart.Log('x='+ x +' date='+data.Data[data.DataOffset+index].Date);
  2158. return data.DataOffset + index;
  2159. }
  2160. this.SaveToImage = function (callback)
  2161. {
  2162. let width = this.UIElement.Width;
  2163. let height = this.UIElement.Height;;
  2164. JSConsole.Chart.Log('[JSChartContainer::SaveToImage]', this.UIElement);
  2165. wx.canvasToTempFilePath({
  2166. x: 0,
  2167. y: 0,
  2168. width: width,
  2169. height: height,
  2170. canvasId: this.UIElement.ID,
  2171. success: function (res)
  2172. {
  2173. let data = { ImagePath: res.tempFilePath, Width: width, Height: height };
  2174. if (typeof (callback) == 'function') callback(data);
  2175. }
  2176. })
  2177. }
  2178. //全屏提示信息 { Title:提示信息, Draw:false/true 是否立即重绘, }
  2179. this.EnableSplashScreen=function(option)
  2180. {
  2181. if (!this.ChartSplashPaint) return;
  2182. if (!option) return;
  2183. if (IFrameSplitOperator.IsString(option.Title)) this.ChartSplashPaint.SetTitle(option.Title);
  2184. this.ChartSplashPaint.EnableSplash(true);
  2185. if (option.Draw===false) return;
  2186. this.Draw();
  2187. }
  2188. //增加一个指标窗口
  2189. this.AddIndexWindow=function(indexName,option)
  2190. {
  2191. //查找系统指标
  2192. let scriptData = new JSCommonIndexScript.JSIndexScript();
  2193. let indexInfo = scriptData.Get(indexName);
  2194. if (!indexInfo) return;
  2195. var index=this.Frame.SubFrame.length;
  2196. var subFrame=this.CreateSubFrameItem(index);
  2197. this.Frame.SubFrame[index]=subFrame;
  2198. var titlePaint=new DynamicChartTitlePainting();
  2199. titlePaint.Frame=this.Frame.SubFrame[index].Frame;
  2200. titlePaint.Canvas=this.Canvas;
  2201. titlePaint.LanguageID=this.LanguageID;
  2202. titlePaint.GetEventCallback=(id)=> { return this.GetEventCallback(id); }
  2203. this.TitlePaint[index+1]=titlePaint;
  2204. if (option)
  2205. {
  2206. if (option.Window)
  2207. {
  2208. var item=option.Window;
  2209. if (item.IsDrawTitleBG==true) subFrame.Frame.IsDrawTitleBG=item.IsDrawTitleBG;
  2210. }
  2211. if (IFrameSplitOperator.IsNumber(option.SplitCount)) subFrame.Frame.YSplitOperator.SplitCount=option.SplitCount;
  2212. if (IFrameSplitOperator.IsNumber(option.TitleHeight)) subFrame.Frame.ChartBorder.TitleHeight=option.TitleHeight;
  2213. if (IFrameSplitOperator.IsBool(option.IsShowTitleArraw)) subFrame.Frame.IsShowTitleArraw=option.IsShowTitleArraw;
  2214. if (IFrameSplitOperator.IsBool(option.IsShowIndexName)) subFrame.Frame.IsShowIndexName=option.IsShowIndexName;
  2215. if (IFrameSplitOperator.IsBool(option.IsShowOverlayIndexName)) subFrame.Frame.IsShowOverlayIndexName=option.IsShowOverlayIndexName;
  2216. if (IFrameSplitOperator.IsNumber(option.IndexParamSpace)) subFrame.Frame.IndexParamSpace=option.IndexParamSpace;
  2217. if (IFrameSplitOperator.IsBool(option.IsShowXLine)) subFrame.Frame.IsShowXLine=option.IsShowXLine;
  2218. if (IFrameSplitOperator.IsBool(option.IsShowYLine)) subFrame.Frame.IsShowYLine=option.IsShowYLine;
  2219. if (IFrameSplitOperator.IsBool(option.IsShowIndexTitle)) subFrame.Frame.IsShowTitle=option.IsShowIndexTitle;
  2220. if (IFrameSplitOperator.IsBool(option.IsShowLeftText)) subFrame.Frame.IsShowYText[0] = option.IsShowLeftText; //显示左边刻度
  2221. if (IFrameSplitOperator.IsBool(option.IsShowRightText)) subFrame.Frame.IsShowYText[1] = option.IsShowRightText; //显示右边刻度
  2222. }
  2223. //最后一个显示X轴坐标
  2224. for(var i=0;i<this.Frame.SubFrame.length;++i)
  2225. {
  2226. var item=this.Frame.SubFrame[i].Frame;
  2227. if (i==this.Frame.SubFrame.length-1) item.XSplitOperator.ShowText=true;
  2228. else item.XSplitOperator.ShowText=false;
  2229. }
  2230. this.UpdataDataoffset(); //更新数据偏移
  2231. this.Frame.SetSizeChage(true);
  2232. if (this.UpdateXShowText) this.UpdateXShowText();
  2233. this.ResetFrameXYSplit();
  2234. this.UpdateFrameMaxMin(); //调整坐标最大 最小值
  2235. this.Draw();
  2236. var indexData =
  2237. {
  2238. Name:indexInfo.Name, Script:indexInfo.Script, Args: indexInfo.Args, ID:indexName ,
  2239. //扩展属性 可以是空
  2240. KLineType:indexInfo.KLineType, YSpecificMaxMin:indexInfo.YSpecificMaxMin, YSplitScale:indexInfo.YSplitScale,
  2241. FloatPrecision:indexInfo.FloatPrecision, Condition:indexInfo.Condition,StringFormat:indexInfo.StringFormat,
  2242. OutName:indexInfo.OutName
  2243. };
  2244. if (option)
  2245. {
  2246. if (option.FloatPrecision>=0) indexData.FloatPrecision=option.FloatPrecision;
  2247. if (option.StringFormat>0) indexData.StringFormat=option.StringFormat;
  2248. if (option.Args) indexData.Args=option.Args;
  2249. }
  2250. this.WindowIndex[index] = new ScriptIndex(indexData.Name, indexData.Script, indexData.Args,indexData); //脚本执行
  2251. if (this.ClassName=="MinuteChartContainer" || this.ClassName=="MinuteChartHScreenContainer")
  2252. var bindData=this.SourceData;
  2253. else
  2254. var bindData=this.ChartPaint[0].Data;
  2255. this.BindIndexData(index,bindData); //执行脚本
  2256. }
  2257. }
  2258. function ToFixed(number, precision)
  2259. {
  2260. var b = 1;
  2261. if (isNaN(number)) return number;
  2262. if (number < 0) b = -1;
  2263. var multiplier = Math.pow(10, precision);
  2264. var value = Math.round(Math.abs(number) * multiplier) / multiplier * b;
  2265. if (/^(\d+(?:\.\d+)?)(e)([\-]?\d+)$/.test(value))
  2266. var s = value.toFixed2(precision);
  2267. else
  2268. var s = value.toString();
  2269. var rs = s.indexOf('.');
  2270. if (rs < 0 && precision > 0)
  2271. {
  2272. rs = s.length;
  2273. s += '.';
  2274. }
  2275. while (s.length <= rs + precision)
  2276. {
  2277. s += '0';
  2278. }
  2279. return s;
  2280. }
  2281. Number.prototype.toFixed2 = Number.prototype.toFixed; //备份下老的
  2282. Number.prototype.toFixed = function (precision) {
  2283. return ToFixed(this, precision)
  2284. }
  2285. function Guid()
  2286. {
  2287. function S4()
  2288. {
  2289. return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
  2290. }
  2291. return (S4() + S4() + "-" + S4() + "-" + S4() + "-" + S4() + "-" + S4() + S4() + S4());
  2292. }
  2293. function GetScrollPosition() {
  2294. var scrollPos = {};
  2295. var scrollTop = 0;
  2296. var scrollLeft = 0;
  2297. if (document.documentElement && document.documentElement.scrollTop) {
  2298. scrollTop = document.documentElement.scrollTop;
  2299. scrollLeft = document.documentElement.scrollLeft;
  2300. } else if (document.body) {
  2301. scrollTop = document.body.scrollTop;
  2302. scrollLeft = document.body.scrollLeft;
  2303. }
  2304. scrollPos.Top = scrollTop;
  2305. scrollPos.Left = scrollLeft;
  2306. return scrollPos;
  2307. }
  2308. //修正线段有毛刺
  2309. function ToFixedPoint(value) {
  2310. //return value;
  2311. return parseInt(value) + 0.5;
  2312. }
  2313. function ToFixedRect(value) {
  2314. //return value;
  2315. // With a bitwise or.
  2316. //rounded = (0.5 + somenum) | 0;
  2317. // A double bitwise not.
  2318. //rounded = ~~ (0.5 + somenum);
  2319. // Finally, a left bitwise shift.
  2320. var rounded;
  2321. return rounded = (0.5 + value) << 0;
  2322. }
  2323. function Point() {
  2324. this.X;
  2325. this.Y;
  2326. }
  2327. function SelectRectData() {
  2328. this.Data; //主数据
  2329. this.JSChartContainer; //行情控件
  2330. this.Start; //数据起始位子
  2331. this.End; //数据结束位置
  2332. this.XStart;//X坐标起始位置
  2333. this.XEnd; //X位置结束为止
  2334. }
  2335. //边框信息
  2336. function ChartBorder()
  2337. {
  2338. this.UIElement;
  2339. //四周间距
  2340. this.Left = 50;
  2341. this.Right = 80;
  2342. this.Top = 50;
  2343. this.Bottom = 50;
  2344. this.TitleHeight = 15; //标题高度
  2345. //上下间距
  2346. this.TopSpace = 0;
  2347. this.BottomSpace = 0;
  2348. this.LeftExtendWidth=0; //左边扩展图形宽度
  2349. this.RightExtendWidth=0;
  2350. this.GetBorder=function()
  2351. {
  2352. var data=
  2353. {
  2354. Left:this.Left,
  2355. LeftEx:this.Left+this.LeftExtendWidth,
  2356. Right:this.UIElement.width-this.Right,
  2357. RightEx:this.UIElement.width-this.Right-this.RightExtendWidth,
  2358. Top:this.Top,
  2359. TopEx:this.Top+this.TitleHeight+this.TopSpace,
  2360. TopTitle:this.Top+this.TitleHeight,
  2361. Bottom:this.UIElement.height-this.Bottom,
  2362. BottomEx:this.UIElement.height-this.Bottom-this.BottomSpace,
  2363. ChartWidth:this.UIElement.width,
  2364. ChartHeight:this.UIElement.height
  2365. };
  2366. return data;
  2367. }
  2368. this.GetHScreenBorder=function()
  2369. {
  2370. var data=
  2371. {
  2372. Left:this.Left,
  2373. LeftEx:this.Left+this.BottomSpace,
  2374. Right:this.UIElement.width-this.Right,
  2375. RightEx:this.UIElement.width-this.Right-this.TitleHeight- this.TopSpace,
  2376. RightTitle:this.UIElement.width-this.Right-this.TitleHeight,
  2377. Top:this.Top,
  2378. TopEx:this.Top+this.LeftExtendWidth,
  2379. Bottom:this.UIElement.height-this.Bottom,
  2380. BottomEx:this.UIElement.height-this.Bottom-this.RightExtendWidth,
  2381. ChartWidth:this.UIElement.width,
  2382. ChartHeight:this.UIElement.height
  2383. };
  2384. return data;
  2385. }
  2386. this.GetChartWidth = function () {
  2387. return this.UIElement.Width;
  2388. }
  2389. this.GetChartHeight = function () {
  2390. return this.UIElement.Height;
  2391. }
  2392. this.GetLeft = function () {
  2393. return this.Left;
  2394. }
  2395. this.GetRight = function () {
  2396. return this.UIElement.Width - this.Right;
  2397. }
  2398. this.GetTop = function () {
  2399. return this.Top;
  2400. }
  2401. this.GetTopEx = function () //去掉标题,上面间距
  2402. {
  2403. return this.Top + this.TitleHeight + this.TopSpace;
  2404. }
  2405. this.GetTopTitle = function () //去掉标题
  2406. {
  2407. return this.Top + this.TitleHeight;
  2408. }
  2409. this.GetBottom = function () {
  2410. return this.UIElement.Height - this.Bottom;
  2411. }
  2412. this.GetBottomEx = function () {
  2413. return this.UIElement.Height - this.Bottom - this.BottomSpace;
  2414. }
  2415. this.GetWidth = function () {
  2416. return this.UIElement.Width - this.Left - this.Right;
  2417. }
  2418. this.GetHeight = function () {
  2419. return this.UIElement.Height - this.Top - this.Bottom;
  2420. }
  2421. this.GetHeightEx = function () //去掉标题的高度 上下间距
  2422. {
  2423. return this.UIElement.Height - this.Top - this.Bottom - this.TitleHeight - this.TopSpace - this.BottomSpace;
  2424. }
  2425. this.GetRightEx = function () //横屏去掉标题高度的 上面间距
  2426. {
  2427. return this.UIElement.Width - this.Right - this.TitleHeight - this.TopSpace;
  2428. }
  2429. this.GetWidthEx = function () //横屏去掉标题宽度 上下间距
  2430. {
  2431. return this.UIElement.Width - this.Left - this.Right - this.TitleHeight - this.TopSpace - this.BottomSpace;
  2432. }
  2433. this.GetLeftEx = function () //横屏
  2434. {
  2435. return this.Left + this.BottomSpace;
  2436. }
  2437. this.GetRightTitle = function ()//横屏
  2438. {
  2439. return this.UIElement.Width - this.Right - this.TitleHeight;
  2440. }
  2441. this.GetTitleHeight = function () {
  2442. return this.TitleHeight;
  2443. }
  2444. }
  2445. function IChartFramePainting()
  2446. {
  2447. this.HorizontalInfo = new Array(); //Y轴
  2448. this.VerticalInfo = new Array(); //X轴
  2449. this.ClassName='IChartFramePainting';
  2450. this.Canvas; //画布
  2451. this.Identify; //窗口标识
  2452. this.ChartBorder;
  2453. this.PenBorder = g_JSChartResource.FrameBorderPen; //边框颜色
  2454. this.TitleBGColor = g_JSChartResource.FrameTitleBGColor; //标题背景色
  2455. this.IsShow = true; //是否显示
  2456. this.SizeChange = true; //大小是否改变
  2457. this.XYSplit = true; //XY轴坐标信息改变
  2458. this.HorizontalMax; //Y轴最大值
  2459. this.HorizontalMin; //Y轴最小值
  2460. this.XPointCount = 10; //X轴数据个数
  2461. this.YSplitOperator; //Y轴分割
  2462. this.XSplitOperator; //X轴分割
  2463. this.Data; //主数据
  2464. this.YSpecificMaxMin = null; //指定Y轴最大最小值
  2465. this.YSplitScale=null; //固定分割刻度数组 [2,5,8]
  2466. this.IsShowBorder = true; //是否显示边框
  2467. this.IsShowIndexName = true; //是否显示指标名字
  2468. this.IndexParamSpace = 2; //指标参数数值显示间距
  2469. //上锁信息
  2470. this.IsLocked = false; //是否上锁
  2471. this.LockPaint = null;
  2472. this.BorderLine=null; //1=上 2=下 4=左 8=右
  2473. this.IsMinSize=false; //窗口是否最小化
  2474. this.Draw = function ()
  2475. {
  2476. this.DrawFrame();
  2477. this.DrawBorder();
  2478. this.SizeChange = false;
  2479. this.XYSplit = false;
  2480. }
  2481. this.DrawFrame = function () { }
  2482. this.ClearCoordinateText=function(option)
  2483. {
  2484. if (IFrameSplitOperator.IsNonEmptyArray(this.HorizontalInfo))
  2485. {
  2486. for(var i=0;i<this.HorizontalInfo.length;++i)
  2487. {
  2488. var item=this.HorizontalInfo[i];
  2489. item.Message[0]=item.Message[1]=null;
  2490. }
  2491. }
  2492. if (IFrameSplitOperator.IsNonEmptyArray(this.VerticalInfo))
  2493. {
  2494. for(var i=0;i<this.VerticalInfo.length;++i)
  2495. {
  2496. var item=this.VerticalInfo[i];
  2497. item.Message[0]=item.Message[1]=null;
  2498. }
  2499. }
  2500. }
  2501. //画边框
  2502. this.DrawBorder = function ()
  2503. {
  2504. if (!this.IsShowBorder) return;
  2505. if (this.IsMinSize) return;
  2506. var left = ToFixedPoint(this.ChartBorder.GetLeft());
  2507. var top = ToFixedPoint(this.ChartBorder.GetTop());
  2508. var right = ToFixedPoint(this.ChartBorder.GetRight());
  2509. var bottom = ToFixedPoint(this.ChartBorder.GetBottom());
  2510. var width = right - left;
  2511. var height = bottom - top;
  2512. if (this.BorderLine==null)
  2513. {
  2514. this.Canvas.setStrokeStyle(this.PenBorder);
  2515. this.Canvas.strokeRect(left, top, width, height);
  2516. }
  2517. else if (IFrameSplitOperator.IsNumber(this.BorderLine))
  2518. {
  2519. this.Canvas.strokeStyle=this.PenBorder;
  2520. this.Canvas.beginPath();
  2521. if ((this.BorderLine&1)>0) //上
  2522. {
  2523. this.Canvas.moveTo(left,top);
  2524. this.Canvas.lineTo(right,top);
  2525. }
  2526. if ((this.BorderLine&2)>0) //下
  2527. {
  2528. this.Canvas.moveTo(left,bottom);
  2529. this.Canvas.lineTo(right,bottom);
  2530. }
  2531. if ((this.BorderLine&4)>0) //左
  2532. {
  2533. this.Canvas.moveTo(left,top);
  2534. this.Canvas.lineTo(left,bottom);
  2535. }
  2536. if ((this.BorderLine&8)>0) //右
  2537. {
  2538. this.Canvas.moveTo(right,top);
  2539. this.Canvas.lineTo(right,bottom);
  2540. }
  2541. this.Canvas.stroke();
  2542. }
  2543. }
  2544. //左右刻度文字宽度
  2545. this.GetScaleTextWidth=function() { }
  2546. //画标题背景色
  2547. this.DrawTitleBG = function ()
  2548. {
  2549. /* 指标信息背景色不画,画了感觉框架变小了
  2550. if (this.ChartBorder.TitleHeight<=0) return;
  2551. var left=ToFixedPoint(this.ChartBorder.GetLeft());
  2552. var top=ToFixedPoint(this.ChartBorder.GetTop());
  2553. var right=ToFixedPoint(this.ChartBorder.GetRight());
  2554. var bottom=ToFixedPoint(this.ChartBorder.GetTopEx());
  2555. var width=right-left;
  2556. var height=bottom-top;
  2557. this.Canvas.fillStyle=this.TitleBGColor;
  2558. this.Canvas.fillRect(left,top,width,height);
  2559. */
  2560. }
  2561. this.DrawLock = function () {
  2562. if (this.IsLocked) {
  2563. if (this.LockPaint == null) this.LockPaint = new ChartLock();
  2564. this.LockPaint.Canvas = this.Canvas;
  2565. this.LockPaint.ChartBorder = this.ChartBorder;
  2566. this.LockPaint.ChartFrame = this;
  2567. this.LockPaint.Draw();
  2568. }
  2569. }
  2570. //设施上锁
  2571. this.SetLock = function (lockData) {
  2572. if (!lockData) //空数据不上锁
  2573. {
  2574. this.IsLocked = false;
  2575. return;
  2576. }
  2577. this.IsLocked = true;
  2578. if (!this.LockPaint) this.LockPaint = new ChartLock(); //创建锁
  2579. if (lockData.Callback) this.LockPaint.Callback = lockData.Callback; //回调
  2580. if (lockData.IndexName) this.LockPaint.IndexName = lockData.IndexName; //指标名字
  2581. if (lockData.ID) this.LockPaint.LockID = lockData.ID; //锁ID
  2582. if (lockData.BG) this.LockPaint.BGColor = lockData.BG; //背景色
  2583. if (lockData.Text) this.LockPaint.Title = lockData.Text;
  2584. if (lockData.TextColor) this.LockPaint.TextColor = lockData.TextColor;
  2585. if (lockData.Font) this.LockPaint.Font = lockData.Font;
  2586. if (lockData.Count) this.LockPaint.LockCount = lockData.Count;
  2587. }
  2588. }
  2589. //空框架只画边框
  2590. function NoneFrame()
  2591. {
  2592. this.newMethod = IChartFramePainting; //派生
  2593. this.newMethod();
  2594. delete this.newMethod;
  2595. this.ClassName='NoneFrame';
  2596. this.Snapshot = function () { }
  2597. this.DrawInsideHorizontal = function () { }
  2598. this.SetSizeChage = function (sizeChange)
  2599. {
  2600. this.SizeChange = sizeChange;
  2601. //画布的位置
  2602. this.Position =
  2603. {
  2604. X: this.ChartBorder.UIElement.offsetLeft,
  2605. Y: this.ChartBorder.UIElement.offsetTop,
  2606. W: this.ChartBorder.UIElement.clientWidth,
  2607. H: this.ChartBorder.UIElement.clientHeight
  2608. };
  2609. }
  2610. }
  2611. function AverageWidthFrame()
  2612. {
  2613. this.newMethod = IChartFramePainting; //派生
  2614. this.newMethod();
  2615. delete this.newMethod;
  2616. this.ClassName='AverageWidthFrame';
  2617. this.DataWidth = 50;
  2618. this.DistanceWidth = 10;
  2619. this.MinXDistance = 30; //X轴刻度最小间距
  2620. this.MinYDistance=10;
  2621. this.XMessageAlign = 'top'; //X轴刻度文字上下对齐方式
  2622. this.IsShowTitle = true; //是否显示动态标题
  2623. this.IsShowYText = [true, true]; //是否显示Y轴坐标坐标 [0=左侧] [1=右侧]
  2624. this.XBottomOffset = g_JSChartResource.Frame.XBottomOffset; //X轴文字显示向下偏移
  2625. this.YTextTopOffset=g_JSChartResource.Frame.YTopOffset; //Y轴顶部文字向下偏移
  2626. this.YTextPosition=[0,0], //是坐标否强制画在内部 [0=左侧] [1=右侧] 1=OUT" , 2=INSIDE
  2627. this.IsShowXLine=true; //是否显示X轴刻度线
  2628. this.IsShowYLine=true;
  2629. this.YTextBaseline=0; //0=居中 1=上部 (目前就支持内部刻度)
  2630. this.ShortYLineLength=5;
  2631. this.ShortXLineLength=5;
  2632. this.DrawOtherChart; //其他画法调用
  2633. this.DrawFrame = function ()
  2634. {
  2635. if (this.XPointCount > 0)
  2636. {
  2637. this.DistanceWidth = this.ChartBorder.GetWidth() / (4 * this.XPointCount);
  2638. this.DataWidth = 2 * this.DistanceWidth;
  2639. }
  2640. this.DrawHorizontal();
  2641. this.DrawVertical();
  2642. }
  2643. this.GetYFromData = function (value)
  2644. {
  2645. if (value <= this.HorizontalMin) return this.ChartBorder.GetBottomEx();
  2646. if (value >= this.HorizontalMax) return this.ChartBorder.GetTopEx();
  2647. var height = this.ChartBorder.GetHeightEx() * (value - this.HorizontalMin) / (this.HorizontalMax - this.HorizontalMin);
  2648. return this.ChartBorder.GetBottomEx() - height;
  2649. }
  2650. //Y刻度画在内部
  2651. this.DrawInsideHorizontal = function ()
  2652. {
  2653. if (this.IsHScreen === true) return; //横屏不画
  2654. if (this.IsMinSize) return;
  2655. if (this.IsShowYText[0] === false && this.IsShowYText[1] === false) return;
  2656. var left = this.ChartBorder.GetLeft();
  2657. var right = this.ChartBorder.GetRight();
  2658. var bottom = this.ChartBorder.GetBottom();
  2659. var top = this.ChartBorder.GetTopTitle();
  2660. var borderRight = this.ChartBorder.Right;
  2661. var borderLeft = this.ChartBorder.Left;
  2662. var titleHeight = this.ChartBorder.TitleHeight;
  2663. if (borderLeft >= 10) return;
  2664. if ((borderLeft < 10 && this.IsShowYText[0] === true) || (borderRight < 10 && this.IsShowYText[1] === true))
  2665. {
  2666. var yPrev = null; //上一个坐标y的值
  2667. for (var i = this.HorizontalInfo.length - 1; i >= 0; --i) //从上往下画分割线
  2668. {
  2669. var item = this.HorizontalInfo[i];
  2670. if (!item) continue;
  2671. var y = this.GetYFromData(item.Value);
  2672. if (y != null && yPrev !=null && Math.abs(y - yPrev) < this.MinYDistance) continue; //两个坐标在近了 就不画了
  2673. //坐标信息 左边 间距小于10 画在内部
  2674. if (item.Message[0] != null && borderLeft < 10 && this.IsShowYText[0] === true)
  2675. {
  2676. if (item.Font != null) this.Canvas.font = item.Font;
  2677. this.Canvas.setFillStyle(item.TextColor);
  2678. this.Canvas.textAlign = "left";
  2679. var yText=y;
  2680. if (y >= bottom - 2)
  2681. {
  2682. this.Canvas.textBaseline = 'bottom';
  2683. }
  2684. else if (y <= top + 2)
  2685. {
  2686. this.Canvas.textBaseline = 'top';
  2687. yText+=this.YTextTopOffset;
  2688. }
  2689. else
  2690. {
  2691. if (this.YTextBaseline==1) this.Canvas.textBaseline = "bottom";
  2692. else this.Canvas.textBaseline = "middle";
  2693. }
  2694. var textObj = { X: left, Y: yText, Text: { BaseLine: this.Canvas.textBaseline, Font: this.Canvas.font, Value: item.Message[0] } };
  2695. if (!this.IsOverlayMaxMin || !this.IsOverlayMaxMin(textObj)) this.Canvas.fillText(item.Message[0], left + 1, yText);
  2696. }
  2697. if (item.Message[1] != null && borderRight < 10 && this.IsShowYText[1] === true)
  2698. {
  2699. if (item.Font != null) this.Canvas.font = item.Font;
  2700. this.Canvas.setFillStyle(item.TextColor);
  2701. this.Canvas.textAlign = "right";
  2702. var yText=y;
  2703. if (y >= bottom - 2)
  2704. {
  2705. this.Canvas.textBaseline = 'bottom';
  2706. }
  2707. else if (y <= top + 2)
  2708. {
  2709. this.Canvas.textBaseline = 'top';
  2710. yText+=this.YTextTopOffset;
  2711. }
  2712. else
  2713. {
  2714. if (this.YTextBaseline==1) this.Canvas.textBaseline = "bottom";
  2715. else this.Canvas.textBaseline = "middle";
  2716. }
  2717. var textWidth = this.Canvas.measureText(item.Message[1]).width;
  2718. var textObj = { X: right - textWidth, Y: yText, Text: { BaseLine: this.Canvas.textBaseline, TextAlign: this.Canvas.textAlign, Font: this.Canvas.font, Value: item.Message[1] } };
  2719. if (!this.IsOverlayMaxMin || !this.IsOverlayMaxMin(textObj))
  2720. this.Canvas.fillText(item.Message[1], right - 1, yText);
  2721. }
  2722. yPrev = y;
  2723. }
  2724. }
  2725. }
  2726. //画Y轴
  2727. this.DrawHorizontal = function ()
  2728. {
  2729. var left = this.ChartBorder.GetLeft();
  2730. var right = this.ChartBorder.GetRight();
  2731. var bottom = this.ChartBorder.GetBottom();
  2732. var top = this.ChartBorder.GetTopTitle();
  2733. var borderRight = this.ChartBorder.Right;
  2734. var borderLeft = this.ChartBorder.Left;
  2735. var titleHeight = this.ChartBorder.TitleHeight;
  2736. this.Canvas.save();
  2737. var yPrev = null; //上一个坐标y的值
  2738. for (var i = this.HorizontalInfo.length - 1; i >= 0; --i) //从上往下画分割线
  2739. {
  2740. var item = this.HorizontalInfo[i];
  2741. var y = this.GetYFromData(item.Value);
  2742. if (y != null && yPrev != null && Math.abs(y - yPrev) <this.MinYDistance) continue; //两个坐标在近了 就不画了
  2743. var yFixed=ToFixedPoint(y);
  2744. if (bottom!=y && this.IsShowYLine) //和底部线段重叠了就不绘制
  2745. {
  2746. if (item.LineType==2)
  2747. {
  2748. this.Canvas.setStrokeStyle(item.LineColor);
  2749. this.Canvas.setLineDash([5,5]);
  2750. this.Canvas.beginPath();
  2751. this.Canvas.moveTo(left, yFixed);
  2752. this.Canvas.lineTo(right,yFixed);
  2753. this.Canvas.stroke();
  2754. this.Canvas.setLineDash([]);
  2755. }
  2756. else if (item.LineType==3) //只在刻度边上画一个短横线
  2757. {
  2758. }
  2759. else if (item.LineType>0)
  2760. {
  2761. this.Canvas.setStrokeStyle(item.LineColor);
  2762. if(g_JSChartResource.FrameYLineDash)
  2763. {
  2764. this.Canvas.setLineDash(g_JSChartResource.FrameYLineDash); //虚线
  2765. this.Canvas.beginPath();
  2766. this.Canvas.moveTo(left, yFixed);
  2767. this.Canvas.lineTo(right, yFixed);
  2768. this.Canvas.stroke();
  2769. this.Canvas.setLineDash([]);
  2770. }
  2771. else
  2772. {
  2773. this.Canvas.beginPath();
  2774. this.Canvas.moveTo(left, yFixed);
  2775. this.Canvas.lineTo(right, yFixed);
  2776. this.Canvas.stroke();
  2777. }
  2778. }
  2779. }
  2780. var yText=y;
  2781. if (y >= bottom - 2)
  2782. {
  2783. this.Canvas.textBaseline = 'bottom';
  2784. }
  2785. else if (y <= top + 2)
  2786. {
  2787. this.Canvas.textBaseline = 'top';
  2788. yText+=this.YTextTopOffset;
  2789. }
  2790. else
  2791. {
  2792. this.Canvas.textBaseline = "middle";
  2793. }
  2794. //坐标信息 左边 间距小于10 不画坐标
  2795. this.Canvas.setFillStyle(item.TextColor);
  2796. this.Canvas.setStrokeStyle(item.TextColor);
  2797. if (item.Message[0] != null && borderLeft > 10 && this.IsShowYText[0] === true)
  2798. {
  2799. if (item.Font != null) this.Canvas.font = item.Font;
  2800. this.Canvas.textAlign = "right";
  2801. this.Canvas.fillText(item.Message[0], left - 2, yText);
  2802. }
  2803. //坐标信息 右边 间距小于10 不画坐标
  2804. if (item.Message[1] != null && borderRight > 10 && this.IsShowYText[1] === true)
  2805. {
  2806. if (item.Font != null) this.Canvas.font = item.Font;
  2807. var xText=right;
  2808. if (item.LineType==3)
  2809. {
  2810. var lineLength=this.ShortYLineLength;
  2811. this.Canvas.beginPath();
  2812. this.Canvas.moveTo(xText,yFixed);
  2813. this.Canvas.lineTo(xText+lineLength,yFixed);
  2814. this.Canvas.stroke();
  2815. xText+=lineLength;
  2816. }
  2817. this.Canvas.textAlign = "left";
  2818. this.Canvas.fillText(item.Message[1], xText + 2, yText);
  2819. }
  2820. yPrev = y;
  2821. }
  2822. this.Canvas.restore();
  2823. }
  2824. this.GetXFromIndex = function (index)
  2825. {
  2826. var count = this.XPointCount;
  2827. if (count == 1)
  2828. {
  2829. if (index == 0) return this.ChartBorder.GetLeft();
  2830. else return this.ChartBorder.GetRight();
  2831. }
  2832. else if (count <= 0)
  2833. {
  2834. return this.ChartBorder.GetLeft();
  2835. }
  2836. else if (index >= count)
  2837. {
  2838. return this.ChartBorder.GetRight();
  2839. }
  2840. else
  2841. {
  2842. var offset = this.ChartBorder.GetLeft() + this.ChartBorder.GetWidth() * index / count;
  2843. return offset;
  2844. }
  2845. }
  2846. //画X轴
  2847. this.DrawVertical = function ()
  2848. {
  2849. var top = this.ChartBorder.GetTopTitle();
  2850. var bottom = this.ChartBorder.GetBottom();
  2851. var right = this.ChartBorder.GetRight();
  2852. if (this.ChartBorder.Bottom<=5) return; //高度不够 不显示
  2853. var yText = bottom;
  2854. if (this.XMessageAlign == 'bottom') yText = this.ChartBorder.GetChartHeight();
  2855. else this.XMessageAlign = 'top';
  2856. var xPrev = null; //上一个坐标x的值
  2857. let xPrevTextRight = null;
  2858. for (var i in this.VerticalInfo)
  2859. {
  2860. var x = this.GetXFromIndex(this.VerticalInfo[i].Value);
  2861. if (x > right) break;
  2862. if (xPrev != null && Math.abs(x - xPrev) < this.MinXDistance) continue;
  2863. var item=this.VerticalInfo[i];
  2864. var xFixed=ToFixedPoint(x);
  2865. if (this.IsShowXLine && item.LineType > 0)
  2866. {
  2867. if (item.LineType==2)
  2868. {
  2869. this.Canvas.setStrokeStyle(item.LineColor);
  2870. this.Canvas.setLineDash([5,5]);
  2871. this.Canvas.beginPath();
  2872. this.Canvas.moveTo(xFixed, top);
  2873. this.Canvas.lineTo(xFixed, bottom);
  2874. this.Canvas.stroke();
  2875. this.Canvas.setLineDash([]);
  2876. }
  2877. else if (item.LineType==3)
  2878. {
  2879. }
  2880. else if (item.LineType>0)
  2881. {
  2882. if(g_JSChartResource.FrameXLineDash)
  2883. {
  2884. this.Canvas.setStrokeStyle(item.LineColor);
  2885. this.Canvas.beginPath();
  2886. this.Canvas.setLineDash(g_JSChartResource.FrameXLineDash);
  2887. this.Canvas.moveTo(xFixed, top);
  2888. this.Canvas.lineTo(xFixed, bottom);
  2889. this.Canvas.stroke();
  2890. this.Canvas.setLineDash([]);
  2891. }
  2892. else
  2893. {
  2894. this.Canvas.setStrokeStyle(item.LineColor);
  2895. this.Canvas.beginPath();
  2896. this.Canvas.moveTo(xFixed, top);
  2897. this.Canvas.lineTo(xFixed, bottom);
  2898. this.Canvas.stroke();
  2899. }
  2900. }
  2901. }
  2902. if (this.VerticalInfo[i].Message[0] != null && this.ChartBorder.Bottom > 5)
  2903. {
  2904. let xTextRight = null;
  2905. let xTextLeft = null;
  2906. if (this.VerticalInfo[i].Font != null)
  2907. this.Canvas.font = this.VerticalInfo[i].Font;
  2908. this.Canvas.fillStyle=item.TextColor;
  2909. this.Canvas.strokeStyle=item.TextColor;
  2910. var testWidth = this.Canvas.measureText(this.VerticalInfo[i].Message[0]).width;
  2911. if (x < testWidth / 2)
  2912. {
  2913. this.Canvas.textAlign = "left";
  2914. this.Canvas.textBaseline = this.XMessageAlign;
  2915. xTextRight = x + testWidth;
  2916. xTextLeft = x;
  2917. }
  2918. else if ((x + testWidth / 2) >= this.ChartBorder.GetChartWidth())
  2919. {
  2920. this.Canvas.textAlign = "right";
  2921. this.Canvas.textBaseline = this.XMessageAlign;
  2922. xTextRight = x + testWidth;
  2923. xTextLeft = x;
  2924. }
  2925. else
  2926. {
  2927. this.Canvas.textAlign = "center";
  2928. this.Canvas.textBaseline = this.XMessageAlign;
  2929. xTextRight = x + testWidth / 2;
  2930. xTextLeft = x - testWidth / 2;
  2931. }
  2932. if (xPrevTextRight != null && xPrevTextRight > xTextLeft) continue;
  2933. var yText=bottom;
  2934. if (item.LineType==3)
  2935. {
  2936. var lineLength=this.ShortXLineLength;
  2937. this.Canvas.beginPath();
  2938. this.Canvas.moveTo(xFixed,yText);
  2939. this.Canvas.lineTo(xFixed,yText+lineLength);
  2940. this.Canvas.stroke();
  2941. yText+=lineLength+2;
  2942. }
  2943. this.Canvas.fillText(this.VerticalInfo[i].Message[0], x, yText + this.XBottomOffset);
  2944. xPrevTextRight = xTextRight;
  2945. }
  2946. xPrev = x;
  2947. }
  2948. }
  2949. this.GetYData = function (y) //Y坐标转y轴数值
  2950. {
  2951. if (y < this.ChartBorder.GetTopEx()) return this.HorizontalMax;
  2952. if (y > this.ChartBorder.GetBottomEx()) return this.HorizontalMin;
  2953. return (this.ChartBorder.GetBottomEx() - y) / this.ChartBorder.GetHeightEx() * (this.HorizontalMax - this.HorizontalMin) + this.HorizontalMin;
  2954. }
  2955. this.GetXData = function (x) //X坐标转x轴数值
  2956. {
  2957. if (x <= this.ChartBorder.GetLeft()) return 0;
  2958. if (x >= this.ChartBorder.GetRight()) return this.XPointCount;
  2959. return (x - this.ChartBorder.GetLeft()) * (this.XPointCount * 1.0 / this.ChartBorder.GetWidth());
  2960. }
  2961. this.DrawCustomItem = function (item) //显示自定义刻度
  2962. {
  2963. //if (this.IsHScreen === true) return; //横屏不画
  2964. if (!item.Message[1] && !item.Message[0]) return;
  2965. if (item.Value > this.HorizontalMax || item.Value < this.HorizontalMin) return;
  2966. var left = this.ChartBorder.GetLeft();
  2967. var right = this.ChartBorder.GetRight();
  2968. var bottom = this.ChartBorder.GetBottom();
  2969. var top = this.ChartBorder.GetTopTitle();
  2970. var borderRight = this.ChartBorder.Right;
  2971. var borderLeft = this.ChartBorder.Left;
  2972. var titleHeight = this.ChartBorder.TitleHeight;
  2973. if (this.IsHScreen)
  2974. {
  2975. borderLeft = this.ChartBorder.Top;
  2976. borderRight = this.ChartBorder.Bottom;
  2977. top = this.ChartBorder.GetTop();
  2978. bottom = this.ChartBorder.GetBottom();
  2979. }
  2980. var textHeight = 18;
  2981. var y = this.GetYFromData(item.Value);
  2982. if (item.Message[0])
  2983. {
  2984. if (borderLeft < 10)
  2985. {
  2986. if (item.Font != null) this.Canvas.font = item.Font;
  2987. this.Canvas.textAlign = "left";
  2988. this.Canvas.textBaseline = "middle";
  2989. var textWidth = this.Canvas.measureText(item.Message[0]).width + 2;
  2990. var bgColor = item.LineColor;
  2991. var rgb = this.RGBToStruct(item.LineColor);
  2992. if (rgb) bgColor = `rgba(${rgb.R}, ${rgb.G}, ${rgb.B}, ${g_JSChartResource.FrameLatestPrice.BGAlpha})`; //内部刻度 背景增加透明度
  2993. this.Canvas.setFillStyle(bgColor);
  2994. if (this.IsHScreen)
  2995. {
  2996. var bgTop = top;
  2997. var textLeft = y - textHeight / 2 - 1;
  2998. this.Canvas.fillRect(textLeft, bgTop, textHeight, textWidth);
  2999. this.DrawHScreenText({ X: y, Y: bgTop }, { Text: item.Message[0], Color: item.TextColor, XOffset: 1, YOffset: 2 });
  3000. this.DrawLine(bgTop + textWidth, bottom, y, item.LineColor,item.LineType);
  3001. }
  3002. else
  3003. {
  3004. var bgTop = y - textHeight / 2 - 1;
  3005. var textLeft = left + 1;
  3006. this.Canvas.fillRect(textLeft, bgTop, textWidth, textHeight);
  3007. this.Canvas.setFillStyle(item.TextColor);
  3008. this.Canvas.fillText(item.Message[0], textLeft + 1, y);
  3009. this.DrawLine(textLeft + textWidth, right, y, item.LineColor,item.LineType);
  3010. }
  3011. }
  3012. else
  3013. {
  3014. if (item.Font != null) this.Canvas.font = item.Font;
  3015. this.Canvas.textAlign = "right";
  3016. this.Canvas.textBaseline = "middle";
  3017. var textWidth = this.Canvas.measureText(item.Message[0]).width + 2;
  3018. this.Canvas.setFillStyle(item.LineColor);
  3019. if (this.IsHScreen)
  3020. {
  3021. var bgTop = top - textWidth;
  3022. var textLeft = y - textHeight / 2 - 1 ;
  3023. this.Canvas.fillRect(textLeft, bgTop, textHeight, textWidth);
  3024. this.DrawHScreenText({ X: y, Y: bgTop }, { Text: item.Message[0], Color: item.TextColor, XOffset: 1, YOffset: 2 });
  3025. this.DrawLine(bgTop + textWidth, bottom, y, item.LineColor,item.LineType);
  3026. }
  3027. else
  3028. {
  3029. var bgTop = y - textHeight / 2 - 1;
  3030. this.Canvas.fillRect(left - textWidth, bgTop, textWidth, textHeight);
  3031. this.Canvas.setFillStyle(item.TextColor);
  3032. this.Canvas.fillText(item.Message[0], left - 1, y);
  3033. this.DrawLine(left, right, y, item.LineColor,item.LineType);
  3034. }
  3035. }
  3036. }
  3037. else if (item.Message[1])
  3038. {
  3039. if (borderRight < 10)
  3040. {
  3041. if (item.Font != null) this.Canvas.font = item.Font;
  3042. this.Canvas.textAlign = "left";
  3043. this.Canvas.textBaseline = "middle";
  3044. var textWidth = this.Canvas.measureText(item.Message[1]).width + 2;
  3045. var bgColor = item.LineColor;
  3046. var rgb = this.RGBToStruct(item.LineColor);
  3047. if (rgb) bgColor = `rgba(${rgb.R}, ${rgb.G}, ${rgb.B}, ${g_JSChartResource.FrameLatestPrice.BGAlpha})`; //内部刻度 背景增加透明度
  3048. this.Canvas.setFillStyle(bgColor);
  3049. if (this.IsHScreen)
  3050. {
  3051. var bgTop = bottom - textWidth;
  3052. var textLeft = y - textHeight / 2 - 1;
  3053. this.Canvas.fillRect(textLeft, bgTop, textHeight, textWidth);
  3054. this.DrawHScreenText({ X: y, Y: bgTop }, { Text: item.Message[1], Color: item.TextColor, XOffset: 1, YOffset: 2 });
  3055. this.DrawLine(top, bgTop, y, item.LineColor,item.LineType);
  3056. }
  3057. else
  3058. {
  3059. var bgTop = y - textHeight / 2 - 1;
  3060. var textLeft = right - textWidth;
  3061. this.Canvas.fillRect(textLeft, bgTop, textWidth, textHeight);
  3062. this.Canvas.setFillStyle(item.TextColor);
  3063. this.Canvas.fillText(item.Message[1], textLeft + 1, y);
  3064. this.DrawLine(left, textLeft, y, item.LineColor,item.LineType);
  3065. }
  3066. }
  3067. else
  3068. {
  3069. if (item.Font != null) this.Canvas.font = item.Font;
  3070. this.Canvas.textAlign = "left";
  3071. this.Canvas.textBaseline = "middle";
  3072. var textWidth = this.Canvas.measureText(item.Message[1]).width + 2;
  3073. this.Canvas.setFillStyle(item.LineColor);
  3074. if (this.IsHScreen)
  3075. {
  3076. var bgTop = bottom;
  3077. var textLeft = y - textHeight / 2 - 1 ;
  3078. this.Canvas.fillRect(textLeft, bgTop, textHeight, textWidth);
  3079. this.DrawHScreenText({ X: y, Y: bgTop }, { Text: item.Message[1], Color: item.TextColor, XOffset: 1 , YOffset: 2 });
  3080. this.DrawLine(top, bgTop, y, item.LineColor,item.LineType);
  3081. }
  3082. else
  3083. {
  3084. var bgTop = y - textHeight / 2 - 1;
  3085. this.Canvas.fillRect(right, bgTop, textWidth, textHeight);
  3086. this.Canvas.setFillStyle(item.TextColor);
  3087. this.Canvas.fillText(item.Message[1], right + 1, y);
  3088. this.DrawLine(left, right, y, item.LineColor,item.LineType);
  3089. }
  3090. }
  3091. }
  3092. }
  3093. this.DrawLine=function(left, right, y, color, lineType)
  3094. {
  3095. if (lineType==-1) return;
  3096. if (lineType==0)
  3097. {
  3098. this.Canvas.setStrokeStyle(color);
  3099. this.Canvas.beginPath();
  3100. if (this.IsHScreen)
  3101. {
  3102. this.Canvas.moveTo(ToFixedPoint(y), left);
  3103. this.Canvas.lineTo(ToFixedPoint(y), right);
  3104. }
  3105. else
  3106. {
  3107. this.Canvas.moveTo(left, ToFixedPoint(y));
  3108. this.Canvas.lineTo(right, ToFixedPoint(y));
  3109. }
  3110. this.Canvas.stroke();
  3111. }
  3112. else
  3113. {
  3114. this.DrawDotLine(left, right, y, color);
  3115. }
  3116. }
  3117. this.DrawDotLine = function (left, right, y, color)
  3118. {
  3119. this.Canvas.save();
  3120. this.Canvas.setStrokeStyle(color);
  3121. this.Canvas.setLineDash([5, 5]); //虚线
  3122. this.Canvas.beginPath();
  3123. if (this.IsHScreen)
  3124. {
  3125. this.Canvas.moveTo(ToFixedPoint(y), left);
  3126. this.Canvas.lineTo(ToFixedPoint(y), right);
  3127. }
  3128. else
  3129. {
  3130. this.Canvas.moveTo(left, ToFixedPoint(y));
  3131. this.Canvas.lineTo(right, ToFixedPoint(y));
  3132. }
  3133. this.Canvas.stroke();
  3134. this.Canvas.restore();
  3135. }
  3136. this.RGBToStruct = function (rgb)
  3137. {
  3138. if (/^(rgb|RGB)/.test(rgb))
  3139. {
  3140. var aColor = rgb.replace(/(?:\(|\)|rgb|RGB)*/g, "").split(",");
  3141. var result = {};
  3142. if (aColor.length != 3) return null;
  3143. result.R = Number(aColor[0]);
  3144. result.G = Number(aColor[1]);
  3145. result.B = Number(aColor[2]);
  3146. return result;
  3147. }
  3148. return null;
  3149. }
  3150. this.DrawHScreenText = function (center, data)
  3151. {
  3152. this.Canvas.textAlign = "left";
  3153. this.Canvas.textBaseline = "middle";
  3154. this.Canvas.setFillStyle(data.Color);
  3155. this.Canvas.save();
  3156. this.Canvas.translate(center.X, center.Y);
  3157. this.Canvas.rotate(90 * Math.PI / 180);
  3158. this.Canvas.fillText(data.Text, data.XOffset, data.YOffset);
  3159. this.Canvas.restore();
  3160. }
  3161. this.GetScaleTextWidth=function()
  3162. {
  3163. var border=this.ChartBorder.GetBorder();
  3164. if (this.IsHScreen)
  3165. {
  3166. var borderTop = this.ChartBorder.Top;
  3167. var borderBottom = this.ChartBorder.Bottom;
  3168. var isDrawLeft=borderTop>10 && this.IsShowYText[0]===true;
  3169. var isDrawRight=borderBottom>10 && this.IsShowYText[1]===true;
  3170. }
  3171. else
  3172. {
  3173. var borderRight=this.ChartBorder.Right;
  3174. var borderLeft=this.ChartBorder.Left;
  3175. var isDrawLeft=borderLeft>10 && this.IsShowYText[0]===true;
  3176. var isDrawRight=borderRight>10 && this.IsShowYText[1]===true;
  3177. }
  3178. var width={ Left:null, Right:null };
  3179. if (!isDrawRight && !isDrawLeft) return width;
  3180. for(var i=0;i<this.HorizontalInfo.length;++i)
  3181. {
  3182. var textWidth=null;
  3183. var item=this.HorizontalInfo[i];
  3184. if (!item) continue;
  3185. if (item.Font!=null) this.Canvas.font=item.Font;
  3186. if (item.Message[0]!=null && isDrawLeft)
  3187. {
  3188. textWidth=this.Canvas.measureText(item.Message[0]).width;
  3189. if (width.Left==null || width.Left<textWidth)
  3190. width.Left=textWidth;
  3191. }
  3192. if (item.Message[1]!=null && isDrawRight)
  3193. {
  3194. textWidth=this.Canvas.measureText(item.Message[1]).width;
  3195. if (width.Right==null || width.Right<textWidth)
  3196. width.Right=textWidth;
  3197. }
  3198. }
  3199. return { TextWidth:width };
  3200. }
  3201. }
  3202. function MinuteFrame()
  3203. {
  3204. this.newMethod = AverageWidthFrame; //派生
  3205. this.newMethod();
  3206. delete this.newMethod;
  3207. this.ClassName='MinuteFrame';
  3208. this.DataWidth=1;
  3209. this.DistanceWidth=1;
  3210. this.MinXDistance = 10;
  3211. this.CustomHorizontalInfo = [];
  3212. this.DrawFrame = function ()
  3213. {
  3214. if (this.IsMinSize) return;
  3215. this.SplitXYCoordinate();
  3216. this.DrawTitleBG();
  3217. this.DrawHorizontal();
  3218. this.DrawVertical();
  3219. }
  3220. //分割x,y轴坐标信息
  3221. this.SplitXYCoordinate = function ()
  3222. {
  3223. if (this.XYSplit == false) return;
  3224. if (this.YSplitOperator != null) this.YSplitOperator.Operator();
  3225. if (this.XSplitOperator != null) this.XSplitOperator.Operator();
  3226. }
  3227. this.GetXFromIndex = function (index)
  3228. {
  3229. var count = this.XPointCount - 1;
  3230. if (count == 1)
  3231. {
  3232. if (index == 0) return this.ChartBorder.GetLeft();
  3233. else return this.ChartBorder.GetRight();
  3234. }
  3235. else if (count <= 0)
  3236. {
  3237. return this.ChartBorder.GetLeft();
  3238. }
  3239. else if (index >= count)
  3240. {
  3241. return this.ChartBorder.GetRight();
  3242. }
  3243. else
  3244. {
  3245. var offset = this.ChartBorder.GetLeft() + this.ChartBorder.GetWidth() * index / count;
  3246. return offset;
  3247. }
  3248. }
  3249. //X坐标转x轴数值
  3250. this.GetXData = function (x)
  3251. {
  3252. if (x <= this.ChartBorder.GetLeft()) return 0;
  3253. if (x >= this.ChartBorder.GetRight()) return this.XPointCount;
  3254. return (x - this.ChartBorder.GetLeft()) * (this.XPointCount * 1.0 / this.ChartBorder.GetWidth());
  3255. }
  3256. this.DrawCustomHorizontal = function () //Y轴刻度定制显示
  3257. {
  3258. if (this.IsMinSize) return;
  3259. for (var i in this.CustomHorizontalInfo)
  3260. {
  3261. var item = this.CustomHorizontalInfo[i];
  3262. switch (item.Type)
  3263. {
  3264. case 0:
  3265. case 1:
  3266. this.DrawCustomItem(item); //自定义刻度
  3267. break;
  3268. }
  3269. }
  3270. }
  3271. }
  3272. function MinuteHScreenFrame()
  3273. {
  3274. this.newMethod = MinuteFrame; //派生
  3275. this.newMethod();
  3276. delete this.newMethod;
  3277. this.ClassName='MinuteHScreenFrame';
  3278. this.IsHScreen = true; //是否是横屏
  3279. //画标题背景色
  3280. this.DrawTitleBG = function ()
  3281. {
  3282. /*
  3283. if (this.ChartBorder.TitleHeight <= 0) return;
  3284. var left = ToFixedPoint(this.ChartBorder.GetRightEx());
  3285. var top = ToFixedPoint(this.ChartBorder.GetTop());
  3286. var bottom = ToFixedPoint(this.ChartBorder.GetBottom());
  3287. var width = this.ChartBorder.TitleHeight;
  3288. var height = bottom - top;
  3289. this.Canvas.setFillStyle(this.TitleBGColor);
  3290. this.Canvas.fillRect(left, top, width, height);
  3291. */
  3292. }
  3293. this.DrawInsideHorizontal = function ()
  3294. {
  3295. }
  3296. //Y坐标转y轴数值
  3297. this.GetYData = function (x)
  3298. {
  3299. if (x < this.ChartBorder.GetLeftEx()) return this.HorizontalMin;
  3300. if (x > this.ChartBorder.GetRightEx()) return this.HorizontalMax;
  3301. return (x - this.ChartBorder.GetLeftEx()) / this.ChartBorder.GetWidthEx() * (this.HorizontalMax - this.HorizontalMin) + this.HorizontalMin;
  3302. }
  3303. //X坐标转x轴数值
  3304. this.GetXData = function (y)
  3305. {
  3306. if (y <= this.ChartBorder.GetTop()) return 0;
  3307. if (y >= this.ChartBorder.GetBottom()) return this.XPointCount;
  3308. var count=this.XPointCount-1;
  3309. return (y - this.ChartBorder.GetTop()) * (count * 1.0 / this.ChartBorder.GetHeight());
  3310. }
  3311. this.GetXFromIndex = function (index)
  3312. {
  3313. var count = this.XPointCount - 1;
  3314. if (count == 1)
  3315. {
  3316. if (index == 0) return this.ChartBorder.GetTop();
  3317. else return this.ChartBorder.GetBottom();
  3318. }
  3319. else if (count <= 0)
  3320. {
  3321. return this.ChartBorder.GetTop();
  3322. }
  3323. else if (index >= count)
  3324. {
  3325. return this.ChartBorder.GetBottom();
  3326. }
  3327. else
  3328. {
  3329. var offset = this.ChartBorder.GetTop() + this.ChartBorder.GetHeight() * index / count;
  3330. return offset;
  3331. }
  3332. }
  3333. this.GetYFromData = function (value)
  3334. {
  3335. if (value <= this.HorizontalMin) return this.ChartBorder.GetLeft();
  3336. if (value >= this.HorizontalMax) return this.ChartBorder.GetRightEx();
  3337. var width = this.ChartBorder.GetWidthEx() * (value - this.HorizontalMin) / (this.HorizontalMax - this.HorizontalMin);
  3338. return this.ChartBorder.GetLeft() + width;
  3339. }
  3340. //画Y轴
  3341. this.DrawHorizontal = function ()
  3342. {
  3343. var top = this.ChartBorder.GetTop();
  3344. var bottom = this.ChartBorder.GetBottom();
  3345. var left=this.ChartBorder.GetLeft();
  3346. var right=this.ChartBorder.GetRight();
  3347. var borderTop = this.ChartBorder.Top;
  3348. var borderBottom = this.ChartBorder.Bottom;
  3349. var yPrev = null; //上一个坐标y的值
  3350. for (var i = this.HorizontalInfo.length - 1; i >= 0; --i) //从左往右画分割线
  3351. {
  3352. var item = this.HorizontalInfo[i];
  3353. var y = this.GetYFromData(item.Value);
  3354. if (y != null && Math.abs(y - yPrev) < this.MinYDistance) continue; //两个坐标在近了 就不画了
  3355. this.Canvas.setStrokeStyle(item.LineColor);
  3356. this.Canvas.beginPath();
  3357. this.Canvas.moveTo(ToFixedPoint(y), top);
  3358. this.Canvas.lineTo(ToFixedPoint(y), bottom);
  3359. this.Canvas.stroke();
  3360. if (y >= right - 2)
  3361. {
  3362. this.Canvas.textBaseline = 'top';
  3363. y = right;
  3364. }
  3365. else if (y <= left + 2)
  3366. {
  3367. this.Canvas.textBaseline = 'bottom';
  3368. y=left;
  3369. if (y != null && Math.abs(y - yPrev) < 2*this.MinYDistance) continue; //两个坐标在近了 就不画了
  3370. }
  3371. else
  3372. {
  3373. this.Canvas.textBaseline = "middle";
  3374. }
  3375. //坐标信息 左边 间距小于10 不画坐标
  3376. if (item.Message[0] != null && borderTop > 10)
  3377. {
  3378. if (item.Font != null) this.Canvas.font = item.Font;
  3379. this.Canvas.setFillStyle(item.TextColor);
  3380. this.Canvas.textAlign = "right";
  3381. //this.Canvas.textBaseline = "middle";
  3382. var xText = y, yText = top;
  3383. this.Canvas.save();
  3384. this.Canvas.translate(xText, yText);
  3385. this.Canvas.rotate(90 * Math.PI / 180);
  3386. this.Canvas.fillText(item.Message[0], -2, 0);
  3387. this.Canvas.restore();
  3388. }
  3389. //坐标信息 右边 间距小于10 不画坐标
  3390. if (item.Message[1] != null && borderBottom > 10)
  3391. {
  3392. if (item.Font != null) this.Canvas.font = item.Font;
  3393. this.Canvas.setFillStyle(item.TextColor);
  3394. this.Canvas.textAlign = "left";
  3395. //this.Canvas.textBaseline = "middle";
  3396. var xText = y, yText = bottom;
  3397. this.Canvas.save();
  3398. this.Canvas.translate(xText, yText);
  3399. this.Canvas.rotate(90 * Math.PI / 180);
  3400. this.Canvas.fillText(item.Message[1], 2, 0);
  3401. this.Canvas.restore();
  3402. }
  3403. yPrev = y;
  3404. }
  3405. }
  3406. //画X轴
  3407. this.DrawVertical = function () {
  3408. var left = this.ChartBorder.GetLeft();
  3409. var right = this.ChartBorder.GetRightEx();
  3410. var bottom = this.ChartBorder.GetBottom();
  3411. var xPrev = null; //上一个坐标x的值
  3412. for (var i in this.VerticalInfo) {
  3413. var x = this.GetXFromIndex(this.VerticalInfo[i].Value);
  3414. if (x > bottom) break;
  3415. if (xPrev != null && Math.abs(x - xPrev) < this.MinXDistance) continue;
  3416. this.Canvas.setStrokeStyle(this.VerticalInfo[i].LineColor);
  3417. this.Canvas.beginPath();
  3418. this.Canvas.moveTo(left, ToFixedPoint(x));
  3419. this.Canvas.lineTo(right, ToFixedPoint(x));
  3420. this.Canvas.stroke();
  3421. if (this.VerticalInfo[i].Message[0] != null) {
  3422. if (this.VerticalInfo[i].Font != null)
  3423. this.Canvas.font = this.VerticalInfo[i].Font;
  3424. this.Canvas.setFillStyle(this.VerticalInfo[i].TextColor);
  3425. var testWidth = this.Canvas.measureText(this.VerticalInfo[i].Message[0]).width;
  3426. if (x < testWidth / 2) {
  3427. this.Canvas.textAlign = "left";
  3428. this.Canvas.textBaseline = "top";
  3429. }
  3430. else if ((x + testWidth / 2) >= this.ChartBorder.GetChartHeight()) {
  3431. this.Canvas.textAlign = "right";
  3432. this.Canvas.textBaseline = "top";
  3433. }
  3434. else {
  3435. this.Canvas.textAlign = "center";
  3436. this.Canvas.textBaseline = "top";
  3437. }
  3438. var xText = left, yText = x;
  3439. this.Canvas.save();
  3440. this.Canvas.translate(xText, yText);
  3441. this.Canvas.rotate(90 * Math.PI / 180);
  3442. this.Canvas.fillText(this.VerticalInfo[i].Message[0], 0, 0);
  3443. this.Canvas.restore();
  3444. }
  3445. xPrev = x;
  3446. }
  3447. }
  3448. }
  3449. //K线框架
  3450. function KLineFrame()
  3451. {
  3452. this.newMethod = AverageWidthFrame; //派生
  3453. this.newMethod();
  3454. delete this.newMethod;
  3455. this.ClassName='KLineFrame';
  3456. this.ToolbarID = Guid(); //工具条Div id
  3457. this.ModifyIndex = true; //是否显示'改参数'菜单
  3458. this.ChangeIndex = true; //是否显示'换指标'菜单
  3459. this.CustomHorizontalInfo = [];
  3460. this.LastCalculateStatus = { Width: 0, XPointCount: 0 }; //最后一次计算宽度的状态
  3461. //定制X轴刻度
  3462. //Type:0, Date:, Time: , Name:名字, Line:{ Color:线段颜色, Type:线段类型 0 直线 1 虚线 }
  3463. //Type: 1, Space: 第几个空白间距, Name:名字, Line: { Color: 线段颜色, Type: 线段类型 0 直线 1 虚线 }
  3464. this.CustomVerticalInfo = [];
  3465. this.DrawCustomVerticalEvent;
  3466. this.RightSpaceCount = 0;
  3467. this.DrawFrame = function ()
  3468. {
  3469. if (this.IsMinSize) return;
  3470. this.SplitXYCoordinate();
  3471. if (this.SizeChange == true) this.CalculateDataWidth();
  3472. if (this.DrawOtherChart) this.DrawOtherChart();
  3473. this.DrawTitleBG();
  3474. this.DrawHorizontal();
  3475. this.DrawVertical();
  3476. }
  3477. this.GetXFromIndex = function (index)
  3478. {
  3479. if (index < 0) index = 0;
  3480. if (index > this.xPointCount - 1) index = this.xPointCount - 1;
  3481. var offset = this.ChartBorder.GetLeft() + g_JSChartResource.FrameLeftMargin + this.DistanceWidth / 2 + this.DataWidth / 2;
  3482. for (var i = 1; i <= index; ++i) { offset += this.DistanceWidth + this.DataWidth; }
  3483. return offset;
  3484. }
  3485. //X坐标转x轴数值
  3486. this.GetXData = function (x)
  3487. {
  3488. if (x <= this.ChartBorder.GetLeft()) return 0;
  3489. if (x >= this.ChartBorder.GetRight()) return this.XPointCount-1;
  3490. var left=this.ChartBorder.GetLeft()+g_JSChartResource.FrameLeftMargin;
  3491. var right=this.ChartBorder.GetRight()-g_JSChartResource.FrameRightMargin;
  3492. var distanceWidth = this.DistanceWidth;
  3493. var dataWidth = this.DataWidth;
  3494. var index = 0;
  3495. var xPoint = left + distanceWidth/2 + dataWidth + distanceWidth;
  3496. while (xPoint < right && index < 10000 && index+1<this.XPointCount ) //自己算x的数值
  3497. {
  3498. if (xPoint > x) break;
  3499. xPoint += (dataWidth + distanceWidth);
  3500. ++index;
  3501. }
  3502. //var test=(x-this.ChartBorder.GetLeft())*(this.XPointCount*1.0/this.ChartBorder.GetWidth());
  3503. return index;
  3504. }
  3505. this.DrawCustomHorizontal = function () //Y轴刻度定制显示
  3506. {
  3507. if (this.IsMinSize) return;
  3508. for (var i in this.CustomHorizontalInfo)
  3509. {
  3510. var item = this.CustomHorizontalInfo[i];
  3511. switch (item.Type)
  3512. {
  3513. case 0: //最新价格刻度
  3514. case 1: //固定价格刻度
  3515. this.DrawCustomItem(item);
  3516. break;
  3517. }
  3518. }
  3519. }
  3520. this.DrawCustomVerticalItem = function (item) {
  3521. this.Canvas.save();
  3522. if (item.Data.Line.Type == 1) this.Canvas.setLineDash([5, 5]); //虚线
  3523. this.Canvas.setStrokeStyle(item.Data.Line.Color);
  3524. this.Canvas.beginPath();
  3525. if (item.IsHScreen) {
  3526. this.Canvas.moveTo(item.Top, ToFixedPoint(item.X));
  3527. this.Canvas.lineTo(item.Bottom, ToFixedPoint(item.X));
  3528. }
  3529. else {
  3530. this.Canvas.moveTo(ToFixedPoint(item.X), item.Top);
  3531. this.Canvas.lineTo(ToFixedPoint(item.X), item.Bottom);
  3532. }
  3533. this.Canvas.stroke();
  3534. this.Canvas.restore();
  3535. }
  3536. this.DrawCustomVertical = function () //X轴定制刻度显示
  3537. {
  3538. if (!this.CustomVerticalInfo) return;
  3539. if (this.CustomVerticalInfo.length <= 0) return;
  3540. if (!this.Data) return;
  3541. var isHScreen = this.IsHScreen;
  3542. var top = this.ChartBorder.GetTopEx();
  3543. var bottom = this.ChartBorder.GetBottomEx();
  3544. var dataWidth = this.DataWidth;
  3545. var distanceWidth = this.DistanceWidth;
  3546. var xOffset = this.ChartBorder.GetLeft() + distanceWidth / 2.0 + 2.0;
  3547. if (isHScreen)
  3548. {
  3549. xOffset = this.ChartBorder.GetTop() + distanceWidth / 2.0 + 2.0;
  3550. top = this.ChartBorder.GetLeftEx();
  3551. bottom = this.ChartBorder.GetRightEx();
  3552. }
  3553. var j = 0;
  3554. for (var i = this.Data.DataOffset; i < this.Data.Data.length && j < this.XPointCount; ++i, ++j, xOffset += (dataWidth + distanceWidth))
  3555. {
  3556. var kItem = this.Data.Data[i];
  3557. for (var k in this.CustomVerticalInfo)
  3558. {
  3559. var item = this.CustomVerticalInfo[k];
  3560. if (item.Type != 0) continue;
  3561. if (IFrameSplitOperator.IsNumber(item.Time))
  3562. {
  3563. if (kItem.Date != item.Date || kItem.Time != item.Time) continue;
  3564. }
  3565. else
  3566. {
  3567. if (kItem.Date != item.Date) continue;
  3568. }
  3569. var left = xOffset;
  3570. var right = xOffset + dataWidth;
  3571. var x = left + (right - left) / 2;
  3572. var DrawData = { X: x, Top: top, Bottom: bottom, Data: item, IsHScreen: isHScreen };
  3573. this.DrawCustomVerticalItem(DrawData);
  3574. if (this.DrawCustomVerticalEvent)
  3575. this.DrawCustomVerticalEvent.Callback(this.DrawCustomVerticalEvent, DrawData, this);
  3576. break;
  3577. }
  3578. }
  3579. for (var i = 1; j < this.XPointCount; ++i, ++j, xOffset += (dataWidth + distanceWidth))
  3580. {
  3581. for (var k in this.CustomVerticalInfo)
  3582. {
  3583. var item = this.CustomVerticalInfo[k];
  3584. if (item.Type != 1) continue;
  3585. if (item.Space != i) continue;
  3586. var left = xOffset;
  3587. var right = xOffset + dataWidth;
  3588. var x = left + (right - left) / 2;
  3589. var DrawData = { X: x, Top: top, Bottom: bottom, Data: item, IsHScreen: isHScreen };
  3590. this.DrawCustomVerticalItem(DrawData);
  3591. if (this.DrawCustomVerticalEvent)
  3592. this.DrawCustomVerticalEvent.Callback(this.DrawCustomVerticalEvent, DrawData, this);
  3593. break;
  3594. }
  3595. }
  3596. }
  3597. this.CalculateDataWidth = function () //计算数据宽度
  3598. {
  3599. if (this.XPointCount < 2) return;
  3600. var width = this.GetFrameWidth() - g_JSChartResource.FrameMargin; //预留4个像素 防止最后1个柱子不够画
  3601. if (this.ZoomIndex>=0 && this.LastCalculateStatus.Width==width && this.LastCalculateStatus.XPointCount==this.XPointCount) //宽度没变 尝试使用原来的柱子宽度
  3602. {
  3603. var caclWidth=(this.DistanceWidth/2+g_JSChartResource.FrameLeftMargin)+(this.DataWidth + this.DistanceWidth)*(this.XPointCount-1);
  3604. var caclWidth2=(this.DataWidth + this.DistanceWidth) * this.XPointCount;
  3605. if (caclWidth<= width) //当前的柱子宽度够用 就不调整了
  3606. return;
  3607. }
  3608. this.LastCalculateStatus.Width=width;
  3609. this.LastCalculateStatus.XPointCount=this.XPointCount;
  3610. for (var i = 0; i < ZOOM_SEED.length; ++i)
  3611. {
  3612. let barWidth = ZOOM_SEED[i][0]; //数据宽度
  3613. let distanceWidth = ZOOM_SEED[i][1]; //间距宽度
  3614. if ((ZOOM_SEED[i][0] + ZOOM_SEED[i][1]) * this.XPointCount < width)
  3615. {
  3616. this.ZoomIndex = i;
  3617. this.DataWidth = ZOOM_SEED[i][0];
  3618. this.DistanceWidth = ZOOM_SEED[i][1];
  3619. this.TrimKLineDataWidth(width);
  3620. JSConsole.Chart.Log(`[KLineFrame::CalculateDataWidth] ZoomIndex=${this.ZoomIndex} DataWidth=${this.DataWidth} DistanceWidth=${this.DistanceWidth}` );
  3621. return;
  3622. }
  3623. }
  3624. //太多了 就平均分了
  3625. this.ZoomIndex = ZOOM_SEED.length - 1;
  3626. this.DataWidth = width / this.XPointCount;
  3627. this.DistanceWidth = 0;
  3628. }
  3629. this.OnSize=function(obj)
  3630. {
  3631. var width=this.GetFrameWidth()-g_JSChartResource.FrameMargin;
  3632. var xPointCount=0;
  3633. var y=this.DistanceWidth/2+g_JSChartResource.FrameLeftMargin+(this.DataWidth+this.DistanceWidth);
  3634. for(;y<width; y+=(this.DataWidth+this.DistanceWidth), ++xPointCount) { }
  3635. obj.CurCount=this.XPointCount;
  3636. obj.CalcCount=xPointCount;
  3637. obj.DataWidth=this.DataWidth;
  3638. obj.DistanceWidth=this.DistanceWidth;
  3639. obj.Changed=false;
  3640. this.LastCalculateStatus.Width=width;
  3641. if (obj.CurCount==obj.CalcCount) return obj;
  3642. this.XPointCount=xPointCount;
  3643. this.LastCalculateStatus.XPointCount=this.XPointCount;
  3644. if (this.Data)
  3645. {
  3646. this.Data.DataOffset+=(obj.CurCount-obj.CalcCount);
  3647. if (this.Data.DataOffset<0) this.Data.DataOffset=0;
  3648. obj.Changed=true;
  3649. }
  3650. return obj;
  3651. }
  3652. this.SetDataWidth=function(dataWidth)
  3653. {
  3654. var zoomIndex=ZOOM_SEED.length-1;
  3655. for(var i in ZOOM_SEED)
  3656. {
  3657. var item=ZOOM_SEED[i];
  3658. if (item[0]<=dataWidth)
  3659. {
  3660. zoomIndex=parseInt(i)-1;
  3661. break;
  3662. }
  3663. }
  3664. this.ZoomIndex=zoomIndex;
  3665. this.DataWidth=ZOOM_SEED[this.ZoomIndex][0];
  3666. this.DistanceWidth=ZOOM_SEED[this.ZoomIndex][1];
  3667. var width=this.GetFrameWidth()-g_JSChartResource.FrameMargin;
  3668. var xPointCount=0;
  3669. var y=this.DistanceWidth/2+g_JSChartResource.FrameLeftMargin+(this.DataWidth+this.DistanceWidth);
  3670. for(;y<=width; y+=(this.DataWidth+this.DistanceWidth), ++xPointCount) { }
  3671. this.XPointCount=xPointCount;
  3672. this.LastCalculateStatus.XPointCount=this.XPointCount;
  3673. this.LastCalculateStatus.Width=width;
  3674. var obj={ XPointCount:this.XPointCount, DataWidth:this.DataWidth, DistanceWidth:this.DistanceWidth };
  3675. return obj;
  3676. }
  3677. this.TrimKLineDataWidth = function (width)
  3678. {
  3679. var zoom = ZOOM_SEED[this.ZoomIndex];
  3680. var dataWidth = ZOOM_SEED[this.ZoomIndex][0];
  3681. var distanceWidth = ZOOM_SEED[this.ZoomIndex][1];
  3682. if (dataWidth == 1 && distanceWidth == 0)
  3683. {
  3684. this.DataWidth = width / this.XPointCount;
  3685. return;
  3686. }
  3687. if (zoom[0]<4) //最后2个缩放,调整间距不调整数据宽度, 数据都是画竖线的
  3688. {
  3689. while (true)
  3690. {
  3691. if ((this.DistanceWidth + this.DataWidth) * this.XPointCount + this.DistanceWidth > width)
  3692. {
  3693. this.DistanceWidth -= 0.01;
  3694. break;
  3695. }
  3696. this.DistanceWidth += 0.01;
  3697. }
  3698. }
  3699. else
  3700. {
  3701. while (true)
  3702. {
  3703. if ((this.DistanceWidth + this.DataWidth) * this.XPointCount + this.DistanceWidth > width)
  3704. {
  3705. this.DataWidth -= 0.01;
  3706. break;
  3707. }
  3708. this.DataWidth += 0.01;
  3709. }
  3710. }
  3711. }
  3712. this.IsOverlayMaxMin = function (obj) //当前坐标信息 是否覆盖最大 最小值输出
  3713. {
  3714. if (!this.ChartKLine) return false;
  3715. if (!this.ChartKLine.Max || !this.ChartKLine.Min) return false;
  3716. var textWidth = this.Canvas.measureText(obj.Text.Value).width + 4; //刻度文字宽度
  3717. var max = this.ChartKLine.Max, min = this.ChartKLine.Min;
  3718. var isOverlayMax = false, isOverlayMin = false;
  3719. const textHeight = 20; //字体高度
  3720. if (max.X >= obj.X && max.X <= obj.X + textWidth)
  3721. {
  3722. var y1 = max.Y + textHeight, y2 = max.Y - textHeight;
  3723. if ((y1 >= obj.Y - textHeight && y1 <= obj.Y + textHeight) || (y2 >= obj.Y - textHeight && y2 <= obj.Y + textHeight))
  3724. isOverlayMax = true;
  3725. }
  3726. if (isOverlayMax == true) return true;
  3727. if (min.X >= obj.X && min.X <= obj.X + textWidth) //最小值X 坐标不在 刻度文字范围内
  3728. {
  3729. var y1 = min.Y + textHeight, y2 = min.Y - textHeight;
  3730. if ((y1 >= obj.Y - textHeight && y1 <= obj.Y + textHeight) || (y2 >= obj.Y - textHeight && y2 <= obj.Y + textHeight))
  3731. isOverlayMin = true;
  3732. }
  3733. return isOverlayMax || isOverlayMin;
  3734. }
  3735. //分割x,y轴坐标信息
  3736. this.SplitXYCoordinate = function ()
  3737. {
  3738. if (this.XYSplit == false) return;
  3739. if (this.YSplitOperator != null) this.YSplitOperator.Operator();
  3740. if (this.XSplitOperator != null) this.XSplitOperator.Operator();
  3741. }
  3742. this.CalculateCount = function (zoomIndex)
  3743. {
  3744. var width = this.GetFrameWidth() - g_JSChartResource.FrameMargin;
  3745. return parseInt(width / (ZOOM_SEED[zoomIndex][0] + ZOOM_SEED[zoomIndex][1]));
  3746. }
  3747. this.ZoomUp = function (cursorIndex)
  3748. {
  3749. if (this.ZoomIndex <= 0) return false;
  3750. if (this.Data.DataOffset < 0) return false;
  3751. var dataCount = this.Data.Data.length;
  3752. var maxDataCount = dataCount + this.RightSpaceCount;
  3753. var rightSpaceCount = 0;
  3754. var lastDataIndex = this.Data.DataOffset + this.XPointCount - 1; //最右边的数据索引
  3755. var lastCursorIndex = this.Data.DataOffset + cursorIndex.Index;
  3756. if (lastDataIndex >= dataCount)
  3757. {
  3758. rightSpaceCount = lastDataIndex - (this.Data.Data.length - 1); //计算右边预留空间
  3759. lastDataIndex = this.Data.Data.length - 1;
  3760. if (rightSpaceCount > this.RightSpaceCount) rightSpaceCount = this.RightSpaceCount;
  3761. }
  3762. var xPointCount = this.CalculateCount(this.ZoomIndex-1);
  3763. --this.ZoomIndex;
  3764. this.XPointCount = xPointCount;
  3765. if (xPointCount >= maxDataCount)
  3766. {
  3767. xPointCount = maxDataCount;
  3768. this.XPointCount = xPointCount;
  3769. this.Data.DataOffset = 0;
  3770. }
  3771. else
  3772. {
  3773. this.XPointCount = xPointCount;
  3774. this.Data.DataOffset = lastDataIndex - (this.XPointCount - rightSpaceCount) + 1;
  3775. }
  3776. this.DataWidth = ZOOM_SEED[this.ZoomIndex][0];
  3777. this.DistanceWidth = ZOOM_SEED[this.ZoomIndex][1];
  3778. var width = this.GetFrameWidth() - g_JSChartResource.FrameMargin;
  3779. this.TrimKLineDataWidth(width);
  3780. this.LastCalculateStatus.XPointCount = this.XPointCount;
  3781. cursorIndex.Index = lastCursorIndex - this.Data.DataOffset;
  3782. return true;
  3783. }
  3784. this.ZoomDown = function (cursorIndex)
  3785. {
  3786. if (this.ZoomIndex + 1 >= ZOOM_SEED.length) return false;
  3787. if (this.Data.DataOffset < 0) return false;
  3788. var dataCount = this.Data.Data.length;
  3789. var maxDataCount = dataCount + this.RightSpaceCount;
  3790. if (this.XPointCount >= dataCount) return false;
  3791. var rightSpaceCount = 0;
  3792. var lastDataIndex = this.Data.DataOffset + this.XPointCount - 1; //最右边的数据索引
  3793. if (lastDataIndex >= this.Data.Data.length)
  3794. {
  3795. rightSpaceCount = lastDataIndex - (this.Data.Data.length - 1); //计算右边预留空间
  3796. lastDataIndex = this.Data.Data.length - 1;
  3797. if (rightSpaceCount > this.RightSpaceCount) rightSpaceCount = this.RightSpaceCount;
  3798. }
  3799. var xPointCount = this.CalculateCount(this.ZoomIndex + 1);
  3800. var lastCursorIndex = this.Data.DataOffset + cursorIndex.Index;
  3801. ++this.ZoomIndex;
  3802. if (xPointCount >= maxDataCount)
  3803. {
  3804. xPointCount = maxDataCount;
  3805. this.XPointCount = xPointCount;
  3806. this.Data.DataOffset = 0;
  3807. }
  3808. else
  3809. {
  3810. this.XPointCount = xPointCount;
  3811. this.Data.DataOffset = lastDataIndex - (this.XPointCount - rightSpaceCount) + 1;
  3812. }
  3813. this.DataWidth = ZOOM_SEED[this.ZoomIndex][0];
  3814. this.DistanceWidth = ZOOM_SEED[this.ZoomIndex][1];
  3815. var width = this.GetFrameWidth() - g_JSChartResource.FrameMargin;
  3816. this.TrimKLineDataWidth(width);
  3817. this.LastCalculateStatus.XPointCount = this.XPointCount;
  3818. cursorIndex.Index = lastCursorIndex - this.Data.DataOffset;
  3819. return true;
  3820. }
  3821. this.GetFrameWidth = function ()
  3822. {
  3823. if (this.IsHScreen) return this.ChartBorder.GetHeight();
  3824. return this.ChartBorder.GetWidth();
  3825. }
  3826. }
  3827. //K线横屏框架
  3828. function KLineHScreenFrame()
  3829. {
  3830. this.newMethod = KLineFrame; //派生
  3831. this.newMethod();
  3832. delete this.newMethod;
  3833. this.ClassName='KLineHScreenFrame';
  3834. this.IsHScreen = true; //是否是横屏
  3835. this.DrawInsideHorizontal = function ()
  3836. {
  3837. if (this.IsMinSize) return;
  3838. if (this.IsShowYText[0] === false && this.IsShowYText[1] === false) return;
  3839. var left = this.ChartBorder.GetLeft();
  3840. var right = this.ChartBorder.GetRightEx();
  3841. var top = this.ChartBorder.GetTop();
  3842. var bottom = this.ChartBorder.GetBottom();
  3843. var borderTop = this.ChartBorder.Top;
  3844. var borderBottom = this.ChartBorder.Bottom;
  3845. var titleHeight = this.ChartBorder.TitleHeight;
  3846. var pixelTatio = 1;
  3847. var isDrawLeft = (borderTop < 10 * pixelTatio || this.YTextPosition[0] == 2) && this.IsShowYText[0] === true;
  3848. var isDrawRight = (borderBottom < 10 * pixelTatio || this.YTextPosition[1] == 2) && this.IsShowYText[1] === true;
  3849. if (isDrawLeft || isDrawRight)
  3850. {
  3851. var yPrev = null; //上一个坐标y的值
  3852. for (var i = this.HorizontalInfo.length - 1; i >= 0; --i) //从上往下画分割线
  3853. {
  3854. var item = this.HorizontalInfo[i];
  3855. var y = this.GetYFromData(item.Value);
  3856. if (y != null && yPrev != null && Math.abs(y - yPrev) < this.MinYDistance) continue; //两个坐标在近了 就不画了
  3857. //坐标信息 左边 间距小于10 画在内部
  3858. if (item.Message[0] != null && isDrawLeft)
  3859. {
  3860. if (item.Font != null) this.Canvas.font = item.Font;
  3861. this.Canvas.setFillStyle(item.TextColor);
  3862. this.Canvas.textAlign = "left";
  3863. if (y >= right - 2) this.Canvas.textBaseline = 'top';
  3864. else if (y <= left + 2) this.Canvas.textBaseline = 'bottom';
  3865. else this.Canvas.textBaseline = "middle";
  3866. var textObj = { X: left, Y: y, Text: { BaseLine: this.Canvas.textBaseline, TextAlign: this.Canvas.textAlign, Font: this.Canvas.font, Value: item.Message[0] } };
  3867. var xText = y, yText = top;
  3868. this.Canvas.save();
  3869. this.Canvas.translate(xText, yText);
  3870. this.Canvas.rotate(90 * Math.PI / 180);
  3871. this.Canvas.fillText(item.Message[0], -2, 0);
  3872. this.Canvas.restore();
  3873. }
  3874. if (item.Message[1] != null && isDrawRight)
  3875. {
  3876. if (item.Font != null) this.Canvas.font = item.Font;
  3877. this.Canvas.setFillStyle(item.TextColor);
  3878. this.Canvas.textAlign = "right";
  3879. if (y >= right - 2) this.Canvas.textBaseline = 'top';
  3880. else if (y <= left + 2) this.Canvas.textBaseline = 'bottom';
  3881. else this.Canvas.textBaseline = "middle";
  3882. var textWidth = this.Canvas.measureText(item.Message[1]).width;
  3883. var textObj = { X: right - textWidth, Y: y, Text: { BaseLine: this.Canvas.textBaseline, TextAlign: this.Canvas.textAlign, Font: this.Canvas.font, Value: item.Message[1] } };
  3884. var xText = y, yText = bottom;
  3885. this.Canvas.save();
  3886. this.Canvas.translate(xText, yText);
  3887. this.Canvas.rotate(90 * Math.PI / 180);
  3888. this.Canvas.fillText(item.Message[1], 2, 0);
  3889. this.Canvas.restore();
  3890. }
  3891. yPrev = y;
  3892. }
  3893. }
  3894. }
  3895. //画标题背景色
  3896. this.DrawTitleBG = function ()
  3897. {
  3898. /*
  3899. if (this.ChartBorder.TitleHeight <= 0) return;
  3900. var left = ToFixedPoint(this.ChartBorder.GetRightEx());
  3901. var top = ToFixedPoint(this.ChartBorder.GetTop());
  3902. var bottom = ToFixedPoint(this.ChartBorder.GetBottom());
  3903. var width = this.ChartBorder.TitleHeight;
  3904. var height = bottom - top;
  3905. this.Canvas.setFillStyle(this.TitleBGColor);
  3906. this.Canvas.fillRect(left, top, width, height);
  3907. */
  3908. }
  3909. this.GetYFromData = function (value)
  3910. {
  3911. if (value <= this.HorizontalMin) return this.ChartBorder.GetLeftEx();
  3912. if (value >= this.HorizontalMax) return this.ChartBorder.GetRightEx();
  3913. var width = this.ChartBorder.GetWidthEx() * (value - this.HorizontalMin) / (this.HorizontalMax - this.HorizontalMin);
  3914. return this.ChartBorder.GetLeftEx() + width;
  3915. }
  3916. //画Y轴
  3917. this.DrawHorizontal = function ()
  3918. {
  3919. var top = this.ChartBorder.GetTop();
  3920. var bottom = this.ChartBorder.GetBottom();
  3921. var borderTop = this.ChartBorder.Top;
  3922. var borderBottom = this.ChartBorder.Bottom;
  3923. var left=this.ChartBorder.GetLeft();
  3924. var yPrev = null; //上一个坐标y的值
  3925. for (var i = this.HorizontalInfo.length - 1; i >= 0; --i) //从左往右画分割线
  3926. {
  3927. var item = this.HorizontalInfo[i];
  3928. var y = this.GetYFromData(item.Value);
  3929. if (y != null && Math.abs(y - yPrev) < 15) continue; //两个坐标在近了 就不画了
  3930. if (y!=left)
  3931. {
  3932. if (item.LineType==2)
  3933. {
  3934. this.Canvas.setStrokeStyle(item.LineColor);
  3935. this.Canvas.setLineDash([5,5]); //虚线
  3936. this.Canvas.beginPath();
  3937. this.Canvas.moveTo(ToFixedPoint(y),top);
  3938. this.Canvas.lineTo(ToFixedPoint(y),bottom);
  3939. this.Canvas.stroke();
  3940. this.Canvas.setLineDash([]);
  3941. }
  3942. else if (item.LineType>0)
  3943. {
  3944. this.Canvas.setStrokeStyle(item.LineColor);
  3945. if (g_JSChartResource.FrameYLineDash)
  3946. {
  3947. this.Canvas.setLineDash(g_JSChartResource.FrameYLineDash); //虚线
  3948. this.Canvas.beginPath();
  3949. this.Canvas.moveTo(ToFixedPoint(y),top);
  3950. this.Canvas.lineTo(ToFixedPoint(y),bottom);
  3951. this.Canvas.stroke();
  3952. this.Canvas.setLineDash([]);
  3953. }
  3954. else
  3955. {
  3956. this.Canvas.beginPath();
  3957. this.Canvas.moveTo(ToFixedPoint(y), top);
  3958. this.Canvas.lineTo(ToFixedPoint(y), bottom);
  3959. this.Canvas.stroke();
  3960. }
  3961. }
  3962. }
  3963. //坐标信息 左边 间距小于10 不画坐标
  3964. if (item.Message[0] != null && borderTop > 10)
  3965. {
  3966. if (item.Font != null) this.Canvas.font = item.Font;
  3967. this.Canvas.setFillStyle(item.TextColor);
  3968. this.Canvas.textAlign = "right";
  3969. this.Canvas.textBaseline = "middle";
  3970. var xText = y, yText = top;
  3971. this.Canvas.save();
  3972. this.Canvas.translate(xText, yText);
  3973. this.Canvas.rotate(90 * Math.PI / 180);
  3974. this.Canvas.fillText(item.Message[0], -2, 0);
  3975. this.Canvas.restore();
  3976. }
  3977. //坐标信息 右边 间距小于10 不画坐标
  3978. if (item.Message[1] != null && borderBottom > 10)
  3979. {
  3980. if (item.Font != null) this.Canvas.font = item.Font;
  3981. this.Canvas.setFillStyle(item.TextColor);
  3982. this.Canvas.textAlign = "left";
  3983. this.Canvas.textBaseline = "middle";
  3984. var xText = y, yText = bottom;
  3985. this.Canvas.save();
  3986. this.Canvas.translate(xText, yText);
  3987. this.Canvas.rotate(90 * Math.PI / 180);
  3988. this.Canvas.fillText(item.Message[1], 2, 0);
  3989. this.Canvas.restore();
  3990. }
  3991. yPrev = y;
  3992. }
  3993. }
  3994. this.GetXFromIndex = function (index)
  3995. {
  3996. if (index < 0) index = 0;
  3997. if (index > this.xPointCount - 1) index = this.xPointCount - 1;
  3998. var offset = this.ChartBorder.GetTop() + g_JSChartResource.FrameLeftMargin + this.DistanceWidth / 2 + this.DataWidth / 2;
  3999. for (var i = 1; i <= index; ++i)
  4000. {
  4001. offset += this.DistanceWidth + this.DataWidth;
  4002. }
  4003. return offset;
  4004. }
  4005. //画X轴
  4006. this.DrawVertical = function ()
  4007. {
  4008. var left = this.ChartBorder.GetLeft();
  4009. var right = this.ChartBorder.GetRightTitle();
  4010. var bottom = this.ChartBorder.GetBottom();
  4011. var xPrev = null; //上一个坐标x的值
  4012. for (var i in this.VerticalInfo)
  4013. {
  4014. var x = this.GetXFromIndex(this.VerticalInfo[i].Value);
  4015. if (x >= bottom) break;
  4016. if (xPrev != null && Math.abs(x - xPrev) < 80) continue;
  4017. var item=this.VerticalInfo[i];
  4018. if (item.LineType==2)
  4019. {
  4020. this.Canvas.setLineDash([5,5]);
  4021. this.Canvas.beginPath();
  4022. this.Canvas.moveTo(left, ToFixedPoint(x));
  4023. this.Canvas.lineTo(right, ToFixedPoint(x));
  4024. this.Canvas.stroke();
  4025. this.Canvas.setLineDash([]);
  4026. }
  4027. else if (item.LineType>0)
  4028. {
  4029. this.Canvas.setStrokeStyle(item.LineColor);
  4030. if (g_JSChartResource.FrameXLineDash)
  4031. {
  4032. this.Canvas.setLineDash(g_JSChartResource.FrameXLineDash);
  4033. this.Canvas.beginPath();
  4034. this.Canvas.moveTo(left, ToFixedPoint(x));
  4035. this.Canvas.lineTo(right, ToFixedPoint(x));
  4036. this.Canvas.stroke();
  4037. this.Canvas.setLineDash([]);
  4038. }
  4039. else
  4040. {
  4041. this.Canvas.beginPath();
  4042. this.Canvas.moveTo(left, ToFixedPoint(x));
  4043. this.Canvas.lineTo(right, ToFixedPoint(x));
  4044. this.Canvas.stroke();
  4045. }
  4046. }
  4047. if (this.VerticalInfo[i].Message[0] != null)
  4048. {
  4049. if (this.VerticalInfo[i].Font != null)
  4050. this.Canvas.font = this.VerticalInfo[i].Font;
  4051. this.Canvas.setFillStyle(this.VerticalInfo[i].TextColor);
  4052. var testWidth = this.Canvas.measureText(this.VerticalInfo[i].Message[0]).width;
  4053. if (x < testWidth / 2)
  4054. {
  4055. this.Canvas.textAlign = "left";
  4056. this.Canvas.textBaseline = "top";
  4057. }
  4058. else
  4059. {
  4060. this.Canvas.textAlign = "center";
  4061. this.Canvas.textBaseline = "top";
  4062. }
  4063. var xText = left, yText = x;
  4064. this.Canvas.save();
  4065. this.Canvas.translate(xText, yText);
  4066. this.Canvas.rotate(90 * Math.PI / 180);
  4067. this.Canvas.fillText(this.VerticalInfo[i].Message[0], 0, this.XBottomOffset);
  4068. this.Canvas.restore();
  4069. }
  4070. xPrev = x;
  4071. }
  4072. }
  4073. //Y坐标转y轴数值
  4074. this.GetYData = function (x)
  4075. {
  4076. if (x < this.ChartBorder.GetLeftEx()) return this.HorizontalMin;
  4077. if (x > this.ChartBorder.GetRightEx()) return this.HorizontalMax;
  4078. return (x - this.ChartBorder.GetLeftEx()) / this.ChartBorder.GetWidthEx() * (this.HorizontalMax - this.HorizontalMin) + this.HorizontalMin;
  4079. }
  4080. //X坐标转x轴数值
  4081. this.GetXData = function (y)
  4082. {
  4083. if (y <= this.ChartBorder.GetTop()) return 0;
  4084. if (y >= this.ChartBorder.GetBottom()) return this.XPointCount-1;
  4085. var distanceWidth=this.DistanceWidth;
  4086. var dataWidth=this.DataWidth;
  4087. var left=this.ChartBorder.GetTop()+g_JSChartResource.FrameLeftMargin;
  4088. var right=this.ChartBorder.GetBottom()-g_JSChartResource.FrameRightMargin;
  4089. var index=0;
  4090. var xPoint=left+distanceWidth/2+dataWidth+distanceWidth;
  4091. while(xPoint<right && index<10000 && index+1<this.XPointCount) //自己算x的数值
  4092. {
  4093. if (xPoint>=y) break;
  4094. xPoint+=(dataWidth+distanceWidth);
  4095. ++index;
  4096. }
  4097. return index;
  4098. }
  4099. }
  4100. function SubFrameItem()
  4101. {
  4102. this.Frame;
  4103. this.Height;
  4104. }
  4105. //行情框架
  4106. function HQTradeFrame()
  4107. {
  4108. this.ClassName='HQTradeFrame';
  4109. this.SubFrame = new Array(); //SubFrameItem 数组
  4110. this.SizeChange = true; //大小是否改变
  4111. this.ChartBorder;
  4112. this.Canvas; //画布
  4113. this.ScreenImagePath; //截图路径
  4114. this.ScreenImageData=null; //截图数据
  4115. this.Data; //主数据
  4116. this.Position; //画布的位置
  4117. this.SizeChange = true;
  4118. this.SnapshotID=0;
  4119. this.CurrentSnapshotID=0;
  4120. this.SnapshotStatus=0; //0空闲 1工作
  4121. this.AutoLeftBorder=null; //{ Blank:10 留白宽度, MinWidth:最小宽度 }
  4122. this.AutoRightBorder=null; //{ Blank:10 留白宽度, MinWidth:最小宽度 }
  4123. this.ZoomWindowsInfo=null; //附图指标缩放,备份信息
  4124. this.ZoomStartWindowIndex=1; //允许缩放窗口起始位置
  4125. this.CalculateChartBorder = function () //计算每个子框架的边框信息
  4126. {
  4127. if (this.SubFrame.length <= 0) return;
  4128. var top = this.ChartBorder.GetTop();
  4129. var height = this.ChartBorder.GetHeight();
  4130. var totalHeight = 0;
  4131. for (var i in this.SubFrame)
  4132. {
  4133. var item = this.SubFrame[i];
  4134. totalHeight += item.Height;
  4135. }
  4136. for (var i in this.SubFrame)
  4137. {
  4138. var item = this.SubFrame[i];
  4139. item.Frame.ChartBorder.Top = top;
  4140. item.Frame.ChartBorder.Left = this.ChartBorder.Left;
  4141. item.Frame.ChartBorder.Right = this.ChartBorder.Right;
  4142. var frameHeight = height * (item.Height / totalHeight) + top;
  4143. item.Frame.ChartBorder.Bottom = this.ChartBorder.GetChartHeight() - frameHeight;
  4144. top = frameHeight;
  4145. }
  4146. }
  4147. this.GetScaleTextWidth=function()
  4148. {
  4149. var width={ Left:null, Right:null };
  4150. for(var i in this.SubFrame)
  4151. {
  4152. var item=this.SubFrame[i];
  4153. if (item.Height<=0) continue;
  4154. var frame=item.Frame;
  4155. if (!frame) continue;
  4156. if (!frame.XSplitOperator) continue;
  4157. var maxValue=frame.HorizontalMax; //最大最小要还原
  4158. var minValue=frame.HorizontalMin;
  4159. frame.YSplitOperator.Operator();
  4160. var value=frame.GetScaleTextWidth();
  4161. frame.HorizontalMax=maxValue;
  4162. frame.HorizontalMin=minValue;
  4163. if (value && value.TextWidth)
  4164. {
  4165. var widthItem=value.TextWidth;
  4166. if (IFrameSplitOperator.IsNumber(widthItem.Left))
  4167. {
  4168. if (width.Left==null || width.Left<widthItem.Left) width.Left=widthItem.Left;
  4169. }
  4170. if (IFrameSplitOperator.IsNumber(widthItem.Right))
  4171. {
  4172. if (width.Right==null || width.Right<widthItem.Right) width.Right=widthItem.Right;
  4173. }
  4174. }
  4175. }
  4176. return width;
  4177. }
  4178. this.IsFrameXYSplit=function()
  4179. {
  4180. for(var i in this.SubFrame)
  4181. {
  4182. if (this.SubFrame[i].Frame.XYSplit) return true;
  4183. }
  4184. return false;
  4185. }
  4186. this.Draw = function (option)
  4187. {
  4188. if (this.SizeChange === true) this.CalculateChartBorder();
  4189. var isSplash=false; //是否过场动画
  4190. if (option && option.IsEnableSplash===true) isSplash=true;
  4191. if (isSplash==false && (this.AutoLeftBorder || this.AutoRightBorder) &&this.IsFrameXYSplit())
  4192. {
  4193. var textWidth=this.GetScaleTextWidth();
  4194. if (IFrameSplitOperator.IsNumber(textWidth.Left) && this.AutoLeftBorder)
  4195. {
  4196. var blank=0;
  4197. if (IFrameSplitOperator.IsNumber(this.AutoLeftBorder.Blank)) blank=this.AutoLeftBorder.Blank;
  4198. var value=textWidth.Left+blank;
  4199. if (IFrameSplitOperator.IsNumber(this.AutoLeftBorder.MinWidth))
  4200. {
  4201. if (this.AutoLeftBorder.MinWidth>value) value=this.AutoLeftBorder.MinWidth;
  4202. }
  4203. if (this.IsHScreen) this.ChartBorder.Top=value;
  4204. else this.ChartBorder.Left=value;
  4205. for(var i=0; i<this.SubFrame.length; ++i)
  4206. {
  4207. var item=this.SubFrame[i];
  4208. if (this.IsHScreen) item.Frame.ChartBorder.Top=value;
  4209. else item.Frame.ChartBorder.Left=value;
  4210. }
  4211. }
  4212. if (IFrameSplitOperator.IsNumber(textWidth.Right) && this.AutoRightBorder)
  4213. {
  4214. var blank=0;
  4215. if (IFrameSplitOperator.IsNumber(this.AutoRightBorder.Blank)) blank=this.AutoRightBorder.Blank;
  4216. var value=textWidth.Right+blank;
  4217. if (IFrameSplitOperator.IsNumber(this.AutoRightBorder.MinWidth))
  4218. {
  4219. if (this.AutoRightBorder.MinWidth>value) value=this.AutoRightBorder.MinWidth;
  4220. }
  4221. if (this.IsHScreen) this.ChartBorder.Bottom=value;
  4222. else this.ChartBorder.Right=value;
  4223. for(var i=0; i<this.SubFrame.length; ++i)
  4224. {
  4225. var item=this.SubFrame[i];
  4226. if (this.IsHScreen) item.Frame.ChartBorder.Bottom=value;
  4227. else item.Frame.ChartBorder.Right=value;
  4228. }
  4229. }
  4230. }
  4231. for (var i in this.SubFrame)
  4232. {
  4233. var item = this.SubFrame[i];
  4234. if (item.Height <= 0) continue;
  4235. item.Frame.Draw();
  4236. }
  4237. this.SizeChange = false;
  4238. }
  4239. this.DrawLock = function ()
  4240. {
  4241. for (var i in this.SubFrame)
  4242. {
  4243. var item = this.SubFrame[i];
  4244. item.Frame.DrawLock();
  4245. }
  4246. }
  4247. this.DrawInsideHorizontal = function () {
  4248. for (var i in this.SubFrame) {
  4249. var item = this.SubFrame[i];
  4250. item.Frame.DrawInsideHorizontal();
  4251. }
  4252. }
  4253. this.DrawCustomHorizontal = function () //定制Y坐标
  4254. {
  4255. for (var i in this.SubFrame)
  4256. {
  4257. var item = this.SubFrame[i];
  4258. if (item.Frame.DrawCustomHorizontal) item.Frame.DrawCustomHorizontal();
  4259. }
  4260. }
  4261. this.DrawCustomVertical = function (event) //定制X坐标
  4262. {
  4263. for (var i in this.SubFrame)
  4264. {
  4265. var item = this.SubFrame[i];
  4266. item.Frame.DrawCustomVerticalEvent = event;
  4267. if (item.Frame.DrawCustomVertical) item.Frame.DrawCustomVertical();
  4268. }
  4269. }
  4270. this.SetSizeChage = function (sizeChange)
  4271. {
  4272. this.SizeChange = sizeChange;
  4273. for (var i in this.SubFrame)
  4274. {
  4275. var item = this.SubFrame[i];
  4276. item.Frame.SizeChange = sizeChange;
  4277. }
  4278. //画布的位置
  4279. this.Position =
  4280. {
  4281. X: this.ChartBorder.UIElement.offsetLeft,
  4282. Y: this.ChartBorder.UIElement.offsetTop,
  4283. W: this.ChartBorder.UIElement.clientWidth,
  4284. H: this.ChartBorder.UIElement.clientHeight
  4285. };
  4286. }
  4287. this.SetDrawOtherChart = function (callback) //在画完框架以后调用的扩展画法
  4288. {
  4289. for (var i in this.SubFrame)
  4290. {
  4291. var item = this.SubFrame[i];
  4292. item.Frame.DrawOtherChart = callback;
  4293. }
  4294. }
  4295. this.Snapshot=function(type)
  4296. {
  4297. if (type == 1) this.SnapshotImageData();
  4298. else this.SnapshotImagePath();
  4299. }
  4300. //图形快照
  4301. this.SnapshotImagePath = function ()
  4302. {
  4303. var self = this;
  4304. var width = this.ChartBorder.GetChartWidth();
  4305. var height = this.ChartBorder.GetChartHeight();
  4306. //JSConsole.Chart.Log('[HQTradeFrame::SnapshotImageData][ID=' + this.ChartBorder.UIElement.ID + '] invoke canvasToTempFilePath' + '(width=' + width + ',height=' + height + ')' + ' SnapshotStatus='+ this.SnapshotStatus);
  4307. //if (this.SnapshotStatus==1) return;
  4308. ++this.SnapshotID;
  4309. var id = this.SnapshotID;
  4310. this.SnapshotStatus=1;
  4311. if (this.Canvas && this.Canvas.DomNode) //新版2D画布
  4312. {
  4313. wx.canvasToTempFilePath({
  4314. x: 0,
  4315. y: 0,
  4316. width: width,
  4317. height: height,
  4318. canvas: this.Canvas.DomNode,
  4319. success: function (res) {
  4320. self.ScreenImagePath = res.tempFilePath;
  4321. self.SnapshotStatus = 0;
  4322. self.CurrentSnapshotID = id;
  4323. JSConsole.Chart.Log(`[HQTradeFrame::SnapshotImagePath] SnapshotID(${self.SnapshotID}, ${self.CurrentSnapshotID}), Path=${res.tempFilePath}`);
  4324. }
  4325. })
  4326. }
  4327. else
  4328. {
  4329. wx.canvasToTempFilePath({
  4330. x: 0,
  4331. y: 0,
  4332. width: width,
  4333. height: height,
  4334. canvasId: this.ChartBorder.UIElement.ID,
  4335. success: function (res) {
  4336. self.ScreenImagePath = res.tempFilePath;
  4337. self.SnapshotStatus = 0;
  4338. self.CurrentSnapshotID = id;
  4339. //JSConsole.Chart.Log('[HQTradeFrame::SnapshotImagePath] SnapshotID(' + self.SnapshotID + ',' + self.CurrentSnapshotID + ') Path ='+ res.tempFilePath);
  4340. }
  4341. })
  4342. }
  4343. }
  4344. this.SnapshotImageData=function()
  4345. {
  4346. var self = this;
  4347. var width = this.ChartBorder.GetChartWidth();
  4348. var height = this.ChartBorder.GetChartHeight();
  4349. JSConsole.Chart.Log(`[HQTradeFrame::SnapshotImageData][ID=${this.ChartBorder.UIElement.ID} invoke canvasGetImageData(${width}, ${height}) SnapshotStatus=${this.SnapshotStatus}`);
  4350. ++this.SnapshotID;
  4351. var id = this.SnapshotID;
  4352. this.SnapshotStatus = 1;
  4353. wx.canvasGetImageData({
  4354. canvasId: this.ChartBorder.UIElement.ID,
  4355. x: 0,
  4356. y: 0,
  4357. width: width,
  4358. height: height,
  4359. success(res)
  4360. {
  4361. self.ScreenImageData = res.data;
  4362. self.SnapshotStatus = 0;
  4363. self.CurrentSnapshotID = id;
  4364. JSConsole.Chart.Log(`[HQTradeFrame::SnapshotImageData] SnapshotID=${self.SnapshotID}, CurrentSnapshotID=${self.CurrentSnapshotID}, size=${res.data.length}`);
  4365. }
  4366. })
  4367. }
  4368. this.GetXData = function (x) { return this.SubFrame[0].Frame.GetXData(x); }
  4369. this.GetYData = function (y, outObject) //outObject 可以保存返回的额外数据)
  4370. {
  4371. var frame;
  4372. for (var i in this.SubFrame)
  4373. {
  4374. var item = this.SubFrame[i];
  4375. var left = item.Frame.ChartBorder.GetLeft();
  4376. var top = item.Frame.ChartBorder.GetTopEx();
  4377. var width = item.Frame.ChartBorder.GetWidth();
  4378. var height = item.Frame.ChartBorder.GetHeightEx();
  4379. var rtItem = new Rect(left, top, width, height);
  4380. if (rtItem.IsPointIn(left, y))
  4381. {
  4382. frame = item.Frame;
  4383. if (outObject) outObject.FrameID = i;
  4384. break;
  4385. }
  4386. }
  4387. if (frame != null)
  4388. {
  4389. var yValue=frame.GetYData(y);
  4390. if (frame.YSplitOperator.CoordinateType == 1) //百分比坐标 右边显示百分比信息
  4391. {
  4392. var firstOpenPrice = frame.YSplitOperator.GetFirstOpenPrice();
  4393. outObject.RightYValue = ((yValue - firstOpenPrice) / firstOpenPrice * 100).toFixed(2) + '%';
  4394. }
  4395. return yValue;
  4396. }
  4397. }
  4398. this.GetXFromIndex = function (index) { return this.SubFrame[0].Frame.GetXFromIndex(index); }
  4399. this.GetYFromData = function (value) { return this.SubFrame[0].Frame.GetYFromData(value); }
  4400. this.PtInFrame=function(x,y) //鼠标哪个指标窗口
  4401. {
  4402. for(var i=0; i<this.SubFrame.length; ++i)
  4403. {
  4404. var item=this.SubFrame[i];
  4405. var left=item.Frame.ChartBorder.GetLeft();
  4406. var top=item.Frame.ChartBorder.GetTop();
  4407. var width=item.Frame.ChartBorder.GetWidth();
  4408. var height=item.Frame.ChartBorder.GetHeight();
  4409. var rtClient = new Rect(left, top, width, height);
  4410. var isInClient = rtClient.IsPointIn(x, y);
  4411. if (isInClient)
  4412. {
  4413. return i; //转成整形
  4414. }
  4415. }
  4416. return -1;
  4417. }
  4418. this.ZoomUp = function (cursorIndex)
  4419. {
  4420. var result = this.SubFrame[0].Frame.ZoomUp(cursorIndex);
  4421. this.UpdateAllFrame();
  4422. return result;
  4423. }
  4424. this.ZoomDown = function (cursorIndex)
  4425. {
  4426. var result = this.SubFrame[0].Frame.ZoomDown(cursorIndex);
  4427. this.UpdateAllFrame();
  4428. return result;
  4429. }
  4430. this.SetDataWidth=function(dataWidth)
  4431. {
  4432. var obj=this.SubFrame[0].Frame.SetDataWidth(dataWidth);
  4433. this.UpdateAllFrame();
  4434. return obj;
  4435. }
  4436. this.OnSize=function()
  4437. {
  4438. var obj={};
  4439. this.SubFrame[0].Frame.OnSize(obj);
  4440. this.UpdateAllFrame();
  4441. return obj;
  4442. }
  4443. this.UpdateAllFrame=function()
  4444. {
  4445. var mainFrame=this.SubFrame[0].Frame;
  4446. for (var i = 1; i < this.SubFrame.length; ++i)
  4447. {
  4448. var item=this.SubFrame[i];
  4449. item.Frame.XPointCount = mainFrame.XPointCount;
  4450. item.Frame.ZoomIndex = mainFrame.ZoomIndex;
  4451. item.Frame.DataWidth = mainFrame.DataWidth;
  4452. item.Frame.DistanceWidth = mainFrame.DistanceWidth;
  4453. item.Frame.LastCalculateStatus.Width=mainFrame.LastCalculateStatus.Width;
  4454. item.Frame.LastCalculateStatus.XPointCount=mainFrame.LastCalculateStatus.XPointCount;
  4455. }
  4456. }
  4457. //设置重新计算刻度坐标
  4458. this.ResetXYSplit = function ()
  4459. {
  4460. for (let i in this.SubFrame)
  4461. {
  4462. this.SubFrame[i].Frame.XYSplit = true;
  4463. }
  4464. }
  4465. this.GetCurrentPageSize = function () //获取当前页显示的数据个数
  4466. {
  4467. if (this.SubFrame.length <= 0) return null;
  4468. var item = this.SubFrame[0];
  4469. if (!item || !item.Frame) return null;
  4470. return item.Frame.XPointCount;
  4471. }
  4472. this.ClearCoordinateText=function(option) //清空X,Y轴刻度文字, 线段保留
  4473. {
  4474. for(var i=0;i<this.SubFrame.length;++i)
  4475. {
  4476. var item=this.SubFrame[i];
  4477. if (!item.Frame) continue;
  4478. item.Frame.ClearCoordinateText(option);
  4479. }
  4480. }
  4481. this.RestoreIndexWindows=function()
  4482. {
  4483. if (!this.ZoomWindowsInfo) return false;
  4484. var subFrame=this.SubFrame[this.ZoomWindowsInfo.FrameID];
  4485. for(var i=this.ZoomStartWindowIndex;i<this.ZoomWindowsInfo.Data.length; ++i)
  4486. {
  4487. var restoreItem=this.ZoomWindowsInfo.Data[i];
  4488. var frameItem=this.SubFrame[i];
  4489. frameItem.Height=restoreItem.Height;
  4490. frameItem.Frame.IsMinSize=false;
  4491. frameItem.Frame.XSplitOperator.ShowText=restoreItem.ShowXText;
  4492. frameItem.Frame.XYSplit=true;
  4493. }
  4494. this.ZoomWindowsInfo=null;
  4495. return true;
  4496. }
  4497. this.ZoomIndexWindow=function(frameID, option)
  4498. {
  4499. var subFrame=this.SubFrame[frameID];
  4500. if (!subFrame) return false;
  4501. if (this.ZoomWindowsInfo) //还原
  4502. {
  4503. return this.RestoreIndexWindows();
  4504. }
  4505. else //放大
  4506. {
  4507. var zoomInfo={ FrameID:frameID, Data:[] }; //备份下放大前各个窗口的高度
  4508. for(var i=0; i<this.SubFrame.length; ++i)
  4509. {
  4510. var item=this.SubFrame[i];
  4511. zoomInfo.Data[i]={ Height:item.Height, ShowXText:item.Frame.XSplitOperator.ShowText };
  4512. }
  4513. this.ZoomWindowsInfo=zoomInfo;
  4514. var totalHeight=0;
  4515. for(var i=this.ZoomStartWindowIndex;i<this.SubFrame.length;++i)
  4516. {
  4517. var item=this.SubFrame[i];
  4518. var frame=item.Frame;
  4519. frame.XYSplit=true;
  4520. totalHeight+=item.Height;
  4521. if (i!=frameID)
  4522. {
  4523. item.Height=0;
  4524. frame.IsMinSize=true; //最小化
  4525. frame.XSplitOperator.ShowText=false;
  4526. }
  4527. }
  4528. subFrame.Height=totalHeight;
  4529. subFrame.Frame.XSplitOperator.ShowText=true;
  4530. return true;
  4531. }
  4532. }
  4533. }
  4534. //行情框架横屏
  4535. function HQTradeHScreenFrame() {
  4536. this.newMethod = HQTradeFrame; //派生
  4537. this.newMethod();
  4538. delete this.newMethod;
  4539. this.ClassName='HQTradeHScreenFrame';
  4540. this.IsHScreen = true; //是否是横屏
  4541. this.CalculateChartBorder = function () //计算每个子框架的边框信息
  4542. {
  4543. if (this.SubFrame.length <= 0) return;
  4544. var right = this.ChartBorder.Right;
  4545. var left = this.ChartBorder.GetRight();
  4546. var width = this.ChartBorder.GetWidth();
  4547. var totalHeight = 0;
  4548. for (var i in this.SubFrame) {
  4549. var item = this.SubFrame[i];
  4550. totalHeight += item.Height;
  4551. }
  4552. for (var i in this.SubFrame) {
  4553. var item = this.SubFrame[i];
  4554. item.Frame.ChartBorder.Top = this.ChartBorder.Top;
  4555. item.Frame.ChartBorder.Bottom = this.ChartBorder.Bottom;
  4556. var frameWidth = width * (item.Height / totalHeight);
  4557. item.Frame.ChartBorder.Right = right;
  4558. item.Frame.ChartBorder.Left = left - frameWidth;
  4559. right += frameWidth;
  4560. left -= frameWidth;
  4561. }
  4562. }
  4563. this.GetYData = function (x, outObject) {
  4564. var frame;
  4565. for (var i in this.SubFrame) {
  4566. var item = this.SubFrame[i];
  4567. var left = item.Frame.ChartBorder.GetLeftEx();
  4568. var top = item.Frame.ChartBorder.GetTop();
  4569. var width = item.Frame.ChartBorder.GetWidthEx();
  4570. var height = item.Frame.ChartBorder.GetHeight();
  4571. var rtItem = new Rect(left, top, width, height);
  4572. if (rtItem.IsPointIn(x, top)) {
  4573. frame = item.Frame;
  4574. if (outObject) outObject.FrameID = i;
  4575. break;
  4576. }
  4577. }
  4578. if (frame != null) return frame.GetYData(x);
  4579. }
  4580. }
  4581. //深度图框架
  4582. function DepthChartFrame()
  4583. {
  4584. this.newMethod=AverageWidthFrame; //派生
  4585. this.newMethod();
  4586. delete this.newMethod;
  4587. this.ScreenImageData; //截图
  4588. this.Position; //画布的位置
  4589. this.ClassName="DepthChartFrame";
  4590. //X轴价格 最大,最小
  4591. this.VerticalRange={ Max:null, Min:null, Center:null, MaxDiffer:null, Differ:null, Step:0.05 };
  4592. this.AskPrice;
  4593. this.BidPrice;
  4594. this.MinZoom=0.05; //最小缩放
  4595. this.SetPriceList=function(aryAskPrice, aryBidPrice)
  4596. {
  4597. this.AskPrice=aryAskPrice;
  4598. this.BidPrice=aryBidPrice;
  4599. }
  4600. this.SetDrawOtherChart = function (callback) //在画完框架以后调用的扩展画法
  4601. {
  4602. }
  4603. this.DrawFrame=function()
  4604. {
  4605. this.SplitXYCoordinate();
  4606. this.DrawHorizontal();
  4607. this.DrawVertical();
  4608. }
  4609. this.GetXFromIndex=function(value)
  4610. {
  4611. var left=this.ChartBorder.GetLeft();
  4612. var right=this.ChartBorder.GetRight();
  4613. var width=this.ChartBorder.GetWidth();
  4614. var offset=width*(value-this.VerticalRange.Min)/(this.VerticalRange.Max-this.VerticalRange.Min);
  4615. return left+offset;
  4616. }
  4617. this.GetXData=function(x)
  4618. {
  4619. var left=this.ChartBorder.GetLeft();
  4620. var right=this.ChartBorder.GetRight();
  4621. var width=this.ChartBorder.GetWidth();
  4622. return (x-left)/width*(this.VerticalRange.Max-this.VerticalRange.Min)+this.VerticalRange.Min;
  4623. }
  4624. this.GetXFromPrice=function(price)
  4625. {
  4626. var isAskPrice=false;
  4627. var find=this.GetPrice(this.BidPrice, price);
  4628. if (find==null)
  4629. {
  4630. find=this.GetPrice(this.AskPrice, price);
  4631. isAskPrice=true;
  4632. }
  4633. if (find==null)
  4634. {
  4635. if (this.BidPrice && Array.isArray(this.BidPrice) && this.BidPrice.length>0)
  4636. {
  4637. var minPrice=this.BidPrice[0];
  4638. if (price<minPrice)
  4639. {
  4640. isAskPrice=false;
  4641. find= minPrice;
  4642. }
  4643. }
  4644. }
  4645. if (find==null)
  4646. {
  4647. if (this.AskPrice && Array.isArray(this.AskPrice) && this.AskPrice.length>0)
  4648. {
  4649. var maxPrice=this.AskPrice[this.AskPrice.length-1];
  4650. if (price>maxPrice)
  4651. {
  4652. isAskPrice=true;
  4653. find=maxPrice;
  4654. }
  4655. }
  4656. }
  4657. if (find==null) return null;
  4658. var x=this.GetXFromIndex(find);
  4659. return { X:x, Price:find, IsAsk:isAskPrice };
  4660. }
  4661. this.GetPrice=function(aryPrice, price)
  4662. {
  4663. if (!aryPrice || !Array.isArray(aryPrice) || aryPrice.length<=0) return null;
  4664. if (price<aryPrice[0] || price>aryPrice[aryPrice.length-1]) return null;
  4665. var lastPrice=null;
  4666. for(var i in aryPrice)
  4667. {
  4668. var item=aryPrice[i];
  4669. if (price==item)
  4670. {
  4671. return item;
  4672. }
  4673. if (price<item)
  4674. return lastPrice;
  4675. lastPrice=item;
  4676. }
  4677. }
  4678. //分割x,y轴坐标信息
  4679. this.SplitXYCoordinate=function()
  4680. {
  4681. if (this.XYSplit==false) return;
  4682. if (this.YSplitOperator!=null) this.YSplitOperator.Operator();
  4683. if (this.XSplitOperator!=null) this.XSplitOperator.Operator();
  4684. }
  4685. //图形快照
  4686. this.Snapshot=function()
  4687. {
  4688. this.ScreenImageData=this.Canvas.getImageData(0,0,this.ChartBorder.GetChartWidth(),this.ChartBorder.GetChartHeight());
  4689. }
  4690. this.SetSizeChage=function(sizeChange)
  4691. {
  4692. this.SizeChange=sizeChange;
  4693. //画布的位置
  4694. this.Position={
  4695. X:this.ChartBorder.UIElement.offsetLeft,
  4696. Y:this.ChartBorder.UIElement.offsetTop,
  4697. W:this.ChartBorder.UIElement.clientWidth,
  4698. H:this.ChartBorder.UIElement.clientHeight
  4699. };
  4700. }
  4701. this.ZoomUp=function() //放大
  4702. {
  4703. var xRange=this.VerticalRange;
  4704. var differ=xRange.Differ;
  4705. var minDiffer=xRange.MaxDiffer*this.MinZoom;
  4706. if (differ<minDiffer) return false;
  4707. var offsetDiffer=xRange.Differ*xRange.Step;
  4708. differ-=offsetDiffer;
  4709. xRange.Differ=differ;
  4710. xRange.Min=xRange.Center-xRange.Differ;
  4711. xRange.Max=xRange.Center+xRange.Differ;
  4712. return true;
  4713. }
  4714. this.ZoomDown=function() //缩小
  4715. {
  4716. var xRange=this.VerticalRange;
  4717. var differ=xRange.Differ;
  4718. if (differ==xRange.MaxDiffer) return false;
  4719. var offsetDiffer=xRange.Differ*xRange.Step;
  4720. differ+=offsetDiffer;
  4721. if (differ>xRange.MaxDiffer) differ=xRange.MaxDiffer;
  4722. xRange.Differ=differ;
  4723. xRange.Min=xRange.Center-xRange.Differ;
  4724. xRange.Max=xRange.Center+xRange.Differ;
  4725. return true;
  4726. }
  4727. }
  4728. //一般的图形框架
  4729. function SimpleChartFrame() {
  4730. this.newMethod = AverageWidthFrame; //派生
  4731. this.newMethod();
  4732. delete this.newMethod;
  4733. this.ScreenImageData; //截图
  4734. this.Position; //画布的位置
  4735. this.IsShowBorder = false; //是否显示边框
  4736. this.IsShowVertical = false; //是否显示X轴
  4737. this.XFontType = 0; //X轴文本文字类型
  4738. this.MaxDistanceWidth = 4;
  4739. this.BarCount = 0; //多柱子个数
  4740. this.Draw = function () {
  4741. this.DrawFrame();
  4742. if (this.IsShowBorder) this.DrawBorder();
  4743. this.SizeChange = false;
  4744. this.XYSplit = false;
  4745. }
  4746. this.DrawFrame = function () {
  4747. if (this.XPointCount > 0) {
  4748. let dInterval = this.ChartBorder.GetWidth() / (10 * this.XPointCount); //分6份, 数据4 间距2
  4749. this.DistanceWidth = 4 * dInterval;
  4750. this.DataWidth = 6 * dInterval;
  4751. if (this.DistanceWidth > this.MaxDistanceWidth) {
  4752. this.DistanceWidth = this.MaxDistanceWidth;
  4753. dInterval = this.ChartBorder.GetWidth() / this.XPointCount;
  4754. this.DataWidth = dInterval - this.MaxDistanceWidth;
  4755. }
  4756. }
  4757. this.SplitXYCoordinate();
  4758. this.DrawHorizontal();
  4759. this.DrawVertical();
  4760. }
  4761. this.GetXFromIndex = function (index) {
  4762. if (index < 0) index = 0;
  4763. if (index > this.xPointCount - 1) index = this.xPointCount - 1;
  4764. var offset = this.ChartBorder.GetLeft() + 2 + this.DistanceWidth / 2 + this.DataWidth / 2;
  4765. for (var i = 1; i <= index; ++i) {
  4766. offset += this.DistanceWidth + this.DataWidth;
  4767. }
  4768. return offset;
  4769. }
  4770. //分割x,y轴坐标信息
  4771. this.SplitXYCoordinate = function () {
  4772. if (this.XYSplit == false) return;
  4773. if (this.YSplitOperator != null) this.YSplitOperator.Operator();
  4774. if (this.XSplitOperator != null) this.XSplitOperator.Operator();
  4775. }
  4776. //画X轴
  4777. this.DrawVertical = function () {
  4778. var top = this.ChartBorder.GetTopEx();
  4779. var bottom = this.ChartBorder.GetBottom();
  4780. var right = this.ChartBorder.GetRight();
  4781. var xPrev = null; //上一个坐标x的值
  4782. for (var i in this.VerticalInfo) {
  4783. var x = this.GetXFromIndex(this.VerticalInfo[i].Value);
  4784. if (x >= right) break;
  4785. if (this.XFontType == 1) {
  4786. if (xPrev != null && Math.abs(x - xPrev) < 20) continue;
  4787. }
  4788. else {
  4789. if (xPrev != null && Math.abs(x - xPrev) < 60) continue;
  4790. }
  4791. if (this.IsShowVertical) {
  4792. this.Canvas.setStrokeStyle(this.VerticalInfo[i].LineColor);
  4793. this.Canvas.beginPath();
  4794. this.Canvas.moveTo(ToFixedPoint(x), top);
  4795. this.Canvas.lineTo(ToFixedPoint(x), bottom);
  4796. this.Canvas.stroke();
  4797. }
  4798. if (this.VerticalInfo[i].Message[0] != null) {
  4799. if (this.VerticalInfo[i].Font != null)
  4800. this.Canvas.font = this.VerticalInfo[i].Font;
  4801. this.Canvas.setFillStyle(this.VerticalInfo[i].TextColor);
  4802. var testWidth = this.Canvas.measureText(this.VerticalInfo[i].Message[0]).width;
  4803. if (x < testWidth / 2) {
  4804. this.Canvas.textAlign = "left";
  4805. this.Canvas.textBaseline = "top";
  4806. }
  4807. else {
  4808. this.Canvas.textAlign = "center";
  4809. this.Canvas.textBaseline = "top";
  4810. }
  4811. if (this.XFontType == 1) {
  4812. this.Canvas.textAlign = "left";
  4813. this.Canvas.textBaseline = "middle";
  4814. this.Canvas.save();
  4815. this.Canvas.translate(x, bottom);
  4816. this.Canvas.rotate(90 * Math.PI / 180);
  4817. this.Canvas.fillText(this.VerticalInfo[i].Message[0], 2, 0);
  4818. this.Canvas.restore();
  4819. }
  4820. else
  4821. this.Canvas.fillText(this.VerticalInfo[i].Message[0], x, bottom);
  4822. }
  4823. xPrev = x;
  4824. }
  4825. }
  4826. //图形快照
  4827. this.Snapshot = function () {
  4828. var self = this;
  4829. var width = this.ChartBorder.GetChartWidth();
  4830. var height = this.ChartBorder.GetChartHeight();
  4831. JSConsole.Chart.Log('[SimpleChartFrame::Snapshot][ID=' + this.ChartBorder.UIElement.ID + '] invoke canvasToTempFilePath' + '(width=' + width + ',height=' + height + ')');
  4832. wx.canvasToTempFilePath({
  4833. x: 0,
  4834. y: 0,
  4835. width: width,
  4836. height: height,
  4837. canvasId: this.ChartBorder.UIElement.ID,
  4838. success: function (res) {
  4839. self.ScreenImagePath = res.tempFilePath;
  4840. JSConsole.Chart.Log(res.tempFilePath)
  4841. }
  4842. })
  4843. }
  4844. this.SetSizeChage = function (sizeChange) {
  4845. this.SizeChange = sizeChange;
  4846. //画布的位置
  4847. this.Position = {
  4848. X: this.ChartBorder.UIElement.offsetLeft,
  4849. Y: this.ChartBorder.UIElement.offsetTop,
  4850. W: this.ChartBorder.UIElement.clientWidth,
  4851. H: this.ChartBorder.UIElement.clientHeight
  4852. };
  4853. }
  4854. }
  4855. //旋转90度坐标
  4856. function Rotate90SimpleChartFrame() {
  4857. this.newMethod = SimpleChartFrame; //派生
  4858. this.newMethod();
  4859. delete this.newMethod;
  4860. this.DrawFrame = function () {
  4861. if (this.XPointCount > 0) {
  4862. let dInterval = this.ChartBorder.GetHeightEx() / (10 * this.XPointCount); //分10份, 数据4 间距6
  4863. this.DistanceWidth = 4 * dInterval;
  4864. this.DataWidth = 6 * dInterval;
  4865. if (this.DistanceWidth > this.MaxDistanceWidth) {
  4866. this.DistanceWidth = this.MaxDistanceWidth;
  4867. dInterval = this.ChartBorder.GetHeightEx() / this.XPointCount;
  4868. this.DataWidth = dInterval - this.MaxDistanceWidth;
  4869. }
  4870. }
  4871. this.SplitXYCoordinate();
  4872. this.DrawHorizontal();
  4873. this.DrawVertical();
  4874. }
  4875. this.GetXFromIndex = function (value) {
  4876. if (value <= this.HorizontalMin) return this.ChartBorder.GetLeft();
  4877. if (value >= this.HorizontalMax) return this.ChartBorder.GetRight();
  4878. var width = this.ChartBorder.GetWidth() * (value - this.HorizontalMin) / (this.HorizontalMax - this.HorizontalMin);
  4879. return this.ChartBorder.GetLeft() + width;
  4880. }
  4881. this.GetYFromData = function (index) {
  4882. if (index < 0) index = 0;
  4883. if (index > this.xPointCount - 1) index = this.xPointCount - 1;
  4884. var offset = this.ChartBorder.GetBottom() - 2 - this.DistanceWidth / 2 - this.DataWidth / 2;
  4885. for (var i = 1; i <= index; ++i) {
  4886. offset -= this.DistanceWidth + this.DataWidth;
  4887. }
  4888. return offset;
  4889. }
  4890. //画Y轴
  4891. this.DrawHorizontal = function () {
  4892. var top = this.ChartBorder.GetTopEx();
  4893. var bottom = this.ChartBorder.GetBottom();
  4894. var right = this.ChartBorder.GetRight();
  4895. var left = this.ChartBorder.GetLeft();
  4896. var yPrev = null; //上一个坐标y的值
  4897. for (var i in this.VerticalInfo) {
  4898. let item = this.VerticalInfo[i];
  4899. var y = this.GetYFromData(item.Value);
  4900. if (y != null && yPrev != null && Math.abs(y - yPrev) < 15) continue; //两个坐标在近了 就不画了
  4901. if (item.Message[0] != null) {
  4902. if (this.VerticalInfo[i].Font != null)
  4903. this.Canvas.font = item.Font;
  4904. this.Canvas.setFillStyle(item.TextColor);
  4905. this.Canvas.textAlign = "right";
  4906. this.Canvas.textBaseline = "middle";
  4907. this.Canvas.fillText(item.Message[0], left - 2, y);
  4908. }
  4909. yPrev = y;
  4910. }
  4911. }
  4912. //画X轴
  4913. this.DrawVertical = function () {
  4914. var top = this.ChartBorder.GetTopEx();
  4915. var bottom = this.ChartBorder.GetBottom();
  4916. var right = this.ChartBorder.GetRight();
  4917. var left = this.ChartBorder.GetLeft();
  4918. var yText = bottom;
  4919. if (this.XMessageAlign == 'bottom')
  4920. yText = this.ChartBorder.GetChartHeight();
  4921. else this.XMessageAlign = 'top';
  4922. var xPrev = null; //上一个坐标x的值
  4923. let xPrevTextRight = null;
  4924. for (var i in this.HorizontalInfo) {
  4925. let item = this.HorizontalInfo[i];
  4926. var x = this.GetXFromIndex(item.Value);
  4927. if (x > right) break;
  4928. if (xPrev != null && Math.abs(x - xPrev) < this.MinXDistance) continue;
  4929. if (this.IsShowXLine) {
  4930. this.Canvas.setStrokeStyle(item.LineColor);
  4931. this.Canvas.beginPath();
  4932. this.Canvas.moveTo(ToFixedPoint(x), top);
  4933. this.Canvas.lineTo(ToFixedPoint(x), bottom);
  4934. this.Canvas.stroke();
  4935. }
  4936. if (item.Message[0] != null) {
  4937. let xTextRight = null;
  4938. let xTextLeft = null;
  4939. if (item.Font != null)
  4940. this.Canvas.font = item.Font;
  4941. this.Canvas.setFillStyle(item.TextColor);
  4942. var testWidth = this.Canvas.measureText(item.Message[0]).width;
  4943. if (x < testWidth / 2) {
  4944. this.Canvas.textAlign = "left";
  4945. this.Canvas.textBaseline = this.XMessageAlign;
  4946. xTextRight = x + testWidth;
  4947. xTextLeft = x;
  4948. }
  4949. else {
  4950. this.Canvas.textAlign = "center";
  4951. this.Canvas.textBaseline = this.XMessageAlign;
  4952. xTextRight = x + testWidth / 2;
  4953. xTextLeft = x - testWidth / 2;
  4954. }
  4955. if (xPrevTextRight != null && xPrevTextRight > xTextLeft) continue;
  4956. //JSConsole.Chart.Log('[AverageWidthFrame::DrawVertical]', this.Canvas.fillStyle,x, yText);
  4957. this.Canvas.fillText(item.Message[0], x, yText);
  4958. xPrevTextRight = xTextRight;
  4959. }
  4960. xPrev = x;
  4961. }
  4962. }
  4963. }
  4964. function TooltipData() //提示信息
  4965. {
  4966. this.ChartPaint;
  4967. this.Data;
  4968. }
  4969. //缩放因子
  4970. var ZOOM_SEED = //0=柱子宽度 1=间距
  4971. [
  4972. [48, 10], [44, 10],
  4973. [40, 9], [36, 9],
  4974. [32, 8], [28, 8],
  4975. [24, 7], [20, 7],
  4976. [18, 6], [16, 6],
  4977. [14, 5], [12, 5],
  4978. [8, 4], [4, 4], [3, 3],
  4979. [3, 1], [2,1], [1,1], [1,0]
  4980. /*
  4981. [49, 10], [46, 9], [43, 8],
  4982. [41, 7.5], [39, 7], [37, 6],
  4983. [31, 5.5], [27, 5], [23, 4.5],
  4984. [21, 4], [18, 3.5], [16, 3],
  4985. [13, 2.5], [11, 2], [8, 1.5],
  4986. [6, 1], [3, 0.6], [2.2, 0.5],
  4987. */
  4988. //太多了卡,
  4989. //[1.1,0.3],
  4990. //[0.9,0.2], [0.7,0.15],
  4991. //[0.6,0.12], [0.5,0.1], [0.4,0.08],
  4992. //[0.3,0.06], [0.2,0.04], [0.1,0.02]
  4993. ];
  4994. //线段 多数据(一个X点有多条Y数据) 支持横屏
  4995. function ChartLineMultiData() {
  4996. this.newMethod = IChartPainting; //派生
  4997. this.newMethod();
  4998. delete this.newMethod;
  4999. this.Color = "rgb(255,193,37)"; //线段颜色
  5000. this.Draw = function () {
  5001. if (this.NotSupportMessage) {
  5002. this.DrawNotSupportmessage();
  5003. return;
  5004. }
  5005. if (!this.Data || !this.Data.Data) return;
  5006. var isHScreen = (this.ChartFrame.IsHScreen === true);
  5007. var dataWidth = this.ChartFrame.DataWidth;
  5008. var distanceWidth = this.ChartFrame.DistanceWidth;
  5009. var chartright = this.ChartBorder.GetRight();
  5010. if (isHScreen) chartright = this.ChartBorder.GetBottom();
  5011. var xPointCount = this.ChartFrame.XPointCount;
  5012. var bFirstPoint = true;
  5013. var drawCount = 0;
  5014. for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j) {
  5015. var aryValue = this.Data.Data[i];
  5016. if (aryValue == null) continue;
  5017. var x = this.ChartFrame.GetXFromIndex(j);
  5018. if (x > chartright) break;
  5019. for (var index in aryValue) {
  5020. var value = aryValue[index].Value;
  5021. var y = this.ChartFrame.GetYFromData(value);
  5022. if (bFirstPoint) {
  5023. this.Canvas.setStrokeStyle(this.Color);
  5024. this.Canvas.beginPath();
  5025. if (isHScreen) this.Canvas.moveTo(y, x);
  5026. else this.Canvas.moveTo(x, y);
  5027. bFirstPoint = false;
  5028. }
  5029. else {
  5030. if (isHScreen) this.Canvas.lineTo(y, x);
  5031. else this.Canvas.lineTo(x, y);
  5032. }
  5033. ++drawCount;
  5034. }
  5035. }
  5036. if (drawCount > 0) this.Canvas.stroke();
  5037. }
  5038. this.GetMaxMin = function () {
  5039. var xPointCount = this.ChartFrame.XPointCount;
  5040. var range = {};
  5041. range.Min = null;
  5042. range.Max = null;
  5043. if (!this.Data || !this.Data.Data) return range;
  5044. for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j) {
  5045. var aryValue = this.Data.Data[i];
  5046. if (aryValue == null) continue;
  5047. for (var index in aryValue) {
  5048. var value = aryValue[index].Value;
  5049. if (range.Max == null) range.Max = value;
  5050. if (range.Min == null) range.Min = value;
  5051. if (range.Max < value) range.Max = value;
  5052. if (range.Min > value) range.Min = value;
  5053. }
  5054. }
  5055. return range;
  5056. }
  5057. }
  5058. //直线 水平直线 只有1个数据 支持横屏
  5059. function ChartStraightLine() {
  5060. this.newMethod = IChartPainting; //派生
  5061. this.newMethod();
  5062. delete this.newMethod;
  5063. this.Color = "rgb(255,193,37)"; //线段颜色
  5064. this.Draw = function () {
  5065. if (!this.Data || !this.Data.Data) return;
  5066. if (this.Data.Data.length != 1) return;
  5067. var isHScreen = this.ChartFrame.IsHScreen;
  5068. var dataWidth = this.ChartFrame.DataWidth;
  5069. var distanceWidth = this.ChartFrame.DistanceWidth;
  5070. var chartright = this.ChartBorder.GetRight();
  5071. if (isHScreen) chartright = this.ChartBorder.GetTop();
  5072. var xPointCount = this.ChartFrame.XPointCount;
  5073. var yValue = this.Data.Data[0];
  5074. var y = this.ChartFrame.GetYFromData(yValue);
  5075. var xLeft = this.ChartFrame.GetXFromIndex(0);
  5076. var xRight = this.ChartFrame.GetXFromIndex(xPointCount - 1);
  5077. var yFix = parseInt(y.toString()) + 0.5;
  5078. this.Canvas.beginPath();
  5079. if (isHScreen) {
  5080. this.Canvas.moveTo(yFix, xLeft);
  5081. this.Canvas.lineTo(yFix, xRight);
  5082. }
  5083. else {
  5084. this.Canvas.moveTo(xLeft, yFix);
  5085. this.Canvas.lineTo(xRight, yFix);
  5086. }
  5087. this.Canvas.setStrokeStyle(this.Color);
  5088. this.Canvas.stroke();
  5089. }
  5090. this.GetMaxMin = function () {
  5091. var xPointCount = this.ChartFrame.XPointCount;
  5092. var range = {};
  5093. range.Min = null;
  5094. range.Max = null;
  5095. if (!this.Data || !this.Data.Data) return range;
  5096. if (this.Data.Data.length != 1) return range;
  5097. range.Min = this.Data.Data[0];
  5098. range.Max = this.Data.Data[0];
  5099. return range;
  5100. }
  5101. }
  5102. //分钟线叠加 支持横屏
  5103. function ChartOverlayMinutePriceLine() {
  5104. this.newMethod = IChartPainting; //派生
  5105. this.newMethod();
  5106. delete this.newMethod;
  5107. this.Color = "rgb(65,105,225)";
  5108. this.MainData; //主图数据
  5109. this.MainYClose; //主图股票的前收盘价
  5110. this.Name = "ChartOverlayMinutePriceLine";
  5111. this.Title;
  5112. this.Symbol; //叠加的股票代码
  5113. this.YClose; //叠加的股票前收盘
  5114. this.Draw = function () {
  5115. if (this.NotSupportMessage) {
  5116. this.DrawNotSupportmessage();
  5117. return;
  5118. }
  5119. var isHScreen = (this.ChartFrame.IsHScreen === true);
  5120. var dataWidth = this.ChartFrame.DataWidth;
  5121. var distanceWidth = this.ChartFrame.DistanceWidth;
  5122. var chartright = this.ChartBorder.GetRight();
  5123. if (isHScreen === true) chartright = this.ChartBorder.GetBottom();
  5124. var xPointCount = this.ChartFrame.XPointCount;
  5125. var minuteCount = this.ChartFrame.MinuteCount;
  5126. var bFirstPoint = true;
  5127. var drawCount = 0;
  5128. for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j) {
  5129. var value = this.Data.Data[i].Close;
  5130. if (value == null) continue;
  5131. var showValue = value / this.YClose * this.MainYClose;
  5132. var x = this.ChartFrame.GetXFromIndex(j);
  5133. var y = this.ChartFrame.GetYFromData(showValue);
  5134. if (bFirstPoint) {
  5135. this.Canvas.setStrokeStyle(this.Color);
  5136. this.Canvas.beginPath();
  5137. if (isHScreen) this.Canvas.moveTo(y, x);
  5138. else this.Canvas.moveTo(x, y);
  5139. bFirstPoint = false;
  5140. }
  5141. else {
  5142. if (isHScreen) this.Canvas.lineTo(y, x);
  5143. else this.Canvas.lineTo(x, y);
  5144. }
  5145. ++drawCount;
  5146. if (drawCount >= minuteCount) //上一天的数据和这天地数据线段要断开
  5147. {
  5148. bFirstPoint = true;
  5149. this.Canvas.stroke();
  5150. drawCount = 0;
  5151. }
  5152. }
  5153. if (drawCount > 0) this.Canvas.stroke();
  5154. }
  5155. this.GetMaxMin = function () {
  5156. var xPointCount = this.ChartFrame.XPointCount;
  5157. var range = {};
  5158. if (this.YClose == null) return range;
  5159. range.Min = this.MainYClose;
  5160. range.Max = this.MainYClose;
  5161. for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j) {
  5162. var value = this.Data.Data[i].Close;
  5163. if (value == null) continue;
  5164. var value = value / this.YClose * this.MainYClose;
  5165. if (range.Max == null) range.Max = value;
  5166. if (range.Min == null) range.Min = value;
  5167. if (range.Max < value) range.Max = value;
  5168. if (range.Min > value) range.Min = value;
  5169. }
  5170. if (range.Max == this.MainYClose && range.Min == this.MainYClose) {
  5171. range.Max = this.MainYClose + this.MainYClose * 0.1;
  5172. range.Min = this.MainYClose - this.MainYClose * 0.1;
  5173. return range;
  5174. }
  5175. var distance = Math.max(Math.abs(this.MainYClose - range.Max), Math.abs(this.MainYClose - range.Min));
  5176. range.Max = this.MainYClose + distance;
  5177. range.Min = this.MainYClose - distance;
  5178. return range;
  5179. }
  5180. }
  5181. //基础图形的XY坐标互换柱子
  5182. function ChartXYSubBar() {
  5183. this.newMethod = ChartBar; //派生
  5184. this.newMethod();
  5185. delete this.newMethod;
  5186. this.BarID = 0;
  5187. this.Draw = function () {
  5188. if (this.NotSupportMessage) {
  5189. this.DrawNotSupportmessage();
  5190. return;
  5191. }
  5192. var dataWidth = this.ChartFrame.DataWidth;
  5193. var distanceWidth = this.ChartFrame.DistanceWidth;
  5194. var chartTop = this.ChartBorder.GetTopEx();
  5195. var xPointCount = this.ChartFrame.XPointCount;
  5196. var yOffset = this.ChartBorder.GetBottom() - distanceWidth / 2.0 - 2.0;
  5197. var xMiddle = this.ChartFrame.GetXFromIndex(0); //0 刻度
  5198. if (dataWidth >= 4) {
  5199. var barCount = this.ChartFrame.BarCount;
  5200. var subBarWidth = dataWidth;
  5201. var subBarOffset = 0;
  5202. if (barCount > 0) //多柱子需要把框架柱子宽度的平均分割
  5203. {
  5204. subBarWidth = dataWidth / barCount;
  5205. subBarOffset = subBarWidth * this.BarID;
  5206. //JSConsole.Chart.Log('[ChartXYSubBar::Draw] ', subBarWidth, this.BarID, subBarOffset);
  5207. }
  5208. xMiddle = ToFixedRect(xMiddle); //调整为整数
  5209. for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j, yOffset -= (dataWidth + distanceWidth)) {
  5210. var value = this.Data.Data[i];
  5211. if (value == null || value == 0) continue;
  5212. var yBottom = yOffset + subBarOffset;
  5213. var yTop = yOffset + subBarOffset - dataWidth;
  5214. if (yBottom < chartTop) break;
  5215. var x = this.ChartFrame.GetXFromIndex(value);
  5216. if (value > 0) {
  5217. this.Canvas.setFillStyle(this.UpBarColor);
  5218. let barWidth = ToFixedRect(Math.abs(x - xMiddle));
  5219. let barHeight = subBarWidth;
  5220. if (Math.abs(chartTop - yBottom) < dataWidth) subBarWidth = Math.abs(chartTop - yBottom); //最后一根柱子可能会超出框架
  5221. this.Canvas.fillRect(xMiddle, ToFixedRect(yTop), barWidth, ToFixedRect(barHeight + 0.5));
  5222. }
  5223. else {
  5224. this.Canvas.setFillStyle(this.DownBarColor);
  5225. //高度调整为整数
  5226. let barWidth = ToFixedRect(Math.abs(x - xMiddle));
  5227. let barHeight = subBarWidth;
  5228. if (Math.abs(chartTop - yBottom) < subBarWidth) barHeight = Math.abs(chartTop - yBottom); //最后一根柱子可能会超出框架
  5229. this.Canvas.fillRect(xMiddle, ToFixedRect(yTop), -barWidth, ToFixedRect(barHeight + 0.5));
  5230. }
  5231. }
  5232. }
  5233. else //太细了 直接画柱子
  5234. {
  5235. for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j, yOffset -= (dataWidth + distanceWidth)) {
  5236. var value = this.Data.Data[i];
  5237. if (value == null || value == 0) continue;
  5238. var yBottom = yOffset;
  5239. var yTop = yOffset - dataWidth;
  5240. if (yTop < chartTop) break;
  5241. var x = this.ChartFrame.GetXFromIndex(value);
  5242. var y = this.ChartFrame.GetYFromData(j);
  5243. if (value > 0) this.Canvas.setStrokeStyle(this.UpBarColor);
  5244. else this.Canvas.setStrokeStyle(this.DownBarColor);
  5245. this.Canvas.beginPath();
  5246. this.Canvas.moveTo(ToFixedPoint(x), y);
  5247. this.Canvas.lineTo(ToFixedPoint(xMiddle), y);
  5248. this.Canvas.stroke();
  5249. }
  5250. }
  5251. }
  5252. }
  5253. function ChartSubBar() {
  5254. this.newMethod = ChartBar; //派生
  5255. this.newMethod();
  5256. delete this.newMethod;
  5257. this.BarID = 0;
  5258. this.Draw = function () {
  5259. if (this.NotSupportMessage) {
  5260. this.DrawNotSupportmessage();
  5261. return;
  5262. }
  5263. var dataWidth = this.ChartFrame.DataWidth;
  5264. var distanceWidth = this.ChartFrame.DistanceWidth;
  5265. var chartright = this.ChartBorder.GetRight();
  5266. var xPointCount = this.ChartFrame.XPointCount;
  5267. var xOffset = this.ChartBorder.GetLeft() + distanceWidth / 2.0 + 2.0;
  5268. var yBottom = this.ChartFrame.GetYFromData(0);
  5269. if (dataWidth >= 4) {
  5270. var barCount = this.ChartFrame.BarCount;
  5271. var subBarWidth = dataWidth;
  5272. var subBarOffset = 0;
  5273. if (barCount > 0) //多柱子需要把框架柱子宽度的平均分割
  5274. {
  5275. subBarWidth = dataWidth / barCount;
  5276. subBarOffset = subBarWidth * this.BarID;
  5277. //JSConsole.Chart.Log('[ChartSubBar::Draw] ', subBarWidth, this.BarID, subBarOffset);
  5278. }
  5279. yBottom = ToFixedRect(yBottom); //调整为整数
  5280. for (let i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j, xOffset += (dataWidth + distanceWidth)) {
  5281. var value = this.Data.Data[i];
  5282. if (value == null || value == 0) continue;
  5283. var left = xOffset + subBarOffset
  5284. var right = xOffset + subBarOffset + subBarWidth;
  5285. if (left > chartright) break;
  5286. var x = this.ChartFrame.GetXFromIndex(j);
  5287. var y = this.ChartFrame.GetYFromData(value);
  5288. if (value > 0) {
  5289. this.Canvas.setFillStyle(this.UpBarColor);
  5290. //高度调整为整数
  5291. let height = ToFixedRect(Math.abs(yBottom - y));
  5292. let barWidth = subBarWidth;
  5293. if (chartright - left < subBarWidth) barWidth = chartright - left;
  5294. if (yBottom - y > 0) y = yBottom - height;
  5295. else y = yBottom + height;
  5296. this.Canvas.fillRect(ToFixedRect(left), y, ToFixedRect(barWidth), height);
  5297. }
  5298. else {
  5299. this.Canvas.setFillStyle(this.DownBarColor);
  5300. //高度调整为整数
  5301. let height = ToFixedRect(Math.abs(yBottom - y));
  5302. let barWidth = subBarWidth;
  5303. if (chartright - left < subBarWidth) barWidth = chartright - left;
  5304. if (yBottom - y > 0) y = yBottom - height;
  5305. else y = yBottom + height;
  5306. this.Canvas.fillRect(ToFixedRect(left), y, ToFixedRect(subBarWidth), -height);
  5307. }
  5308. }
  5309. }
  5310. else //太细了 直接画柱子
  5311. {
  5312. for (let i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j, xOffset += (dataWidth + distanceWidth)) {
  5313. var value = this.Data.Data[i];
  5314. if (value == null || value == 0) continue;
  5315. var left = xOffset;
  5316. var right = xOffset + dataWidth;
  5317. if (right > chartright) break;
  5318. var x = this.ChartFrame.GetXFromIndex(j);
  5319. var y = this.ChartFrame.GetYFromData(value);
  5320. if (value > 0) this.Canvas.setStrokeStyle(this.UpBarColor);
  5321. else this.Canvas.setStrokeStyle(this.DownBarColor);
  5322. this.Canvas.beginPath();
  5323. this.Canvas.moveTo(ToFixedPoint(x), y);
  5324. this.Canvas.lineTo(ToFixedPoint(x), yBottom);
  5325. this.Canvas.stroke();
  5326. }
  5327. }
  5328. }
  5329. }
  5330. //柱子 支持横屏
  5331. function ChartBar() {
  5332. this.newMethod = IChartPainting; //派生
  5333. this.newMethod();
  5334. delete this.newMethod;
  5335. this.UpBarColor = g_JSChartResource.UpBarColor;
  5336. this.DownBarColor = g_JSChartResource.DownBarColor;
  5337. this.Draw = function () {
  5338. if (this.NotSupportMessage) {
  5339. this.DrawNotSupportmessage();
  5340. return;
  5341. }
  5342. var isHScreen = (this.ChartFrame.IsHScreen === true);
  5343. var dataWidth = this.ChartFrame.DataWidth;
  5344. var distanceWidth = this.ChartFrame.DistanceWidth;
  5345. var chartright = this.ChartBorder.GetRight();
  5346. if (isHScreen) chartright = this.ChartBorder.GetBottom();
  5347. var xPointCount = this.ChartFrame.XPointCount;
  5348. var xOffset = this.ChartBorder.GetLeft() + distanceWidth / 2.0 + 2.0;
  5349. if (isHScreen) xOffset = this.ChartBorder.GetTop() + distanceWidth / 2.0 + 2.0;
  5350. var bFirstPoint = true;
  5351. var drawCount = 0;
  5352. var yBottom = this.ChartFrame.GetYFromData(0);
  5353. if (dataWidth >= 4) {
  5354. yBottom = ToFixedRect(yBottom); //调整为整数
  5355. for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j, xOffset += (dataWidth + distanceWidth)) {
  5356. var value = this.Data.Data[i];
  5357. if (value == null || value == 0) continue;
  5358. var left = xOffset;
  5359. var right = xOffset + dataWidth;
  5360. if (right > chartright) break;
  5361. var x = this.ChartFrame.GetXFromIndex(j);
  5362. var y = this.ChartFrame.GetYFromData(value);
  5363. if (value > 0) {
  5364. this.Canvas.setFillStyle(this.UpBarColor);
  5365. if (isHScreen) {
  5366. let height = ToFixedRect(Math.abs(yBottom - y)); //高度调整为整数
  5367. y = Math.min(yBottom, y);
  5368. this.Canvas.fillRect(y, ToFixedRect(left), height, ToFixedRect(dataWidth));
  5369. }
  5370. else {
  5371. let height = ToFixedRect(Math.abs(yBottom - y)); //高度调整为整数
  5372. if (yBottom - y > 0) y = yBottom - height;
  5373. else y = yBottom + height;
  5374. this.Canvas.fillRect(ToFixedRect(left), y, ToFixedRect(dataWidth), height);
  5375. }
  5376. }
  5377. else {
  5378. this.Canvas.setFillStyle(this.DownBarColor);
  5379. //高度调整为整数
  5380. let height = ToFixedRect(Math.abs(yBottom - y));
  5381. if (yBottom - y > 0) y = yBottom - height;
  5382. else y = yBottom + height;
  5383. this.Canvas.fillRect(ToFixedRect(left), y, ToFixedRect(dataWidth), -height);
  5384. }
  5385. }
  5386. }
  5387. else //太细了 直接画柱子
  5388. {
  5389. for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j, xOffset += (dataWidth + distanceWidth)) {
  5390. var value = this.Data.Data[i];
  5391. if (value == null || value == 0) continue;
  5392. var left = xOffset;
  5393. var right = xOffset + dataWidth;
  5394. if (right > chartright) break;
  5395. var x = this.ChartFrame.GetXFromIndex(j);
  5396. var y = this.ChartFrame.GetYFromData(value);
  5397. if (value > 0) this.Canvas.setStrokeStyle(this.UpBarColor);
  5398. else this.Canvas.setStrokeStyle(this.DownBarColor);
  5399. this.Canvas.beginPath();
  5400. if (isHScreen) {
  5401. this.Canvas.moveTo(y, ToFixedPoint(x));
  5402. this.Canvas.lineTo(yBottom, ToFixedPoint(x));
  5403. }
  5404. else {
  5405. this.Canvas.moveTo(ToFixedPoint(x), y);
  5406. this.Canvas.lineTo(ToFixedPoint(x), yBottom);
  5407. }
  5408. this.Canvas.stroke();
  5409. }
  5410. }
  5411. }
  5412. this.GetMaxMin = function () {
  5413. var xPointCount = this.ChartFrame.XPointCount;
  5414. var range = {};
  5415. range.Min = 0;
  5416. range.Max = null;
  5417. for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j) {
  5418. var value = this.Data.Data[i];
  5419. if (range.Max == null) range.Max = value;
  5420. if (range.Max < value) range.Max = value;
  5421. if (range.Min > value) range.Min = value;
  5422. }
  5423. return range;
  5424. }
  5425. }
  5426. /*
  5427. 画图工具
  5428. */
  5429. function IChartDrawPicture() {
  5430. this.Frame;
  5431. this.Canvas;
  5432. this.Point = new Array() //画图的点
  5433. this.Value = new Array(); //XValue,YValue
  5434. this.PointCount = 2; //画点的个数
  5435. this.Status = 0; //0 开始画 1 完成第1个点 2 完成第2个点 10 完成 20 移动
  5436. this.MovePointIndex = null; //移动哪个点 0-10 对应Point索引 100 整体移动
  5437. this.LineColor = g_JSChartResource.DrawPicture.LineColor[0]; //线段颜色
  5438. this.PointColor = g_JSChartResource.DrawPicture.PointColor[0];
  5439. this.Draw = function () {
  5440. }
  5441. //Point => Value
  5442. this.PointToValue = function () {
  5443. if (!this.Frame) return false;
  5444. var data = this.Frame.Data;
  5445. if (!data) return false;
  5446. for (var i in this.Point) {
  5447. var item = this.Point[i];
  5448. var xValue = parseInt(this.Frame.GetXData(item.X)) + data.DataOffset;
  5449. var yValue = this.Frame.GetYData(item.Y);
  5450. this.Value[i] = {};
  5451. this.Value[i].XValue = xValue;
  5452. this.Value[i].YValue = yValue;
  5453. }
  5454. return true;
  5455. }
  5456. this.IsPointIn = function (x, y) {
  5457. return false;
  5458. }
  5459. //Value => Point
  5460. this.ValueToPoint = function () {
  5461. if (!this.Frame) return false;
  5462. var data = this.Frame.Data;
  5463. if (!data) return false;
  5464. this.Point = [];
  5465. for (var i in this.Value) {
  5466. var item = this.Value[i];
  5467. var pt = new Point();
  5468. pt.X = this.Frame.GetXFromIndex(item.XValue - data.DataOffset);
  5469. pt.Y = this.Frame.GetYFromData(item.YValue);
  5470. this.Point[i] = pt;
  5471. }
  5472. }
  5473. //xStep,yStep 移动的偏移量
  5474. this.Move = function (xStep, yStep) {
  5475. if (this.Status != 20) return fasle;
  5476. if (!this.Frame) return false;
  5477. var data = this.Frame.Data;
  5478. if (!data) return false;
  5479. if (this.MovePointIndex == 100) //整体移动
  5480. {
  5481. for (var i in this.Point) {
  5482. this.Point[i].X += xStep;
  5483. this.Point[i].Y += yStep;
  5484. }
  5485. }
  5486. else if (this.MovePointIndex == 0 || this.MovePointIndex == 1) {
  5487. this.Point[this.MovePointIndex].X += xStep;
  5488. this.Point[this.MovePointIndex].Y += yStep;
  5489. }
  5490. }
  5491. this.ClipFrame = function () {
  5492. var left = this.Frame.ChartBorder.GetLeft();
  5493. var top = this.Frame.ChartBorder.GetTopEx();
  5494. var width = this.Frame.ChartBorder.GetWidth();
  5495. var height = this.Frame.ChartBorder.GetHeightEx();
  5496. this.Canvas.save();
  5497. this.Canvas.beginPath();
  5498. this.Canvas.rect(left, top, width, height);
  5499. this.Canvas.clip();
  5500. }
  5501. //计算需要画的点的坐标
  5502. this.CalculateDrawPoint = function () {
  5503. if (this.Status < 2) return null;
  5504. if (!this.Point.length || !this.Frame) return null;
  5505. var drawPoint = new Array();
  5506. if (this.Status == 10) {
  5507. var data = this.Frame.Data;
  5508. if (!data) return null;
  5509. for (var i in this.Value) {
  5510. var item = this.Value[i];
  5511. var pt = new Point();
  5512. pt.X = this.Frame.GetXFromIndex(item.XValue - data.DataOffset);
  5513. pt.Y = this.Frame.GetYFromData(item.YValue);
  5514. drawPoint.push(pt);
  5515. }
  5516. }
  5517. else {
  5518. drawPoint = this.Point;
  5519. }
  5520. return drawPoint;
  5521. }
  5522. this.DrawPoint = function (aryPoint) {
  5523. if (!aryPoint || aryPoint.length <= 0) return;
  5524. //画点
  5525. this.ClipFrame();
  5526. for (var i in aryPoint) {
  5527. var item = aryPoint[i];
  5528. this.Canvas.beginPath();
  5529. this.Canvas.arc(item.X, item.Y, 5, 0, 360, false);
  5530. this.Canvas.setFillStyle(this.PointColor); //填充颜色
  5531. this.Canvas.fill(); //画实心圆
  5532. this.Canvas.closePath();
  5533. }
  5534. this.Canvas.restore();
  5535. }
  5536. }
  5537. /*
  5538. 画图工具-线段
  5539. */
  5540. function ChartDrawPictureLine() {
  5541. this.newMethod = IChartDrawPicture; //派生
  5542. this.newMethod();
  5543. delete this.newMethod;
  5544. this.Draw = function () {
  5545. var drawPoint = this.CalculateDrawPoint();
  5546. if (!drawPoint) return;
  5547. this.ClipFrame();
  5548. for (var i in drawPoint) {
  5549. var item = drawPoint[i];
  5550. if (i == 0) {
  5551. this.Canvas.beginPath();
  5552. this.Canvas.moveTo(item.X, item.Y);
  5553. }
  5554. else {
  5555. this.Canvas.lineTo(item.X, item.Y);
  5556. }
  5557. }
  5558. this.Canvas.setStrokeStyle(this.LineColor);
  5559. this.Canvas.stroke();
  5560. this.Canvas.closePath();
  5561. this.Canvas.restore();
  5562. //画点
  5563. this.DrawPoint(drawPoint);
  5564. }
  5565. //0-10 鼠标对应的点索引 100=鼠标在正个图形上 -1 鼠标不在图形上
  5566. this.IsPointIn = function (x, y) {
  5567. if (!this.Frame || this.Status != 10) return -1;
  5568. var data = this.Frame.Data;
  5569. if (!data) return -1;
  5570. //是否在点上
  5571. var aryPoint = new Array();
  5572. for (var i in this.Value) {
  5573. var item = this.Value[i];
  5574. var pt = new Point();
  5575. pt.X = this.Frame.GetXFromIndex(item.XValue - data.DataOffset);
  5576. pt.Y = this.Frame.GetYFromData(item.YValue);
  5577. this.Canvas.beginPath();
  5578. this.Canvas.arc(pt.X, pt.Y, 5, 0, 360);
  5579. //JSConsole.Chart.Log('['+i+']'+'x='+x+' y='+y+' dataX='+pt.X+" dataY="+pt.Y);
  5580. if (this.Canvas.isPointInPath(x, y))
  5581. return i;
  5582. aryPoint.push(pt);
  5583. }
  5584. //是否在线段上
  5585. this.Canvas.beginPath();
  5586. this.Canvas.moveTo(aryPoint[0].X, aryPoint[0].Y + 5);
  5587. this.Canvas.lineTo(aryPoint[0].X, aryPoint[0].Y - 5);
  5588. this.Canvas.lineTo(aryPoint[1].X, aryPoint[1].Y - 5);
  5589. this.Canvas.lineTo(aryPoint[1].X, aryPoint[1].Y + 5);
  5590. this.Canvas.closePath();
  5591. if (this.Canvas.isPointInPath(x, y))
  5592. return 100;
  5593. return -1;
  5594. }
  5595. }
  5596. /*
  5597. 画图工具-射线
  5598. */
  5599. function ChartDrawPictureHaflLine() {
  5600. this.newMethod = IChartDrawPicture; //派生
  5601. this.newMethod();
  5602. delete this.newMethod;
  5603. this.Draw = function () {
  5604. var drawPoint = this.CalculateDrawPoint();
  5605. if (!drawPoint || drawPoint.length != 2) return;
  5606. this.ClipFrame();
  5607. this.Canvas.beginPath();
  5608. this.Canvas.moveTo(drawPoint[0].X, drawPoint[0].Y);
  5609. this.Canvas.lineTo(drawPoint[1].X, drawPoint[1].Y);
  5610. var endPoint = this.CalculateEndPoint(drawPoint);
  5611. this.Canvas.lineTo(endPoint.X, endPoint.Y);
  5612. this.Canvas.setStrokeStyle(this.LineColor);
  5613. this.Canvas.stroke();
  5614. this.Canvas.closePath();
  5615. this.Canvas.restore();
  5616. //画点
  5617. this.DrawPoint(drawPoint);
  5618. }
  5619. this.CalculateEndPoint = function (aryPoint) {
  5620. var left = this.Frame.ChartBorder.GetLeft();
  5621. var right = this.Frame.ChartBorder.GetRight();
  5622. var a = aryPoint[1].X - aryPoint[0].X;
  5623. var b = aryPoint[1].Y - aryPoint[0].Y;
  5624. if (a > 0) {
  5625. var a1 = right - aryPoint[0].X;
  5626. var b1 = a1 * b / a;
  5627. var y = b1 + aryPoint[0].Y;
  5628. var pt = new Point();
  5629. pt.X = right;
  5630. pt.Y = y;
  5631. return pt;
  5632. }
  5633. else {
  5634. var a1 = aryPoint[0].X - left;
  5635. var b1 = a1 * b / Math.abs(a);
  5636. var y = b1 + aryPoint[0].Y;
  5637. var pt = new Point();
  5638. pt.X = left;
  5639. pt.Y = y;
  5640. return pt;
  5641. }
  5642. }
  5643. //0-10 鼠标对应的点索引 100=鼠标在正个图形上 -1 鼠标不在图形上
  5644. this.IsPointIn = function (x, y) {
  5645. if (!this.Frame || this.Status != 10) return -1;
  5646. var data = this.Frame.Data;
  5647. if (!data) return -1;
  5648. //是否在点上
  5649. var aryPoint = new Array();
  5650. for (var i in this.Value) {
  5651. var item = this.Value[i];
  5652. var pt = new Point();
  5653. pt.X = this.Frame.GetXFromIndex(item.XValue - data.DataOffset);
  5654. pt.Y = this.Frame.GetYFromData(item.YValue);
  5655. this.Canvas.beginPath();
  5656. this.Canvas.arc(pt.X, pt.Y, 5, 0, 360);
  5657. //JSConsole.Chart.Log('['+i+']'+'x='+x+' y='+y+' dataX='+pt.X+" dataY="+pt.Y);
  5658. if (this.Canvas.isPointInPath(x, y))
  5659. return i;
  5660. aryPoint.push(pt);
  5661. }
  5662. //是否在线段上
  5663. this.Canvas.beginPath();
  5664. this.Canvas.moveTo(aryPoint[0].X, aryPoint[0].Y + 5);
  5665. this.Canvas.lineTo(aryPoint[0].X, aryPoint[0].Y - 5);
  5666. this.Canvas.lineTo(aryPoint[1].X, aryPoint[1].Y - 5);
  5667. this.Canvas.lineTo(aryPoint[1].X, aryPoint[1].Y + 5);
  5668. this.Canvas.closePath();
  5669. if (this.Canvas.isPointInPath(x, y))
  5670. return 100;
  5671. return -1;
  5672. }
  5673. }
  5674. /*
  5675. 画图工具-矩形
  5676. */
  5677. function ChartDrawPictureRect() {
  5678. this.newMethod = IChartDrawPicture; //派生
  5679. this.newMethod();
  5680. delete this.newMethod;
  5681. this.Draw = function () {
  5682. var drawPoint = this.CalculateDrawPoint();
  5683. if (!drawPoint || drawPoint.length != 2) return;
  5684. this.ClipFrame();
  5685. this.Canvas.beginPath();
  5686. this.Canvas.rect(drawPoint[0].X, drawPoint[0].Y, drawPoint[1].X - drawPoint[0].X, drawPoint[1].Y - drawPoint[0].Y);
  5687. this.Canvas.setStrokeStyle(this.LineColor);
  5688. this.Canvas.stroke();
  5689. this.Canvas.closePath();
  5690. this.Canvas.restore();
  5691. //画点
  5692. this.DrawPoint(drawPoint);
  5693. }
  5694. //0-10 鼠标对应的点索引 100=鼠标在正个图形上 -1 鼠标不在图形上
  5695. this.IsPointIn = function (x, y) {
  5696. if (!this.Frame || this.Status != 10) return -1;
  5697. var data = this.Frame.Data;
  5698. if (!data) return -1;
  5699. //是否在点上
  5700. var aryPoint = new Array();
  5701. for (var i in this.Value) {
  5702. var item = this.Value[i];
  5703. var pt = new Point();
  5704. pt.X = this.Frame.GetXFromIndex(item.XValue - data.DataOffset);
  5705. pt.Y = this.Frame.GetYFromData(item.YValue);
  5706. this.Canvas.beginPath();
  5707. this.Canvas.arc(pt.X, pt.Y, 5, 0, 360);
  5708. //JSConsole.Chart.Log('['+i+']'+'x='+x+' y='+y+' dataX='+pt.X+" dataY="+pt.Y);
  5709. if (this.Canvas.isPointInPath(x, y))
  5710. return i;
  5711. aryPoint.push(pt);
  5712. }
  5713. //是否在矩形边框上
  5714. var linePoint = [{ X: aryPoint[0].X, Y: aryPoint[0].Y }, { X: aryPoint[1].X, Y: aryPoint[0].Y }];
  5715. if (this.IsPointInLine(linePoint, x, y))
  5716. return 100;
  5717. linePoint = [{ X: aryPoint[1].X, Y: aryPoint[0].Y }, { X: aryPoint[1].X, Y: aryPoint[1].Y }];
  5718. if (this.IsPointInLine2(linePoint, x, y))
  5719. return 100;
  5720. linePoint = [{ X: aryPoint[1].X, Y: aryPoint[1].Y }, { X: aryPoint[0].X, Y: aryPoint[1].Y }];
  5721. if (this.IsPointInLine(linePoint, x, y))
  5722. return 100;
  5723. linePoint = [{ X: aryPoint[0].X, Y: aryPoint[1].Y }, { X: aryPoint[0].X, Y: aryPoint[0].Y }];
  5724. if (this.IsPointInLine2(linePoint, x, y))
  5725. return 100;
  5726. return -1;
  5727. }
  5728. //点是否在线段上 水平线段
  5729. this.IsPointInLine = function (aryPoint, x, y) {
  5730. this.Canvas.beginPath();
  5731. this.Canvas.moveTo(aryPoint[0].X, aryPoint[0].Y + 5);
  5732. this.Canvas.lineTo(aryPoint[0].X, aryPoint[0].Y - 5);
  5733. this.Canvas.lineTo(aryPoint[1].X, aryPoint[1].Y - 5);
  5734. this.Canvas.lineTo(aryPoint[1].X, aryPoint[1].Y + 5);
  5735. this.Canvas.closePath();
  5736. if (this.Canvas.isPointInPath(x, y))
  5737. return true;
  5738. }
  5739. //垂直线段
  5740. this.IsPointInLine2 = function (aryPoint, x, y) {
  5741. this.Canvas.beginPath();
  5742. this.Canvas.moveTo(aryPoint[0].X - 5, aryPoint[0].Y);
  5743. this.Canvas.lineTo(aryPoint[0].X + 5, aryPoint[0].Y);
  5744. this.Canvas.lineTo(aryPoint[1].X + 5, aryPoint[1].Y);
  5745. this.Canvas.lineTo(aryPoint[1].X - 5, aryPoint[1].Y);
  5746. this.Canvas.closePath();
  5747. if (this.Canvas.isPointInPath(x, y))
  5748. return true;
  5749. }
  5750. }
  5751. /*
  5752. 画图工具-弧形
  5753. */
  5754. function ChartDrawPictureArc() {
  5755. this.newMethod = IChartDrawPicture; //派生
  5756. this.newMethod();
  5757. delete this.newMethod;
  5758. this.Draw = function () {
  5759. var drawPoint = this.CalculateDrawPoint();
  5760. if (!drawPoint || drawPoint.length != 2) return;
  5761. this.ClipFrame();
  5762. //this.Canvas.beginPath();
  5763. //this.Canvas.rect(drawPoint[0].X,drawPoint[0].Y,drawPoint[1].X-drawPoint[0].X,drawPoint[1].Y-drawPoint[0].Y);
  5764. if (drawPoint[0].X < drawPoint[1].X && drawPoint[0].Y > drawPoint[1].Y) // 第一象限
  5765. {
  5766. var a = drawPoint[1].X - drawPoint[0].X;
  5767. var b = drawPoint[0].Y - drawPoint[1].Y;
  5768. var step = (a > b) ? 1 / a : 1 / b;
  5769. var xcenter = drawPoint[0].X;
  5770. var ycenter = drawPoint[1].Y;
  5771. this.Canvas.beginPath();
  5772. this.Canvas.moveTo(drawPoint[0].X, drawPoint[0].Y);
  5773. for (var i = 1.5 * Math.PI; i < 2 * Math.PI; i += step) {
  5774. this.Canvas.lineTo(xcenter + a * Math.cos(i), ycenter + b * Math.sin(i) * -1);
  5775. }
  5776. for (var j = 0; j <= 0.5 * Math.PI; j += step) {
  5777. this.Canvas.lineTo(xcenter + a * Math.cos(j), ycenter + b * Math.sin(j) * -1);
  5778. }
  5779. }
  5780. else if (drawPoint[0].X > drawPoint[1].X && drawPoint[0].Y > drawPoint[1].Y) // 第二象限
  5781. {
  5782. var a = drawPoint[0].X - drawPoint[1].X;
  5783. var b = drawPoint[0].Y - drawPoint[1].Y;
  5784. var step = (a > b) ? 1 / a : 1 / b;
  5785. var xcenter = drawPoint[1].X;
  5786. var ycenter = drawPoint[0].Y;
  5787. this.Canvas.beginPath();
  5788. this.Canvas.moveTo(drawPoint[0].X, drawPoint[0].Y);
  5789. for (var i = 0; i <= Math.PI; i += step) {
  5790. this.Canvas.lineTo(xcenter + a * Math.cos(i), ycenter + b * Math.sin(i) * -1);
  5791. }
  5792. }
  5793. else if (drawPoint[0].X > drawPoint[1].X && drawPoint[0].Y < drawPoint[1].Y) // 第三象限
  5794. {
  5795. var a = drawPoint[0].X - drawPoint[1].X;
  5796. var b = drawPoint[1].Y - drawPoint[0].Y;
  5797. var step = (a > b) ? 1 / a : 1 / b;
  5798. var xcenter = drawPoint[0].X;
  5799. var ycenter = drawPoint[1].Y;
  5800. this.Canvas.beginPath();
  5801. this.Canvas.moveTo(drawPoint[0].X, drawPoint[0].Y);
  5802. for (var i = 0.5 * Math.PI; i <= 1.5 * Math.PI; i += step) {
  5803. this.Canvas.lineTo(xcenter + a * Math.cos(i), ycenter + b * Math.sin(i) * -1);
  5804. }
  5805. }
  5806. else if (drawPoint[0].X < drawPoint[1].X && drawPoint[0].Y < drawPoint[1].Y) // 第四象限
  5807. {
  5808. var a = drawPoint[1].X - drawPoint[0].X;
  5809. var b = drawPoint[1].Y - drawPoint[0].Y;
  5810. var step = (a > b) ? 1 / a : 1 / b;
  5811. var xcenter = drawPoint[1].X;
  5812. var ycenter = drawPoint[0].Y;
  5813. this.Canvas.beginPath();
  5814. this.Canvas.moveTo(drawPoint[0].X, drawPoint[0].Y);
  5815. for (var i = Math.PI; i <= 2 * Math.PI; i += step) {
  5816. this.Canvas.lineTo(xcenter + a * Math.cos(i), ycenter + b * Math.sin(i) * -1);
  5817. }
  5818. }
  5819. this.Canvas.setStrokeStyle(this.LineColor);
  5820. this.Canvas.stroke();
  5821. //this.Canvas.closePath();
  5822. this.Canvas.restore();
  5823. //画点
  5824. this.DrawPoint(drawPoint);
  5825. }
  5826. //0-10 鼠标对应的点索引 100=鼠标在正个图形上 -1 鼠标不在图形上
  5827. this.IsPointIn = function (x, y) {
  5828. if (!this.Frame || this.Status != 10) return -1;
  5829. var data = this.Frame.Data;
  5830. if (!data) return -1;
  5831. //是否在点上
  5832. var aryPoint = new Array();
  5833. for (var i in this.Value) {
  5834. var item = this.Value[i];
  5835. var pt = new Point();
  5836. pt.X = this.Frame.GetXFromIndex(item.XValue - data.DataOffset);
  5837. pt.Y = this.Frame.GetYFromData(item.YValue);
  5838. this.Canvas.beginPath();
  5839. this.Canvas.arc(pt.X, pt.Y, 5, 0, 360);
  5840. //JSConsole.Chart.Log('['+i+']'+'x='+x+' y='+y+' dataX='+pt.X+" dataY="+pt.Y);
  5841. if (this.Canvas.isPointInPath(x, y))
  5842. return i;
  5843. aryPoint.push(pt);
  5844. }
  5845. //是否在弧线上
  5846. var ArcPoint = [{ X: aryPoint[0].X, Y: aryPoint[0].Y }, { X: aryPoint[1].X, Y: aryPoint[1].Y }];
  5847. if (this.IsPointInArc(ArcPoint, x, y))
  5848. return 100;
  5849. return -1;
  5850. }
  5851. this.IsPointInArc = function (aryPoint, x, y) {
  5852. if (aryPoint.length != 2)
  5853. return false;
  5854. if (aryPoint[0].X < aryPoint[1].X && aryPoint[0].Y > aryPoint[1].Y) // 第一象限
  5855. {
  5856. var a = aryPoint[1].X - aryPoint[0].X;
  5857. var b = aryPoint[0].Y - aryPoint[1].Y;
  5858. var step = (a > b) ? 1 / a : 1 / b;
  5859. var ainer = a * 0.8;
  5860. var biner = b * 0.8;
  5861. var stepiner = (ainer > biner) ? 1 / ainer : 1 / biner;
  5862. var xcenter = aryPoint[0].X;
  5863. var ycenter = aryPoint[1].Y;
  5864. this.Canvas.beginPath();
  5865. this.Canvas.moveTo(aryPoint[0].X, aryPoint[0].Y);
  5866. for (var i = 1.5 * Math.PI; i < 2 * Math.PI; i += step) {
  5867. this.Canvas.lineTo(xcenter + a * Math.cos(i), ycenter + b * Math.sin(i) * -1);
  5868. }
  5869. for (var j = 0; j <= 0.5 * Math.PI; j += step) {
  5870. this.Canvas.lineTo(xcenter + a * Math.cos(j), ycenter + b * Math.sin(j) * -1);
  5871. }
  5872. for (var k = 0.5 * Math.PI; k >= 0; k -= stepiner) {
  5873. this.Canvas.lineTo(xcenter + ainer * Math.cos(k), ycenter + biner * Math.sin(j) * -1);
  5874. }
  5875. for (var l = 2 * Math.PI; l >= 1.5 * Math.PI; l -= stepiner) {
  5876. this.Canvas.lineTo(xcenter + ainer * Math.cos(l), ycenter + biner * Math.sin(l) * -1);
  5877. }
  5878. this.Canvas.closePath();
  5879. }
  5880. else if (aryPoint[0].X > aryPoint[1].X && aryPoint[0].Y > aryPoint[1].Y) // 第二象限
  5881. {
  5882. var a = aryPoint[0].X - aryPoint[1].X;
  5883. var b = aryPoint[0].Y - aryPoint[1].Y;
  5884. var step = (a > b) ? 1 / a : 1 / b;
  5885. var ainer = a * 0.8;
  5886. var biner = b * 0.8;
  5887. var stepiner = (ainer > biner) ? 1 / ainer : 1 / biner;
  5888. var xcenter = aryPoint[1].X;
  5889. var ycenter = aryPoint[0].Y;
  5890. this.Canvas.beginPath();
  5891. this.Canvas.moveTo(aryPoint[0].X, aryPoint[0].Y);
  5892. for (var i = 0; i <= Math.PI; i += step) {
  5893. this.Canvas.lineTo(xcenter + a * Math.cos(i), ycenter + b * Math.sin(i) * -1);
  5894. }
  5895. for (var j = Math.PI; j >= 0; j -= stepiner) {
  5896. this.Canvas.lineTo(xcenter + ainer * Math.cos(j), ycenter + biner * Math.sin(j) * -1);
  5897. }
  5898. this.Canvas.closePath();
  5899. }
  5900. else if (aryPoint[0].X > aryPoint[1].X && aryPoint[0].Y < aryPoint[1].Y) // 第三象限
  5901. {
  5902. var a = aryPoint[0].X - aryPoint[1].X;
  5903. var b = aryPoint[1].Y - aryPoint[0].Y;
  5904. var step = (a > b) ? 1 / a : 1 / b;
  5905. var ainer = a * 0.8;
  5906. var biner = b * 0.8;
  5907. var stepiner = (ainer > biner) ? 1 / ainer : 1 / biner;
  5908. var xcenter = aryPoint[0].X;
  5909. var ycenter = aryPoint[1].Y;
  5910. this.Canvas.beginPath();
  5911. this.Canvas.moveTo(aryPoint[0].X, aryPoint[0].Y);
  5912. for (var i = 0.5 * Math.PI; i <= 1.5 * Math.PI; i += step) {
  5913. this.Canvas.lineTo(xcenter + a * Math.cos(i), ycenter + b * Math.sin(i) * -1);
  5914. }
  5915. for (var j = 1.5 * Math.PI; j >= 0.5 * Math.PI; j -= stepiner) {
  5916. this.Canvas.lineTo(xcenter + ainer * Math.cos(j), ycenter + biner * Math.sin(j) * -1);
  5917. }
  5918. this.Canvas.closePath();
  5919. }
  5920. else if (aryPoint[0].X < aryPoint[1].X && aryPoint[0].Y < aryPoint[1].Y) // 第四象限
  5921. {
  5922. var a = aryPoint[1].X - aryPoint[0].X;
  5923. var b = aryPoint[1].Y - aryPoint[0].Y;
  5924. var step = (a > b) ? 1 / a : 1 / b;
  5925. var ainer = a * 0.8;
  5926. var biner = b * 0.8;
  5927. var stepiner = (ainer > biner) ? 1 / ainer : 1 / biner;
  5928. var xcenter = aryPoint[1].X;
  5929. var ycenter = aryPoint[0].Y;
  5930. this.Canvas.beginPath();
  5931. this.Canvas.moveTo(aryPoint[0].X, aryPoint[0].Y);
  5932. for (var i = Math.PI; i <= 2 * Math.PI; i += step) {
  5933. this.Canvas.lineTo(xcenter + a * Math.cos(i), ycenter + b * Math.sin(i) * -1);
  5934. }
  5935. for (var j = 2 * Math.PI; j >= Math.PI; j -= stepiner) {
  5936. this.Canvas.lineTo(xcenter + ainer * Math.cos(j), ycenter + biner * Math.sin(j) * -1);
  5937. }
  5938. this.Canvas.closePath();
  5939. }
  5940. if (this.Canvas.isPointInPath(x, y))
  5941. return true;
  5942. else
  5943. return false;
  5944. }
  5945. }
  5946. /*
  5947. 指标列表 指标信息都在这里,不够后面再加字段
  5948. */
  5949. function JSIndexMap() {
  5950. }
  5951. JSIndexMap.Get = function (id) {
  5952. var indexMap = new Map(
  5953. [
  5954. //公司自己的指标
  5955. ["市场多空", { IsMainIndex: false, Create: function () { return new MarketLongShortIndex() } }],
  5956. ["市场择时", { IsMainIndex: false, Create: function () { return new MarketTimingIndex() } }],
  5957. ["市场关注度", { IsMainIndex: false, Create: function () { return new MarketAttentionIndex() } }],
  5958. ["指数热度", { IsMainIndex: false, Create: function () { return new MarketHeatIndex() } }],
  5959. ["自定义指数热度", { IsMainIndex: false, Create: function () { return new CustonIndexHeatIndex() }, Name: '自定义指数热度' }],
  5960. ["财务粉饰", { IsMainIndex: false, Create: function () { return new BenfordIndex() } }],
  5961. //能图指标
  5962. //["能图-趋势", { IsMainIndex: false, Create: function () { return new LighterIndex1() }, Name: '大盘/个股趋势' }],
  5963. //["能图-位置研判", { IsMainIndex: false, Create: function () { return new LighterIndex2() }, Name: '位置研判' }],
  5964. //["能图-点位研判", { IsMainIndex: false, Create: function () { return new LighterIndex3() }, Name: '点位研判' }],
  5965. //["能图-资金分析", { IsMainIndex: false, Create: function () { return new LighterIndex4() }, Name: '资金分析' }],
  5966. //["能图-市场关注度", { IsMainIndex: false, Create: function () { return new LighterIndex5() }, Name: '市场关注度' }]
  5967. ]
  5968. );
  5969. return indexMap.get(id);
  5970. }
  5971. /////////////////////////////////////////////////////////////////////////////////////////////
  5972. // K线图 控件
  5973. // this.ChartPaint[0] K线画法 这个不要修改
  5974. //
  5975. //
  5976. function KLineChartContainer(uielement)
  5977. {
  5978. var _self = this;
  5979. this.newMethod = JSChartContainer; //派生
  5980. this.newMethod(uielement);
  5981. delete this.newMethod;
  5982. this.ClassName = 'KLineChartContainer';
  5983. this.WindowIndex = new Array();
  5984. this.ColorIndex; //五彩K线
  5985. this.TradeIndex; //交易指标/专家系统
  5986. this.Symbol;
  5987. this.Name;
  5988. this.Period = 0; //周期 0=日线 1=周线 2=月线 3=年线 4=1分钟 5=5分钟 6=15分钟 7=30分钟 8=60分钟 9=季线 10=分笔线 11=120分钟 12=240分钟
  5989. this.IsApiPeriod = false; //使用API计算周期
  5990. this.Right = 0; //复权 0 不复权 1 前复权 2 后复权
  5991. this.SourceData; //原始的历史数据
  5992. this.MaxReqeustDataCount = 3000; //数据个数
  5993. this.MaxRequestMinuteDayCount = 5; //分钟数据请求的天数
  5994. this.PageSize = 200; //每页数据个数
  5995. this.KLineDrawType = 0; //0=K线 1=收盘价线 2=美国线
  5996. this.LoadDataSplashTitle = '下载历史数据';
  5997. this.IsAutoUpdate = false; //是否自动更新行情数据
  5998. this.AutoUpdateFrequency = 30000; //30秒更新一次数据
  5999. this.AutoUpdateTimer; //自动定时器
  6000. this.RightSpaceCount=1;
  6001. this.SourceDataLimit = new Map(); //每个周期缓存数据最大个数 key=周期 value=最大个数
  6002. this.KLineSize=null; //{ DataWidth:, }
  6003. this.StepPixel = 4; //移动一个数据需要的像素
  6004. this.ZoomStepPixel = 5; //放大缩小手势需要的最小像素
  6005. this.EnableZoomUpDown=null; //是否手势/键盘/鼠标允许缩放{ Touch:true/false, Mouse:true/false, Keyboard:true/false, Wheel:true/false }
  6006. this.DragDownload = {
  6007. Day: { Enable: false, IsEnd: false, Status: 0 }, //日线数据拖拽下载(暂不支持) Status: 0空闲 1 下载中
  6008. Minute: { Enable: false, IsEnd: false, status: 0 } //分钟数据拖拽下载
  6009. };
  6010. this.KLineApiUrl = g_JSChartResource.Domain + "/API/KLine2"; //历史K线api地址
  6011. this.MinuteKLineApiUrl = g_JSChartResource.Domain + '/API/KLine3'; //历史分钟数据
  6012. this.RealtimeApiUrl = g_JSChartResource.Domain + "/API/Stock"; //实时行情api地址
  6013. this.KLineMatchUrl = g_JSChartResource.Domain + "/API/KLineMatch"; //形态匹配
  6014. this.DragMinuteKLineApiUrl = g_JSChartResource.Domain + '/API/KLine4'; //拖动数据下载
  6015. this.DragKLineApiUrl = g_JSChartResource.Domain + '/API/KLine5'; //拖动日K数据下载
  6016. this.BeforeBindMainData = null; //function(funcName) 在BindMainData() 调用前回调用
  6017. this.AfterBindMainData = null; //function(funcName) 在BindMainData() 调用前后调用
  6018. this.ResetDragDownload = function ()
  6019. {
  6020. this.DragDownload.Day.Status = 0;
  6021. this.DragDownload.Day.IsEnd=false;
  6022. this.DragDownload.Minute.Status = 0;
  6023. this.DragDownload.Minute.isEnd=false;
  6024. }
  6025. this.ChartOperator = function (obj) //图形控制函数 {ID:JSCHART_OPERATOR_ID, ...参数 }
  6026. {
  6027. var id = obj.ID;
  6028. if (id === JSCHART_OPERATOR_ID.OP_SCROLL_LEFT || id === JSCHART_OPERATOR_ID.OP_SCROLL_RIGHT) //左右移动 { Step:移动数据个数 }
  6029. {
  6030. var isLeft = (id === JSCHART_OPERATOR_ID.OP_SCROLL_LEFT ? true : false);
  6031. var step = 1;
  6032. if (obj.Step > 0) step = obj.Step;
  6033. if (this.DataMove(step * this.StepPixel, isLeft)) //每次移动一个数据
  6034. {
  6035. this.UpdataDataoffset();
  6036. this.UpdatePointByCursorIndex();
  6037. this.UpdateFrameMaxMin();
  6038. this.ResetFrameXYSplit();
  6039. this.Draw();
  6040. }
  6041. else
  6042. {
  6043. if (id===JSCHART_OPERATOR_ID.OP_SCROLL_RIGHT && this.DragDownloadData)
  6044. this.DragDownloadData();
  6045. }
  6046. }
  6047. else if (id === JSCHART_OPERATOR_ID.OP_ZOOM_IN || id === JSCHART_OPERATOR_ID.OP_ZOOM_OUT) //缩放
  6048. {
  6049. var cursorIndex = {};
  6050. cursorIndex.Index = parseInt(Math.abs(this.CursorIndex - 0.5).toFixed(0));
  6051. if (id === JSCHART_OPERATOR_ID.OP_ZOOM_IN)
  6052. {
  6053. if (!this.Frame.ZoomUp(cursorIndex)) return;
  6054. }
  6055. else
  6056. {
  6057. if (!this.Frame.ZoomDown(cursorIndex)) return;
  6058. }
  6059. this.CursorIndex = cursorIndex.Index;
  6060. this.UpdataDataoffset();
  6061. this.UpdatePointByCursorIndex();
  6062. this.UpdateFrameMaxMin();
  6063. this.Draw();
  6064. }
  6065. else if (id === JSCHART_OPERATOR_ID.OP_GOTO_HOME) //返回最新
  6066. {
  6067. var hisData = null;
  6068. if (!this.Frame.Data) hisData = this.Frame.Data;
  6069. else hisData = this.Frame.SubFrame[0].Frame.Data;
  6070. if (!hisData) return; //数据还没有到达
  6071. var showCount = this.PageSize;
  6072. //var pageSize = this.GetMaxMinPageSize();
  6073. //if (pageSize.Max < showCount) showCount = pageSize.Max;
  6074. //else if (pageSize.Min > showCount) showCount = pageSize.Min;
  6075. for (var i in this.Frame.SubFrame) //设置一屏显示的数据个数
  6076. {
  6077. var item = this.Frame.SubFrame[i].Frame;
  6078. item.XPointCount = showCount;
  6079. }
  6080. var index = hisData.Data.length - showCount;
  6081. hisData.DataOffset = index;
  6082. this.CursorIndex = 0;
  6083. this.LastPoint.X = null;
  6084. this.LastPoint.Y = null;
  6085. JSConsole.Chart.Log(`[KLineChartContainer::ChartOperator] OP_GOTO_HOME, dataOffset=${hisData.DataOffset} CursorIndex=${this.CursorIndex} PageSize=${showCount}`);
  6086. this.UpdataDataoffset(); //更新数据偏移
  6087. this.UpdateFrameMaxMin(); //调整坐标最大 最小值
  6088. this.Frame.SetSizeChage(true);
  6089. this.Draw();
  6090. this.UpdatePointByCursorIndex(); //更新十字光标位子
  6091. }
  6092. }
  6093. //创建windowCount 窗口个数
  6094. this.Create = function (windowCount)
  6095. {
  6096. this.UIElement.JSChartContainer = this;
  6097. //创建十字光标
  6098. this.ChartCorssCursor = new ChartCorssCursor();
  6099. this.ChartCorssCursor.Canvas = this.Canvas;
  6100. this.ChartCorssCursor.StringFormatX = g_DivTooltipDataForamt.Create("CorssCursor_XStringFormat");
  6101. this.ChartCorssCursor.StringFormatX.LanguageID=this.LanguageID;
  6102. this.ChartCorssCursor.StringFormatY = g_DivTooltipDataForamt.Create("CorssCursor_YStringFormat");
  6103. this.ChartCorssCursor.StringFormatY.LanguageID = this.LanguageID;
  6104. //创建等待提示
  6105. this.ChartSplashPaint = new ChartSplashPaint();
  6106. this.ChartSplashPaint.Canvas = this.Canvas;
  6107. this.ChartSplashPaint.SplashTitle = this.LoadDataSplashTitle;
  6108. this.ChartSplashPaint.HQChart=this;
  6109. //创建框架容器
  6110. this.Frame = new HQTradeFrame();
  6111. this.Frame.ChartBorder = new ChartBorder();
  6112. this.Frame.ChartBorder.UIElement = this.UIElement;
  6113. this.Frame.ChartBorder.Top = 30;
  6114. this.Frame.ChartBorder.Left = 5;
  6115. this.Frame.ChartBorder.Bottom = 20;
  6116. this.Frame.Canvas = this.Canvas;
  6117. this.ChartCorssCursor.Frame = this.Frame; //十字光标绑定框架
  6118. this.ChartSplashPaint.Frame = this.Frame;
  6119. this.CreateChildWindow(windowCount);
  6120. this.CreateMainKLine();
  6121. //子窗口动态标题
  6122. for (var i in this.Frame.SubFrame)
  6123. {
  6124. var titlePaint = new DynamicChartTitlePainting();
  6125. titlePaint.Frame = this.Frame.SubFrame[i].Frame;
  6126. titlePaint.Canvas = this.Canvas;
  6127. titlePaint.LanguageID = this.LanguageID;
  6128. this.Frame.SubFrame[i].Frame.TitlePaint = titlePaint;
  6129. this.TitlePaint.push(titlePaint);
  6130. }
  6131. }
  6132. //创建子窗口
  6133. this.CreateChildWindow = function (windowCount)
  6134. {
  6135. for (var i = 0; i < windowCount; ++i)
  6136. {
  6137. var border = new ChartBorder();
  6138. border.UIElement = this.UIElement;
  6139. var frame = new KLineFrame();
  6140. frame.Canvas = this.Canvas;
  6141. frame.ChartBorder = border;
  6142. frame.Identify = i; //窗口序号
  6143. frame.RightSpaceCount = this.RightSpaceCount; //右边
  6144. frame.HorizontalMax = 20;
  6145. frame.HorizontalMin = 10;
  6146. if (i == 0)
  6147. {
  6148. frame.YSplitOperator = new FrameSplitKLinePriceY();
  6149. frame.YSplitOperator.FrameSplitData = this.FrameSplitData.get('price');
  6150. frame.YSplitOperator.FrameSplitData2 = this.FrameSplitData.get('double');
  6151. frame.YSplitOperator.GetEventCallback=(id)=> { return this.GetEventCallback(id); }
  6152. border.BottomSpace = 12; //主图上下留空间
  6153. border.TopSpace = 12;
  6154. }
  6155. else
  6156. {
  6157. frame.YSplitOperator = new FrameSplitY();
  6158. frame.YSplitOperator.FrameSplitData = this.FrameSplitData.get('double');
  6159. frame.YSplitOperator.LanguageID = this.LanguageID;
  6160. frame.YSplitOperator.GetEventCallback=(id)=> { return this.GetEventCallback(id); }
  6161. }
  6162. frame.YSplitOperator.Frame = frame;
  6163. frame.YSplitOperator.ChartBorder = border;
  6164. frame.XSplitOperator = new FrameSplitKLineX();
  6165. frame.XSplitOperator.Frame = frame;
  6166. frame.XSplitOperator.ChartBorder = border;
  6167. if (i != windowCount - 1) frame.XSplitOperator.ShowText = false;
  6168. for (var j = frame.HorizontalMin; j <= frame.HorizontalMax; j += 1)
  6169. {
  6170. frame.HorizontalInfo[j] = new CoordinateInfo();
  6171. frame.HorizontalInfo[j].Value = j;
  6172. if (i == 0 && j == frame.HorizontalMin) continue;
  6173. frame.HorizontalInfo[j].Message[1] = j.toString();
  6174. frame.HorizontalInfo[j].Font = "12px 微软雅黑";
  6175. }
  6176. var subFrame = new SubFrameItem();
  6177. subFrame.Frame = frame;
  6178. if (i == 0) subFrame.Height = 20;
  6179. else subFrame.Height = 10;
  6180. this.Frame.SubFrame[i] = subFrame;
  6181. }
  6182. }
  6183. this.CreateSubFrameItem = function (id)
  6184. {
  6185. var border = new ChartBorder();
  6186. border.UIElement = this.UIElement;
  6187. var frame = new KLineFrame();
  6188. frame.Canvas = this.Canvas;
  6189. frame.ChartBorder = border;
  6190. frame.Identify = id; //窗口序号
  6191. if (this.ModifyIndexDialog) frame.ModifyIndexEvent = this.ModifyIndexDialog.DoModal; //绑定菜单事件
  6192. if (this.ChangeIndexDialog) frame.ChangeIndexEvent = this.ChangeIndexDialog.DoModal;
  6193. frame.HorizontalMax = 20;
  6194. frame.HorizontalMin = 10;
  6195. frame.YSplitOperator = new FrameSplitY();
  6196. frame.YSplitOperator.LanguageID = this.LanguageID;
  6197. frame.YSplitOperator.FrameSplitData = this.FrameSplitData.get('double');
  6198. frame.YSplitOperator.Frame = frame;
  6199. frame.YSplitOperator.ChartBorder = border;
  6200. frame.XSplitOperator = new FrameSplitKLineX();
  6201. frame.XSplitOperator.Frame = frame;
  6202. frame.XSplitOperator.ChartBorder = border;
  6203. frame.XSplitOperator.ShowText = false;
  6204. //K线数据绑定
  6205. var xPointCouont = this.Frame.SubFrame[0].Frame.XPointCount;
  6206. frame.XPointCount = xPointCouont;
  6207. frame.Data = this.ChartPaint[0].Data;
  6208. for (var j = frame.HorizontalMin; j <= frame.HorizontalMax; j += 1)
  6209. {
  6210. frame.HorizontalInfo[j] = new CoordinateInfo();
  6211. frame.HorizontalInfo[j].Value = j;
  6212. frame.HorizontalInfo[j].Message[1] = j.toString();
  6213. frame.HorizontalInfo[j].Font = "12px 微软雅黑";
  6214. }
  6215. var subFrame = new SubFrameItem();
  6216. subFrame.Frame = frame;
  6217. subFrame.Height = 10;
  6218. return subFrame;
  6219. }
  6220. //创建主图K线画法
  6221. this.CreateMainKLine = function ()
  6222. {
  6223. var kline = new ChartKLine();
  6224. kline.Canvas = this.Canvas;
  6225. kline.ChartBorder = this.Frame.SubFrame[0].Frame.ChartBorder;
  6226. kline.ChartFrame = this.Frame.SubFrame[0].Frame;
  6227. kline.Name = "Main-KLine";
  6228. kline.DrawType = this.KLineDrawType;
  6229. this.ChartPaint[0] = kline;
  6230. this.TitlePaint[0] = new DynamicKLineTitlePainting();
  6231. this.TitlePaint[0].Frame = this.Frame.SubFrame[0].Frame;
  6232. this.TitlePaint[0].Canvas = this.Canvas;
  6233. this.TitlePaint[0].LanguageID = this.LanguageID;
  6234. //主图叠加画法
  6235. var paint = new ChartOverlayKLine();
  6236. paint.Canvas = this.Canvas;
  6237. paint.ChartBorder = this.Frame.SubFrame[0].Frame.ChartBorder;
  6238. paint.ChartFrame = this.Frame.SubFrame[0].Frame;
  6239. paint.Name = "Overlay-KLine";
  6240. paint.DrawType = this.KLineDrawType;
  6241. this.OverlayChartPaint[0] = paint;
  6242. }
  6243. //绑定主图K线数据
  6244. this.BindMainData = function (hisData, showCount)
  6245. {
  6246. this.ChartPaint[0].Data = hisData;
  6247. this.ChartPaint[0].Symbol = this.Symbol;
  6248. if (this.KLineSize)
  6249. {
  6250. if (this.KLineSize.DataWidth==null)
  6251. {
  6252. showCount=this.Frame.SubFrame[0].Frame.XPointCount-this.RightSpaceCount;
  6253. }
  6254. else
  6255. {
  6256. var obj=this.Frame.SetDataWidth(this.KLineSize.DataWidth);
  6257. showCount=obj.XPointCount-this.RightSpaceCount;
  6258. this.KLineSize.DataWidth=null;
  6259. }
  6260. }
  6261. for (var i in this.Frame.SubFrame)
  6262. {
  6263. var item = this.Frame.SubFrame[i].Frame;
  6264. item.XPointCount = showCount + this.RightSpaceCount;
  6265. item.Data = this.ChartPaint[0].Data;
  6266. item.XSplitOperator.Symbol = this.Symbol;
  6267. item.XSplitOperator.Period = this.Period;
  6268. }
  6269. this.TitlePaint[0].Data = this.ChartPaint[0].Data; //动态标题
  6270. this.TitlePaint[0].Symbol = this.Symbol;
  6271. this.TitlePaint[0].Name = this.Name;
  6272. this.TitlePaint[0].Period = this.Period;
  6273. this.ChartCorssCursor.StringFormatX.Data = this.ChartPaint[0].Data; //十字光标
  6274. this.Frame.Data = this.ChartPaint[0].Data;
  6275. this.OverlayChartPaint[0].MainData = this.ChartPaint[0].Data; //K线叠加
  6276. var dataOffset = hisData.Data.length - showCount;
  6277. if (dataOffset < 0) dataOffset = 0;
  6278. this.ChartPaint[0].Data.DataOffset = dataOffset;
  6279. this.ChartCorssCursor.StringFormatY.Symbol = this.Symbol;
  6280. this.CursorIndex = showCount;
  6281. if (this.CursorIndex + dataOffset >= hisData.Data.length) this.CursorIndex = hisData.Data.length - 1 - dataOffset;
  6282. if (this.CursorIndex < 0) this.CursorIndex = 0; //不一定对啊
  6283. }
  6284. this.UpdateMainData = function (hisData, lastDataCount) //更新主图数据(不会放大缩小数据)
  6285. {
  6286. var frameHisdata = null;
  6287. if (!this.Frame.Data) frameHisdata = this.Frame.Data;
  6288. else if (this.Frame.SubFrame && this.Frame.SubFrame[0]) frameHisdata = this.Frame.SubFrame[0].Frame.Data;
  6289. if (!frameHisdata) return;
  6290. var xPointCount=this.Frame.SubFrame[0].Frame.XPointCount; //当前一屏能显示的数据个数
  6291. var newDataCount = 0;
  6292. if (lastDataCount > 0 && hisData.Data.length > lastDataCount)
  6293. {
  6294. newDataCount = hisData.Data.length - lastDataCount;
  6295. JSConsole.Chart.Log(`[KLineChartContainer::UpdateMainData] [count=${lastDataCount}->${hisData.Data.length}], [newDataCount=${newDataCount}]`);
  6296. }
  6297. this.ChartPaint[0].Data = hisData;
  6298. this.ChartPaint[0].Symbol = this.Symbol;
  6299. if (hisData.Data.length>xPointCount) //不满一屏的, 不需要调整索引
  6300. this.ChartPaint[0].Data.DataOffset = frameHisdata.DataOffset + newDataCount; //加上数据增加的个数
  6301. for (var i in this.Frame.SubFrame)
  6302. {
  6303. var item = this.Frame.SubFrame[i].Frame;
  6304. item.Data = this.ChartPaint[0].Data;
  6305. if (i==0)
  6306. {
  6307. item.YSplitOperator.Symbol = this.Symbol;
  6308. item.YSplitOperator.Data = this.ChartPaint[0].Data; //K线数据
  6309. item.YSplitOperator.Period = this.Period; //周期
  6310. }
  6311. }
  6312. this.TitlePaint[0].Data = this.ChartPaint[0].Data; //动态标题
  6313. this.TitlePaint[0].Symbol = this.Symbol;
  6314. this.TitlePaint[0].Name = this.Name;
  6315. this.ChartCorssCursor.StringFormatX.Data = this.ChartPaint[0].Data; //十字光标
  6316. this.Frame.Data = this.ChartPaint[0].Data;
  6317. for (var i in this.OverlayChartPaint) //主图股票数据绑定到叠加股票上
  6318. {
  6319. var item = this.OverlayChartPaint[i];
  6320. item.MainData = this.ChartPaint[0].Data;
  6321. }
  6322. this.ChartCorssCursor.StringFormatY.Symbol = this.Symbol;
  6323. }
  6324. //创建指定窗口指标
  6325. this.CreateWindowIndex = function (windowIndex)
  6326. {
  6327. this.WindowIndex[windowIndex].Create(this, windowIndex);
  6328. }
  6329. this.BindIndexData = function (windowIndex, hisData)
  6330. {
  6331. if (!this.WindowIndex[windowIndex]) return;
  6332. if (typeof (this.WindowIndex[windowIndex].RequestData) == "function") //数据需要另外下载的.
  6333. {
  6334. this.WindowIndex[windowIndex].RequestData(this, windowIndex, hisData);
  6335. return;
  6336. }
  6337. if (typeof (this.WindowIndex[windowIndex].ExecuteScript) == 'function') //脚本指标
  6338. {
  6339. this.WindowIndex[windowIndex].ExecuteScript(this, windowIndex, hisData);
  6340. return;
  6341. }
  6342. this.WindowIndex[windowIndex].BindData(this, windowIndex, hisData);
  6343. }
  6344. //执行指示(专家指示 五彩K线)
  6345. this.BindInstructionIndexData = function (hisData)
  6346. {
  6347. if (this.ColorIndex && typeof (this.ColorIndex.ExecuteScript) == 'function') //五彩K线
  6348. {
  6349. this.ColorIndex.ExecuteScript(this, 0, hisData);
  6350. }
  6351. if (this.TradeIndex && typeof (this.TradeIndex.ExecuteScript) == 'function') //交易指标
  6352. {
  6353. this.TradeIndex.ExecuteScript(this, 0, hisData);
  6354. }
  6355. }
  6356. //获取子窗口的所有画法
  6357. this.GetChartPaint = function (windowIndex)
  6358. {
  6359. var paint = new Array();
  6360. for (var i in this.ChartPaint)
  6361. {
  6362. if (i == 0) continue; //第1个K线数据除外
  6363. var item = this.ChartPaint[i];
  6364. if (item.ChartFrame == this.Frame.SubFrame[windowIndex].Frame)
  6365. paint.push(item);
  6366. }
  6367. return paint;
  6368. }
  6369. this.AutoUpdateEvent = function (bStart) //自定更新事件, 是给websocket使用
  6370. {
  6371. var eventID = bStart ? JSCHART_EVENT_ID.RECV_START_AUTOUPDATE : JSCHART_EVENT_ID.RECV_STOP_AUTOUPDATE;
  6372. if (!this.mapEvent.has(eventID)) return;
  6373. var self = this;
  6374. var event = this.mapEvent.get(eventID);
  6375. var data = { Stock: { Symbol: this.Symbol, Name: this.Name, Right: this.Right, Period: this.Period } };
  6376. if (bStart)
  6377. {
  6378. data.Callback = function (data) //数据到达更新回调
  6379. {
  6380. if (ChartData.IsDayPeriod(self.Period, true)) self.RecvRealtimeData(data);
  6381. else if (ChartData.IsMinutePeriod(self.Period, true)) self.RecvMinuteRealtimeData(data);
  6382. else if (ChartData.IsSecondPeriod(self.Period)) self.RecvMinuteRealtimeData(data);
  6383. }
  6384. }
  6385. event.Callback(event, data, this);
  6386. }
  6387. this.RequestHistoryData = function ()
  6388. {
  6389. var self = this;
  6390. this.CancelAutoUpdate();
  6391. this.ChartSplashPaint.SetTitle(this.LoadDataSplashTitle);
  6392. this.ChartSplashPaint.EnableSplash(true);
  6393. this.ResetDragDownload();
  6394. this.Draw();
  6395. if (this.NetworkFilter)
  6396. {
  6397. var obj =
  6398. {
  6399. Name: 'KLineChartContainer::RequestHistoryData', //类名::
  6400. Explain: '日K数据',
  6401. Request: {
  6402. Url: self.KLineApiUrl, Type: 'POST',
  6403. Data: { symbol: self.Symbol, count: self.MaxReqeustDataCount, field: ["name", "symbol", "yclose", "open", "price", "high", "low", "vol"] }
  6404. },
  6405. Self: this,
  6406. PreventDefault: false
  6407. };
  6408. this.NetworkFilter(obj, function (data) {
  6409. self.ChartSplashPaint.EnableSplash(false);
  6410. self.RecvHistoryData(data);
  6411. self.AutoUpdateEvent(true);
  6412. self.AutoUpdate();
  6413. });
  6414. if (obj.PreventDefault == true) return; //已被上层替换,不调用默认的网络请求
  6415. }
  6416. wx.request({
  6417. url: this.KLineApiUrl,
  6418. data:
  6419. {
  6420. "field": ["name","symbol","yclose","open","price","high","low","vol"],
  6421. "symbol": self.Symbol,
  6422. "start": -1,
  6423. "count": self.MaxReqeustDataCount
  6424. },
  6425. method: 'POST',
  6426. dataType: 'json',
  6427. success: function (data) {
  6428. self.ChartSplashPaint.EnableSplash(false);
  6429. self.RecvHistoryData(data);
  6430. self.AutoUpdateEvent(true);
  6431. self.AutoUpdate();
  6432. }
  6433. });
  6434. }
  6435. this.RecvHistoryData = function (recvData)
  6436. {
  6437. var data = recvData.data;
  6438. var aryDayData = KLineChartContainer.JsonDataToHistoryData(data);
  6439. //原始数据
  6440. var sourceData = new ChartData();
  6441. sourceData.Data = aryDayData;
  6442. sourceData.DataType = 0; //0=日线数据 1=分钟数据
  6443. sourceData.Symbol = data.symbol;
  6444. this.SourceData = sourceData;
  6445. if (this.BeforeBindMainData) this.BeforeBindMainData("RecvHistoryData");
  6446. //显示的数据
  6447. var bindData = new ChartData();
  6448. bindData.Data = aryDayData;
  6449. bindData.Right = this.Right;
  6450. bindData.Period = this.Period;
  6451. bindData.DataType = 0;
  6452. if (bindData.Right > 0 && !this.IsApiPeriod) //复权
  6453. {
  6454. var rightData = bindData.GetRightDate(bindData.Right);
  6455. bindData.Data = rightData;
  6456. }
  6457. if (ChartData.IsDayPeriod(bindData.Period, false) && !this.IsApiPeriod) //周期数据
  6458. {
  6459. var periodData = bindData.GetPeriodData(bindData.Period);
  6460. bindData.Data = periodData;
  6461. }
  6462. //绑定数据
  6463. this.Symbol = data.symbol;
  6464. this.Name = data.name;
  6465. this.BindMainData(bindData, this.PageSize);
  6466. if (this.AfterBindMainData) this.AfterBindMainData("RecvHistoryData");
  6467. this.Frame.SetSizeChage(true); //数据到达通知坐标框架
  6468. this.BindInstructionIndexData(bindData); //执行指示脚本
  6469. var firstSubFrame; //主窗口
  6470. for (var i = 0; i < this.Frame.SubFrame.length; ++i) //执行指标
  6471. {
  6472. if (i == 0) firstSubFrame = this.Frame.SubFrame[i].Frame;
  6473. this.BindIndexData(i, bindData);
  6474. }
  6475. if (firstSubFrame && firstSubFrame.YSplitOperator)
  6476. {
  6477. firstSubFrame.YSplitOperator.Symbol = this.Symbol; //绑定代码
  6478. firstSubFrame.YSplitOperator.Data = this.ChartPaint[0].Data; //K线数据
  6479. }
  6480. //请求叠加数据 (主数据下载完再下载))
  6481. this.ReqeustKLineInfoData();
  6482. this.RequestOverlayHistoryData();
  6483. //刷新画图
  6484. this.UpdataDataoffset(); //更新数据偏移
  6485. this.UpdatePointByCursorIndex(); //更新十字光标位子
  6486. this.UpdateFrameMaxMin(); //调整坐标最大 最小值
  6487. this.Frame.SetSizeChage(true);
  6488. this.Draw();
  6489. if (this.mapEvent.has(JSCHART_EVENT_ID.RECV_HISTROY_DATA))
  6490. {
  6491. var event = this.mapEvent.get(JSCHART_EVENT_ID.RECV_HISTROY_DATA);
  6492. var data = { HistoryData: bindData, Stock: { Symbol: this.Symbol, Name: this.Name } }
  6493. event.Callback(event, data, this);
  6494. }
  6495. else //老的回调暂时保留
  6496. {
  6497. if (typeof (this.UpdateUICallback) == 'function') this.UpdateUICallback('RecvHistroyData', this); //单词拼写错误, 请使用下面的回调
  6498. if (typeof (this.UpdateUICallback) == 'function') this.UpdateUICallback('RecvHistoryData', this);
  6499. }
  6500. }
  6501. this.ReqeustHistoryMinuteData = function ()
  6502. {
  6503. var self = this;
  6504. this.CancelAutoUpdate();
  6505. this.ChartSplashPaint.SetTitle(this.LoadDataSplashTitle);
  6506. this.ChartSplashPaint.EnableSplash(true);
  6507. this.ResetDragDownload();
  6508. this.Draw();
  6509. if (this.NetworkFilter)
  6510. {
  6511. var obj =
  6512. {
  6513. Name: 'KLineChartContainer::ReqeustHistoryMinuteData', //类名
  6514. Explain: '1分钟K线数据',
  6515. Request:
  6516. {
  6517. Url: self.MinuteKLineApiUrl, Type: 'POST', Data: {
  6518. symbol: self.Symbol, count: self.MaxRequestMinuteDayCount,
  6519. field: ["name", "symbol", "yclose", "open", "price", "high", "low", "vol"]
  6520. }
  6521. },
  6522. Self: this,
  6523. PreventDefault: false
  6524. };
  6525. this.NetworkFilter(obj, function (data) {
  6526. self.ChartSplashPaint.EnableSplash(false);
  6527. self.RecvMinuteHistoryData(data);
  6528. self.AutoUpdateEvent(true);
  6529. self.AutoUpdate();
  6530. });
  6531. if (obj.PreventDefault == true) return; //已被上层替换,不调用默认的网络请求
  6532. }
  6533. wx.request({
  6534. url: this.MinuteKLineApiUrl,
  6535. data:
  6536. {
  6537. "field": ["name","symbol","yclose","open","price","high","low","vol"],
  6538. "symbol": self.Symbol,
  6539. "start": -1,
  6540. "count": self.MaxRequestMinuteDayCount
  6541. },
  6542. method: 'POST',
  6543. dataType: "json",
  6544. success: function (data)
  6545. {
  6546. self.ChartSplashPaint.EnableSplash(false);
  6547. self.RecvMinuteHistoryData(data);
  6548. self.AutoUpdateEvent(true);
  6549. self.AutoUpdate();
  6550. }
  6551. });
  6552. }
  6553. this.RecvMinuteHistoryData = function (recvData)
  6554. {
  6555. var data = recvData.data;
  6556. var aryDayData = KLineChartContainer.JsonDataToMinuteHistoryData(data);
  6557. //原始数据
  6558. var sourceData = new ChartData();
  6559. sourceData.Data = aryDayData;
  6560. sourceData.DataType = 1; //0=日线数据 1=分钟数据
  6561. sourceData.Symbol = data.symbol;
  6562. this.SourceData = sourceData;
  6563. if (this.BeforeBindMainData) this.BeforeBindMainData("RecvMinuteHistoryData");
  6564. //显示的数据
  6565. var bindData = new ChartData();
  6566. bindData.Data = aryDayData;
  6567. bindData.Right = this.Right;
  6568. bindData.Period = this.Period;
  6569. bindData.DataType = 1;
  6570. bindData.Symbol = data.symbol;
  6571. if (ChartData.IsMinutePeriod(bindData.Period, false) && !this.IsApiPeriod) //周期数据
  6572. {
  6573. var periodData = sourceData.GetPeriodData(bindData.Period);
  6574. bindData.Data = periodData;
  6575. }
  6576. //绑定数据
  6577. this.Symbol = data.symbol;
  6578. this.Name = data.name;
  6579. this.BindMainData(bindData, this.PageSize);
  6580. if (this.AfterBindMainData) this.AfterBindMainData("RecvMinuteHistoryData");
  6581. this.Frame.SetSizeChage(true);
  6582. this.BindInstructionIndexData(bindData); //执行指示脚本
  6583. var firstSubFrame; //主窗口
  6584. for (var i = 0; i < this.Frame.SubFrame.length; ++i)
  6585. {
  6586. if (i == 0) firstSubFrame = this.Frame.SubFrame[i].Frame;
  6587. this.BindIndexData(i, bindData);
  6588. }
  6589. if (firstSubFrame && firstSubFrame.YSplitOperator)
  6590. {
  6591. firstSubFrame.YSplitOperator.Symbol = this.Symbol; //绑定代码
  6592. firstSubFrame.YSplitOperator.Data = this.ChartPaint[0].Data; //K线数据
  6593. }
  6594. this.OverlayChartPaint[0].Data = null; //分钟数据不支持叠加 清空
  6595. //刷新画图
  6596. this.UpdataDataoffset(); //更新数据偏移
  6597. this.UpdatePointByCursorIndex(); //更新十字光标位子
  6598. this.UpdateFrameMaxMin(); //调整坐标最大 最小值
  6599. this.Frame.SetSizeChage(true);
  6600. this.Draw();
  6601. if (this.mapEvent.has(JSCHART_EVENT_ID.RECV_HISTROY_DATA))
  6602. {
  6603. var event = this.mapEvent.get(JSCHART_EVENT_ID.RECV_HISTROY_DATA);
  6604. var data = { HistoryData: bindData, Stock: { Symbol: this.Symbol, Name: this.Name } }
  6605. event.Callback(event, data, this);
  6606. }
  6607. else
  6608. {
  6609. if (typeof (this.UpdateUICallback) == 'function') this.UpdateUICallback('RecvMinuteHistoryData', this);
  6610. }
  6611. }
  6612. //请求实时行情数据
  6613. this.RequestRealtimeData = function ()
  6614. {
  6615. var self = this;
  6616. if (this.NetworkFilter)
  6617. {
  6618. var obj =
  6619. {
  6620. Name: 'KLineChartContainer::RequestRealtimeData', //类名::函数名
  6621. Explain: '当天最新日线数据',
  6622. Request:
  6623. {
  6624. Url: self.RealtimeApiUrl, Data: {
  6625. symbol: [self.Symbol],
  6626. field: ["name", "symbol", "yclose", "open", "price", "high", "low", "vol", "amount", "date", "time"]
  6627. }, Type: 'POST'
  6628. },
  6629. Self: this,
  6630. PreventDefault: false
  6631. };
  6632. this.NetworkFilter(obj, function (data) {
  6633. self.RecvRealtimeData(data);
  6634. self.AutoUpdate();
  6635. });
  6636. if (obj.PreventDefault == true) return; //已被上层替换,不调用默认的网络请求
  6637. }
  6638. wx.request({
  6639. url: this.RealtimeApiUrl,
  6640. data:
  6641. {
  6642. "field": ["name","symbol","yclose","open","price","high","low","vol","amount","date","time"],
  6643. "symbol": [self.Symbol],
  6644. "start": -1
  6645. },
  6646. method: 'POST',
  6647. dataType: "json",
  6648. async: true,
  6649. success: function (data) {
  6650. self.RecvRealtimeData(data);
  6651. self.AutoUpdate();
  6652. }
  6653. });
  6654. }
  6655. this.RecvRealtimeData = function (recvdata)
  6656. {
  6657. if (this.IsOnTouch == true) return; //正在操作中不更新数据
  6658. var data=recvdata.data;
  6659. if (!data || !data.stock || !data.stock[0] || this.Symbol != data.stock[0].symbol)
  6660. {
  6661. JSConsole.Chart.Log('[KLineChartContainer::RecvRealtimeData] recvdata error', recvdata);
  6662. return;
  6663. }
  6664. var realtimeData = KLineChartContainer.JsonDataToRealtimeData(data);
  6665. var item = this.SourceData.Data[this.SourceData.Data.length - 1]; //最新的一条数据
  6666. var lastDataCount = this.GetHistoryDataCount(); //保存下上一次的数据个数
  6667. if (item.Date == realtimeData.Date) //实时行情数据更新
  6668. {
  6669. //JSConsole.Chart.Log('[KLineChartContainer::RecvRealtimeData] update kline by minute data', realtimeData);
  6670. item.Close = realtimeData.Close;
  6671. item.High = realtimeData.High;
  6672. item.Low = realtimeData.Low;
  6673. item.Vol = realtimeData.Vol;
  6674. item.Amount = realtimeData.Amount;
  6675. }
  6676. else if (item.Date < realtimeData.Date) //新增加数据
  6677. {
  6678. JSConsole.Chart.Log('[KLineChartContainer::RecvRealtimeData] insert kline by minute data', realtimeData);
  6679. var newItem = new HistoryData();
  6680. newItem.YClose = realtimeData.YClose;
  6681. newItem.Open = realtimeData.Open;
  6682. newItem.Close = realtimeData.Close;
  6683. newItem.High = realtimeData.High;
  6684. newItem.Low = realtimeData.Low;
  6685. newItem.Vol = realtimeData.Vol;
  6686. newItem.Amount = realtimeData.Amount;
  6687. newItem.Date = realtimeData.Date;
  6688. //没有前收盘就用上一个数据的收盘价
  6689. if (!IFrameSplitOperator.IsNumber(newItem.YClose) && this.SourceData.Data.length>0)
  6690. newItem.YClose=this.SourceData.Data[this.SourceData.Data.length-1].YClose;
  6691. this.SourceData.Data.push(newItem);
  6692. }
  6693. else
  6694. {
  6695. return;
  6696. }
  6697. var bindData = new ChartData();
  6698. bindData.Data = this.SourceData.Data;
  6699. bindData.Period = this.Period;
  6700. bindData.Right = this.Right;
  6701. bindData.DataType = this.SourceData.DataType;
  6702. bindData.Symbol = this.Symbol;
  6703. if (bindData.Right > 0 && ChartData.IsDayPeriod(bindData.Period,true) && !this.IsApiPeriod) //复权(日线数据才复权)
  6704. {
  6705. var rightData = bindData.GetRightDate(bindData.Right);
  6706. bindData.Data = rightData;
  6707. }
  6708. if (!this.IsApiPeriod)
  6709. {
  6710. if (ChartData.IsDayPeriod(bindData.Period, false) || ChartData.IsMinutePeriod(bindData.Period, false)) //周期数据 (0= 日线,4=1分钟线 不需要处理)
  6711. {
  6712. var periodData = bindData.GetPeriodData(bindData.Period);
  6713. bindData.Data = periodData;
  6714. }
  6715. }
  6716. //绑定数据
  6717. this.UpdateMainData(bindData, lastDataCount);
  6718. this.Frame.SetSizeChage(true);
  6719. this.BindInstructionIndexData(bindData); //执行指示脚本
  6720. for (var i = 0; i < this.Frame.SubFrame.length; ++i) {
  6721. this.BindIndexData(i, bindData);
  6722. }
  6723. //刷新画图
  6724. this.UpdataDataoffset(); //更新数据偏移
  6725. this.UpdatePointByCursorIndex(); //更新十字光标位子
  6726. this.UpdateFrameMaxMin(); //调整坐标最大 最小值
  6727. this.Frame.SetSizeChage(true);
  6728. this.Draw();
  6729. this.SendKLineUpdateEvent(bindData);
  6730. }
  6731. this.GetHistoryDataCount = function ()
  6732. {
  6733. var frameHisdata = null;
  6734. if (!this.Frame.Data) frameHisdata = this.Frame.Data;
  6735. else if (this.Frame.SubFrame && this.Frame.SubFrame[0]) frameHisdata = this.Frame.SubFrame[0].Frame.Data;
  6736. if (!frameHisdata) return -1;
  6737. var lastDataCount = frameHisdata.Data.length; //上一个的数据长度
  6738. return lastDataCount;
  6739. }
  6740. this.RequestMinuteRealtimeData = function ()
  6741. {
  6742. var self = this;
  6743. if (this.NetworkFilter)
  6744. {
  6745. var obj =
  6746. {
  6747. Name: 'KLineChartContainer::RequestMinuteRealtimeData', //类名::
  6748. Explain: '当天1分钟K线数据',
  6749. Request: {
  6750. Url: self.RealtimeApiUrl, Data: {
  6751. symbol: [self.Symbol],
  6752. field: ["name", "symbol", "price", "yclose", "minutecount", "minute", "date", "time"]
  6753. }, Type: 'POST'
  6754. },
  6755. Self: this,
  6756. PreventDefault: false
  6757. };
  6758. this.NetworkFilter(obj, function (data) {
  6759. self.RecvMinuteRealtimeData(data);
  6760. self.AutoUpdate();
  6761. });
  6762. if (obj.PreventDefault == true) return; //已被上层替换,不调用默认的网络请求
  6763. }
  6764. wx.request({
  6765. url: this.RealtimeApiUrl,
  6766. data:
  6767. {
  6768. "field": ["name", "symbol", "price", "yclose", "minutecount", "minute", "date", "time"],
  6769. "symbol": [self.Symbol],
  6770. "start": -1
  6771. },
  6772. method: 'POST',
  6773. dataType: "json",
  6774. async: true,
  6775. success: function (data) {
  6776. self.RecvMinuteRealtimeData(data);
  6777. self.AutoUpdate();
  6778. }
  6779. });
  6780. }
  6781. this.SetSourceDatatLimit = function (aryLimit)
  6782. {
  6783. this.SourceDataLimit = new Map();
  6784. for (var i in aryLimit)
  6785. {
  6786. var item = aryLimit[i];
  6787. this.SourceDataLimit.set(item.Period, item.MaxCount); //每个周期缓存数据最大个数 key=周期 value=最大个数
  6788. JSConsole.Chart.Log(`[KLineChartContainer::SetSourceDatatLimit] Period=${item.Period}, MaxCount=${item.MaxCount}`);
  6789. }
  6790. }
  6791. this.ReduceSourceData = function ()
  6792. {
  6793. if (!this.SourceDataLimit) return;
  6794. if (!this.SourceDataLimit.has(this.Period)) return;
  6795. var limitCount = this.SourceDataLimit.get(this.Period);
  6796. if (limitCount < 50) return;
  6797. var frameHisdata = null;
  6798. if (!this.Frame.Data) frameHisdata = this.Frame.Data;
  6799. else if (this.Frame.SubFrame && this.Frame.SubFrame[0]) frameHisdata = this.Frame.SubFrame[0].Frame.Data;
  6800. if (!frameHisdata) return;
  6801. var dataOffset = frameHisdata.DataOffset;
  6802. var removeCount = 0;
  6803. while (this.SourceData.Data.length > limitCount)
  6804. {
  6805. this.SourceData.Data.shift();
  6806. --dataOffset;
  6807. ++removeCount;
  6808. }
  6809. if (removeCount > 0)
  6810. {
  6811. if (dataOffset < 0) dataOffset = 0;
  6812. frameHisdata.DataOffset = dataOffset;
  6813. JSConsole.Chart.Log(`[KLineChartContainer::ReduceSourceData] remove data ${removeCount}, dataOffset=${dataOffset}`);
  6814. }
  6815. }
  6816. this.RecvMinuteRealtimeData = function (recvData)
  6817. {
  6818. var data=recvData.data;
  6819. if (this.IsOnTouch == true) return; //正在操作中不更新数据
  6820. if (data.ver == 2.0)
  6821. {
  6822. this.RecvMinuteRealtimeDataV2(data); //v2.0数据版本
  6823. return;
  6824. }
  6825. if (!data.stock || !data.stock[0] || this.Symbol != data.stock[0].symbol) return;
  6826. var realtimeData = KLineChartContainer.JsonDataToMinuteRealtimeData(data);
  6827. if (!realtimeData) return;
  6828. if (this.IsApiPeriod) this.ReduceSourceData(); //减少数据
  6829. var lastDataCount = this.GetHistoryDataCount(); //保存下上一次的数据个数
  6830. var lastSourceDataCount = this.SourceData.Data.length;
  6831. if (!this.SourceData.MergeMinuteData(realtimeData)) return;
  6832. JSConsole.Chart.Log(`[KLineChartContainer::RecvMinuteRealtimeData] update kline by 1 minute data [${lastSourceDataCount}->${this.SourceData.Data.length}]`);
  6833. var bindData = new ChartData();
  6834. bindData.Data = this.SourceData.Data;
  6835. bindData.Period = this.Period;
  6836. bindData.Right = this.Right;
  6837. bindData.DataType = this.SourceData.DataType;
  6838. bindData.Symbol = this.Symbol;
  6839. if (bindData.Right > 0 && ChartData.IsDayPeriod(bindData.Period,true) && !this.IsApiPeriod) //复权(日线数据才复权)
  6840. {
  6841. var rightData = bindData.GetRightDate(bindData.Right);
  6842. bindData.Data = rightData;
  6843. }
  6844. if (!this.IsApiPeriod)
  6845. {
  6846. if (ChartData.IsDayPeriod(bindData.Period, false) || ChartData.IsMinutePeriod(bindData.Period, false)) //周期数据 (0= 日线,4=1分钟线 不需要处理)
  6847. {
  6848. var periodData = bindData.GetPeriodData(bindData.Period);
  6849. bindData.Data = periodData;
  6850. }
  6851. }
  6852. //绑定数据
  6853. this.UpdateMainData(bindData, lastDataCount);
  6854. this.Frame.SetSizeChage(true);
  6855. this.BindInstructionIndexData(bindData); //执行指示脚本
  6856. for (var i = 0; i < this.Frame.SubFrame.length; ++i) {
  6857. this.BindIndexData(i, bindData);
  6858. }
  6859. //刷新画图
  6860. this.UpdataDataoffset(); //更新数据偏移
  6861. this.UpdatePointByCursorIndex(); //更新十字光标位子
  6862. this.UpdateFrameMaxMin(); //调整坐标最大 最小值
  6863. this.Frame.SetSizeChage(true);
  6864. this.Draw();
  6865. this.SendKLineUpdateEvent(bindData);
  6866. }
  6867. this.RecvMinuteRealtimeDataV2 = function (data) //新版本的
  6868. {
  6869. if (this.IsOnTouch == true) return; //正在操作中不更新数据
  6870. var aryMinuteData = KLineChartContainer.JsonDataToMinuteHistoryData(data);
  6871. if (!aryMinuteData || aryMinuteData.length <= 0) return;
  6872. if (this.IsApiPeriod) this.ReduceSourceData(); //减少数据
  6873. var lastDataCount = this.GetHistoryDataCount(); //保存下上一次的数据个数
  6874. if (!this.SourceData.MergeMinuteData(aryMinuteData)) return;
  6875. JSConsole.Chart.Log(`[KLineChartContainer::RecvMinuteRealtimeDataV2] update kline by 1 minute data [${lastDataCount}->${this.SourceData.Data.length}]`);
  6876. var bindData = new ChartData();
  6877. bindData.Data = this.SourceData.Data;
  6878. bindData.Period = this.Period;
  6879. bindData.Right = this.Right;
  6880. bindData.DataType = this.SourceData.DataType;
  6881. bindData.Symbol = this.Symbol;
  6882. if (bindData.Right > 0 && ChartData.IsDayPeriod(bindData.Period, true) && !this.IsApiPeriod) //复权(日线数据才复权)
  6883. {
  6884. var rightData = bindData.GetRightDate(bindData.Right);
  6885. bindData.Data = rightData;
  6886. }
  6887. if ((ChartData.IsDayPeriod(bindData.Period, false) || ChartData.IsMinutePeriod(bindData.Period, false)) && !this.IsApiPeriod) //周期数据 (0= 日线,4=1分钟线 不需要处理)
  6888. {
  6889. var periodData = bindData.GetPeriodData(bindData.Period);
  6890. bindData.Data = periodData;
  6891. }
  6892. //绑定数据
  6893. this.UpdateMainData(bindData, lastDataCount);
  6894. this.Frame.SetSizeChage(true);
  6895. this.BindInstructionIndexData(bindData); //执行指示脚本
  6896. for (var i = 0; i < this.Frame.SubFrame.length; ++i) {
  6897. this.BindIndexData(i, bindData);
  6898. }
  6899. //刷新画图
  6900. this.UpdataDataoffset(); //更新数据偏移
  6901. this.UpdatePointByCursorIndex(); //更新十字光标位子
  6902. this.UpdateFrameMaxMin(); //调整坐标最大 最小值
  6903. this.Frame.SetSizeChage(true);
  6904. this.Draw();
  6905. this.SendKLineUpdateEvent(bindData);
  6906. }
  6907. this.SendKLineUpdateEvent = function (bindData)
  6908. {
  6909. var event = this.GetEvent(JSCHART_EVENT_ID.RECV_KLINE_UPDATE_DATA);
  6910. if (event && event.Callback)
  6911. {
  6912. var data = { HistoryData: bindData, Stock: { Symbol: this.Symbol, Name: this.Name } }
  6913. event.Callback(event, data, this);
  6914. return true;
  6915. }
  6916. return false;
  6917. }
  6918. //周期切换
  6919. this.ChangePeriod = function (period, option)
  6920. {
  6921. var isChangeKLineDrawType = false;
  6922. var right=null; //复权
  6923. if (option && option.KLine)
  6924. {
  6925. if (IFrameSplitOperator.IsNumber(option.KLine.DrawType)) isChangeKLineDrawType = true;
  6926. if (IFrameSplitOperator.IsNumber(option.KLine.Right)) right=option.KLine.Right;
  6927. };
  6928. if (this.Period == period)
  6929. {
  6930. if (isChangeKLineDrawType) this.ChangeKLineDrawType(option.KLine.DrawType);
  6931. return;
  6932. }
  6933. if (isChangeKLineDrawType) this.ChangeKLineDrawType(option.KLine.DrawType, false); //切换K线类型, 不重绘
  6934. var isDataTypeChange = true;
  6935. if (this.SourceData)
  6936. {
  6937. var isDataTypeChange=false;
  6938. if (period > CUSTOM_DAY_PERIOD_START && period <= CUSTOM_DAY_PERIOD_END)
  6939. {
  6940. if (this.SourceData.DataType != 0) isDataTypeChange = true;
  6941. }
  6942. else if ((period > CUSTOM_MINUTE_PERIOD_START && period <= CUSTOM_MINUTE_PERIOD_END) ||
  6943. (period > CUSTOM_SECOND_PERIOD_START && period <= CUSTOM_SECOND_PERIOD_END))
  6944. {
  6945. if (this.SourceData.DataType != 1) isDataTypeChange = true;
  6946. }
  6947. else
  6948. {
  6949. switch (period)
  6950. {
  6951. case 0: //日线
  6952. case 1: //周
  6953. case 2: //月
  6954. case 3: //年
  6955. case 21: //双周
  6956. if (this.SourceData.DataType != 0) isDataTypeChange = true;
  6957. break;
  6958. case 4: //1分钟
  6959. case 5: //5分钟
  6960. case 6: //15分钟
  6961. case 7: //30分钟
  6962. case 8: //60分钟
  6963. case 11: //2小时
  6964. case 12: //4小时
  6965. if (this.SourceData.DataType != 1) isDataTypeChange = true;
  6966. break;
  6967. }
  6968. }
  6969. }
  6970. this.Period = period;
  6971. if (right!=null) this.Right=right;
  6972. if (isDataTypeChange == false && !this.IsApiPeriod)
  6973. {
  6974. this.Update();
  6975. return;
  6976. }
  6977. if (ChartData.IsDayPeriod(this.Period, true))
  6978. {
  6979. this.CancelAutoUpdate(); //先停止更新
  6980. this.AutoUpdateEvent(false);
  6981. this.RequestHistoryData(); //请求日线数据
  6982. //this.ReqeustKLineInfoData();
  6983. }
  6984. else if (ChartData.IsMinutePeriod(this.Period, true) || ChartData.IsSecondPeriod(this.Period))
  6985. {
  6986. this.CancelAutoUpdate(); //先停止更新
  6987. this.AutoUpdateEvent(false);
  6988. this.ReqeustHistoryMinuteData(); //请求分钟数据
  6989. }
  6990. }
  6991. //复权切换
  6992. this.ChangeRight = function (right)
  6993. {
  6994. if (IsIndexSymbol(this.Symbol)) return; //指数没有复权
  6995. if (right < 0 || right > 2) return;
  6996. if (this.Right == right) return;
  6997. this.Right = right;
  6998. if (!this.IsApiPeriod)
  6999. {
  7000. this.Update();
  7001. return;
  7002. }
  7003. else
  7004. {
  7005. if (ChartData.IsDayPeriod(this.Period, true))
  7006. {
  7007. this.CancelAutoUpdate(); //先停止更新
  7008. this.AutoUpdateEvent(false);
  7009. this.RequestHistoryData(); //请求日线数据
  7010. //this.ReqeustKLineInfoData();
  7011. }
  7012. else if (ChartData.IsMinutePeriod(this.Period, true) || ChartData.IsSecondPeriod(this.Period))
  7013. {
  7014. this.CancelAutoUpdate(); //先停止更新
  7015. this.AutoUpdateEvent(false);
  7016. this.ReqeustHistoryMinuteData(); //请求分钟数据
  7017. }
  7018. }
  7019. }
  7020. //删除某一个窗口的指标
  7021. this.DeleteIndexPaint = function (windowIndex) {
  7022. let paint = new Array(); //踢出当前窗口的指标画法
  7023. for (let i in this.ChartPaint) {
  7024. let item = this.ChartPaint[i];
  7025. if (i == 0 || item.ChartFrame != this.Frame.SubFrame[windowIndex].Frame)
  7026. paint.push(item);
  7027. }
  7028. this.Frame.SubFrame[windowIndex].Frame.YSpecificMaxMin = null; //清空指定最大最小值
  7029. this.Frame.SubFrame[windowIndex].Frame.IsLocked = false; //解除上锁
  7030. this.Frame.SubFrame[windowIndex].Frame.YSplitScale = null; //清空固定刻度
  7031. this.ChartPaint = paint;
  7032. //清空东条标题
  7033. var titleIndex = windowIndex + 1;
  7034. this.TitlePaint[titleIndex].Data = [];
  7035. this.TitlePaint[titleIndex].Title = null;
  7036. }
  7037. this.ShowKLine = function (isShow) //显示隐藏主图K线
  7038. {
  7039. if (this.ChartPaint.length <= 0 || !this.ChartPaint[0]) return;
  7040. this.ChartPaint[0].IsShow = isShow;
  7041. }
  7042. this.SetInstructionData = function (type, instructionData) //设置指示数据
  7043. {
  7044. if (this.ChartPaint.length <= 0 || !this.ChartPaint[0]) return;
  7045. if (type == 2) //五彩K线
  7046. {
  7047. this.ChartPaint[0].ColorData = instructionData.Data;
  7048. }
  7049. else if (type == 1) //专家指示
  7050. {
  7051. this.ChartPaint[0].TradeData = { Sell: instructionData.Sell, Buy: instructionData.Buy };
  7052. }
  7053. }
  7054. this.ChangeInstructionIndex = function (indexName)
  7055. {
  7056. let scriptData = new JSCommonIndexScript.JSIndexScript();
  7057. let indexInfo = scriptData.Get(indexName);
  7058. if (!indexInfo) return;
  7059. if (indexInfo.InstructionType != 1 && indexInfo.InstructionType != 2) return;
  7060. this.ChangeInstructionScriptIndex(indexInfo);
  7061. }
  7062. this.ChangeInstructionScriptIndex = function (indexData)
  7063. {
  7064. if (indexData.InstructionType == 1) //交易系统
  7065. {
  7066. this.TradeIndex = new ScriptIndex(indexData.Name, indexData.Script, indexData.Args, indexData); //脚本执行
  7067. }
  7068. else if (indexData.InstructionType == 2) //五彩K线
  7069. {
  7070. this.ColorIndex = new ScriptIndex(indexData.Name, indexData.Script, indexData.Args, indexData); //脚本执行
  7071. }
  7072. else
  7073. {
  7074. return;
  7075. }
  7076. var bindData = this.ChartPaint[0].Data;
  7077. this.BindInstructionIndexData(bindData);
  7078. this.UpdataDataoffset(); //更新数据偏移
  7079. this.UpdateFrameMaxMin(); //调整坐标最大 最小值
  7080. this.Draw();
  7081. }
  7082. this.CancelInstructionIndex = function () //取消指示数据
  7083. {
  7084. if (this.ChartPaint.length <= 0 || !this.ChartPaint[0]) return;
  7085. this.ColorIndex=null;
  7086. this.TradeIndex=null;
  7087. this.ChartPaint[0].ColorData = null; //五彩K线数据取消掉
  7088. this.ChartPaint[0].TradeData = null; //交易系统数据取消
  7089. this.UpdataDataoffset(); //更新数据偏移
  7090. this.UpdateFrameMaxMin(); //调整坐标最大 最小值
  7091. this.Draw();
  7092. }
  7093. //切换成 脚本指标
  7094. this.ChangeScriptIndex = function (windowIndex, indexData)
  7095. {
  7096. this.DeleteIndexPaint(windowIndex);
  7097. this.WindowIndex[windowIndex] = new ScriptIndex(indexData.Name, indexData.Script, indexData.Args, indexData); //脚本执行
  7098. var bindData = this.ChartPaint[0].Data;
  7099. this.BindIndexData(windowIndex, bindData); //执行脚本
  7100. this.UpdataDataoffset(); //更新数据偏移
  7101. this.UpdateFrameMaxMin(); //调整坐标最大 最小值
  7102. this.Draw();
  7103. }
  7104. //切换api指标
  7105. this.ChangeAPIIndex = function (windowIndex, indexData)
  7106. {
  7107. this.DeleteIndexPaint(windowIndex);
  7108. //使用API挂接指标数据 API:{ Name:指标名字, Script:指标脚本可以为空, Args:参数可以为空, Url:指标执行地址 }
  7109. var apiItem = indexData.API;
  7110. this.WindowIndex[windowIndex] = new APIScriptIndex(apiItem.Name, apiItem.Script, apiItem.Args, indexData);
  7111. var bindData = this.ChartPaint[0].Data;
  7112. this.BindIndexData(windowIndex, bindData); //执行脚本
  7113. this.UpdataDataoffset(); //更新数据偏移
  7114. this.UpdateFrameMaxMin(); //调整坐标最大 最小值
  7115. this.Draw();
  7116. }
  7117. //切换指标 指定切换窗口指标
  7118. this.ChangeIndex = function (windowIndex, indexName, option)
  7119. {
  7120. if (option && option.API) //切换api指标
  7121. return this.ChangeAPIIndex(windowIndex, option);
  7122. var indexItem = JSIndexMap.Get(indexName);
  7123. if (!indexItem)
  7124. {
  7125. //查找系统指标
  7126. let scriptData = new JSCommonIndexScript.JSIndexScript();
  7127. let indexInfo = scriptData.Get(indexName);
  7128. if (!indexInfo) return;
  7129. if (indexInfo.IsMainIndex)
  7130. {
  7131. windowIndex = 0; //主图指标只能在主图显示
  7132. }
  7133. else
  7134. {
  7135. if (windowIndex == 0) windowIndex = 1; //幅图指标,不能再主图显示
  7136. }
  7137. let indexData = indexInfo;
  7138. if (option)
  7139. {
  7140. if (option.FloatPrecision >= 0) indexData.FloatPrecision = option.FloatPrecision;
  7141. if (option.StringFormat > 0) indexData.StringFormat = option.StringFormat;
  7142. if (option.Args) indexData.Args = option.Args;
  7143. }
  7144. return this.ChangeScriptIndex(windowIndex, indexData);
  7145. }
  7146. //主图指标
  7147. if (indexItem.IsMainIndex)
  7148. {
  7149. if (windowIndex > 0) windowIndex = 0; //主图指标只能在主图显示
  7150. }
  7151. else
  7152. {
  7153. if (windowIndex == 0) windowIndex = 1; //幅图指标,不能再主图显示
  7154. }
  7155. var paint = new Array(); //踢出当前窗口的指标画法
  7156. for (var i in this.ChartPaint)
  7157. {
  7158. var item = this.ChartPaint[i];
  7159. if (i == 0 || item.ChartFrame != this.Frame.SubFrame[windowIndex].Frame) paint.push(item);
  7160. }
  7161. //清空指定最大最小值
  7162. this.Frame.SubFrame[windowIndex].Frame.YSpecificMaxMin = null;
  7163. this.Frame.SubFrame[windowIndex].Frame.YSplitScale=null;
  7164. this.ChartPaint = paint;
  7165. //清空东条标题
  7166. var titleIndex = windowIndex + 1;
  7167. this.TitlePaint[titleIndex].Data = [];
  7168. this.TitlePaint[titleIndex].Title = null;
  7169. this.WindowIndex[windowIndex] = indexItem.Create();
  7170. this.CreateWindowIndex(windowIndex);
  7171. var bindData = this.ChartPaint[0].Data;
  7172. this.BindIndexData(windowIndex, bindData);
  7173. this.UpdataDataoffset(); //更新数据偏移
  7174. this.UpdateFrameMaxMin(); //调整坐标最大 最小值
  7175. this.Draw();
  7176. }
  7177. this.ChangeKLineDrawType = function (drawType, isDraw)
  7178. {
  7179. if (this.KLineDrawType == drawType) return;
  7180. this.KLineDrawType = drawType;
  7181. for (var i in this.ChartPaint)
  7182. {
  7183. var item = this.ChartPaint[i];
  7184. if (i == 0) item.DrawType = this.KLineDrawType;
  7185. else if (item.ClassName == 'ChartVolStick') item.KLineDrawType = this.KLineDrawType
  7186. }
  7187. if (this.OverlayChartPaint[0]) this.OverlayChartPaint[0].DrawType = this.KLineDrawType; //叠加K线修改
  7188. if (isDraw == false) return;
  7189. this.UpdateFrameMaxMin(); //调整坐标最大 最小值
  7190. this.Frame.SetSizeChage(true);
  7191. this.Draw();
  7192. }
  7193. //获取当天的显示的指标
  7194. this.GetIndexInfo = function ()
  7195. {
  7196. var aryIndex = [];
  7197. for (var i in this.WindowIndex)
  7198. {
  7199. var item = this.WindowIndex[i];
  7200. var info = { Name: item.Name };
  7201. if (item.ID) info.ID = item.ID;
  7202. aryIndex.push(info);
  7203. }
  7204. return aryIndex;
  7205. }
  7206. this.ChangeIndexTemplate = function (option) //切换指标模板 可以设置指标窗口个数 每个窗口的指标
  7207. {
  7208. if (!option.Windows) return;
  7209. var count = option.Windows.length;
  7210. if (count <= 0) return;
  7211. var currentLength = this.Frame.SubFrame.length;
  7212. var period=null, right=null;
  7213. if (option.KLine)
  7214. {
  7215. if (IFrameSplitOperator.IsNumber(option.KLine.Period) && option.KLine.Period!=this.Period) period=option.KLine.Period; //周期
  7216. if (IFrameSplitOperator.IsNumber(option.KLine.Right) && option.KLine.Right!=this.Right) right=option.KLine.Right; //复权
  7217. }
  7218. var bRefreshData= (period!=null || right!=null);
  7219. //清空所有的指标图型
  7220. for (var i = 0; i < currentLength; ++i)
  7221. {
  7222. this.DeleteIndexPaint(i);
  7223. var frame = this.Frame.SubFrame[i];
  7224. frame.YSpecificMaxMin = null;
  7225. frame.IsLocked = false;
  7226. frame.YSplitScale = null;
  7227. }
  7228. if (currentLength > count)
  7229. {
  7230. this.Frame.SubFrame.splice(count, currentLength - count);
  7231. this.WindowIndex.splice(count, currentLength - count);
  7232. }
  7233. else
  7234. {
  7235. for (var i = currentLength; i < count; ++i) //创建新的指标窗口
  7236. {
  7237. var subFrame = this.CreateSubFrameItem(i);
  7238. this.Frame.SubFrame[i] = subFrame;
  7239. var titlePaint = new DynamicChartTitlePainting();
  7240. titlePaint.Frame = this.Frame.SubFrame[i].Frame;
  7241. titlePaint.Canvas = this.Canvas;
  7242. titlePaint.LanguageID = this.LanguageID;
  7243. this.TitlePaint[i + 1] = titlePaint;
  7244. }
  7245. }
  7246. var systemScript = new JSCommonIndexScript.JSIndexScript();
  7247. var bindData = this.ChartPaint[0].Data;
  7248. for (var i = 0; i < count; ++i)
  7249. {
  7250. var windowIndex = i;
  7251. var item=option.Windows[i];
  7252. var frameItem=null;
  7253. if(option.Frame && option.Frame.length>i) frameItem=option.Frame[i];
  7254. var titleIndex = windowIndex + 1;
  7255. this.TitlePaint[titleIndex].Data = [];
  7256. this.TitlePaint[titleIndex].Title = null;
  7257. if (item.Script) //自定义指标
  7258. {
  7259. this.WindowIndex[i]=new ScriptIndex(item.Name,item.Script,item.Args,item); //脚本执行
  7260. if (!bRefreshData) this.BindIndexData(windowIndex,bindData); //执行脚本
  7261. }
  7262. else
  7263. {
  7264. var indexID = item.Index;
  7265. var indexItem = JSIndexMap.Get(indexID);
  7266. if (indexItem)
  7267. {
  7268. this.WindowIndex[i] = indexItem.Create();
  7269. this.CreateWindowIndex(windowIndex);
  7270. if (!bRefreshData) this.BindIndexData(windowIndex, bindData);
  7271. }
  7272. else
  7273. {
  7274. var indexInfo = systemScript.Get(indexID);
  7275. if (indexInfo)
  7276. {
  7277. var args = indexInfo.Args;
  7278. if (option.Windows[i].Args) args = option.Windows[i].Args;
  7279. let indexData =
  7280. {
  7281. Name: indexInfo.Name, Script: indexInfo.Script, Args: args, ID: indexID,
  7282. //扩展属性 可以是空
  7283. KLineType: indexInfo.KLineType, YSpecificMaxMin: indexInfo.YSpecificMaxMin, YSplitScale: indexInfo.YSplitScale,
  7284. FloatPrecision: indexInfo.FloatPrecision, Condition: indexInfo.Condition,
  7285. OutName:indexInfo.OutName
  7286. };
  7287. this.WindowIndex[i] = new ScriptIndex(indexData.Name, indexData.Script, indexData.Args, indexData); //脚本执行
  7288. if (!bRefreshData) this.BindIndexData(windowIndex, bindData); //执行脚本
  7289. }
  7290. }
  7291. }
  7292. if (item.IndexParamSpace >= 0) this.Frame.SubFrame[i].Frame.IndexParamSpace = item.IndexParamSpace;
  7293. if (item.IsDrawTitleBG==true) this.Frame.SubFrame[i].Frame.IsDrawTitleBG=item.IsDrawTitleBG;
  7294. if (frameItem)
  7295. {
  7296. if (frameItem.SplitCount) this.Frame.SubFrame[i].Frame.YSplitOperator.SplitCount = frameItem.SplitCount;
  7297. if (frameItem.IsShowBorder == false) this.Frame.SubFrame[i].Frame.IsShowBorder = frameItem.IsShowBorder;
  7298. if (frameItem.IsShowXLine === false || frameItem.IsShowXLine ===true) this.Frame.SubFrame[i].Frame.IsShowXLine = frameItem.IsShowXLine;
  7299. if (frameItem.IsShowYLine===false ||frameItem.IsShowYLine===true) this.Frame.SubFrame[i].Frame.IsShowYLine=frameItem.IsShowYLine;
  7300. if (frameItem.IsShowLeftText === false || item.IsShowLeftText === true) this.Frame.SubFrame[i].Frame.IsShowYText[0] = frameItem.IsShowLeftText; //显示左边刻度
  7301. if (frameItem.IsShowRightText === false || item.IsShowRightText === true) this.Frame.SubFrame[i].Frame.IsShowYText[1] = frameItem.IsShowRightText; //显示右边刻度
  7302. }
  7303. }
  7304. //最后一个显示X轴坐标
  7305. for (var i = 0; i < this.Frame.SubFrame.length; ++i)
  7306. {
  7307. var item = this.Frame.SubFrame[i].Frame;
  7308. if (i == this.Frame.SubFrame.length - 1) item.XSplitOperator.ShowText = true;
  7309. else item.XSplitOperator.ShowText = false;
  7310. }
  7311. if (!bRefreshData)
  7312. {
  7313. this.UpdataDataoffset(); //更新数据偏移
  7314. this.Frame.SetSizeChage(true);
  7315. this.ResetFrameXYSplit();
  7316. this.UpdateFrameMaxMin(); //调整坐标最大 最小值
  7317. this.Draw();
  7318. }
  7319. else
  7320. {
  7321. this.Frame.SetSizeChage(true);
  7322. if (period!=null) this.ChangePeriod(period, option);
  7323. else if (right!=null) this.ChangeRight(right);
  7324. }
  7325. }
  7326. this.RemoveIndexWindow=function(id)
  7327. {
  7328. JSConsole.Chart.Log('[KLineChartContainer::RemoveIndexWindow] remove id', id);
  7329. if (id==0) return;
  7330. if (!this.Frame.SubFrame) return;
  7331. if (id>=this.Frame.SubFrame.length) return;
  7332. var delFrame=this.Frame.SubFrame[id].Frame;
  7333. this.DeleteIndexPaint(id);
  7334. this.Frame.SubFrame.splice(id,1);
  7335. this.WindowIndex.splice(id,1);
  7336. this.TitlePaint.splice(id+1,1); //删除对应的动态标题
  7337. for(var i=0;i<this.Frame.SubFrame.length;++i)
  7338. {
  7339. var item=this.Frame.SubFrame[i].Frame;
  7340. if (i==this.Frame.SubFrame.length-1) item.XSplitOperator.ShowText=true;
  7341. else item.XSplitOperator.ShowText=false;
  7342. item.Identify=i;
  7343. }
  7344. if (this.ChartDrawPicture.length>0)
  7345. {
  7346. var aryDrawPicture=[];
  7347. for(var i=0;i<this.ChartDrawPicture.length;++i)
  7348. {
  7349. var item=this.ChartDrawPicture[i];
  7350. if (item.Frame==delFrame) continue;
  7351. aryDrawPicture.push(item);
  7352. }
  7353. this.ChartDrawPicture=aryDrawPicture;
  7354. }
  7355. this.Frame.SetSizeChage(true);
  7356. this.UpdateFrameMaxMin();
  7357. this.ResetFrameXYSplit();
  7358. this.Draw();
  7359. }
  7360. this.CreateExtendChart = function (name, option) //创建扩展图形
  7361. {
  7362. var chart;
  7363. switch (name)
  7364. {
  7365. case 'KLineTooltip':
  7366. if (option.Create && typeof(option.Create)=='function') chart=option.Create();
  7367. else chart = new KLineTooltipPaint();
  7368. chart.Canvas = this.Canvas;
  7369. chart.ChartBorder = this.Frame.ChartBorder;
  7370. chart.ChartFrame = this.Frame;
  7371. chart.HQChart = this;
  7372. option.LanguageID = this.LanguageID;
  7373. chart.SetOption(option);
  7374. this.ExtendChartPaint.push(chart);
  7375. return chart;
  7376. case '背景图':
  7377. chart = new BackgroundPaint();
  7378. chart.Canvas = this.Canvas;
  7379. chart.ChartBorder = this.Frame.ChartBorder;
  7380. chart.ChartFrame = this.Frame;
  7381. chart.HQChart = this;
  7382. chart.SetOption(option);
  7383. this.ExtendChartPaint.push(chart);
  7384. return chart;
  7385. default:
  7386. return null;
  7387. }
  7388. }
  7389. //锁|解锁指标 { Index:指标名字,IsLocked:是否要锁上,Callback:回调 }
  7390. this.LockIndex = function (lockData) {
  7391. if (!lockData) return;
  7392. if (!lockData.IndexName) return;
  7393. for (let i in this.WindowIndex) {
  7394. let item = this.WindowIndex[i];
  7395. if (!item) conintue;
  7396. if (item.Name == lockData.IndexName) {
  7397. item.SetLock(lockData);
  7398. this.Update();
  7399. break;
  7400. }
  7401. }
  7402. }
  7403. this.TryClickLock = function (x, y)
  7404. {
  7405. for (let i in this.Frame.SubFrame)
  7406. {
  7407. var item = this.Frame.SubFrame[i];
  7408. if (!item.Frame.IsLocked) continue;
  7409. if (!item.Frame.LockPaint) continue;
  7410. var tooltip = new TooltipData();
  7411. if (!item.Frame.LockPaint.GetTooltipData(x, y, tooltip)) continue;
  7412. tooltip.HQChart = this;
  7413. if (tooltip.Data.Callback) tooltip.Data.Callback(tooltip);
  7414. return true;
  7415. }
  7416. return false;
  7417. }
  7418. this.TryClickIndexTitle=function(x,y)
  7419. {
  7420. for(var i in this.TitlePaint)
  7421. {
  7422. var item=this.TitlePaint[i];
  7423. if (!item.IsClickTitle) continue;
  7424. if (!item.IsClickTitle(x,y)) continue;
  7425. var data={ Point:{X:x, Y:y}, Title:item.Title, FrameID:item.Frame.Identify };
  7426. JSConsole.Chart.Log('[KLineChartContainer::TryClickIndexTitle] click title ', data);
  7427. var event=this.GetEvent(JSCHART_EVENT_ID.ON_CLICK_INDEXTITLE);
  7428. if (event && event.Callback) event.Callback(event,data,this);
  7429. return true;
  7430. }
  7431. return false;
  7432. }
  7433. this.StopAutoUpdate = function ()
  7434. {
  7435. this.IsAutoUpdate = false;
  7436. this.CancelAutoUpdate();
  7437. this.AutoUpdateEvent(false);
  7438. }
  7439. this.Update = function ()
  7440. {
  7441. if (!this.SourceData) return;
  7442. if (this.BeforeBindMainData) this.BeforeBindMainData('Update');
  7443. var bindData = new ChartData();
  7444. bindData.Data = this.SourceData.Data;
  7445. bindData.Period = this.Period;
  7446. bindData.Right = this.Right;
  7447. bindData.DataType = this.SourceData.DataType;
  7448. bindData.Symbol = this.Symbol;
  7449. if (bindData.Right > 0 && ChartData.IsDayPeriod(bindData.Period, true)) //复权(日线数据才复权)
  7450. {
  7451. var rightData = bindData.GetRightDate(bindData.Right);
  7452. bindData.Data = rightData;
  7453. }
  7454. if (ChartData.IsDayPeriod(bindData.Period, false) || ChartData.IsMinutePeriod(bindData.Period, false)) //周期数据 (0= 日线,4=1分钟线 不需要处理))
  7455. {
  7456. var periodData = bindData.GetPeriodData(bindData.Period);
  7457. bindData.Data = periodData;
  7458. }
  7459. //绑定数据
  7460. this.BindMainData(bindData, this.PageSize);
  7461. if (this.AfterBindMainData) this.AfterBindMainData("Update");
  7462. for (var i = 0; i < this.Frame.SubFrame.length; ++i) {
  7463. this.BindIndexData(i, bindData);
  7464. }
  7465. //叠加数据周期调整
  7466. if (this.OverlayChartPaint[0].SourceData)
  7467. {
  7468. if (ChartData.IsMinutePeriod(this.Period, true)) //分钟不支持 清空掉
  7469. {
  7470. this.OverlayChartPaint[0].Data = null;
  7471. }
  7472. else
  7473. {
  7474. var bindData = new ChartData();
  7475. bindData.Data = this.OverlayChartPaint[0].SourceData.Data;
  7476. bindData.Period = this.Period;
  7477. bindData.Right = this.Right;
  7478. if (bindData.Right > 0 && !IsIndexSymbol(this.OverlayChartPaint[0].Symbol)) //复权数据
  7479. {
  7480. var rightData = bindData.GetRightDate(bindData.Right);
  7481. bindData.Data = rightData;
  7482. }
  7483. var aryOverlayData = this.SourceData.GetOverlayData(bindData.Data); //和主图数据拟合以后的数据
  7484. bindData.Data = aryOverlayData;
  7485. if (ChartData.IsDayPeriod(bindData.Period, false)) //周期数据
  7486. {
  7487. var periodData = bindData.GetPeriodData(bindData.Period);
  7488. bindData.Data = periodData;
  7489. }
  7490. this.OverlayChartPaint[0].Data = bindData;
  7491. }
  7492. }
  7493. this.ReqeustKLineInfoData();
  7494. //刷新画图
  7495. this.UpdataDataoffset(); //更新数据偏移
  7496. this.UpdatePointByCursorIndex(); //更新十字光标位子
  7497. this.UpdateFrameMaxMin(); //调整坐标最大 最小值
  7498. this.Frame.SetSizeChage(true);
  7499. this.Draw();
  7500. }
  7501. //切换股票代码
  7502. this.ChangeSymbol = function (symbol)
  7503. {
  7504. this.CancelAutoUpdate(); //先停止更新
  7505. this.AutoUpdateEvent(false);
  7506. this.Symbol = symbol;
  7507. if (IsIndexSymbol(symbol)) this.Right = 0; //指数没有复权
  7508. if (this.Frame && this.Frame.SubFrame) //清空指标
  7509. {
  7510. for (var i = 0; i < this.Frame.SubFrame.length; ++i)
  7511. this.DeleteIndexPaint(i);
  7512. }
  7513. if (ChartData.IsDayPeriod(this.Period, true))
  7514. {
  7515. this.RequestHistoryData(); //请求日线数据
  7516. //this.ReqeustKLineInfoData();
  7517. }
  7518. else if (ChartData.IsMinutePeriod(this.Period, true) || ChartData.IsSecondPeriod(this.Period))
  7519. {
  7520. this.ReqeustHistoryMinuteData(); //请求分钟数据
  7521. }
  7522. }
  7523. this.ReqeustKLineInfoData = function ()
  7524. {
  7525. if (this.ChartPaint.length > 0)
  7526. {
  7527. var klinePaint = this.ChartPaint[0];
  7528. klinePaint.InfoData = new Map();
  7529. }
  7530. //信息地雷信息
  7531. for (var i in this.ChartInfo)
  7532. {
  7533. this.ChartInfo[i].RequestData(this);
  7534. }
  7535. }
  7536. //设置K线信息地雷
  7537. this.SetKLineInfo = function (aryInfo, bUpdate)
  7538. {
  7539. this.ChartInfo = []; //清空信息地雷
  7540. for (var i in aryInfo)
  7541. {
  7542. var infoItem = JSKLineInfoMap.Get(aryInfo[i]);
  7543. if (!infoItem) continue;
  7544. var item = infoItem.Create();
  7545. item.MaxReqeustDataCount = this.MaxReqeustDataCount;
  7546. this.ChartInfo.push(item);
  7547. }
  7548. if (bUpdate == true) this.ReqeustKLineInfoData();
  7549. }
  7550. this.SetPolicyInfo = function (aryPolicy, bUpdate)
  7551. {
  7552. if (!aryPolicy || !aryPolicy.length) return;
  7553. var infoItem = JSKLineInfoMap.Get('策略选股');
  7554. if (!infoItem) return;
  7555. var policyInfo = infoItem.Create();
  7556. policyInfo.SetPolicyList(aryPolicy);
  7557. policyInfo.MaxReqeustDataCount = this.MaxReqeustDataCount;
  7558. this.ChartInfo.push(policyInfo);
  7559. if (bUpdate == true) this.ReqeustKLineInfoData();
  7560. }
  7561. //叠加股票
  7562. this.OverlaySymbol = function (symbol,option)
  7563. {
  7564. var paint = this.OverlayChartPaint[0];
  7565. if (!paint.MainData) return false;
  7566. paint.Symbol = symbol;
  7567. if (option)
  7568. {
  7569. if (paint.Color) paint.Color = option.Color;
  7570. }
  7571. if (ChartData.IsDayPeriod(this.Period, true)) this.RequestOverlayHistoryData(); //请求日线数据
  7572. return true;
  7573. }
  7574. this.GetRequestDataCount = function () //K线请求数据个数 (由于可以拖拽下载历史数据,所有原来固定个数的就不能用了)
  7575. {
  7576. var result = { MaxRequestDataCount: this.MaxReqeustDataCount, MaxRequestMinuteDayCount: this.MaxRequestMinuteDayCount };
  7577. if (!this.SourceData || !this.SourceData.Data || this.SourceData.Data.length <= 0) return result;
  7578. if (ChartData.IsDayPeriod(this.Period, true))
  7579. {
  7580. var lCount = this.SourceData.Data.length;
  7581. if (lCount > result.MaxRequestDataCount) result.MaxRequestDataCount = lCount;
  7582. }
  7583. else if (ChartData.IsMinutePeriod(this.Period, true))
  7584. {
  7585. }
  7586. return result;
  7587. }
  7588. this.RequestOverlayHistoryData = function ()
  7589. {
  7590. if (!this.OverlayChartPaint.length) return;
  7591. var symbol = this.OverlayChartPaint[0].Symbol;
  7592. if (!symbol) return;
  7593. var self = this;
  7594. var dataCount = this.GetRequestDataCount();
  7595. var firstDate = this.SourceData.Data[0].Date;
  7596. if (this.NetworkFilter)
  7597. {
  7598. var obj =
  7599. {
  7600. Name: 'KLineChartContainer::RequestOverlayHistoryData', //类名::
  7601. Explain: '叠加股票日K线数据',
  7602. Request: {
  7603. Url: self.KLineApiUrl, Data: {
  7604. symbol: symbol, count: dataCount.MaxRequestDataCount, "first": { date: firstDate },
  7605. field: ["name", "symbol", "yclose", "open", "price", "high", 'vol', 'amount']
  7606. }, Type: 'POST'
  7607. },
  7608. Self: this,
  7609. PreventDefault: false
  7610. };
  7611. this.NetworkFilter(obj, function (data) {
  7612. self.RecvOverlayHistoryData(data);
  7613. });
  7614. if (obj.PreventDefault == true) return; //已被上层替换,不调用默认的网络请求
  7615. }
  7616. //请求数据
  7617. wx.request({
  7618. url: this.KLineApiUrl,
  7619. data:
  7620. {
  7621. "field":["name","symbol","yclose","open","price","high"],
  7622. "symbol": symbol,
  7623. "start": -1,
  7624. "count": this.MaxReqeustDataCount
  7625. },
  7626. method: 'POST',
  7627. dataType: "json",
  7628. async: true,
  7629. success: function (data) {
  7630. self.RecvOverlayHistoryData(data);
  7631. }
  7632. });
  7633. }
  7634. this.RecvOverlayHistoryData = function (recvData)
  7635. {
  7636. var data = recvData.data;
  7637. var aryDayData = KLineChartContainer.JsonDataToHistoryData(data);
  7638. //原始叠加数据
  7639. var sourceData = new ChartData();
  7640. sourceData.Data = aryDayData;
  7641. var bindData = new ChartData();
  7642. bindData.Data = aryDayData;
  7643. bindData.Period = this.Period;
  7644. bindData.Right = this.Right;
  7645. if (bindData.Right > 0 && !IsIndexSymbol(data.symbol)) //复权数据 ,指数没有复权)
  7646. {
  7647. var rightData = bindData.GetRightDate(bindData.Right);
  7648. bindData.Data = rightData;
  7649. }
  7650. var aryOverlayData = this.SourceData.GetOverlayData(bindData.Data); //和主图数据拟合以后的数据
  7651. bindData.Data = aryOverlayData;
  7652. if (ChartData.IsDayPeriod(bindData.Period, false)) //周期数据
  7653. {
  7654. var periodData = bindData.GetPeriodData(bindData.Period);
  7655. bindData.Data = periodData;
  7656. }
  7657. this.OverlayChartPaint[0].Data = bindData;
  7658. this.OverlayChartPaint[0].SourceData = sourceData;
  7659. this.OverlayChartPaint[0].Title = data.name;
  7660. this.OverlayChartPaint[0].Symbol = data.symbol;
  7661. this.Frame.SubFrame[0].Frame.YSplitOperator.CoordinateType = 1; //调整为百份比坐标
  7662. this.UpdataDataoffset(); //更新数据偏移
  7663. this.UpdateFrameMaxMin(); //调整坐标最大 最小值
  7664. this.Frame.SetSizeChage(true);
  7665. this.Draw();
  7666. }
  7667. //取消叠加股票
  7668. this.ClearOverlaySymbol = function ()
  7669. {
  7670. this.OverlayChartPaint[0].Symbol = null;
  7671. this.OverlayChartPaint[0].Data = null;
  7672. this.OverlayChartPaint[0].SourceData = null;
  7673. this.OverlayChartPaint[0].TooltipRect = [];
  7674. this.Frame.SubFrame[0].Frame.YSplitOperator.CoordinateType = 0; //调整一般坐标
  7675. this.UpdateFrameMaxMin();
  7676. this.Draw();
  7677. }
  7678. //创建画图工具
  7679. this.CreateChartDrawPicture = function (name) {
  7680. return false;
  7681. }
  7682. this.SetChartDrawPictureFirstPoint = function (x, y) {
  7683. var drawPicture = this.CurrentChartDrawPicture;
  7684. if (!drawPicture) return false;
  7685. if (!this.Frame.SubFrame || this.Frame.SubFrame.length <= 0) return false;
  7686. for (var i in this.Frame.SubFrame) {
  7687. var frame = this.Frame.SubFrame[i].Frame;
  7688. var left = frame.ChartBorder.GetLeft();
  7689. var top = frame.ChartBorder.GetTopEx();
  7690. var height = frame.ChartBorder.GetHeight();
  7691. var width = frame.ChartBorder.GetWidth();
  7692. this.Canvas.rect(left, top, width, height);
  7693. if (this.Canvas.isPointInPath(x, y)) {
  7694. drawPicture.Frame = frame;
  7695. break;
  7696. }
  7697. }
  7698. if (!drawPicture.Frame) return false;
  7699. drawPicture.Point[0] = new Point();
  7700. drawPicture.Point[0].X = x - this.UIElement.getBoundingClientRect().left;
  7701. drawPicture.Point[0].Y = y - this.UIElement.getBoundingClientRect().top;
  7702. drawPicture.Status = 1; //第1个点完成
  7703. }
  7704. this.SetChartDrawPictureSecondPoint = function (x, y) {
  7705. var drawPicture = this.CurrentChartDrawPicture;
  7706. if (!drawPicture) return false;
  7707. drawPicture.Point[1] = new Point();
  7708. drawPicture.Point[1].X = x - this.UIElement.getBoundingClientRect().left;
  7709. drawPicture.Point[1].Y = y - this.UIElement.getBoundingClientRect().top;
  7710. drawPicture.Status = 2; //设置第2个点
  7711. }
  7712. //xStep,yStep 移动的偏移量
  7713. this.MoveChartDrawPicture = function (xStep, yStep) {
  7714. var drawPicture = this.CurrentChartDrawPicture;
  7715. if (!drawPicture) return false;
  7716. //JSConsole.Chart.Log("xStep="+xStep+" yStep="+yStep);
  7717. drawPicture.Move(xStep, yStep);
  7718. return true;
  7719. }
  7720. this.FinishChartDrawPicturePoint = function () {
  7721. var drawPicture = this.CurrentChartDrawPicture;
  7722. if (!drawPicture) return false;
  7723. if (drawPicture.PointCount != drawPicture.Point.length) return false;
  7724. drawPicture.Status = 10; //完成
  7725. drawPicture.PointToValue();
  7726. this.ChartDrawPicture.push(drawPicture);
  7727. this.CurrentChartDrawPicture = null;
  7728. return true;
  7729. }
  7730. this.FinishMoveChartDrawPicture = function () {
  7731. var drawPicture = this.CurrentChartDrawPicture;
  7732. if (!drawPicture) return false;
  7733. if (drawPicture.PointCount != drawPicture.Point.length) return false;
  7734. drawPicture.Status = 10; //完成
  7735. drawPicture.PointToValue();
  7736. this.CurrentChartDrawPicture = null;
  7737. return true;
  7738. }
  7739. //清空所有的画线工具
  7740. this.ClearChartDrawPicture = function (drawPicture) {
  7741. if (!drawPicture) {
  7742. this.ChartDrawPicture = [];
  7743. this.Draw();
  7744. }
  7745. else {
  7746. for (var i in this.ChartDrawPicture) {
  7747. if (this.ChartDrawPicture[i] == drawPicture) {
  7748. this.ChartDrawPicture.splice(i, 1);
  7749. this.Draw();
  7750. }
  7751. }
  7752. }
  7753. }
  7754. //更新信息地雷
  7755. this.UpdataChartInfo = function ()
  7756. {
  7757. //TODO: 根据K线数据日期来做map, 不在K线上的合并到下一个k线日期里面
  7758. var mapInfoData = new Map();
  7759. if (this.Period==0) //日线数据 根据日期
  7760. {
  7761. for (var i in this.ChartInfo)
  7762. {
  7763. var infoData = this.ChartInfo[i].Data;
  7764. for (var j in infoData)
  7765. {
  7766. var item = infoData[j];
  7767. if (mapInfoData.has(item.Date.toString()))
  7768. mapInfoData.get(item.Date.toString()).Data.push(item);
  7769. else
  7770. mapInfoData.set(item.Date.toString(), { Data: new Array(item) });
  7771. }
  7772. }
  7773. }
  7774. else if (ChartData.IsDayPeriod(this.Period,false))
  7775. {
  7776. mapInfoData=new Map();
  7777. var hisData=this.ChartPaint[0].Data;
  7778. if (hisData && hisData.Data && hisData.Data.length>0)
  7779. {
  7780. var fristKItem=hisData.Data[0];
  7781. var aryInfo=[];
  7782. for(var i in this.ChartInfo)
  7783. {
  7784. var infoItem=this.ChartInfo[i];
  7785. for(var j in infoItem.Data)
  7786. {
  7787. var item=infoItem.Data[j];
  7788. if (item.Date>=fristKItem.Date) //在K线范围内的才显示
  7789. aryInfo.push(item);
  7790. }
  7791. }
  7792. aryInfo.sort(function(a,b) { return a.Date-b.Date }); //排序
  7793. for(var i=0;i<hisData.Data.length;)
  7794. {
  7795. var kItem=hisData.Data[i]; //K线数据
  7796. if (aryInfo.length<=0) break;
  7797. var infoItem=aryInfo[0];
  7798. if (kItem.Date<infoItem.Date)
  7799. {
  7800. ++i;
  7801. continue;
  7802. }
  7803. //信息地雷日期<K线上的日期 就是属于这个K线上的
  7804. if (mapInfoData.has(kItem.Date.toString()))
  7805. mapInfoData.get(kItem.Date.toString()).Data.push(infoItem);
  7806. else
  7807. mapInfoData.set(kItem.Date.toString(),{Data:new Array(infoItem)});
  7808. aryInfo.shift();
  7809. //JSConsole.Chart.Log('[KLineChartContainer::UpdataChartInfo]',item);
  7810. }
  7811. }
  7812. }
  7813. var klinePaint = this.ChartPaint[0];
  7814. klinePaint.InfoData = mapInfoData;
  7815. var titlePaint = this.TitlePaint[0];
  7816. if (titlePaint) titlePaint.InfoData = mapInfoData;
  7817. }
  7818. //更新窗口指标
  7819. this.UpdateWindowIndex = function (index)
  7820. {
  7821. var bindData = new ChartData();
  7822. bindData.Data = this.SourceData.Data;
  7823. bindData.Period = this.Period;
  7824. bindData.Right = this.Right;
  7825. if (this.IsApiPeriod)
  7826. {
  7827. }
  7828. else
  7829. {
  7830. if (bindData.Right > 0) //复权
  7831. {
  7832. var rightData = bindData.GetRightDate(bindData.Right);
  7833. bindData.Data = rightData;
  7834. }
  7835. if (ChartData.IsDayPeriod(bindData.Period, false) || ChartData.IsMinutePeriod(bindData.Period, false)) //周期数据
  7836. {
  7837. var periodData = bindData.GetPeriodData(bindData.Period);
  7838. bindData.Data = periodData;
  7839. }
  7840. }
  7841. this.WindowIndex[index].BindData(this, index, bindData);
  7842. this.UpdataDataoffset(); //更新数据偏移
  7843. this.UpdateFrameMaxMin(); //调整坐标最大 最小值
  7844. this.Draw();
  7845. }
  7846. //修改参数指标
  7847. this.ChangeWindowIndexParam = function (index) {
  7848. this.WindowIndex[index].Index[0].Param += 1;
  7849. this.WindowIndex[index].Index[1].Param += 1;
  7850. this.UpdateWindowIndex(index);
  7851. }
  7852. this.OnDoubleClick = function (x, y, e)
  7853. {
  7854. var tooltip = new TooltipData();
  7855. for (var i in this.ChartPaint)
  7856. {
  7857. var item = this.ChartPaint[i];
  7858. if (item.GetTooltipData(x, y, tooltip))
  7859. break;
  7860. }
  7861. if (!tooltip.Data) return;
  7862. e.data = { Chart: this, Tooltip: tooltip };
  7863. }
  7864. this.CancelAutoUpdate=function() //关闭停止更新
  7865. {
  7866. if (typeof (this.AutoUpdateTimer) == 'number')
  7867. {
  7868. clearTimeout(this.AutoUpdateTimer);
  7869. this.AutoUpdateTimer = undefined;
  7870. }
  7871. }
  7872. //数据自动更新
  7873. this.AutoUpdate = function (waitTime) //waitTime 更新时间
  7874. {
  7875. this.CancelAutoUpdate();
  7876. if (!this.IsAutoUpdate) return;
  7877. if (!this.Symbol) return;
  7878. if (this.IsDestroy) return;
  7879. var self = this;
  7880. var marketStatus = MARKET_SUFFIX_NAME.GetMarketStatus(this.Symbol);
  7881. if (marketStatus == 0 || marketStatus == 3) return; //闭市,盘后
  7882. var frequency = this.AutoUpdateFrequency;
  7883. if (marketStatus == 1) //盘前
  7884. {
  7885. this.AutoUpdateTimer=setTimeout(function () { self.AutoUpdate(); }, frequency);
  7886. }
  7887. else if (marketStatus == 2) //盘中
  7888. {
  7889. this.AutoUpdateTimer=setTimeout(function ()
  7890. {
  7891. if (ChartData.IsDayPeriod(self.Period, true))
  7892. {
  7893. self.RequestRealtimeData(); //更新最新行情
  7894. //self.ReqeustKLineInfoData();
  7895. }
  7896. else if (ChartData.IsMinutePeriod(self.Period, true) || ChartData.IsSecondPeriod(self.Period))
  7897. {
  7898. self.RequestMinuteRealtimeData(); //请求分钟数据
  7899. }
  7900. }, frequency);
  7901. }
  7902. }
  7903. this.GetMaxPageSize = function ()
  7904. {
  7905. let width = this.Frame.ChartBorder.GetWidth();
  7906. let barWidth = (ZOOM_SEED[ZOOM_SEED.length - 1][0] + ZOOM_SEED[ZOOM_SEED.length - 1][1]);
  7907. let pageSize = parseInt(width / barWidth) - 8;
  7908. JSConsole.Chart.Log(`[KLineChartContainer::GetMaxPageSize] width=${width} barWidth=${barWidth} pageSize=${pageSize}`);
  7909. return pageSize
  7910. }
  7911. //数据拖拽下载
  7912. this.DragDownloadData = function ()
  7913. {
  7914. var data = null;
  7915. if (!this.Frame.Data) data = this.Frame.Data;
  7916. else data = this.Frame.SubFrame[0].Frame.Data;
  7917. if (!data) return false;
  7918. if (data.DataOffset > 0) return;
  7919. if (ChartData.IsMinutePeriod(this.Period, true)) //下载分钟数据
  7920. {
  7921. JSConsole.Chart.Log(`[KLineChartContainer.DragDownloadData] Minute:[Enable=${this.DragDownload.Minute.Enable}, IsEnd=${this.DragDownload.Minute.IsEnd}, Status=${this.DragDownload.Minute.Status}]`);
  7922. if (!this.DragDownload.Minute.Enable) return;
  7923. if (this.DragDownload.Minute.IsEnd) return; //全部下载完了
  7924. if (this.DragDownload.Minute.Status != 0) return;
  7925. this.RequestDragMinuteData();
  7926. }
  7927. else if (ChartData.IsDayPeriod(this.Period, true)) // 下载日线
  7928. {
  7929. JSConsole.Chart.Log(`[KLineChartContainer.DragDownloadData] Day:[Enable=${this.DragDownload.Minute.Enable}, IsEnd=${this.DragDownload.Minute.IsEnd}, Status=${this.DragDownload.Minute.Status}]`);
  7930. if (!this.DragDownload.Day.Enable) return;
  7931. if (this.DragDownload.Day.IsEnd) return; //全部下载完了
  7932. if (this.DragDownload.Day.Status != 0) return;
  7933. this.RequestDragDayData();
  7934. }
  7935. }
  7936. this.RequestDragMinuteData = function ()
  7937. {
  7938. var self = this;
  7939. this.AutoUpdateEvent(false, 'KLineChartContainer::RequestDragMinuteData'); //停止自动更新
  7940. this.CancelAutoUpdate();
  7941. var download = this.DragDownload.Minute;
  7942. download.Status = 1;
  7943. var firstItem = this.SourceData.Data[0]; //最新的一条数据
  7944. var postData =
  7945. {
  7946. "field": ["name", "symbol", "yclose", "open", "price", "high", "low", "vol"],
  7947. "symbol": self.Symbol,
  7948. "enddate": firstItem.Date,
  7949. "endtime": firstItem.Time,
  7950. "count": self.MaxRequestMinuteDayCount,
  7951. "first": { date: firstItem.Date, time: firstItem.Time },
  7952. };
  7953. if (this.NetworkFilter) {
  7954. var obj =
  7955. {
  7956. Name: 'KLineChartContainer::RequestDragMinuteData', //类名::函数
  7957. Explain: '拖拽1分钟K线数据下载',
  7958. Request: { Url: this.DragMinuteKLineApiUrl, Type: 'POST', Data: postData, Period:this.Period },
  7959. DragDownload: download,
  7960. Self: this,
  7961. PreventDefault: false
  7962. };
  7963. this.NetworkFilter(obj, function (data) {
  7964. self.RecvDragMinuteData(data);
  7965. download.Status = 0;
  7966. self.AutoUpdateEvent(true, 'KLineChartContainer::RequestDragMinuteData'); //自动更新
  7967. self.AutoUpdate();
  7968. });
  7969. if (obj.PreventDefault == true) return; //已被上层替换,不调用默认的网络请求
  7970. }
  7971. wx.request({
  7972. url: this.DragMinuteKLineApiUrl,
  7973. data: postData,
  7974. method: 'POST',
  7975. dataType: "json",
  7976. async: true,
  7977. success: function (data) {
  7978. self.RecvDragMinuteData(data);
  7979. download.Status = 0;
  7980. self.AutoUpdateEvent(true, 'KLineChartContainer::RequestDragMinuteData'); //自动更新
  7981. self.AutoUpdate();
  7982. }
  7983. });
  7984. }
  7985. this.RecvDragMinuteData = function (recvdata)
  7986. {
  7987. var data=recvdata.data;
  7988. var aryDayData = KLineChartContainer.JsonDataToMinuteHistoryData(data);
  7989. var lastDataCount = this.GetHistoryDataCount(); //保存下上一次的数据个数
  7990. for (var i in aryDayData) //数据往前插
  7991. {
  7992. var item = aryDayData[i];
  7993. this.SourceData.Data.splice(i, 0, item);
  7994. }
  7995. var bindData = new ChartData();
  7996. bindData.Data = this.SourceData.Data;
  7997. bindData.Period = this.Period;
  7998. bindData.Right = this.Right;
  7999. bindData.DataType = this.SourceData.DataType;
  8000. bindData.Symbol = this.Symbol;
  8001. if (!this.IsApiPeriod)
  8002. {
  8003. if (ChartData.IsDayPeriod(bindData.Period, false) || ChartData.IsMinutePeriod(bindData.Period, false)) //周期数据 (0= 日线,4=1分钟线 不需要处理)
  8004. {
  8005. var periodData = bindData.GetPeriodData(bindData.Period);
  8006. bindData.Data = periodData;
  8007. }
  8008. }
  8009. //绑定数据
  8010. this.UpdateMainData(bindData, lastDataCount);
  8011. this.BindInstructionIndexData(bindData); //执行指示脚本
  8012. for (var i = 0; i < this.Frame.SubFrame.length; ++i)
  8013. {
  8014. this.BindIndexData(i, bindData);
  8015. }
  8016. //刷新画图
  8017. this.UpdataDataoffset(); //更新数据偏移
  8018. this.UpdatePointByCursorIndex(); //更新十字光标位子
  8019. this.UpdateFrameMaxMin(); //调整坐标最大 最小值
  8020. this.Frame.SetSizeChage(true);
  8021. this.Draw();
  8022. }
  8023. this.RequestDragDayData = function ()
  8024. {
  8025. var self = this;
  8026. this.AutoUpdateEvent(false, 'KLineChartContainer::RequestDragDayData'); //停止自动更新
  8027. this.CancelAutoUpdate();
  8028. var download = this.DragDownload.Day;
  8029. download.Status = 1;
  8030. var firstItem = this.SourceData.Data[0]; //最新的一条数据
  8031. var postData =
  8032. {
  8033. "field": ["name", "symbol", "yclose", "open", "price", "high", "low", "vol"],
  8034. "symbol": self.Symbol,
  8035. "enddate": firstItem.Date,
  8036. "count": self.MaxReqeustDataCount,
  8037. "first": { date: firstItem.Date }
  8038. };
  8039. if (this.NetworkFilter) {
  8040. var obj =
  8041. {
  8042. Name: 'KLineChartContainer::RequestDragDayData', //类名::函数
  8043. Explain: '拖拽日K数据下载',
  8044. Request: { Url: this.DragKLineApiUrl, Type: 'POST', Data: postData , Period:this.Period, Right:this.Right },
  8045. DragDownload: download,
  8046. Self: this,
  8047. PreventDefault: false
  8048. };
  8049. this.NetworkFilter(obj, function (data) {
  8050. self.RecvDragDayData(data);
  8051. download.Status = 0;
  8052. self.AutoUpdateEvent(true, 'KLineChartContainer::RequestDragDayData'); //自动更新
  8053. self.AutoUpdate();
  8054. });
  8055. if (obj.PreventDefault == true) return; //已被上层替换,不调用默认的网络请求
  8056. }
  8057. wx.request({
  8058. url: this.DragKLineApiUrl,
  8059. data: postData,
  8060. method: 'POST',
  8061. dataType: "json",
  8062. async: true,
  8063. success: function (data) {
  8064. self.RecvDragDayData(data);
  8065. download.Status = 0;
  8066. self.AutoUpdateEvent(true, 'KLineChartContainer::RequestDragDayData'); //自动更新
  8067. self.AutoUpdate();
  8068. }
  8069. });
  8070. }
  8071. this.RecvDragDayData = function (recvdata)
  8072. {
  8073. var data = recvdata.data;
  8074. var aryDayData = KLineChartContainer.JsonDataToHistoryData(data);
  8075. if (!aryDayData || aryDayData.length<=0)
  8076. {
  8077. this.DragDownload.Day.IsEnd=true; //下完了
  8078. return;
  8079. }
  8080. var lastDataCount = this.GetHistoryDataCount(); //保存下上一次的数据个数
  8081. for (var i in aryDayData) //数据往前插
  8082. {
  8083. var item = aryDayData[i];
  8084. this.SourceData.Data.splice(i, 0, item);
  8085. }
  8086. var bindData = new ChartData();
  8087. bindData.Data = this.SourceData.Data;
  8088. bindData.Period = this.Period;
  8089. bindData.Right = this.Right;
  8090. bindData.DataType = this.SourceData.DataType;
  8091. bindData.Symbol = this.Symbol;
  8092. if (!this.IsApiPeriod)
  8093. {
  8094. if (ChartData.IsDayPeriod(bindData.Period, false) || ChartData.IsMinutePeriod(bindData.Period, false)) //周期数据 (0= 日线,4=1分钟线 不需要处理)
  8095. {
  8096. var periodData = bindData.GetPeriodData(bindData.Period);
  8097. bindData.Data = periodData;
  8098. }
  8099. }
  8100. //绑定数据
  8101. this.UpdateMainData(bindData, lastDataCount);
  8102. this.BindInstructionIndexData(bindData); //执行指示脚本
  8103. for (var i = 0; i < this.Frame.SubFrame.length; ++i)
  8104. {
  8105. this.BindIndexData(i, bindData);
  8106. }
  8107. //刷新画图
  8108. this.UpdataDataoffset(); //更新数据偏移
  8109. this.UpdatePointByCursorIndex(); //更新十字光标位子
  8110. this.UpdateFrameMaxMin(); //调整坐标最大 最小值
  8111. this.Frame.SetSizeChage(true);
  8112. this.Draw();
  8113. }
  8114. this.SetCustomVerical = function (windowId, data)
  8115. {
  8116. if (!this.Frame) return;
  8117. if (windowId >= this.Frame.SubFrame.length) return;
  8118. var item = this.Frame.SubFrame[windowId];
  8119. if (item.Frame) item.Frame.CustomVerticalInfo = data;
  8120. }
  8121. this.OnSize=function()
  8122. {
  8123. if (!this.Frame) return;
  8124. if (!this.Frame.OnSize) return;
  8125. var obj=this.Frame.OnSize();
  8126. this.Frame.SetSizeChage(true);
  8127. if (obj.Changed)
  8128. {
  8129. this.UpdataDataoffset();
  8130. this.UpdatePointByCursorIndex();
  8131. this.UpdateFrameMaxMin();
  8132. }
  8133. this.Draw();
  8134. }
  8135. }
  8136. //API 返回数据 转化为array[]
  8137. KLineChartContainer.JsonDataToHistoryData = function (data)
  8138. {
  8139. var list = data.data;
  8140. var aryDayData = new Array();
  8141. if (!list) return aryDayData;
  8142. var upperSymbol = null;
  8143. if (data.symbol) upperSymbol = data.symbol.toUpperCase();
  8144. var isFutures = false; //是否是期货
  8145. isFutures = MARKET_SUFFIX_NAME.IsChinaFutures(upperSymbol);
  8146. var date = 0, yclose = 1, open = 2, high = 3, low = 4, close = 5, vol = 6, amount = 7, position = 8;
  8147. for (var i = 0; i < list.length; ++i)
  8148. {
  8149. var item = new HistoryData();
  8150. var jsData = list[i];
  8151. item.Date = jsData[date];
  8152. item.Open = jsData[open];
  8153. item.YClose = jsData[yclose];
  8154. item.Close = jsData[close];
  8155. item.High = jsData[high];
  8156. item.Low = jsData[low];
  8157. item.Vol = jsData[vol]; //原始单位股
  8158. item.Amount = jsData[amount];
  8159. if (IFrameSplitOperator.IsNumber(jsData[position])) item.Position = jsData[position];//期货持仓
  8160. if (!IFrameSplitOperator.IsNumber(item.Open)) continue;
  8161. aryDayData.push(item);
  8162. }
  8163. return aryDayData;
  8164. }
  8165. KLineChartContainer.JsonDataToRealtimeData = function (data)
  8166. {
  8167. var symbol = data.stock[0].symbol;
  8168. var upperSymbol = symbol.toUpperCase();
  8169. var isSHSZ = MARKET_SUFFIX_NAME.IsSHSZ(upperSymbol);
  8170. var item = new HistoryData();
  8171. item.Date = data.stock[0].date;
  8172. item.Open = data.stock[0].open;
  8173. item.YClose = data.stock[0].yclose;
  8174. item.High = data.stock[0].high;
  8175. item.Low = data.stock[0].low;
  8176. item.Vol=data.stock[0].vol; //单位股
  8177. item.Amount = data.stock[0].amount;
  8178. item.Close = data.stock[0].price;
  8179. if (IFrameSplitOperator.IsNumber(data.stock[0].position)) item.Position = data.stock[0].position; //持仓量
  8180. return item;
  8181. }
  8182. KLineChartContainer.JsonDataToMinuteRealtimeData = function (data)
  8183. {
  8184. var symbol = data.stock[0].symbol;
  8185. var upperSymbol = symbol.toUpperCase();
  8186. var isSHSZ = MARKET_SUFFIX_NAME.IsSHSZ(upperSymbol);
  8187. var isFutures = MARKET_SUFFIX_NAME.IsChinaFutures(upperSymbol);
  8188. var aryMinuteData = new Array();
  8189. var preClose = data.stock[0].yclose; //前一个数据价格
  8190. var date = data.stock[0].date;
  8191. if (isFutures && data.stock[0].yclearing) preClose = data.stock[0].yclearing; //期货使用昨结算价
  8192. for (var i in data.stock[0].minute)
  8193. {
  8194. var jsData = data.stock[0].minute[i];
  8195. var item = new HistoryData();
  8196. item.Close = jsData.price;
  8197. item.Open = jsData.open;
  8198. item.High = jsData.high;
  8199. item.Low = jsData.low;
  8200. item.Vol = jsData.vol; //单位股
  8201. item.Amount = jsData.amount;
  8202. if (jsData.date > 0) item.Date = jsData.date;
  8203. else item.Date = date;
  8204. item.Time = jsData.time;
  8205. item.YClose = preClose;
  8206. if (IFrameSplitOperator.IsNumber(jsData.position)) item.Position = jsData.position; //持仓量
  8207. if (!IFrameSplitOperator.IsNumber(item.Close)) //当前没有价格 使用上一个价格填充
  8208. {
  8209. item.Close = preClose;
  8210. item.Open = item.High = item.Low = item.Close;
  8211. }
  8212. //价格是0的 都用空
  8213. if (!IFrameSplitOperator.IsNumber(item.Open)) item.Open = null;
  8214. if (!IFrameSplitOperator.IsNumber(item.Close)) item.Close = null;
  8215. if (!IFrameSplitOperator.IsNumber(item.High)) item.High = null;
  8216. if (!IFrameSplitOperator.IsNumber(item.Low)) item.Low = null;
  8217. //上次价格
  8218. if (IFrameSplitOperator.IsNumber(jsData.price)) preClose = jsData.price;
  8219. aryMinuteData[i] = item;
  8220. }
  8221. return aryMinuteData;
  8222. }
  8223. //API 返回数据 转化为array[]
  8224. KLineChartContainer.JsonDataToMinuteHistoryData = function (data)
  8225. {
  8226. var upperSymbol = null;
  8227. if (data.symbol) upperSymbol = data.symbol.toUpperCase();
  8228. var isSHSZ = false;
  8229. if (upperSymbol) isSHSZ = MARKET_SUFFIX_NAME.IsSHSZ(upperSymbol);
  8230. var isFutures = false; //是否是期货
  8231. if (upperSymbol) isFutures = MARKET_SUFFIX_NAME.IsChinaFutures(upperSymbol);
  8232. var list = data.data;
  8233. var aryDayData = new Array();
  8234. var date = 0, yclose = 1, open = 2, high = 3, low = 4, close = 5, vol = 6, amount = 7, time = 8, position = 9;
  8235. for (var i = 0; i < list.length; ++i)
  8236. {
  8237. var item = new HistoryData();
  8238. var jsData=list[i];
  8239. item.Date = jsData[date];
  8240. item.Open = jsData[open];
  8241. item.YClose = jsData[yclose];
  8242. item.Close = jsData[close];
  8243. item.High = jsData[high];
  8244. item.Low = jsData[low];
  8245. item.Vol = jsData[vol]; //原始单位股
  8246. item.Amount = jsData[amount];
  8247. item.Time = jsData[time];
  8248. if (IFrameSplitOperator.IsNumber(jsData[position])) item.Position = jsData[position]; //期货持仓
  8249. aryDayData.push(item);
  8250. }
  8251. return aryDayData;
  8252. }
  8253. ///////////////////////////////////////////////////////////////////////////////////////////
  8254. // 走势图
  8255. //
  8256. function MinuteChartContainer(uielement)
  8257. {
  8258. this.newMethod = JSChartContainer; //派生
  8259. this.newMethod(uielement);
  8260. delete this.newMethod;
  8261. this.ClassName = 'MinuteChartContainer';
  8262. this.WindowIndex = new Array();
  8263. this.Symbol;
  8264. this.Name;
  8265. this.SourceData; //原始的历史数据
  8266. this.OverlaySourceData; //叠加的原始数据
  8267. this.IsAutoUpdate = false; //是否自动更新行情数据
  8268. this.AutoUpdateFrequency = 30000; //30秒更新一次数据
  8269. this.AutoUpdateTimer; //更新定时器
  8270. this.TradeDate = 0; //行情交易日期
  8271. this.LoadDataSplashTitle = '下载分钟数据';
  8272. this.UpdateUICallback; //数据到达回调
  8273. this.DayCount = 1; //显示几天的数据
  8274. this.DayData; //多日分钟数据
  8275. this.MinuteApiUrl = g_JSChartResource.Domain + "/API/Stock";
  8276. this.HistoryMinuteApiUrl = g_JSChartResource.Domain + "/API/StockMinuteData"; //历史分钟数据
  8277. //手机拖拽
  8278. this.ontouchstart = function (e)
  8279. {
  8280. if (this.ChartSplashPaint && this.ChartSplashPaint.IsEnableSplash == true) return;
  8281. this.IsOnTouch = true;
  8282. var jsChart = this;
  8283. if (jsChart.DragMode == 0) return;
  8284. if (this.IsPhoneDragging(e))
  8285. {
  8286. if (jsChart.TryClickLock)
  8287. {
  8288. var touches = this.GetToucheData(e, jsChart.IsForceLandscape);
  8289. var x = touches[0].clientX;
  8290. var y = touches[0].clientY;
  8291. if (jsChart.TryClickLock(x, y)) return;
  8292. }
  8293. //长按2秒,十字光标
  8294. this.ClearTouchTimer();
  8295. var drag =
  8296. {
  8297. "Click": {},
  8298. "LastMove": {}, //最后移动的位置
  8299. };
  8300. var touches = this.GetToucheData(e, jsChart.IsForceLandscape);
  8301. drag.Click.X = touches[0].clientX;
  8302. drag.Click.Y = touches[0].clientY;
  8303. drag.LastMove.X = touches[0].clientX;
  8304. drag.LastMove.Y = touches[0].clientY;
  8305. var T_ShowCorssCursor=()=>
  8306. {
  8307. if (this.ChartCorssCursor.IsShow === true) //移动十字光标
  8308. {
  8309. var x = drag.Click.X;
  8310. var y = drag.Click.Y;
  8311. if (jsChart.IsForceLandscape) y = jsChart.UIElement.Height - drag.Click.Y; //强制横屏Y计算
  8312. jsChart.OnMouseMove(x, y, e);
  8313. }
  8314. }
  8315. if (this.EnableZoomIndexWindow)
  8316. {
  8317. this.PhoneDBClick.AddTouchStart(touches[0].clientX, touches[0].clientY, Date.now());
  8318. JSConsole.Chart.Log("[MinuteChartContainer::OnTouchStart] PhoneDBClick ", this.PhoneDBClick);
  8319. }
  8320. if (this.EnableScrollUpDown==true)
  8321. {
  8322. this.TouchTimer=setTimeout(()=>
  8323. {
  8324. this.MouseDrag=null;
  8325. T_ShowCorssCursor();
  8326. }, 800);
  8327. }
  8328. this.MouseDrag=drag;
  8329. if (this.EnableScrollUpDown==false)
  8330. T_ShowCorssCursor();
  8331. }
  8332. }
  8333. this.ontouchmove = function (e)
  8334. {
  8335. if (this.ChartSplashPaint && this.ChartSplashPaint.IsEnableSplash == true) return;
  8336. var jsChart = this;
  8337. var drag = jsChart.MouseDrag;
  8338. var touches = this.GetToucheData(e, jsChart.IsForceLandscape);
  8339. if (this.ChartCorssCursor.IsShow === true && this.IsPhoneDragging(e))
  8340. {
  8341. if (drag == null)
  8342. {
  8343. var x = touches[0].clientX;
  8344. var y = touches[0].clientY;
  8345. this.LastMovePoint={ X:x, Y:y };
  8346. if (this.DrawMoveTimer) return;
  8347. this.DrawMoveTimer=setTimeout(()=>
  8348. {
  8349. if (!this.LastMovePoint) return;
  8350. this.OnMouseMove(this.LastMovePoint.X, this.LastMovePoint.Y, e);
  8351. this.DrawMoveTimer=null;
  8352. }, this.DrawMoveWaitTime);
  8353. }
  8354. }
  8355. if (drag!=null)
  8356. {
  8357. //TODO:上下滚动
  8358. this.ClearTouchTimer();
  8359. this.MouseDrag=null;
  8360. var x = touches[0].clientX;
  8361. var y = touches[0].clientY;
  8362. this.OnMouseMove(x,y,e);
  8363. }
  8364. }
  8365. //创建
  8366. //windowCount 窗口个数
  8367. this.Create = function (windowCount)
  8368. {
  8369. this.UIElement.JSChartContainer = this;
  8370. //创建十字光标
  8371. this.ChartCorssCursor = new ChartCorssCursor();
  8372. this.ChartCorssCursor.Canvas = this.Canvas;
  8373. this.ChartCorssCursor.StringFormatX = new HQMinuteTimeStringFormat();
  8374. this.ChartCorssCursor.StringFormatY = new HQPriceStringFormat();
  8375. this.ChartCorssCursor.StringFormatY.LanguageID = this.LanguageID;
  8376. //创建等待提示
  8377. this.ChartSplashPaint = new ChartSplashPaint();
  8378. this.ChartSplashPaint.Canvas = this.Canvas;
  8379. this.ChartSplashPaint.SplashTitle = this.LoadDataSplashTitle;
  8380. this.ChartSplashPaint.HQChart=this;
  8381. //创建框架容器
  8382. this.Frame = new HQTradeFrame();
  8383. this.Frame.ChartBorder = new ChartBorder();
  8384. this.Frame.ChartBorder.UIElement = this.UIElement;
  8385. this.Frame.ChartBorder.Top = 25;
  8386. this.Frame.ChartBorder.Left = 50;
  8387. this.Frame.ChartBorder.Bottom = 20;
  8388. this.Frame.Canvas = this.Canvas;
  8389. this.Frame.ZoomStartWindowIndex=2;
  8390. this.ChartCorssCursor.Frame = this.Frame; //十字光标绑定框架
  8391. this.ChartSplashPaint.Frame = this.Frame;
  8392. this.CreateChildWindow(windowCount);
  8393. this.CreateMainKLine();
  8394. //子窗口动态标题
  8395. for (var i in this.Frame.SubFrame)
  8396. {
  8397. var titlePaint = new DynamicChartTitlePainting();
  8398. titlePaint.Frame = this.Frame.SubFrame[i].Frame;
  8399. titlePaint.Canvas = this.Canvas;
  8400. titlePaint.LanguageID = this.LanguageID;
  8401. this.TitlePaint.push(titlePaint);
  8402. }
  8403. this.ChartCorssCursor.StringFormatX.Frame = this.Frame.SubFrame[0].Frame;
  8404. }
  8405. //创建子窗口
  8406. this.CreateChildWindow = function (windowCount)
  8407. {
  8408. for (var i = 0; i < windowCount; ++i)
  8409. {
  8410. var border = new ChartBorder();
  8411. border.UIElement = this.UIElement;
  8412. var frame = new MinuteFrame();
  8413. frame.Canvas = this.Canvas;
  8414. frame.ChartBorder = border;
  8415. frame.Identify=i;
  8416. if (i < 2) frame.ChartBorder.TitleHeight = 0;
  8417. frame.XPointCount = 243;
  8418. var DEFAULT_HORIZONTAL = [9, 8, 7, 6, 5, 4, 3, 2, 1];
  8419. frame.HorizontalMax = DEFAULT_HORIZONTAL[0];
  8420. frame.HorizontalMin = DEFAULT_HORIZONTAL[DEFAULT_HORIZONTAL.length - 1];
  8421. if (i == 0)
  8422. {
  8423. frame.YSplitOperator = new FrameSplitMinutePriceY();
  8424. frame.YSplitOperator.FrameSplitData = this.FrameSplitData.get('price');
  8425. frame.YSplitOperator.GetEventCallback=(id)=> { return this.GetEventCallback(id); }
  8426. }
  8427. else
  8428. {
  8429. frame.YSplitOperator = new FrameSplitY();
  8430. frame.YSplitOperator.FrameSplitData = this.FrameSplitData.get('double');
  8431. frame.YSplitOperator.LanguageID = this.LanguageID;
  8432. frame.YSplitOperator.GetEventCallback=(id)=> { return this.GetEventCallback(id); }
  8433. }
  8434. frame.YSplitOperator.Frame = frame;
  8435. frame.YSplitOperator.ChartBorder = border;
  8436. frame.XSplitOperator = new FrameSplitMinuteX();
  8437. frame.XSplitOperator.Frame = frame;
  8438. frame.XSplitOperator.ChartBorder = border;
  8439. if (i != windowCount - 1) frame.XSplitOperator.ShowText = false;
  8440. frame.XSplitOperator.Operator();
  8441. for (var j in DEFAULT_HORIZONTAL)
  8442. {
  8443. frame.HorizontalInfo[j] = new CoordinateInfo();
  8444. frame.HorizontalInfo[j].Value = DEFAULT_HORIZONTAL[j];
  8445. if (i == 0 && j == frame.HorizontalMin) continue;
  8446. frame.HorizontalInfo[j].Message[1] = DEFAULT_HORIZONTAL[j].toString();
  8447. frame.HorizontalInfo[j].Font = "12px 微软雅黑";
  8448. }
  8449. var subFrame = new SubFrameItem();
  8450. subFrame.Frame = frame;
  8451. if (i == 0) subFrame.Height = 20;
  8452. else subFrame.Height = 10;
  8453. this.Frame.SubFrame[i] = subFrame;
  8454. }
  8455. }
  8456. this.CreateSubFrameItem=function(id)
  8457. {
  8458. var border=new ChartBorder();
  8459. border.UIElement=this.UIElement;
  8460. var frame=new MinuteFrame();
  8461. frame.Canvas=this.Canvas;
  8462. frame.ChartBorder=border;
  8463. frame.Identify=id; //窗口序号
  8464. frame.XPointCount=243;
  8465. if (id>=2)
  8466. {
  8467. if (this.ModifyIndexDialog) frame.ModifyIndexEvent=this.ModifyIndexDialog.DoModal; //绑定菜单事件
  8468. if (this.ChangeIndexDialog) frame.ChangeIndexEvent=this.ChangeIndexDialog.DoModal;
  8469. }
  8470. var DEFAULT_HORIZONTAL=[9,8,7,6,5,4,3,2,1];
  8471. frame.HorizontalMax=DEFAULT_HORIZONTAL[0];
  8472. frame.HorizontalMin=DEFAULT_HORIZONTAL[DEFAULT_HORIZONTAL.length-1];
  8473. frame.YSplitOperator=new FrameSplitY();
  8474. frame.YSplitOperator.LanguageID=this.LanguageID;
  8475. frame.YSplitOperator.FrameSplitData=this.FrameSplitData.get('double');
  8476. frame.YSplitOperator.Frame=frame;
  8477. frame.YSplitOperator.ChartBorder=border;
  8478. frame.XSplitOperator=new FrameSplitMinuteX();
  8479. frame.XSplitOperator.Frame=frame;
  8480. frame.XSplitOperator.ChartBorder=border;
  8481. frame.XSplitOperator.ShowText=false;
  8482. frame.XSplitOperator.GetEventCallback=(id)=> { return this.GetEventCallback(id); }
  8483. frame.YSplitOperator.GetEventCallback=(id)=> { return this.GetEventCallback(id); }
  8484. //K线数据绑定
  8485. var xPointCouont=this.Frame.SubFrame[0].Frame.XPointCount;
  8486. frame.XPointCount=xPointCouont;
  8487. frame.Data=this.ChartPaint[0].Data;
  8488. for(var j in DEFAULT_HORIZONTAL)
  8489. {
  8490. frame.HorizontalInfo[j]= new CoordinateInfo();
  8491. frame.HorizontalInfo[j].Value=DEFAULT_HORIZONTAL[j];
  8492. frame.HorizontalInfo[j].Message[1]=DEFAULT_HORIZONTAL[j].toString();
  8493. frame.HorizontalInfo[j].Font="12px 微软雅黑";
  8494. }
  8495. var subFrame=new SubFrameItem();
  8496. subFrame.Frame=frame;
  8497. subFrame.Height=10;
  8498. return subFrame;
  8499. }
  8500. this.UpdateXShowText=function()
  8501. {
  8502. var bLastFrame=true;
  8503. for(var i=this.Frame.SubFrame.length-1;i>=0;--i)
  8504. {
  8505. var item=this.Frame.SubFrame[i].Frame;
  8506. var subFrame=this.Frame.SubFrame[i];
  8507. if (bLastFrame)
  8508. {
  8509. item.XSplitOperator.ShowText=true;
  8510. if (subFrame.Height>0) bLastFrame=false;
  8511. }
  8512. else
  8513. {
  8514. item.XSplitOperator.ShowText=false;
  8515. }
  8516. }
  8517. }
  8518. //删除某一个窗口的指标
  8519. this.DeleteIndexPaint = function (windowIndex)
  8520. {
  8521. let paint = new Array();
  8522. for (let i in this.ChartPaint) //踢出当前窗口的指标画法
  8523. {
  8524. let item = this.ChartPaint[i];
  8525. if (i == 0 || item.ChartFrame != this.Frame.SubFrame[windowIndex].Frame)
  8526. paint.push(item);
  8527. }
  8528. //清空指定最大最小值
  8529. this.Frame.SubFrame[windowIndex].Frame.YSpecificMaxMin = null;
  8530. this.Frame.SubFrame[windowIndex].Frame.IsLocked = false; //解除上锁
  8531. this.ChartPaint = paint;
  8532. //清空东条标题
  8533. var titleIndex = windowIndex + 1;
  8534. this.TitlePaint[titleIndex].Data = [];
  8535. this.TitlePaint[titleIndex].Title = null;
  8536. }
  8537. this.CreateStockInfo = function () {
  8538. this.ExtendChartPaint[0] = new StockInfoExtendChartPaint();
  8539. this.ExtendChartPaint[0].Canvas = this.Canvas;
  8540. this.ExtendChartPaint[0].ChartBorder = this.Frame.ChartBorder;
  8541. this.ExtendChartPaint[0].ChartFrame = this.Frame;
  8542. this.Frame.ChartBorder.Right = 300;
  8543. }
  8544. //创建主图K线画法
  8545. this.CreateMainKLine = function ()
  8546. {
  8547. //分钟线
  8548. var minuteLine = new ChartMinutePriceLine();
  8549. minuteLine.Canvas = this.Canvas;
  8550. minuteLine.ChartBorder = this.Frame.SubFrame[0].Frame.ChartBorder;
  8551. minuteLine.ChartFrame = this.Frame.SubFrame[0].Frame;
  8552. minuteLine.Name = "Minute-Line";
  8553. minuteLine.Color = g_JSChartResource.Minute.PriceColor;
  8554. minuteLine.AreaColor = g_JSChartResource.Minute.AreaPriceColor;
  8555. this.ChartPaint[0] = minuteLine;
  8556. //分钟线均线
  8557. var averageLine = new ChartMinutePriceLine();
  8558. averageLine.Canvas = this.Canvas;
  8559. averageLine.ChartBorder = this.Frame.SubFrame[0].Frame.ChartBorder;
  8560. averageLine.ChartFrame = this.Frame.SubFrame[0].Frame;
  8561. averageLine.Name = "Minute-Average-Line";
  8562. averageLine.Color = g_JSChartResource.Minute.AvPriceColor;
  8563. averageLine.IsDrawArea = false;
  8564. this.ChartPaint[1] = averageLine;
  8565. //成交量柱子
  8566. var chartVol = new ChartMinuteVolumBar();
  8567. chartVol.Color = g_JSChartResource.Minute.VolBarColor;
  8568. chartVol.Canvas = this.Canvas;
  8569. chartVol.ChartBorder = this.Frame.SubFrame[1].Frame.ChartBorder;
  8570. chartVol.ChartFrame = this.Frame.SubFrame[1].Frame;
  8571. chartVol.Name = "Minute-Vol-Bar";
  8572. this.ChartPaint[2] = chartVol;
  8573. //持仓线
  8574. var chartPosition=new ChartSubLine();
  8575. chartPosition.Color = g_JSChartResource.Minute.PriceColor;
  8576. chartPosition.Canvas = this.Canvas;
  8577. chartPosition.ChartBorder = this.Frame.SubFrame[1].Frame.ChartBorder;
  8578. chartPosition.ChartFrame = this.Frame.SubFrame[1].Frame;
  8579. chartPosition.Name = "Minute-Position-Line";
  8580. this.ChartPaint[3] = chartPosition;
  8581. this.TitlePaint[0] = new DynamicMinuteTitlePainting();
  8582. this.TitlePaint[0].Frame = this.Frame.SubFrame[0].Frame;
  8583. this.TitlePaint[0].Canvas = this.Canvas;
  8584. this.TitlePaint[0].LanguageID = this.LanguageID;
  8585. //主图叠加画法
  8586. var paint = new ChartOverlayMinutePriceLine();
  8587. paint.Canvas = this.Canvas;
  8588. paint.ChartBorder = this.Frame.SubFrame[0].Frame.ChartBorder;
  8589. paint.ChartFrame = this.Frame.SubFrame[0].Frame;
  8590. paint.Name = "Overlay-Minute";
  8591. this.OverlayChartPaint[0] = paint;
  8592. }
  8593. //切换成 脚本指标
  8594. this.ChangeScriptIndex = function (windowIndex, indexData)
  8595. {
  8596. this.DeleteIndexPaint(windowIndex);
  8597. this.WindowIndex[windowIndex] = new ScriptIndex(indexData.Name, indexData.Script, indexData.Args, indexData); //脚本执行
  8598. var bindData = this.SourceData;
  8599. this.BindIndexData(windowIndex, bindData); //执行脚本
  8600. this.UpdataDataoffset(); //更新数据偏移
  8601. this.UpdateFrameMaxMin(); //调整坐标最大 最小值
  8602. this.Draw();
  8603. }
  8604. this.ChangeIndex = function (windowIndex, indexName, option)
  8605. {
  8606. if (this.Frame.SubFrame.length < 3) return;
  8607. //查找系统指标
  8608. let scriptData = new JSCommonIndexScript.JSIndexScript();
  8609. let indexInfo = scriptData.Get(indexName);
  8610. if (!indexInfo) return;
  8611. if (windowIndex < 2) windowIndex = 2;
  8612. if (windowIndex >= this.Frame.SubFrame.length) windowIndex = 2;
  8613. let indexData =
  8614. {
  8615. Name: indexInfo.Name, Script: indexInfo.Script, Args: indexInfo.Args, ID: indexName,
  8616. //扩展属性 可以是空
  8617. KLineType: indexInfo.KLineType, YSpecificMaxMin: indexInfo.YSpecificMaxMin, YSplitScale: indexInfo.YSplitScale,
  8618. FloatPrecision: indexInfo.FloatPrecision, Condition: indexInfo.Condition, StringFormat: indexInfo.StringFormat
  8619. };
  8620. if (option)
  8621. {
  8622. if (option.FloatPrecision >= 0) indexData.FloatPrecision = option.FloatPrecision;
  8623. if (option.StringFormat > 0) indexData.StringFormat = option.StringFormat;
  8624. if (option.Args) indexData.Args = option.Args;
  8625. }
  8626. return this.ChangeScriptIndex(windowIndex, indexData);
  8627. }
  8628. this.RemoveIndexWindow=function(id)
  8629. {
  8630. JSConsole.Chart.Log('[MinuteChartContainer::RemoveIndexWindow] remove id', id);
  8631. if (id<2) return;
  8632. if (!this.Frame.SubFrame) return;
  8633. if (id>=this.Frame.SubFrame.length) return;
  8634. var delFrame=this.Frame.SubFrame[id].Frame;
  8635. this.DeleteIndexPaint(id);
  8636. this.Frame.SubFrame.splice(id,1);
  8637. this.WindowIndex.splice(id,1);
  8638. this.TitlePaint.splice(id+1,1); //删除对应的动态标题
  8639. for(var i=0;i<this.Frame.SubFrame.length;++i)
  8640. {
  8641. var item=this.Frame.SubFrame[i].Frame;
  8642. if (i==this.Frame.SubFrame.length-1) item.XSplitOperator.ShowText=true;
  8643. else item.XSplitOperator.ShowText=false;
  8644. item.Identify=i;
  8645. }
  8646. this.Frame.SetSizeChage(true);
  8647. this.UpdateFrameMaxMin();
  8648. this.ResetFrameXYSplit();
  8649. this.Draw();
  8650. }
  8651. //切换股票代码
  8652. this.ChangeSymbol = function (symbol)
  8653. {
  8654. this.Symbol = symbol;
  8655. this.CancelAutoUpdate(); //先停止定时器
  8656. this.ChartSplashPaint.SetTitle(this.LoadDataSplashTitle);
  8657. this.ChartSplashPaint.EnableSplash(true);
  8658. this.RequestData();
  8659. }
  8660. this.ChangeDayCount = function (count)
  8661. {
  8662. if (count < 0 || count > 10) return;
  8663. this.DayCount = count;
  8664. this.CancelAutoUpdate(); //先停止定时器
  8665. this.RequestData();
  8666. }
  8667. //叠加股票 只支持日线数据
  8668. this.OverlaySymbol = function (symbol,option)
  8669. {
  8670. var paint = this.OverlayChartPaint[0];
  8671. if (!paint.MainData) return false;
  8672. paint.Symbol = symbol;
  8673. if (option)
  8674. {
  8675. if (option.Color) paint.Color=option.Color;
  8676. }
  8677. if (this.DayCount <= 1) this.RequestOverlayMinuteData(); //请求数据
  8678. else this.RequestOverlayHistoryMinuteData();
  8679. return true;
  8680. }
  8681. this.TryClickLock = function (x, y) {
  8682. for (let i in this.Frame.SubFrame) {
  8683. var item = this.Frame.SubFrame[i];
  8684. if (!item.Frame.IsLocked) continue;
  8685. if (!item.Frame.LockPaint) continue;
  8686. var tooltip = new TooltipData();
  8687. if (!item.Frame.LockPaint.GetTooltipData(x, y, tooltip)) continue;
  8688. tooltip.HQChart = this;
  8689. if (tooltip.Data.Callback) tooltip.Data.Callback(tooltip);
  8690. return true;
  8691. }
  8692. return false;
  8693. }
  8694. this.RequestData = function ()
  8695. {
  8696. if (this.DayCount <= 1) this.RequestMinuteData();
  8697. else this.RequestHistoryMinuteData(); //请求数据
  8698. }
  8699. this.RecvMinuteDataEvent = function ()
  8700. {
  8701. if (!this.mapEvent.has(JSCHART_EVENT_ID.RECV_MINUTE_DATA)) return;
  8702. var event = this.mapEvent.get(JSCHART_EVENT_ID.RECV_MINUTE_DATA);
  8703. var data = { MinuteData: this.SourceData, Stock: { Symbol: this.Symbol, Name: this.Name } }
  8704. event.Callback(event, data, this);
  8705. }
  8706. this.RequestHistoryMinuteData = function () //请求历史分钟数据
  8707. {
  8708. var self = this;
  8709. this.ChartSplashPaint.SetTitle(this.LoadDataSplashTitle);
  8710. this.ChartSplashPaint.EnableSplash(true);
  8711. this.Draw();
  8712. if (this.NetworkFilter)
  8713. {
  8714. var obj =
  8715. {
  8716. Name: 'MinuteChartContainer::RequestHistoryMinuteData', //类名::
  8717. Explain: '多日分时数据',
  8718. Request: { Url: self.HistoryMinuteApiUrl, Data: { daycount: self.DayCount, symbol: self.Symbol }, Type: 'POST' },
  8719. Self: this,
  8720. PreventDefault: false
  8721. };
  8722. this.NetworkFilter(obj, function (data) {
  8723. self.ChartSplashPaint.EnableSplash(false);
  8724. self.RecvHistoryMinuteData(data);
  8725. });
  8726. if (obj.PreventDefault == true) return; //已被上层替换,不调用默认的网络请求
  8727. }
  8728. wx.request({
  8729. url: self.HistoryMinuteApiUrl,
  8730. data:
  8731. {
  8732. "symbol": self.Symbol,
  8733. "daycount": self.DayCount
  8734. },
  8735. method: "post",
  8736. dataType: "json",
  8737. success: function (data) {
  8738. self.ChartSplashPaint.EnableSplash(false);
  8739. self.RecvHistoryMinuteData(data);
  8740. }
  8741. });
  8742. }
  8743. this.RecvHistoryMinuteData = function (recvdata)
  8744. {
  8745. var data = recvdata.data;
  8746. if (data.code!=0)
  8747. {
  8748. JSConsole.Chart.Log('[MinuteChartContainer::RecvHistoryMinuteData] failed.',data);
  8749. return;
  8750. }
  8751. this.DayData = MinuteChartContainer.JsonDataToMinuteDataArray(data);;
  8752. this.Symbol = data.symbol;
  8753. this.Name = data.name;
  8754. this.CaclutateLimitPrice(this.DayData[0].YClose, data.data[0].limitprice); //计算涨停价格
  8755. this.UpdateHistoryMinuteUI();
  8756. this.RecvMinuteDataEvent();
  8757. this.RequestOverlayHistoryMinuteData();
  8758. if (typeof (this.UpdateUICallback) == 'function') this.UpdateUICallback('RecvHistoryMinuteData', this);
  8759. this.AutoUpdate();
  8760. }
  8761. this.CaclutateLimitPrice=function(yClose, limitData)
  8762. {
  8763. this.LimitPrice=null;
  8764. //var limitData=data.stock[0].limitprice;
  8765. if (limitData && limitData.max>0 && limitData.min>0) //API里带涨停价格 直接使用
  8766. {
  8767. this.LimitPrice={ Max:limitData.max, Min:limitData.min };
  8768. return;
  8769. }
  8770. var range=MARKET_SUFFIX_NAME.GetLimitPriceRange(this.Symbol, this.Name); //通过规则获取涨停价格
  8771. if (!range)
  8772. {
  8773. JSConsole.Chart.Log(`[MinuteChartContainer::CaclutateLimitPrice] ${this.Symbol} no limit price.`)
  8774. return;
  8775. }
  8776. //var yClose=data.stock[0].yclose;
  8777. if (yClose<=0) return;
  8778. this.LimitPrice={ Max:yClose*(1+range.Max), Min:yClose*(1+range.Min) };
  8779. JSConsole.Chart.Log(`[MinuteChartContainer::CaclutateLimitPrice] ${this.Symbol} yClose:${yClose} max:${this.LimitPrice.Max} min:${this.LimitPrice.Min}`);
  8780. this.LimitPrice.Max=parseFloat(this.LimitPrice.Max.toFixed(2));
  8781. this.LimitPrice.Min=parseFloat(this.LimitPrice.Min.toFixed(2));
  8782. JSConsole.Chart.Log(`[MinuteChartContainer::CaclutateLimitPrice] ${this.Symbol} tofixed(2) max:${this.LimitPrice.Max} min:${this.LimitPrice.Min}`);
  8783. }
  8784. this.UpdateHistoryMinuteUI = function ()
  8785. {
  8786. var allMinuteData = this.HistoryMinuteDataToArray(this.DayData);
  8787. //原始数据
  8788. var sourceData = new ChartData();
  8789. sourceData.Data = allMinuteData;
  8790. this.SourceData = sourceData;
  8791. this.TradeDate = this.DayData[0].Date;
  8792. this.BindMainData(sourceData, this.DayData[0].YClose);
  8793. //if (MARKET_SUFFIX_NAME.IsChinaFutures(this.Symbol)) this.ChartPaint[1].Data = null; //期货均线暂时不用
  8794. if (this.Frame.SubFrame.length > 2)
  8795. {
  8796. var bindData = new ChartData();
  8797. bindData.Data = allMinuteData;
  8798. for (var i = 2; i < this.Frame.SubFrame.length; ++i)
  8799. {
  8800. this.BindIndexData(i, bindData);
  8801. }
  8802. }
  8803. for (let i in this.Frame.SubFrame)
  8804. {
  8805. var item = this.Frame.SubFrame[i];
  8806. item.Frame.XSplitOperator.Symbol = this.Symbol;
  8807. item.Frame.XSplitOperator.DayCount = this.DayData.length;
  8808. item.Frame.XSplitOperator.DayData = this.DayData;
  8809. item.Frame.XSplitOperator.Operator(); //调整X轴个数
  8810. item.Frame.YSplitOperator.Symbol = this.Symbol;
  8811. }
  8812. this.ChartCorssCursor.StringFormatY.Symbol = this.Symbol;
  8813. this.ChartCorssCursor.StringFormatX.Symbol = this.Symbol;
  8814. this.TitlePaint[0].IsShowDate = true;
  8815. this.UpdateFrameMaxMin(); //调整坐标最大 最小值
  8816. this.Frame.SetSizeChage(true);
  8817. this.Draw();
  8818. }
  8819. this.HistoryMinuteDataToArray = function (data) //把多日分钟数据转化为单数组
  8820. {
  8821. var result = [];
  8822. for (var i = data.length - 1; i >= 0; --i) {
  8823. var item = data[i];
  8824. for (var j in item.Data) {
  8825. result.push(item.Data[j]);
  8826. }
  8827. }
  8828. return result;
  8829. }
  8830. this.UpdateLatestMinuteData = function (data, date) //更新最新交易日的分钟数据
  8831. {
  8832. for (var i in this.DayData) {
  8833. var item = this.DayData[i];
  8834. if (item.Date === date) {
  8835. item.Data = data;
  8836. break;
  8837. }
  8838. }
  8839. }
  8840. //请求分钟数据
  8841. this.RequestMinuteData = function ()
  8842. {
  8843. var self = this;
  8844. var fields =
  8845. [
  8846. "name", "symbol",
  8847. "yclose", "open", "price", "high", "low",
  8848. "vol", "amount",
  8849. "date", "time",
  8850. "minute", "minutecount"
  8851. ];
  8852. var upperSymbol = this.Symbol.toUpperCase();
  8853. if (MARKET_SUFFIX_NAME.IsChinaFutures(upperSymbol)) //期货的需要加上结算价
  8854. {
  8855. fields.push("clearing");
  8856. fields.push("yclearing");
  8857. }
  8858. if (this.NetworkFilter)
  8859. {
  8860. var obj =
  8861. {
  8862. Name: 'MinuteChartContainer::RequestMinuteData', //类名::函数名
  8863. Explain: '最新分时数据',
  8864. Request: { Url: self.MinuteApiUrl, Data: { field: fields, symbol: [self.Symbol] }, Type: 'POST' },
  8865. Self: this,
  8866. PreventDefault: false
  8867. };
  8868. this.NetworkFilter(obj, function (data)
  8869. {
  8870. self.ChartSplashPaint.EnableSplash(false);
  8871. self.RecvMinuteData(data);
  8872. });
  8873. if (obj.PreventDefault == true) return; //已被上层替换,不调用默认的网络请求
  8874. }
  8875. wx.request({
  8876. url: this.MinuteApiUrl,
  8877. data:
  8878. {
  8879. "field": fields,
  8880. "symbol": [this.Symbol],
  8881. "start": -1
  8882. },
  8883. method: "post",
  8884. dataType: "json",
  8885. success: function (data) {
  8886. self.ChartSplashPaint.EnableSplash(false);
  8887. self.RecvMinuteData(data);
  8888. }
  8889. });
  8890. }
  8891. this.RecvMinuteData = function (data)
  8892. {
  8893. var aryMinuteData = MinuteChartContainer.JsonDataToMinuteData(data.data);
  8894. if (this.DayCount > 1) //多日走势图
  8895. {
  8896. this.UpdateLatestMinuteData(aryMinuteData, data.data.stock[0].date);
  8897. this.UpdateHistoryMinuteUI();
  8898. this.RecvMinuteDataEvent();
  8899. this.RequestOverlayMinuteData(); //更新最新叠加数据
  8900. if (typeof (this.UpdateUICallback) == 'function') this.UpdateUICallback('RecvMinuteData', this);
  8901. this.AutoUpdate();
  8902. return;
  8903. }
  8904. //原始数据
  8905. var sourceData = new ChartData();
  8906. sourceData.Data = aryMinuteData;
  8907. this.TradeDate = data.data.stock[0].date;
  8908. this.SourceData = sourceData;
  8909. this.Symbol = data.data.stock[0].symbol;
  8910. this.Name = data.data.stock[0].name;
  8911. var yClose = data.data.stock[0].yclose;
  8912. var upperSymbol = this.Symbol.toUpperCase();
  8913. var isFutures = MARKET_SUFFIX_NAME.IsFutures(upperSymbol);
  8914. if (data.data.stock[0].yclearing && isFutures) yClose = data.data.stock[0].yclearing; //期货使用前结算价
  8915. this.CaclutateLimitPrice(yClose, data.data.stock[0].limitprice); //计算涨停价格
  8916. var extendData = { High: data.data.stock[0].high, Low: data.data.stock[0].low };
  8917. this.BindMainData(sourceData, yClose, extendData);
  8918. for (let i in this.Frame.SubFrame) //把股票代码设置到X轴刻度类里
  8919. {
  8920. var item = this.Frame.SubFrame[i];
  8921. item.Frame.XSplitOperator.Symbol = this.Symbol;
  8922. item.Frame.XSplitOperator.DayCount = 1;
  8923. item.Frame.XSplitOperator.Operator(); //调整X轴个数
  8924. item.Frame.YSplitOperator.Symbol = this.Symbol;
  8925. }
  8926. //计算指标
  8927. if (this.Frame.SubFrame.length > 2)
  8928. {
  8929. var bindData = new ChartData();
  8930. bindData.Data = aryMinuteData;
  8931. for (var i = 2; i < this.Frame.SubFrame.length; ++i)
  8932. {
  8933. this.BindIndexData(i, bindData);
  8934. }
  8935. }
  8936. this.ChartCorssCursor.StringFormatY.Symbol = this.Symbol;
  8937. this.ChartCorssCursor.StringFormatX.Symbol = this.Symbol;
  8938. var chartInfo = this.GetChartMinuteInfo();
  8939. if (chartInfo) chartInfo.SourceData = this.SourceData; //数据绑定到信息地雷上
  8940. this.RecvMinuteDataEvent();
  8941. this.RequestMinuteInfoData();
  8942. this.RequestOverlayMinuteData();//请求叠加数据 (主数据下载完再下载)
  8943. this.UpdateFrameMaxMin(); //调整坐标最大 最小值
  8944. this.Frame.SetSizeChage(true);
  8945. this.Draw();
  8946. if (typeof (this.UpdateUICallback) == 'function') this.UpdateUICallback('RecvMinuteData', this);
  8947. this.AutoUpdate();
  8948. }
  8949. //请求叠加数据 (主数据下载完再下载))
  8950. this.RequestOverlayMinuteData = function ()
  8951. {
  8952. if (!this.OverlayChartPaint.length) return;
  8953. var symbol = this.OverlayChartPaint[0].Symbol;
  8954. if (!symbol) return;
  8955. var self = this;
  8956. var date = this.TradeDate; //最后一个交易日期
  8957. if (this.NetworkFilter)
  8958. {
  8959. var obj =
  8960. {
  8961. Name: 'MinuteChartContainer::RequestOverlayMinuteData', //类名::函数名
  8962. Explain: '叠加股票最新分时数据',
  8963. Request: { Url: self.HistoryMinuteApiUrl, Data: { days: [date], symbol: symbol }, Type: 'POST' },
  8964. Self: this,
  8965. PreventDefault: false
  8966. };
  8967. this.NetworkFilter(obj, function (data)
  8968. {
  8969. self.RecvOverlayMinuteData(data);
  8970. });
  8971. if (obj.PreventDefault == true) return; //已被上层替换,不调用默认的网络请求
  8972. }
  8973. //请求数据
  8974. wx.request({
  8975. url: self.HistoryMinuteApiUrl,
  8976. data:
  8977. {
  8978. "symbol": symbol,
  8979. "days": [date],
  8980. },
  8981. method: "post",
  8982. dataType: "json",
  8983. success: function (data) {
  8984. self.RecvOverlayMinuteData(data);
  8985. }
  8986. });
  8987. }
  8988. this.RecvOverlayMinuteData = function (recvData) {
  8989. var data = recvData.data;
  8990. var aryMinuteData = MinuteChartContainer.JsonDataToMinuteDataArray(data);
  8991. var sourceData = null;
  8992. var yClose;
  8993. if (this.DayCount > 1) //多日数据
  8994. {
  8995. if (aryMinuteData.length <= 0) return;
  8996. var minuteData = aryMinuteData[0];
  8997. for (var i in this.OverlaySourceData) {
  8998. var item = this.OverlaySourceData[i];
  8999. if (item.Date == minuteData.Date) {
  9000. this.OverlaySourceData[i] = minuteData;
  9001. var allMinuteData = this.HistoryMinuteDataToArray(this.OverlaySourceData);
  9002. var sourceData = new ChartData();
  9003. sourceData.Data = allMinuteData;
  9004. yClose = minuteData.YClose;
  9005. break;
  9006. }
  9007. }
  9008. if (sourceData == null) return;
  9009. }
  9010. else {
  9011. if (aryMinuteData.length > 0) sourceData = aryMinuteData[0];
  9012. else sourceData = new ChartData();
  9013. yClose = sourceData.YClose;
  9014. }
  9015. this.OverlayChartPaint[0].Data = sourceData;
  9016. this.OverlayChartPaint[0].Title = data.name;
  9017. this.OverlayChartPaint[0].Symbol = data.symbol;
  9018. this.OverlayChartPaint[0].YClose = yClose;
  9019. this.UpdateFrameMaxMin(); //调整坐标最大 最小值
  9020. this.Frame.SetSizeChage(true);
  9021. this.Draw();
  9022. if (typeof (this.UpdateUICallback) == 'function') this.UpdateUICallback('RecvOverlayMinuteData', this);
  9023. }
  9024. this.RequestOverlayHistoryMinuteData = function ()
  9025. {
  9026. if (!this.OverlayChartPaint.length) return;
  9027. var symbol = this.OverlayChartPaint[0].Symbol;
  9028. if (!symbol) return;
  9029. var self = this;
  9030. var days = [];
  9031. for (var i in this.DayData)
  9032. {
  9033. var item = this.DayData[i];
  9034. days.push(item.Date);
  9035. }
  9036. if (days.length <= 0) return;
  9037. if (this.NetworkFilter)
  9038. {
  9039. var obj =
  9040. {
  9041. Name: 'MinuteChartContainer::RequestOverlayHistoryMinuteData', //类名::函数名
  9042. Explain: '叠加股票多日分时数据',
  9043. Request: { Url: self.HistoryMinuteApiUrl, Data: { days: days, symbol: symbol }, Type: 'POST' },
  9044. Self: this,
  9045. PreventDefault: false
  9046. };
  9047. this.NetworkFilter(obj, function (data)
  9048. {
  9049. self.RecvOverlayHistoryMinuteData(data);
  9050. });
  9051. if (obj.PreventDefault == true) return; //已被上层替换,不调用默认的网络请求
  9052. }
  9053. wx.request({
  9054. url: self.HistoryMinuteApiUrl,
  9055. data:
  9056. {
  9057. "symbol": symbol,
  9058. "days": days
  9059. },
  9060. method: "post",
  9061. dataType: "json",
  9062. async: true,
  9063. success: function (data) {
  9064. self.RecvOverlayHistoryMinuteData(data);
  9065. }
  9066. });
  9067. }
  9068. this.RecvOverlayHistoryMinuteData = function (recvData) //叠加历史的分钟数据
  9069. {
  9070. var data = recvData.data;
  9071. var dayData = MinuteChartContainer.JsonDataToMinuteDataArray(data);
  9072. var overlayDayData = [];
  9073. for (var i in this.DayData) {
  9074. var item = this.DayData[i];
  9075. var bFind = false;
  9076. for (var j in dayData) {
  9077. if (item.Date == dayData[j].Date) {
  9078. overlayDayData.push(dayData[i]);
  9079. bFind = true;
  9080. break;
  9081. }
  9082. }
  9083. if (!bFind) //当天不存在叠加数据, 存空
  9084. {
  9085. var empytData = new ChartData();
  9086. empytData.Date = item.Date;
  9087. }
  9088. }
  9089. this.OverlaySourceData = overlayDayData;
  9090. var allMinuteData = this.HistoryMinuteDataToArray(overlayDayData);
  9091. //原始数据
  9092. var sourceData = new ChartData();
  9093. sourceData.Data = allMinuteData;
  9094. var yClose = overlayDayData[0].YClose;
  9095. this.OverlayChartPaint[0].Data = sourceData;
  9096. this.OverlayChartPaint[0].Title = data.name;
  9097. this.OverlayChartPaint[0].Symbol = data.symbol;
  9098. this.OverlayChartPaint[0].YClose = yClose;
  9099. this.UpdateFrameMaxMin(); //调整坐标最大 最小值
  9100. this.Frame.SetSizeChage(true);
  9101. this.Draw();
  9102. if (typeof (this.UpdateUICallback) == 'function') this.UpdateUICallback('RecvOverlayHistoryMinuteData', this);
  9103. }
  9104. this.CancelAutoUpdate = function () //关闭停止更新
  9105. {
  9106. if (typeof (this.AutoUpdateTimer) == 'number')
  9107. {
  9108. clearTimeout(this.AutoUpdateTimer);
  9109. this.AutoUpdateTimer = undefined;
  9110. }
  9111. }
  9112. //数据自动更新
  9113. this.AutoUpdate = function ()
  9114. {
  9115. this.CancelAutoUpdate();
  9116. if (!this.IsAutoUpdate) return;
  9117. if (!this.Symbol) return;
  9118. if (this.IsDestroy) return;
  9119. var self = this;
  9120. var marketStatus = MARKET_SUFFIX_NAME.GetMarketStatus(this.Symbol);
  9121. if (marketStatus == 0 || marketStatus == 3) return; //闭市,盘后
  9122. var frequency = this.AutoUpdateFrequency;
  9123. if (marketStatus == 1) //盘前
  9124. {
  9125. this.AutoUpdateTimer=setTimeout(function () { self.AutoUpdate(); }, frequency);
  9126. }
  9127. else if (marketStatus == 2) //盘中
  9128. {
  9129. this.AutoUpdateTimer=setTimeout(function ()
  9130. {
  9131. //self.ResetOverlaySymbolStatus();
  9132. self.RequestMinuteData();
  9133. }, frequency);
  9134. }
  9135. }
  9136. this.StopAutoUpdate = function ()
  9137. {
  9138. this.CancelAutoUpdate();
  9139. this.IsAutoUpdate = false;
  9140. }
  9141. this.BindIndexData = function (windowIndex, hisData)
  9142. {
  9143. if (!this.WindowIndex[windowIndex]) return;
  9144. if (typeof (this.WindowIndex[windowIndex].RequestData) == "function") //数据需要另外下载的.
  9145. {
  9146. this.WindowIndex[windowIndex].RequestData(this, windowIndex, hisData);
  9147. return;
  9148. }
  9149. if (typeof (this.WindowIndex[windowIndex].ExecuteScript) == 'function')
  9150. {
  9151. this.WindowIndex[windowIndex].ExecuteScript(this, windowIndex, hisData);
  9152. return;
  9153. }
  9154. this.WindowIndex[windowIndex].BindData(this, windowIndex, hisData);
  9155. }
  9156. this.BindMainData = function (minuteData, yClose, extendData) //绑定分钟数据
  9157. {
  9158. //分钟数据
  9159. var bindData = new ChartData();
  9160. bindData.Data = minuteData.GetClose();
  9161. this.ChartPaint[0].Data = bindData;
  9162. this.ChartPaint[0].YClose = yClose;
  9163. this.ChartPaint[0].NotSupportMessage = null;
  9164. this.Frame.SubFrame[0].Frame.YSplitOperator.YClose = yClose;
  9165. this.Frame.SubFrame[0].Frame.YSplitOperator.Data = bindData;
  9166. //均线
  9167. bindData = new ChartData();
  9168. bindData.Data = minuteData.GetMinuteAvPrice();
  9169. this.ChartPaint[1].Data = bindData;
  9170. this.Frame.SubFrame[0].Frame.YSplitOperator.AverageData = bindData;
  9171. this.Frame.SubFrame[0].Frame.YSplitOperator.OverlayChartPaint = this.OverlayChartPaint;
  9172. this.Frame.SubFrame[0].Frame.YSplitOperator.LimitPrice=this.LimitPrice;
  9173. if (extendData)
  9174. {
  9175. this.Frame.SubFrame[0].Frame.YSplitOperator.High = extendData.High;
  9176. this.Frame.SubFrame[0].Frame.YSplitOperator.Low = extendData.Low;
  9177. }
  9178. //成交量
  9179. this.ChartPaint[2].Data = minuteData;
  9180. this.ChartPaint[2].YClose = yClose;
  9181. var upperSymbol=this.Symbol.toUpperCase();
  9182. var bFutures=MARKET_SUFFIX_NAME.IsChinaFutures(upperSymbol);
  9183. var bSHO = MARKET_SUFFIX_NAME.IsSHO(upperSymbol);
  9184. if (bFutures || bSHO)
  9185. {
  9186. this.ChartPaint[3].Data.Data = minuteData.GetPosition();
  9187. }
  9188. else
  9189. {
  9190. this.ChartPaint[3].Data.Data=null;
  9191. }
  9192. this.TitlePaint[0].Data = this.SourceData; //动态标题
  9193. this.TitlePaint[0].Symbol = this.Symbol;
  9194. this.TitlePaint[0].Name = this.Name;
  9195. this.TitlePaint[0].YClose = yClose;
  9196. if (this.ChartCorssCursor)
  9197. {
  9198. if (this.ChartCorssCursor.StringFormatY)
  9199. {
  9200. this.ChartCorssCursor.StringFormatY.YClose=yClose;
  9201. this.ChartCorssCursor.StringFormatX.Data=this.ChartPaint[0].Data; //十字光标
  9202. }
  9203. }
  9204. if (this.ExtendChartPaint[0])
  9205. {
  9206. this.ExtendChartPaint[0].Symbol = this.Symbol;
  9207. this.ExtendChartPaint[0].Name = this.Name;
  9208. }
  9209. this.OverlayChartPaint[0].MainData = this.ChartPaint[0].Data; //叠加
  9210. this.OverlayChartPaint[0].MainYClose = yClose;
  9211. }
  9212. //获取子窗口的所有画法
  9213. this.GetChartPaint = function (windowIndex)
  9214. {
  9215. var paint = new Array();
  9216. for (var i in this.ChartPaint)
  9217. {
  9218. if (i < 3) continue; //分钟 均线 成交量 3个线不能改
  9219. var item = this.ChartPaint[i];
  9220. if (item.ChartFrame == this.Frame.SubFrame[windowIndex].Frame)
  9221. paint.push(item);
  9222. }
  9223. return paint;
  9224. }
  9225. //创建指定窗口指标
  9226. this.CreateWindowIndex = function (windowIndex)
  9227. {
  9228. this.WindowIndex[windowIndex].Create(this, windowIndex);
  9229. }
  9230. this.CreateExtendChart = function (name, option) //创建扩展图形
  9231. {
  9232. var chart;
  9233. switch (name)
  9234. {
  9235. case 'MinuteTooltip':
  9236. chart = new MinuteTooltipPaint();
  9237. chart.Canvas = this.Canvas;
  9238. chart.ChartBorder = this.Frame.ChartBorder;
  9239. chart.ChartFrame = this.Frame;
  9240. chart.HQChart = this;
  9241. option.LanguageID = this.LanguageID;
  9242. chart.SetOption(option);
  9243. this.ExtendChartPaint.push(chart);
  9244. return chart;
  9245. default:
  9246. return null;
  9247. }
  9248. }
  9249. this.SetMinuteInfo = function (aryInfo, bUpdate)
  9250. {
  9251. this.ChartInfo = []; //先清空
  9252. for (var i in aryInfo)
  9253. {
  9254. var infoItem = JSMinuteInfoMap.Get(aryInfo[i]);
  9255. if (!infoItem) continue;
  9256. var item = infoItem.Create();
  9257. this.ChartInfo.push(item);
  9258. }
  9259. if (bUpdate == true) this.RequestMinuteInfoData();
  9260. }
  9261. this.GetChartMinuteInfo = function ()
  9262. {
  9263. return this.ChartInfoPaint;
  9264. }
  9265. this.CreateMinuteInfo = function (option) //在Create()以后 在调用
  9266. {
  9267. var chart = new ChartMinuteInfo();
  9268. chart.Canvas = this.Canvas;
  9269. chart.ChartBorder = this.Frame.SubFrame[0].Frame.ChartBorder;
  9270. chart.ChartFrame = this.Frame.SubFrame[0].Frame;
  9271. chart.ChartMinutePrice = this.ChartPaint[0];
  9272. if (option && chart.SetOption) chart.SetOption(option);
  9273. this.ChartInfoPaint = chart;
  9274. return chart;
  9275. }
  9276. //信息地雷数据请求
  9277. this.RequestMinuteInfoData = function ()
  9278. {
  9279. if (this.ChartInfo.length <= 0) return;
  9280. var chart = this.GetChartMinuteInfo();
  9281. if (!chart) chart = this.CreateMinuteInfo(null); //不存在就创建
  9282. chart.SourceData = this.SourceData;
  9283. //信息地雷信息
  9284. for (var i in this.ChartInfo) {
  9285. this.ChartInfo[i].RequestData(this);
  9286. }
  9287. }
  9288. //更新信息地雷
  9289. this.UpdataChartInfo = function ()
  9290. {
  9291. var chart = this.GetChartMinuteInfo();
  9292. if (!chart) return;
  9293. var infoMap = new Map();
  9294. for (var i in this.ChartInfo)
  9295. {
  9296. var infoData = this.ChartInfo[i].Data;
  9297. for (var j in infoData)
  9298. {
  9299. var item = infoData[j];
  9300. var dateTime = `${item.Date} ${item.Time}`;
  9301. if (infoMap.has(dateTime)) infoMap.get(dateTime).Data.push(item);
  9302. else infoMap.set(dateTime, { Data: new Array(item) });
  9303. }
  9304. }
  9305. chart.Data = infoMap;
  9306. }
  9307. }
  9308. //API 返回数据 转化为array[]
  9309. MinuteChartContainer.JsonDataToMinuteData = function (data)
  9310. {
  9311. var upperSymbol = data.stock[0].symbol.toUpperCase();
  9312. var isSHSZ = MARKET_SUFFIX_NAME.IsSHSZ(upperSymbol);
  9313. var isFutures = MARKET_SUFFIX_NAME.IsChinaFutures(upperSymbol) || MARKET_SUFFIX_NAME.IsNYMEX(upperSymbol);
  9314. var isSHO = MARKET_SUFFIX_NAME.IsSHO(upperSymbol); //上海股票期权
  9315. var preClose = data.stock[0].yclose; //前一个数据价格
  9316. var preAvPrice = data.stock[0].yclose; //前一个均价
  9317. var yClose = data.stock[0].yclose;
  9318. if (isFutures && data.stock[0].yclearing) yClose = preClose = preAvPrice = data.stock[0].yclearing; //期货使用昨结算价
  9319. var date = data.stock[0].date;
  9320. var aryMinuteData = new Array();
  9321. for (var i in data.stock[0].minute)
  9322. {
  9323. var jsData = data.stock[0].minute[i];
  9324. var item = new MinuteData();
  9325. if (jsData.price) preClose = jsData.price;
  9326. if (jsData.avprice) preAvPrice = jsData.avprice;
  9327. item.Close = jsData.price;
  9328. item.Open = jsData.open;
  9329. item.High = jsData.high;
  9330. item.Low = jsData.low;
  9331. if (isSHSZ) item.Vol = jsData.vol / 100; //原始单位股
  9332. else item.Vol = jsData.vol;
  9333. item.Amount = jsData.amount;
  9334. item.Increase = jsData.increase;
  9335. item.Risefall = jsData.risefall;
  9336. item.AvPrice = jsData.avprice;
  9337. if (!item.Close) //当前没有价格 使用上一个价格填充
  9338. {
  9339. item.Close = preClose;
  9340. item.Open = item.High = item.Low = item.Close;
  9341. }
  9342. if (!item.AvPrice) item.AvPrice = preAvPrice;
  9343. if (jsData.date > 0) date = jsData.date; //分钟数据中有日期 优先使用
  9344. item.DateTime = date.toString() + " " + jsData.time.toString();
  9345. item.Date = data.stock[0].date;
  9346. item.Time = jsData.time;
  9347. if (8<jsData.length && jsData[8]>0)
  9348. {
  9349. item.Date=jsData[8]; //日期
  9350. item.DateTime=item.Date.toString()+" "+jsData[0].toString();
  9351. }
  9352. if (isFutures || isSHO) item.Position = jsData.position; //期货 期权有持仓
  9353. if (i == 0) //第1个数据 写死9:25
  9354. {
  9355. item.IsFristData = true;
  9356. //if (isSHSZ) item.DateTime = data.stock[0].date.toString() + " 0925";
  9357. if (item.Close <= 0) //第1分钟 没数据就用开盘价
  9358. {
  9359. item.Close = data.stock[0].open;
  9360. item.High = item.Low = data.stock[0].open;
  9361. item.AvPrice = data.stock[0].open;
  9362. JSConsole.Chart.Log('[MinuteChartContainer::JsonDataToMinuteData] first minute data is empty.', data.stock[0].symbol, jsData);
  9363. }
  9364. }
  9365. //价格是0的 都用空
  9366. if (item.Open <= 0) item.Open = null;
  9367. if (item.Close <= 0) item.Close = null;
  9368. if (item.AvPrice <= 0) item.AvPrice = null;
  9369. if (item.High <= 0) item.High = null;
  9370. if (item.Low <= 0) item.Low = null;
  9371. if (yClose && item.Close) item.Increase = (item.Close - yClose) / yClose * 100; //涨幅 (最新价格-昨收)/昨收*10
  9372. aryMinuteData[i] = item;
  9373. }
  9374. return aryMinuteData;
  9375. }
  9376. //多日日线数据API 转化成array[];
  9377. MinuteChartContainer.JsonDataToMinuteDataArray = function (data)
  9378. {
  9379. var upperSymbol = data.symbol.toUpperCase();
  9380. var isSHSZ = MARKET_SUFFIX_NAME.IsSHSZ(upperSymbol);
  9381. var isFutures = MARKET_SUFFIX_NAME.IsChinaFutures(upperSymbol) || MARKET_SUFFIX_NAME.IsNYMEX(upperSymbol);
  9382. var isSHO = MARKET_SUFFIX_NAME.IsSHO(upperSymbol); //上海股票期权
  9383. var result = [];
  9384. for (var i in data.data)
  9385. {
  9386. var minuteData = [];
  9387. var dayData = data.data[i];
  9388. var date = dayData.date;
  9389. var yClose = dayData.yclose; //前收盘 计算涨幅
  9390. var preClose = yClose; //前一个数据价格
  9391. var preAvPrice=null; //前一个均价
  9392. for (var j in dayData.minute)
  9393. {
  9394. var jsData = dayData.minute[j];
  9395. if (jsData[2]) preClose = jsData[2]; //保存上一个收盘数据
  9396. var item = new MinuteData();
  9397. item.Close = jsData[2];
  9398. item.Open = jsData[1];
  9399. item.High = jsData[3];
  9400. item.Low = jsData[4];
  9401. if(isSHSZ) item.Vol = jsData[5] / 100; //原始单位股
  9402. else item.Vol = jsData[5];
  9403. item.Amount = jsData[6];
  9404. if (7 < jsData.length && jsData[7] > 0)
  9405. {
  9406. item.AvPrice = jsData[7]; //均价
  9407. preAvPrice = jsData[7];
  9408. }
  9409. if (!item.Close) //当前没有价格 使用上一个价格填充
  9410. {
  9411. item.Close = preClose;
  9412. item.Open = item.High = item.Low = item.Close;
  9413. }
  9414. if (!item.AvPrice && preAvPrice) item.AvPrice = preAvPrice;
  9415. if (item.Close && yClose) item.Increase = (item.Close - yClose) / yClose * 100;
  9416. else item.Increase = null;
  9417. item.DateTime = date.toString() + " " + jsData[0].toString();
  9418. item.Date = date;
  9419. item.Time = jsData[0];
  9420. if (8<jsData.length && jsData[8]>0)
  9421. {
  9422. item.Date=jsData[8]; //日期
  9423. item.DateTime=item.Date.toString()+" "+jsData[0].toString();
  9424. }
  9425. if ((isFutures || isSHO) && 9 < jsData.length) item.Position = jsData[9]; //持仓
  9426. if (j == 0 )
  9427. {
  9428. //if (isSHSZ) item.DateTime = date.toString() + " 0925";//第1个数据 写死9:25
  9429. item.IsFristData = true;
  9430. }
  9431. //价格是0的 都用空
  9432. if (item.Open <= 0) item.Open = null;
  9433. if (item.Close <= 0) item.Close = null;
  9434. if (item.AvPrice <= 0) item.AvPrice = null;
  9435. if (item.High <= 0) item.High = null;
  9436. if (item.Low <= 0) item.Low = null;
  9437. if (item.AvPrice <= 0) item.AvPrice = null;
  9438. minuteData[j] = item;
  9439. }
  9440. var newData = new ChartData();
  9441. newData.Data = minuteData;
  9442. newData.YClose = yClose;
  9443. newData.Close = dayData.close;
  9444. newData.Date = date;
  9445. result.push(newData);
  9446. }
  9447. return result;
  9448. }
  9449. /*
  9450. 历史分钟走势图
  9451. */
  9452. function HistoryMinuteChartContainer(uielement) {
  9453. this.newMethod = MinuteChartContainer; //派生
  9454. this.newMethod(uielement);
  9455. delete this.newMethod;
  9456. this.HistoryMinuteApiUrl = "https://opensourcecache.zealink.com/cache/minuteday/day/";
  9457. //创建主图K线画法
  9458. this.CreateMainKLine = function () {
  9459. //分钟线
  9460. var minuteLine = new ChartMinutePriceLine();
  9461. minuteLine.Canvas = this.Canvas;
  9462. minuteLine.ChartBorder = this.Frame.SubFrame[0].Frame.ChartBorder;
  9463. minuteLine.ChartFrame = this.Frame.SubFrame[0].Frame;
  9464. minuteLine.Name = "Minute-Line";
  9465. minuteLine.Color = g_JSChartResource.Minute.PriceColor;
  9466. this.ChartPaint[0] = minuteLine;
  9467. //分钟线均线
  9468. var averageLine = new ChartLine();
  9469. averageLine.Canvas = this.Canvas;
  9470. averageLine.ChartBorder = this.Frame.SubFrame[0].Frame.ChartBorder;
  9471. averageLine.ChartFrame = this.Frame.SubFrame[0].Frame;
  9472. averageLine.Name = "Minute-Average-Line";
  9473. averageLine.Color = g_JSChartResource.Minute.AvPriceColor;
  9474. this.ChartPaint[1] = averageLine;
  9475. var averageLine = new ChartMinuteVolumBar();
  9476. averageLine.Color = g_JSChartResource.Minute.VolBarColor;
  9477. averageLine.Canvas = this.Canvas;
  9478. averageLine.ChartBorder = this.Frame.SubFrame[1].Frame.ChartBorder;
  9479. averageLine.ChartFrame = this.Frame.SubFrame[1].Frame;
  9480. averageLine.Name = "Minute-Vol-Bar";
  9481. this.ChartPaint[2] = averageLine;
  9482. this.TitlePaint[0] = new DynamicMinuteTitlePainting();
  9483. this.TitlePaint[0].Frame = this.Frame.SubFrame[0].Frame;
  9484. this.TitlePaint[0].Canvas = this.Canvas;
  9485. this.TitlePaint[0].IsShowDate = true;
  9486. /*
  9487. //主图叠加画法
  9488. var paint=new ChartOverlayKLine();
  9489. paint.Canvas=this.Canvas;
  9490. paint.ChartBorder=this.Frame.SubFrame[0].Frame.ChartBorder;
  9491. paint.ChartFrame=this.Frame.SubFrame[0].Frame;
  9492. paint.Name="Overlay-KLine";
  9493. this.OverlayChartPaint[0]=paint;
  9494. */
  9495. }
  9496. //设置交易日期
  9497. this.ChangeTradeDate = function (trdateDate) {
  9498. if (!trdateDate) return;
  9499. this.TradeDate = trdateDate;
  9500. this.RequestData(); //更新数据
  9501. }
  9502. this.RequestData = function () {
  9503. var date = new Date();
  9504. var nowDate = date.getFullYear() * 10000 + (date.getMonth() + 1) * 100 + date.getDate();
  9505. if (nowDate == this.TradeDate) this.RequestMinuteData();
  9506. else this.RequestHistoryMinuteData();
  9507. }
  9508. //请求分钟数据
  9509. this.RequestHistoryMinuteData = function () {
  9510. var self = this;
  9511. var url = this.HistoryMinuteApiUrl + this.TradeDate.toString() + "/" + this.Symbol + ".json";
  9512. wx.request({
  9513. url: url,
  9514. method: "get",
  9515. dataType: "json",
  9516. success: function (data) {
  9517. self.ChartSplashPaint.EnableSplash(false);
  9518. self.RecvHistoryMinuteData(data);
  9519. },
  9520. error: function (reqeust) {
  9521. self.ChartSplashPaint.EnableSplash(false);
  9522. self.RecvHistoryMinuteError(reqeust);
  9523. }
  9524. });
  9525. }
  9526. this.RecvHistoryMinuteError = function (reqeust) {
  9527. if (reqeust.status != 404) return;
  9528. var sourceData = new ChartData();
  9529. this.SourceData = sourceData;
  9530. for (var i in this.ChartPaint) {
  9531. this.ChartPaint[i].Data = sourceData;
  9532. if (i == 0) this.ChartPaint[i].NotSupportMessage = '没有权限访问!';
  9533. }
  9534. this.TitlePaint[0].Data = this.SourceData; //动态标题
  9535. this.TitlePaint[0].Symbol = this.Symbol;
  9536. this.TitlePaint[0].Name = null;
  9537. this.Draw();
  9538. }
  9539. this.RecvHistoryMinuteData = function (recvData) {
  9540. if (recvData.statusCode != 200) {
  9541. var sourceData = new ChartData();
  9542. this.SourceData = sourceData;
  9543. for (var i in this.ChartPaint) {
  9544. this.ChartPaint[i].Data = sourceData;
  9545. if (i == 0) this.ChartPaint[i].NotSupportMessage = '没有权限访问!';
  9546. }
  9547. this.TitlePaint[0].Data = this.SourceData; //动态标题
  9548. this.TitlePaint[0].Symbol = this.Symbol;
  9549. this.TitlePaint[0].Name = null;
  9550. this.Draw();
  9551. return;
  9552. }
  9553. var data = recvData.data;
  9554. var aryMinuteData = HistoryMinuteChartContainer.JsonDataToMinuteData(data);
  9555. //原始数据
  9556. var sourceData = new ChartData();
  9557. sourceData.Data = aryMinuteData;
  9558. this.TradeDate = data.date;
  9559. this.SourceData = sourceData;
  9560. this.Symbol = data.symbol;
  9561. this.Name = data.name;
  9562. this.BindMainData(sourceData, data.day.yclose);
  9563. if (this.Frame.SubFrame.length > 2) {
  9564. var bindData = new ChartData();
  9565. bindData.Data = aryMinuteData;
  9566. for (var i = 2; i < this.Frame.SubFrame.length; ++i) {
  9567. this.BindIndexData(i, bindData);
  9568. }
  9569. }
  9570. this.UpdateFrameMaxMin(); //调整坐标最大 最小值
  9571. this.Frame.SetSizeChage(true);
  9572. this.Draw();
  9573. //this.AutoUpdata();
  9574. }
  9575. }
  9576. //API 返回数据 转化为array[]
  9577. HistoryMinuteChartContainer.JsonDataToMinuteData = function (data)
  9578. {
  9579. var aryMinuteData = new Array();
  9580. for (var i in data.minute.time)
  9581. {
  9582. var item = new MinuteData();
  9583. if (data.minute.price[i] <= 0 && i > 0) //当前这一分钟价格为空,使用上一分钟的数据
  9584. {
  9585. item.Close = aryMinuteData[i - 1].Close;
  9586. item.Open = aryMinuteData[i - 1].Close;
  9587. item.High = item.Close;
  9588. item.Low = item.Close;
  9589. item.Vol = data.minute.vol[i] / 100; //原始单位股
  9590. item.Amount = data.minute.amount[i];
  9591. item.DateTime = data.date.toString() + " " + data.minute.time[i].toString();
  9592. item.Date = data.date;
  9593. item.Time = data.minute.time[i];
  9594. //item.Increate=jsData.increate;
  9595. //item.Risefall=jsData.risefall;
  9596. item.AvPrice = aryMinuteData[i - 1].AvPrice;
  9597. }
  9598. else
  9599. {
  9600. item.Close = data.minute.price[i];
  9601. item.Open = data.minute.open[i];
  9602. item.High = data.minute.high[i];
  9603. item.Low = data.minute.low[i];
  9604. item.Vol = data.minute.vol[i] / 100; //原始单位股
  9605. item.Amount = data.minute.amount[i];
  9606. item.DateTime = data.date.toString() + " " + data.minute.time[i].toString();
  9607. item.Date = data.date;
  9608. item.Time = data.minute.time[i];
  9609. //item.Increate=jsData.increate;
  9610. //item.Risefall=jsData.risefall;
  9611. item.AvPrice = data.minute.avprice[i];
  9612. }
  9613. //价格是0的 都用空
  9614. if (item.Open <= 0) item.Open = null;
  9615. if (item.Close <= 0) item.Close = null;
  9616. if (item.AvPrice <= 0) item.AvPrice = null;
  9617. if (item.High <= 0) item.High = null;
  9618. if (item.Low <= 0) item.Low = null;
  9619. aryMinuteData[i] = item;
  9620. }
  9621. return aryMinuteData;
  9622. }
  9623. /////////////////////////////////////////////////////////////////////////////
  9624. // 自定义指数
  9625. //
  9626. function CustomKLineChartContainer(uielement) {
  9627. this.newMethod = KLineChartContainer; //派生
  9628. this.newMethod(uielement);
  9629. delete this.newMethod;
  9630. this.ClassName = 'CustomKLineChartContainer';
  9631. this.ChangeRight = null; //没有复权设置
  9632. this.LoadDataSplashTitle = '计算指数数据';
  9633. this.CustomKLineApiUrl = g_JSChartResource.Domain + "/API/IndexCalculate"; //自定义指数计算地址
  9634. this.CustomStock; //成分
  9635. this.QueryDate = { Start: 20180101, End: 20180627 }; //计算时间区间
  9636. this.RequestHistoryData = function () {
  9637. var self = this;
  9638. this.ChartSplashPaint.SetTitle(this.LoadDataSplashTitle);
  9639. this.ChartSplashPaint.EnableSplash(true);
  9640. this.Draw();
  9641. wx.request({
  9642. url: this.CustomKLineApiUrl,
  9643. data:
  9644. {
  9645. "stock": self.CustomStock,
  9646. "Name": self.Symbol,
  9647. "date": { "startdate": self.QueryDate.Start, "enddate": self.QueryDate.End }
  9648. },
  9649. method: 'POST',
  9650. dataType: "json",
  9651. async: true,
  9652. success: function (data) {
  9653. self.ChartSplashPaint.EnableSplash(false);
  9654. self.RecvHistoryData(data);
  9655. }
  9656. });
  9657. }
  9658. this.RecvHistoryData = function (recvData)
  9659. {
  9660. var data = recvData.data;
  9661. var aryDayData = KLineChartContainer.JsonDataToHistoryData(data);
  9662. //原始数据
  9663. var sourceData = new ChartData();
  9664. sourceData.Data = aryDayData;
  9665. sourceData.DataType = 0; //0=日线数据 1=分钟数据
  9666. sourceData.Symbol = data.symbol;
  9667. //显示的数据
  9668. var bindData = new ChartData();
  9669. bindData.Data = aryDayData;
  9670. bindData.Right = 0; //指数没有复权
  9671. bindData.Period = this.Period;
  9672. bindData.DataType = 0;
  9673. bindData.Symbol = data.symbol;
  9674. if (ChartData.IsDayPeriod(this.Period, false)) //周期数据
  9675. {
  9676. var periodData = sourceData.GetPeriodData(bindData.Period);
  9677. bindData.Data = periodData;
  9678. }
  9679. //绑定数据
  9680. this.SourceData = sourceData;
  9681. this.Name = data.name;
  9682. this.BindMainData(bindData, this.PageSize);
  9683. for (var i = 0; i < this.Frame.SubFrame.length; ++i)
  9684. {
  9685. this.BindIndexData(i, bindData);
  9686. }
  9687. //this.BindIndexData(0,hisData);
  9688. //this.BindIndexData(1,hisData);
  9689. //this.BindIndexData(2,hisData);
  9690. //刷新画图
  9691. this.UpdataDataoffset(); //更新数据偏移
  9692. this.UpdatePointByCursorIndex(); //更新十字光标位子
  9693. this.UpdateFrameMaxMin(); //调整坐标最大 最小值
  9694. this.Frame.SetSizeChage(true);
  9695. this.Draw();
  9696. if (typeof (this.UpdateUICallback) == 'function') this.UpdateUICallback('RecvHistoryData', this);
  9697. }
  9698. }
  9699. ////////////////////////////////////////////////////////////////////////////////
  9700. // K线横屏显示
  9701. //
  9702. function KLineChartHScreenContainer(uielement)
  9703. {
  9704. this.newMethod = KLineChartContainer; //派生
  9705. this.newMethod(uielement);
  9706. delete this.newMethod;
  9707. this.ClassName = 'KLineChartHScreenContainer';
  9708. this.OnMouseMove = function (x, y, e)
  9709. {
  9710. this.LastPoint.X = x;
  9711. this.LastPoint.Y = y;
  9712. this.CursorIndex = this.Frame.GetXData(y);
  9713. this.DrawDynamicInfo();
  9714. }
  9715. //手机拖拽
  9716. this.ontouchstart = function (e)
  9717. {
  9718. if (this.ChartSplashPaint && this.ChartSplashPaint.IsEnableSplash == true) return;
  9719. var jsChart = this;
  9720. if (jsChart.DragMode == 0) return;
  9721. jsChart.IsOnTouch = true;
  9722. jsChart.PhonePinch = null;
  9723. if (this.IsPhoneDragging(e))
  9724. {
  9725. if (jsChart.TryClickLock || this.TryClickIndexTitle)
  9726. {
  9727. var touches = this.GetToucheData(e);
  9728. var x = touches[0].clientX;
  9729. var y = touches[0].clientY;
  9730. if (jsChart.TryClickLock && jsChart.TryClickLock(x, y)) return;
  9731. if (jsChart.TryClickIndexTitle && jsChart.TryClickIndexTitle(x, y)) return;
  9732. }
  9733. //长按2秒,十字光标
  9734. if (this.TouchTimer != null) clearTimeout(this.TouchTimer);
  9735. if (this.ChartCorssCursor.IsShow == true)
  9736. {
  9737. this.TouchTimer = setTimeout(function () {
  9738. if (drag.Click.X == drag.LastMove.X && drag.Click.Y == drag.LastMove.Y) //手指没有移动,出现十字光标
  9739. {
  9740. var mouseDrag = jsChart.MouseDrag;
  9741. jsChart.MouseDrag = null;
  9742. //移动十字光标
  9743. var x = drag.Click.X;
  9744. var y = drag.Click.Y;
  9745. jsChart.OnMouseMove(x, y, e);
  9746. }
  9747. }, 800);
  9748. }
  9749. var drag = { "Click": {}, "LastMove": {}, };//最后移动的位置
  9750. var touches = this.GetToucheData(e);
  9751. drag.Click.X = touches[0].clientX;
  9752. drag.Click.Y = touches[0].clientY;
  9753. drag.LastMove.X = touches[0].clientX;
  9754. drag.LastMove.Y = touches[0].clientY;
  9755. jsChart.MouseDrag = drag;
  9756. }
  9757. else if (this.IsPhonePinching(e))
  9758. {
  9759. var phonePinch = { "Start": {}, "Last": {}};
  9760. var touches = this.GetToucheData(e);
  9761. phonePinch.Start = { "X": touches[0].pageX, "Y": touches[0].pageY, "X2": touches[1].pageX, "Y2": touches[1].pageY };
  9762. phonePinch.Last = { "X": touches[0].pageX, "Y": touches[0].pageY, "X2": touches[1].pageX, "Y2": touches[1].pageY };
  9763. jsChart.PhonePinch = phonePinch;
  9764. }
  9765. }
  9766. this.ontouchmove = function (e)
  9767. {
  9768. if (this.ChartSplashPaint && this.ChartSplashPaint.IsEnableSplash == true) return;
  9769. var jsChart = this;
  9770. var touches = this.GetToucheData(e);
  9771. if (this.IsPhoneDragging(e))
  9772. {
  9773. var drag = jsChart.MouseDrag;
  9774. if (drag == null)
  9775. {
  9776. var x = touches[0].clientX;
  9777. var y = touches[0].clientY;
  9778. jsChart.OnMouseMove(x, y, e);
  9779. }
  9780. else
  9781. {
  9782. var moveSetp = Math.abs(drag.LastMove.Y - touches[0].clientY);
  9783. moveSetp = parseInt(moveSetp);
  9784. if (jsChart.DragMode == 1) //数据左右拖拽
  9785. {
  9786. if (moveSetp < 5) return;
  9787. var isLeft = true;
  9788. if (drag.LastMove.Y < touches[0].clientY) isLeft = false;//右移数据
  9789. if (jsChart.DataMove(moveSetp, isLeft))
  9790. {
  9791. jsChart.UpdataDataoffset();
  9792. jsChart.UpdatePointByCursorIndex();
  9793. jsChart.UpdateFrameMaxMin();
  9794. jsChart.ResetFrameXYSplit();
  9795. jsChart.Draw();
  9796. }
  9797. drag.LastMove.X = touches[0].clientX;
  9798. drag.LastMove.Y = touches[0].clientY;
  9799. }
  9800. }
  9801. }
  9802. else if (this.IsPhonePinching(e))
  9803. {
  9804. var phonePinch = jsChart.PhonePinch;
  9805. if (!phonePinch) return;
  9806. if (this.EnableZoomUpDown && this.EnableZoomUpDown.Touch===false) return;
  9807. var yHeight = Math.abs(touches[0].pageX - touches[1].pageX);
  9808. var yLastHeight = Math.abs(phonePinch.Last.X - phonePinch.Last.X2);
  9809. var yStep = yHeight - yLastHeight;
  9810. if (Math.abs(yStep) < 5) return;
  9811. if (yStep > 0) //放大
  9812. {
  9813. var cursorIndex = {};
  9814. cursorIndex.Index = parseInt(Math.abs(jsChart.CursorIndex - 0.5).toFixed(0));
  9815. if (!jsChart.Frame.ZoomUp(cursorIndex)) return;
  9816. jsChart.CursorIndex = cursorIndex.Index;
  9817. jsChart.UpdatePointByCursorIndex();
  9818. jsChart.UpdataDataoffset();
  9819. jsChart.UpdateFrameMaxMin();
  9820. jsChart.ResetFrameXYSplit();
  9821. jsChart.Draw();
  9822. }
  9823. else //缩小
  9824. {
  9825. var cursorIndex = {};
  9826. cursorIndex.Index = parseInt(Math.abs(jsChart.CursorIndex - 0.5).toFixed(0));
  9827. if (!jsChart.Frame.ZoomDown(cursorIndex)) return;
  9828. jsChart.CursorIndex = cursorIndex.Index;
  9829. jsChart.UpdataDataoffset();
  9830. jsChart.UpdatePointByCursorIndex();
  9831. jsChart.UpdateFrameMaxMin();
  9832. jsChart.ResetFrameXYSplit();
  9833. jsChart.Draw();
  9834. }
  9835. phonePinch.Last = { "X": touches[0].pageX, "Y": touches[0].pageY, "X2": touches[1].pageX, "Y2": touches[1].pageY };
  9836. }
  9837. }
  9838. uielement.onmousedown = function (e) //鼠标拖拽
  9839. {
  9840. if (!this.JSChartContainer) return;
  9841. if (this.JSChartContainer.DragMode == 0) return;
  9842. if (this.JSChartContainer.TryClickLock) {
  9843. var x = e.clientX - this.getBoundingClientRect().left;
  9844. var y = e.clientY - this.getBoundingClientRect().top;
  9845. if (this.JSChartContainer.TryClickLock(x, y)) return;
  9846. }
  9847. var drag =
  9848. {
  9849. "Click": {},
  9850. "LastMove": {}, //最后移动的位置
  9851. };
  9852. drag.Click.X = e.clientX;
  9853. drag.Click.Y = e.clientY;
  9854. drag.LastMove.X = e.clientX;
  9855. drag.LastMove.Y = e.clientY;
  9856. this.JSChartContainer.MouseDrag = drag;
  9857. document.JSChartContainer = this.JSChartContainer;
  9858. this.JSChartContainer.SelectChartDrawPicture = null;
  9859. uielement.ondblclick = function (e) {
  9860. var x = e.clientX - this.getBoundingClientRect().left;
  9861. var y = e.clientY - this.getBoundingClientRect().top;
  9862. if (this.JSChartContainer)
  9863. this.JSChartContainer.OnDoubleClick(x, y, e);
  9864. }
  9865. document.onmousemove = function (e) {
  9866. if (!this.JSChartContainer) return;
  9867. //加载数据中,禁用鼠标事件
  9868. if (this.JSChartContainer.ChartSplashPaint && this.JSChartContainer.ChartSplashPaint.IsEnableSplash == true) return;
  9869. var drag = this.JSChartContainer.MouseDrag;
  9870. if (!drag) return;
  9871. var moveSetp = Math.abs(drag.LastMove.Y - e.clientY);
  9872. if (this.JSChartContainer.DragMode == 1) //数据左右拖拽
  9873. {
  9874. if (moveSetp < 5) return;
  9875. var isLeft = true;
  9876. if (drag.LastMove.Y < e.clientY) isLeft = false;//右移数据
  9877. if (this.JSChartContainer.DataMove(moveSetp, isLeft)) {
  9878. this.JSChartContainer.UpdataDataoffset();
  9879. this.JSChartContainer.UpdatePointByCursorIndex();
  9880. this.JSChartContainer.UpdateFrameMaxMin();
  9881. this.JSChartContainer.ResetFrameXYSplit();
  9882. this.JSChartContainer.Draw();
  9883. }
  9884. drag.LastMove.X = e.clientX;
  9885. drag.LastMove.Y = e.clientY;
  9886. }
  9887. };
  9888. document.onmouseup = function (e) {
  9889. //清空事件
  9890. document.onmousemove = null;
  9891. document.onmouseup = null;
  9892. //清空数据
  9893. this.JSChartContainer.MouseDrag = null;
  9894. this.JSChartContainer.CurrentChartDrawPicture = null;
  9895. this.JSChartContainer = null;
  9896. }
  9897. }
  9898. //创建
  9899. //windowCount 窗口个数
  9900. this.Create = function (windowCount) {
  9901. this.UIElement.JSChartContainer = this;
  9902. //创建十字光标
  9903. this.ChartCorssCursor = new ChartCorssCursor();
  9904. this.ChartCorssCursor.Canvas = this.Canvas;
  9905. this.ChartCorssCursor.StringFormatX = g_DivTooltipDataForamt.Create("CorssCursor_XStringFormat");
  9906. this.ChartCorssCursor.StringFormatX.LanguageID=this.LanguageID;
  9907. this.ChartCorssCursor.StringFormatY = g_DivTooltipDataForamt.Create("CorssCursor_YStringFormat");
  9908. this.ChartCorssCursor.StringFormatY.LanguageID=this.LanguageID;
  9909. //创建等待提示
  9910. this.ChartSplashPaint = new ChartSplashPaint();
  9911. this.ChartSplashPaint.Canvas = this.Canvas;
  9912. this.ChartSplashPaint.HQChart=this;
  9913. //创建框架容器
  9914. this.Frame = new HQTradeHScreenFrame();
  9915. this.Frame.ChartBorder = new ChartBorder();
  9916. this.Frame.ChartBorder.UIElement = this.UIElement;
  9917. this.Frame.ChartBorder.Top = 30;
  9918. this.Frame.ChartBorder.Left = 5;
  9919. this.Frame.ChartBorder.Bottom = 20;
  9920. this.Frame.Canvas = this.Canvas;
  9921. this.ChartCorssCursor.Frame = this.Frame; //十字光标绑定框架
  9922. this.ChartSplashPaint.Frame = this.Frame;
  9923. this.CreateChildWindow(windowCount);
  9924. this.CreateMainKLine();
  9925. //子窗口动态标题
  9926. for (var i in this.Frame.SubFrame) {
  9927. var titlePaint = new DynamicChartTitlePainting();
  9928. titlePaint.Frame = this.Frame.SubFrame[i].Frame;
  9929. titlePaint.Canvas = this.Canvas;
  9930. this.TitlePaint.push(titlePaint);
  9931. }
  9932. }
  9933. //创建子窗口
  9934. this.CreateChildWindow = function (windowCount)
  9935. {
  9936. for (var i = 0; i < windowCount; ++i)
  9937. {
  9938. var border = new ChartBorder();
  9939. border.UIElement = this.UIElement;
  9940. var frame = new KLineHScreenFrame();
  9941. frame.Canvas = this.Canvas;
  9942. frame.ChartBorder = border;
  9943. frame.Identify = i; //窗口序号
  9944. frame.RightSpaceCount = this.RightSpaceCount; //右边
  9945. if (this.ModifyIndexDialog) frame.ModifyIndexEvent = this.ModifyIndexDialog.DoModal; //绑定菜单事件
  9946. if (this.ChangeIndexDialog) frame.ChangeIndexEvent = this.ChangeIndexDialog.DoModal;
  9947. frame.HorizontalMax = 20;
  9948. frame.HorizontalMin = 10;
  9949. if (i == 0)
  9950. {
  9951. frame.YSplitOperator = new FrameSplitKLinePriceY();
  9952. frame.YSplitOperator.FrameSplitData = this.FrameSplitData.get('price');
  9953. //主图上下间距
  9954. border.TopSpace = 12;
  9955. border.BottomSpace = 12;
  9956. }
  9957. else
  9958. {
  9959. frame.YSplitOperator = new FrameSplitY();
  9960. frame.YSplitOperator.FrameSplitData = this.FrameSplitData.get('double');
  9961. //frame.IsLocked = true;
  9962. }
  9963. frame.YSplitOperator.Frame = frame;
  9964. frame.YSplitOperator.ChartBorder = border;
  9965. frame.XSplitOperator = new FrameSplitKLineX();
  9966. frame.XSplitOperator.Frame = frame;
  9967. frame.XSplitOperator.ChartBorder = border;
  9968. if (i != windowCount - 1) frame.XSplitOperator.ShowText = false;
  9969. for (var j = frame.HorizontalMin; j <= frame.HorizontalMax; j += 1)
  9970. {
  9971. frame.HorizontalInfo[j] = new CoordinateInfo();
  9972. frame.HorizontalInfo[j].Value = j;
  9973. if (i == 0 && j == frame.HorizontalMin) continue;
  9974. frame.HorizontalInfo[j].Message[1] = j.toString();
  9975. frame.HorizontalInfo[j].Font = "12px 微软雅黑";
  9976. }
  9977. var subFrame = new SubFrameItem();
  9978. subFrame.Frame = frame;
  9979. if (i == 0)
  9980. subFrame.Height = 20;
  9981. else
  9982. subFrame.Height = 10;
  9983. this.Frame.SubFrame[i] = subFrame;
  9984. }
  9985. }
  9986. }
  9987. ////////////////////////////////////////////////////////////////////////////////
  9988. // 走势图横屏显示
  9989. //
  9990. function MinuteChartHScreenContainer(uielement) {
  9991. this.newMethod = MinuteChartContainer; //派生
  9992. this.newMethod(uielement);
  9993. delete this.newMethod;
  9994. this.ClassName = 'MinuteChartHScreenContainer';
  9995. this.OnMouseMove = function (x, y, e) {
  9996. this.LastPoint.X = x;
  9997. this.LastPoint.Y = y;
  9998. this.CursorIndex = this.Frame.GetXData(y);
  9999. this.DrawDynamicInfo();
  10000. }
  10001. //创建
  10002. //windowCount 窗口个数
  10003. this.Create = function (windowCount) {
  10004. this.UIElement.JSChartContainer = this;
  10005. //创建十字光标
  10006. this.ChartCorssCursor = new ChartCorssCursor();
  10007. this.ChartCorssCursor.Canvas = this.Canvas;
  10008. this.ChartCorssCursor.StringFormatX = new HQMinuteTimeStringFormat();
  10009. this.ChartCorssCursor.StringFormatY = new HQPriceStringFormat();
  10010. //创建等待提示
  10011. this.ChartSplashPaint = new ChartSplashPaint();
  10012. this.ChartSplashPaint.Canvas = this.Canvas;
  10013. this.ChartSplashPaint.SplashTitle = this.LoadDataSplashTitle;
  10014. //创建框架容器
  10015. this.Frame = new HQTradeHScreenFrame();
  10016. this.Frame.ChartBorder = new ChartBorder();
  10017. this.Frame.ChartBorder.UIElement = this.UIElement;
  10018. this.Frame.ChartBorder.Top = 25;
  10019. this.Frame.ChartBorder.Left = 50;
  10020. this.Frame.ChartBorder.Bottom = 20;
  10021. this.Frame.Canvas = this.Canvas;
  10022. this.ChartCorssCursor.Frame = this.Frame; //十字光标绑定框架
  10023. this.ChartSplashPaint.Frame = this.Frame;
  10024. this.CreateChildWindow(windowCount);
  10025. this.CreateMainKLine();
  10026. //子窗口动态标题
  10027. for (var i in this.Frame.SubFrame) {
  10028. var titlePaint = new DynamicChartTitlePainting();
  10029. titlePaint.Frame = this.Frame.SubFrame[i].Frame;
  10030. titlePaint.Canvas = this.Canvas;
  10031. this.TitlePaint.push(titlePaint);
  10032. }
  10033. this.ChartCorssCursor.StringFormatX.Frame = this.Frame.SubFrame[0].Frame;
  10034. }
  10035. //创建子窗口
  10036. this.CreateChildWindow = function (windowCount) {
  10037. for (var i = 0; i < windowCount; ++i) {
  10038. var border = new ChartBorder();
  10039. border.UIElement = this.UIElement;
  10040. var frame = new MinuteHScreenFrame();
  10041. frame.Canvas = this.Canvas;
  10042. frame.ChartBorder = border;
  10043. if (i < 2) frame.ChartBorder.TitleHeight = 0;
  10044. frame.XPointCount = 243;
  10045. var DEFAULT_HORIZONTAL = [9, 8, 7, 6, 5, 4, 3, 2, 1];
  10046. frame.HorizontalMax = DEFAULT_HORIZONTAL[0];
  10047. frame.HorizontalMin = DEFAULT_HORIZONTAL[DEFAULT_HORIZONTAL.length - 1];
  10048. if (i == 0) {
  10049. frame.YSplitOperator = new FrameSplitMinutePriceY();
  10050. frame.YSplitOperator.FrameSplitData = this.FrameSplitData.get('price');
  10051. }
  10052. else {
  10053. frame.YSplitOperator = new FrameSplitY();
  10054. frame.YSplitOperator.FrameSplitData = this.FrameSplitData.get('double');
  10055. }
  10056. frame.YSplitOperator.Frame = frame;
  10057. frame.YSplitOperator.ChartBorder = border;
  10058. frame.XSplitOperator = new FrameSplitMinuteX();
  10059. frame.XSplitOperator.Frame = frame;
  10060. frame.XSplitOperator.ChartBorder = border;
  10061. if (i != windowCount - 1) frame.XSplitOperator.ShowText = false;
  10062. frame.XSplitOperator.Operator();
  10063. for (var j in DEFAULT_HORIZONTAL) {
  10064. frame.HorizontalInfo[j] = new CoordinateInfo();
  10065. frame.HorizontalInfo[j].Value = DEFAULT_HORIZONTAL[j];
  10066. if (i == 0 && j == frame.HorizontalMin) continue;
  10067. frame.HorizontalInfo[j].Message[1] = DEFAULT_HORIZONTAL[j].toString();
  10068. frame.HorizontalInfo[j].Font = "12px 微软雅黑";
  10069. }
  10070. var subFrame = new SubFrameItem();
  10071. subFrame.Frame = frame;
  10072. if (i == 0)
  10073. subFrame.Height = 20;
  10074. else
  10075. subFrame.Height = 10;
  10076. this.Frame.SubFrame[i] = subFrame;
  10077. }
  10078. }
  10079. }
  10080. ////////////////////////////////////////////////////////////////////////////////
  10081. // K线训练,包含横屏
  10082. //
  10083. function KLineTrainChartContainer(uielement, bHScreen)
  10084. {
  10085. if (bHScreen === true)
  10086. {
  10087. this.newMethod = KLineChartHScreenContainer; //派生
  10088. this.newMethod(uielement);
  10089. delete this.newMethod;
  10090. }
  10091. else
  10092. {
  10093. this.newMethod = KLineChartContainer; //派生
  10094. this.newMethod(uielement);
  10095. delete this.newMethod;
  10096. }
  10097. this.ClassName2 = 'KLineTrainChartContainer';
  10098. this.BuySellPaint; //买卖点画法
  10099. this.TrainDataCount = 300; //训练数据个数
  10100. this.AutoRunTimer = null; //K线自动前进定时器
  10101. this.BuySellData = []; //模拟买卖数据 {Buy:{Price:价格,Date:日期,Time:时间} , Sell:{Price:价格,Date:日期,Time:时间}
  10102. this.TrainDataIndex; //当前训练的数据索引
  10103. this.TrainCallback; //训练回调 (K线每前进一次就调用一次)
  10104. this.DragMode = 1;
  10105. this.TrainStartEnd = {};
  10106. this.KLineSourceData; //原始K线数据 对应 SourceData
  10107. this.TrainInfo = { Start: {}, End: {} }; // Index:数据索引, Date:日期 Time:时间
  10108. this.CreateBuySellPaint = function () //在主窗口建立以后 创建买卖点
  10109. {
  10110. var chart = new ChartBuySell();
  10111. chart.Canvas = this.Canvas;
  10112. chart.ChartBorder = this.Frame.SubFrame[0].Frame.ChartBorder;
  10113. chart.ChartFrame = this.Frame.SubFrame[0].Frame;
  10114. chart.Name = "KLine-Train-BuySell";
  10115. this.ChartPaintEx[0] = chart;
  10116. }
  10117. this.GetKDataIndexByDateTime = function (kData, dateTime)
  10118. {
  10119. if (!dateTime || !kData) return -1;
  10120. for (var i in kData)
  10121. {
  10122. var item = kData[i];
  10123. if (ChartData.IsMinutePeriod(this.Period, true))
  10124. {
  10125. if (IFrameSplitOperator.IsNumber(this.TrainStartDate.Time))
  10126. {
  10127. if (item.Date >= this.TrainStartDate.Date && item.Time >= this.TrainStartDate.Time)
  10128. return parseInt(i);
  10129. }
  10130. else
  10131. {
  10132. if (item.Date >= this.TrainStartDate.Date)
  10133. return parseInt(i);
  10134. }
  10135. }
  10136. else if (ChartData.IsDayPeriod(this.Period, true) || ChartData.IsTickPeriod(this.Period))
  10137. {
  10138. if (item.Date >= this.TrainStartDate.Date)
  10139. return parseInt(i);
  10140. }
  10141. }
  10142. return -1;
  10143. }
  10144. this.AfterBindMainData = function (funcName)
  10145. {
  10146. if (!this.ChartPaintEx[0]) this.CreateBuySellPaint();
  10147. var hisData = this.ChartPaint[0].Data;
  10148. this.ChartPaintEx[0].Data = hisData;
  10149. var showItem = hisData.Data[hisData.Data.length - 1];
  10150. //最后一个显示数据
  10151. this.TrainInfo.LastShowData = showItem;
  10152. //最后一个原始数据
  10153. this.TrainInfo.LastData = this.SourceData.Data[this.SourceData.Data.length - 1];
  10154. if (funcName != 'Update')
  10155. this.UpdateTrainUICallback("开始");
  10156. }
  10157. this.BeforeBindMainData = function (funcName)
  10158. {
  10159. if (funcName == "Update") return;
  10160. //全量数据 需要过滤
  10161. this.KLineSourceData = new ChartData();
  10162. this.KLineSourceData.Data = this.SourceData.Data.slice(0);
  10163. var count = this.SourceData.Data.length;
  10164. var lEnd = count - this.TrainDataCount - 20;
  10165. var findIndex = this.GetKDataIndexByDateTime(this.SourceData.Data, this.TrainStartDate);
  10166. if (findIndex >= 0)
  10167. {
  10168. lEnd = findIndex + 1;
  10169. if (count - lEnd < this.TrainDataCount) this.TrainDataCount = count - lEnd;
  10170. }
  10171. //训练起始日期
  10172. var index = lEnd - 1;
  10173. var kItem = this.SourceData.Data[index];
  10174. this.TrainInfo.Start.Index = index;
  10175. this.TrainInfo.Start.Date = kItem.Date;
  10176. this.TrainInfo.Start.Time = kItem.Time;
  10177. //训练结束日期
  10178. this.TrainInfo.End.Index = index;
  10179. this.TrainInfo.End.Date = kItem.Date;
  10180. this.TrainInfo.End.Time = kItem.Time;
  10181. //最后一个数据
  10182. this.TrainInfo.LastData = kItem;
  10183. //修改数据个数
  10184. this.SourceData.Data.length = lEnd;
  10185. }
  10186. this.Run = function (option)
  10187. {
  10188. if (this.AutoRunTimer) return;
  10189. if (this.TrainDataCount <= 0) return;
  10190. var self = this;
  10191. this.AutoRunTimer = setInterval(function () {
  10192. if (!self.MoveNextKLineData(option)) clearInterval(self.AutoRunTimer);
  10193. }, 1000);
  10194. }
  10195. this.MoveNextKLineData = function (option) //{PageSize:, Step:}
  10196. {
  10197. if (this.TrainDataCount <= 0) return false;
  10198. var step = 1, moveStep=0;
  10199. if (option && option.Step > 1) step = option.Step;
  10200. for (var i = 0; i < step; ++i)
  10201. {
  10202. var index = this.TrainInfo.End.Index + 1;
  10203. if (index >= this.KLineSourceData.Data.length) break;
  10204. var kItem = this.KLineSourceData.Data[index];
  10205. this.SourceData.Data.push(kItem);
  10206. this.TrainInfo.End.Index = index;
  10207. this.TrainInfo.End.Date = kItem.Date;
  10208. this.TrainInfo.End.Time = kItem.Time;
  10209. --this.TrainDataCount;
  10210. ++moveStep;
  10211. if (this.TrainDataCount <= 0) break;
  10212. }
  10213. if (moveStep == 0) return false;
  10214. //使用当前页数据个数移动K线
  10215. var pageSize = this.Frame.GetCurrentPageSize();
  10216. if (IFrameSplitOperator.IsNumber(pageSize))
  10217. this.PageSize = pageSize - this.RightSpaceCount;
  10218. this.Update();
  10219. if (this.TrainDataCount <= 0)
  10220. {
  10221. this.FinishTrainData();
  10222. this.UpdateTrainUICallback("结束");
  10223. return false;
  10224. }
  10225. this.UpdateTrainUICallback("训练中");
  10226. return true;
  10227. }
  10228. this.UpdateTrainUICallback = function (description)
  10229. {
  10230. //新的监听事件
  10231. if (!this.mapEvent.has(JSCHART_EVENT_ID.RECV_TRAIN_MOVE_STEP)) return;
  10232. var item = this.mapEvent.get(JSCHART_EVENT_ID.RECV_TRAIN_MOVE_STEP);
  10233. if (!item.Callback) return;
  10234. var data =
  10235. {
  10236. TrainDataCount: this.TrainDataCount,
  10237. BuySellData: this.BuySellData,
  10238. KLine:
  10239. {
  10240. Start: { Index: this.TrainInfo.Start.Index, Date: this.TrainInfo.Start.Date },
  10241. End: { Index: this.TrainInfo.End.Index, Date: this.TrainInfo.End.Date }
  10242. },
  10243. LastData: this.TrainInfo.LastData,
  10244. LastShowData: this.TrainInfo.LastShowData
  10245. };
  10246. if (IFrameSplitOperator.IsNumber(this.TrainInfo.Start.Time)) data.KLine.Start.Time = this.TrainInfo.Start.Time;
  10247. if (IFrameSplitOperator.IsNumber(this.TrainInfo.End.Time)) data.KLine.End.Time = this.TrainInfo.End.Time;
  10248. if (description) data.Description = description
  10249. if (this.TrainDataCount <= 0)
  10250. {
  10251. data.Symbol = this.Symbol;
  10252. data.Name = this.Name;
  10253. }
  10254. item.Callback(item, data, this);
  10255. }
  10256. this.FinishTrainData = function ()
  10257. {
  10258. }
  10259. this.Stop = function ()
  10260. {
  10261. if (this.AutoRunTimer != null) clearInterval(this.AutoRunTimer);
  10262. this.AutoRunTimer = null;
  10263. }
  10264. this.BuyOrSell = function (obj, bDraw) //{ Price:价格, Vol:数量, Op: 买/卖 0=buy 1=sell, ID:单号 } bDraw是否立即绘制图标
  10265. {
  10266. var kItem = this.TrainInfo.LastShowData;
  10267. if (!kItem) return false;
  10268. var buySellPaint = this.ChartPaintEx[0];
  10269. if (!buySellPaint) return false;
  10270. var hisData = this.ChartPaint[0].Data;
  10271. if (!hisData || hisData.Data.length <= 0) return false;
  10272. var index = hisData.Data.length - 1; //数据索引
  10273. var buyItem = { Date: this.TrainInfo.End.Date, Time: this.TrainInfo.End.Time, Price: obj.Price, Vol: obj.Vol, Op: 0, ID: obj.ID };
  10274. if (obj.Op == 1) buyItem.Op = 1;
  10275. var key = index;
  10276. buyItem.Key = key;
  10277. this.BuySellData.push(buyItem);
  10278. buySellPaint.AddTradeItem(buyItem);
  10279. if (bDraw == true) this.Draw();
  10280. }
  10281. this.RestartTrain = function (option) // { Symbol:, Period:周期, Right:复权, Train:{ DataCount:, DateTime: } }
  10282. {
  10283. JSConsole.Chart.Log('[KLineTrainChartContainer::RestartTrain] option ', option);
  10284. this.TrainInfo = { Start: {}, End: {} };
  10285. this.BuySellData = [];
  10286. this.KLineSourceData = null;
  10287. var buySellPaint = this.ChartPaintEx[0];
  10288. if (buySellPaint)
  10289. {
  10290. buySellPaint.Data = null;
  10291. buySellPaint.ClearTradeData();
  10292. }
  10293. if (option.Symbol) this.Symbol = option.Symbol;
  10294. if (IFrameSplitOperator.IsNumber(option.Period)) this.Period = option.Period;
  10295. if (IFrameSplitOperator.IsNumber(option.Right)) this.Right = option.Right;
  10296. if (option.Train)
  10297. {
  10298. if (option.Train.DataCount > 1) this.TrainDataCount = option.Train.DataCount;
  10299. if (option.Train.DateTime) this.TrainStartDate = option.Train.DateTime;
  10300. }
  10301. var symbol = this.Symbol;
  10302. this.ChangeSymbol(symbol);
  10303. }
  10304. }
  10305. /////////////////////////////////////////////////////////////////////////////////
  10306. // 深度图
  10307. //
  10308. function DepthChartContainer(uielement)
  10309. {
  10310. this.newMethod=JSChartContainer; //派生
  10311. this.newMethod(uielement);
  10312. delete this.newMethod;
  10313. this.ClassName="DepthChartContainer";
  10314. this.Symbol;
  10315. //数据
  10316. this.MapAsk=new Map();
  10317. this.MapBid=new Map();
  10318. this.IsAutoUpdate=false; //是否自动更新行情数据
  10319. this.AutoUpdateFrequency=30000; //30秒更新一次数据
  10320. this.AutoUpdateTimer;
  10321. this.DefaultZoom=0.8; //默认显示80%的盘口 (0 - 1)
  10322. this.MaxVolRate=1.1;
  10323. this.Create=function(option)
  10324. {
  10325. this.UIElement.JSChartContainer=this;
  10326. //创建十字光标
  10327. this.ChartCorssCursor=new DepthChartCorssCursor();
  10328. this.ChartCorssCursor.Canvas=this.Canvas;
  10329. this.ChartCorssCursor.HQChart=this;
  10330. //this.ChartCorssCursor.StringFormatX=g_DivTooltipDataForamt.Create("CorssCursor_XStringFormat");
  10331. //this.ChartCorssCursor.StringFormatX.LanguageID=this.LanguageID;
  10332. //this.ChartCorssCursor.StringFormatY=g_DivTooltipDataForamt.Create("CorssCursor_YStringFormat");
  10333. //this.ChartCorssCursor.StringFormatY.LanguageID=this.LanguageID;
  10334. //创建等待提示
  10335. this.ChartSplashPaint = new ChartSplashPaint();
  10336. this.ChartSplashPaint.Canvas = this.Canvas;
  10337. //创建框架
  10338. this.Frame=new DepthChartFrame();
  10339. this.Frame.ChartBorder=new ChartBorder();
  10340. this.Frame.ChartBorder.UIElement=this.UIElement;
  10341. this.Frame.ChartBorder.Top=30;
  10342. this.Frame.ChartBorder.Left=5;
  10343. this.Frame.ChartBorder.Bottom=20;
  10344. this.Frame.ChartBorder.TitleHeight=0;
  10345. this.Frame.Canvas=this.Canvas;
  10346. var ySplitOper=new FrameSplitY();
  10347. ySplitOper.FrameSplitData=this.FrameSplitData.get('double');
  10348. ySplitOper.LanguageID=this.LanguageID;
  10349. ySplitOper.Frame=this.Frame;
  10350. ySplitOper.SplitCount=5;
  10351. ySplitOper.IgnoreYValue=[0];
  10352. ySplitOper.LineType=3;
  10353. ySplitOper.ChartBorder=this.Frame.ChartBorder;
  10354. this.Frame.YSplitOperator=ySplitOper;
  10355. var xSplitOper=new FrameSplitXDepth();
  10356. xSplitOper.Frame=this.Frame;;
  10357. xSplitOper.ChartBorder=this.Frame.ChartBorder;;
  10358. xSplitOper.LanguageID=this.LanguageID;
  10359. xSplitOper.LineType=3;
  10360. this.Frame.XSplitOperator=xSplitOper
  10361. if (this.ChartCorssCursor) this.ChartCorssCursor.Frame=this.Frame; //十字光标绑定框架
  10362. this.ChartSplashPaint.Frame = this.Frame;
  10363. var chartItem=new ChartOrderbookDepth();
  10364. chartItem.Canvas=this.Canvas;
  10365. chartItem.ChartBorder=this.Frame.ChartBorder;
  10366. chartItem.ChartFrame=this.Frame;
  10367. chartItem.Name="深度图"
  10368. this.ChartPaint.push(chartItem);
  10369. }
  10370. this.ontouchstart=function(e)
  10371. {
  10372. this.IsOnTouch=true;
  10373. this.TouchDrawCount=0;
  10374. this.PhonePinch=null;
  10375. var isSingleTouch=this.IsSingleTouch(e);
  10376. if (this.EnableScrollUpDown==false || !isSingleTouch) //多点触屏
  10377. {
  10378. }
  10379. if (this.IsPhoneDragging(e))
  10380. {
  10381. var drag=
  10382. {
  10383. "Click":{},
  10384. "LastMove":{} //最后移动的位置
  10385. };
  10386. var touches=this.GetToucheData(e,this.IsForceLandscape);
  10387. drag.Click.X=touches[0].clientX;
  10388. drag.Click.Y=touches[0].clientY;
  10389. drag.LastMove.X=touches[0].clientX;
  10390. drag.LastMove.Y=touches[0].clientY;
  10391. this.MouseDrag=drag;
  10392. var x = drag.Click.X;
  10393. var y = drag.Click.Y;
  10394. this.OnMouseMove(x, y, e);
  10395. }
  10396. else if (this.IsPhonePinching(e))
  10397. {
  10398. var phonePinch=
  10399. {
  10400. "Start":{},
  10401. "Last":{}
  10402. };
  10403. var touches=this.GetToucheData(e,this.IsForceLandscape);
  10404. phonePinch.Start={"X":touches[0].pageX,"Y":touches[0].pageY,"X2":touches[1].pageX,"Y2":touches[1].pageY};
  10405. phonePinch.Last={"X":touches[0].pageX,"Y":touches[0].pageY,"X2":touches[1].pageX,"Y2":touches[1].pageY};
  10406. this.PhonePinch=phonePinch;
  10407. }
  10408. }
  10409. this.ontouchmove=function(e)
  10410. {
  10411. var touches=this.GetToucheData(e,false);
  10412. if (this.IsPhoneDragging(e))
  10413. {
  10414. var drag=this.MouseDrag;
  10415. if (drag==null)
  10416. {
  10417. var x = touches[0].clientX;
  10418. var y = touches[0].clientY;
  10419. this.OnMouseMove(x,y,e);
  10420. }
  10421. else
  10422. {
  10423. this.MouseDrag=null;
  10424. var x = touches[0].clientX;
  10425. var y = touches[0].clientY;
  10426. this.OnMouseMove(x,y,e);
  10427. }
  10428. }
  10429. else if (this.IsPhonePinching(e))
  10430. {
  10431. var phonePinch=this.PhonePinch;
  10432. if (!phonePinch) return;
  10433. if (this.EnableZoomUpDown && this.EnableZoomUpDown.Touch===false) return;
  10434. var yHeight = Math.abs(touches[0].pageY - touches[1].pageY);
  10435. var yLastHeight = Math.abs(phonePinch.Last.Y - phonePinch.Last.Y2);
  10436. var yStep = yHeight - yLastHeight;
  10437. var xHeight = Math.abs(touches[0].pageX - touches[1].pageX);
  10438. var xLastHeight = Math.abs(phonePinch.Last.X - phonePinch.Last.X2);
  10439. var xStep = xHeight - xLastHeight;
  10440. var minStep=this.ZoomStepPixel;
  10441. if (Math.abs(yStep) <minStep && Math.abs(xStep) < minStep) return;
  10442. var step = yStep;
  10443. if (Math.abs(yStep) < minStep) step = xStep;
  10444. if (step>0) //放大
  10445. {
  10446. if (!this.Frame.ZoomUp()) return;
  10447. this.UpdateFrameMaxMin();
  10448. this.Draw();
  10449. }
  10450. else //缩小
  10451. {
  10452. if (!this.Frame.ZoomDown()) return;
  10453. this.UpdateFrameMaxMin();
  10454. this.Draw();
  10455. }
  10456. phonePinch.Last={"X":touches[0].pageX,"Y":touches[0].pageY,"X2":touches[1].pageX,"Y2":touches[1].pageY};
  10457. }
  10458. }
  10459. this.ontouchend=function(e)
  10460. {
  10461. JSConsole.Chart.Log('[DepthChartContainer::OnTouchEnd]',e);
  10462. this.IsOnTouch = false;
  10463. this.Draw();
  10464. this.TouchDrawCount=0;
  10465. }
  10466. this.OnMouseMove = function (x, y, e, bFullDraw)
  10467. {
  10468. var lastY = this.LastPoint.Y;
  10469. this.LastPoint.X = x;
  10470. this.LastPoint.Y = y;
  10471. this.FullDraw();
  10472. }
  10473. this.ChangeSymbol=function(symbol)
  10474. {
  10475. this.CancelAutoUpdate(); //先停止定时器
  10476. this.Symbol=symbol;
  10477. this.MapBid=new Map();
  10478. this.MapAsk=new Map();
  10479. this.Frame.VerticalRange.Differ=null;
  10480. this.ChartSplashPaint.SetTitle(this.LoadDataSplashTitle);
  10481. this.ChartSplashPaint.EnableSplash(true);
  10482. this.Draw();
  10483. this.RequestDepthData();
  10484. }
  10485. this.RequestDepthData=function() //全量历史数据
  10486. {
  10487. var self=this;
  10488. if (this.NetworkFilter)
  10489. {
  10490. var obj=
  10491. {
  10492. Name:'DepthChartContainer::RequestDepthData', //类名::
  10493. Explain:'深度图数据',
  10494. Request:{ Data: { symbol:self.Symbol } },
  10495. Self:this,
  10496. PreventDefault:false
  10497. };
  10498. this.NetworkFilter(obj, function(data)
  10499. {
  10500. self.ChartSplashPaint.EnableSplash(false);
  10501. self.RecvDepthData(data);
  10502. self.AutoUpdate();
  10503. });
  10504. if (obj.PreventDefault==true) return; //已被上层替换,不调用默认的网络请求
  10505. }
  10506. }
  10507. this.RecvDepthData=function(data)
  10508. {
  10509. this.UpdateAskAndBid(data);
  10510. var aryAsk=Array.from(this.MapAsk.values()); //卖 右边
  10511. aryAsk.sort((a,b)=> { return a.Price-b.Price; });
  10512. var sumVol=0;
  10513. for(var i in aryAsk)
  10514. {
  10515. var item=aryAsk[i];
  10516. sumVol+=item.Vol;
  10517. aryAsk[i]={Price:item.Price, Vol:sumVol };
  10518. }
  10519. var aryBid=Array.from(this.MapBid.values()); //买 左边
  10520. aryBid.sort((a,b)=> { return b.Price-a.Price; });
  10521. var sumVol=0;
  10522. for(var i in aryBid)
  10523. {
  10524. var item=aryBid[i];
  10525. sumVol+=item.Vol;
  10526. aryBid[i]={Price:item.Price, Vol:sumVol };
  10527. }
  10528. var drawData={ Asks:aryAsk, Bids:aryBid };
  10529. var chart=this.ChartPaint[0];
  10530. chart.Data=drawData;
  10531. this.Frame.XSplitOperator.Symbol=this.Symbol;
  10532. this.ChartCorssCursor.Data=drawData;
  10533. this.ChartCorssCursor.Symbol=this.Symbol;
  10534. this.UpdateFramePriceList();
  10535. this.UpdateFrameMaxMin();
  10536. this.Draw();
  10537. }
  10538. this.UpdateAskAndBid=function(data) //更新数据
  10539. {
  10540. if(data.datatype=="snapshot") //全量数据
  10541. {
  10542. this.MapBid=new Map();
  10543. this.MapAsk=new Map();
  10544. }
  10545. for(var i in data.asks)
  10546. {
  10547. var item=data.asks[i];
  10548. var price=parseFloat(item[0]);
  10549. var vol=parseFloat(item[1]);
  10550. if (this.MapAsk.has(price))
  10551. {
  10552. var value=this.MapAsk.get(price);
  10553. if (vol<=0) this.MapAsk.delete(price);
  10554. else value.Vol=vol;
  10555. }
  10556. else
  10557. {
  10558. if (vol>0) this.MapAsk.set(price, { Price:price, Vol:vol});
  10559. }
  10560. }
  10561. for(var i in data.bids)
  10562. {
  10563. var item=data.bids[i];
  10564. var price=parseFloat(item[0]);
  10565. var vol=parseFloat(item[1]);
  10566. if (this.MapBid.has(price))
  10567. {
  10568. var value=this.MapBid.get(price);
  10569. if (vol<=0) this.MapBid.delete(price);
  10570. else value.Vol=vol;
  10571. }
  10572. else
  10573. {
  10574. if (vol>0) this.MapBid.set(price, { Price:price, Vol:vol});
  10575. }
  10576. }
  10577. }
  10578. this.UpdateFramePriceList=function()
  10579. {
  10580. var aryAskPrice=Array.from(this.MapAsk.keys());
  10581. var aryBidPrice=Array.from(this.MapBid.keys());
  10582. aryAskPrice.sort((a,b)=> { return a-b; });
  10583. aryBidPrice.sort((a,b)=> { return a-b; });
  10584. if (aryAskPrice.length>1 && aryBidPrice.length>1)
  10585. {
  10586. var askMin=aryAskPrice[0], askMax=aryAskPrice[aryAskPrice.length-1];
  10587. var bidMin=aryBidPrice[0], bidMax=aryBidPrice[aryBidPrice.length-1];
  10588. var askDifference=askMax-askMin; //卖差值
  10589. var bidDifference=bidMax-bidMin; //买差值
  10590. var difference=Math.max(askDifference, bidDifference); //取最大的差值,2边调整
  10591. var ask={Min:askMin, Max:askMin+difference};
  10592. var bid={Max:bidMax, Min:bidMax-difference};
  10593. var range={ Max:ask.Max, Min:bid.Min };
  10594. }
  10595. this.Frame.SetPriceList(aryAskPrice,aryBidPrice);
  10596. var xRange=this.Frame.VerticalRange;
  10597. xRange.Max=range.Max;
  10598. xRange.Center=range.Min+(range.Max-range.Min)/2;
  10599. xRange.Min=range.Min;
  10600. xRange.MaxDiffer=difference; //差值
  10601. xRange.Ask=ask;
  10602. xRange.Bid=bid;
  10603. if (!IFrameSplitOperator.IsNumber(xRange.Differ))
  10604. xRange.Differ=difference*this.DefaultZoom;
  10605. xRange.Min=xRange.Center-xRange.Differ;
  10606. xRange.Max=xRange.Center+xRange.Differ;
  10607. }
  10608. this.UpdateFrameMaxMin=function()
  10609. {
  10610. var range=this.ChartPaint[0].GetMaxMin();
  10611. this.Frame.HorizontalMax=range.Max*this.MaxVolRate;
  10612. this.Frame.HorizontalMin=0;
  10613. this.Frame.XYSplit=true;
  10614. }
  10615. this.CancelAutoUpdate=function() //关闭停止更新
  10616. {
  10617. if (typeof (this.AutoUpdateTimer) == 'number')
  10618. {
  10619. clearTimeout(this.AutoUpdateTimer);
  10620. this.AutoUpdateTimer = undefined;
  10621. }
  10622. }
  10623. this.StopAutoUpdate=function()
  10624. {
  10625. this.CancelAutoUpdate();
  10626. if (!this.IsAutoUpdate) return;
  10627. this.IsAutoUpdate=false;
  10628. }
  10629. this.AutoUpdate=function() //数据自动更新
  10630. {
  10631. this.CancelAutoUpdate();
  10632. if (!this.IsAutoUpdate) return;
  10633. if (!this.Symbol) return;
  10634. if (this.IsDestroy) return;
  10635. var self = this;
  10636. var marketStatus=MARKET_SUFFIX_NAME.GetMarketStatus(this.Symbol);
  10637. if (marketStatus==0 || marketStatus==3) return; //闭市,盘后
  10638. var frequency=this.AutoUpdateFrequency;
  10639. if (marketStatus==1) //盘前
  10640. {
  10641. this.AutoUpdateTimer=setTimeout(function()
  10642. {
  10643. self.AutoUpdate();
  10644. },frequency);
  10645. }
  10646. else if (marketStatus==2) //盘中
  10647. {
  10648. this.AutoUpdateTimer=setTimeout(function()
  10649. {
  10650. self.RequestDepthData();
  10651. },frequency);
  10652. }
  10653. }
  10654. }
  10655. ////////////////////////////////////////////////////////////////////////////////
  10656. // 简单的图形框架
  10657. //
  10658. function SimlpleChartContainer(uielement) {
  10659. this.newMethod = JSChartContainer; //派生
  10660. this.newMethod(uielement);
  10661. delete this.newMethod;
  10662. this.WindowIndex = new Array();
  10663. this.MainDataControl; //主数据类(对外的接口类)
  10664. this.SubDataControl = new Array();
  10665. this.FrameType = 0; //框架类型
  10666. this.YSplitCount = 4;
  10667. //创建
  10668. this.Create = function () {
  10669. this.UIElement.JSChartContainer = this;
  10670. //创建十字光标
  10671. //this.ChartCorssCursor=new ChartCorssCursor();
  10672. //this.ChartCorssCursor.Canvas=this.Canvas;
  10673. //this.ChartCorssCursor.StringFormatX=new HQDateStringFormat();
  10674. //this.ChartCorssCursor.StringFormatY=new HQPriceStringFormat();
  10675. //创建等待提示
  10676. this.ChartSplashPaint = new ChartSplashPaint();
  10677. this.ChartSplashPaint.Canvas = this.Canvas;
  10678. //创建框架容器
  10679. if (this.FrameType == 1) this.Frame = new Rotate90SimpleChartFrame();
  10680. else this.Frame = new SimpleChartFrame();
  10681. this.Frame.ChartBorder = new ChartBorder();
  10682. this.Frame.ChartBorder.UIElement = this.UIElement;
  10683. this.Frame.ChartBorder.Top = 30;
  10684. this.Frame.ChartBorder.Left = 5;
  10685. this.Frame.ChartBorder.Bottom = 20;
  10686. this.Frame.Canvas = this.Canvas;
  10687. if (this.ChartCorssCursor) this.ChartCorssCursor.Frame = this.Frame; //十字光标绑定框架
  10688. this.ChartSplashPaint.Frame = this.Frame;
  10689. this.CreateMainChart();
  10690. }
  10691. this.SetMainDataConotrl = function (dataControl) {
  10692. if (!dataControl) return;
  10693. this.MainDataControl = dataControl;
  10694. this.ChartPaint = []; //图形
  10695. this.Frame.BarCount = 0;
  10696. let yStringFormat = this.Frame.YSplitOperator.StringFormat;//保存配置
  10697. this.CreateMainChart();
  10698. this.Frame.YSplitOperator.StringFormat = yStringFormat;//还原配置
  10699. this.Draw();
  10700. this.RequestData();
  10701. }
  10702. //创建主数据画法
  10703. this.CreateMainChart = function ()
  10704. {
  10705. if (!this.MainDataControl) return;
  10706. let barIndex = 0;
  10707. for (let i in this.MainDataControl.DataType)
  10708. {
  10709. let item = this.MainDataControl.DataType[i];
  10710. if (item.Type == "BAR")
  10711. {
  10712. let chartItem;
  10713. if (this.FrameType == 1) chartItem = new ChartXYSubBar();
  10714. else chartItem = new ChartSubBar();
  10715. chartItem.BarID = barIndex;
  10716. chartItem.Canvas = this.Canvas;
  10717. chartItem.ChartBorder = this.Frame.ChartBorder;
  10718. chartItem.ChartFrame = this.Frame;
  10719. chartItem.Name = item.Name;
  10720. if (item.Color) chartItem.UpBarColor = item.Color;
  10721. if (item.Color2) chartItem.DownBarColor = item.Color2;
  10722. this.ChartPaint.push(chartItem);
  10723. ++this.Frame.BarCount;
  10724. ++barIndex;
  10725. }
  10726. else if (item.Type == "LINE")
  10727. {
  10728. let chartItem = new ChartLine();
  10729. chartItem.Canvas = this.Canvas;
  10730. chartItem.ChartBorder = this.Frame.ChartBorder;
  10731. chartItem.ChartFrame = this.Frame;
  10732. chartItem.Name = item.Name;
  10733. if (item.Color) chartItem.Color = item.Color;
  10734. this.ChartPaint.push(chartItem);
  10735. }
  10736. }
  10737. var floatPrecision = 2; //设置纵坐标的小数位数 默认为2
  10738. var ignoreYValue=null
  10739. if (this.Frame.YSplitOperator)
  10740. {
  10741. floatPrecision = this.Frame.YSplitOperator.FloatPrecision; //备份上次实例化的值
  10742. if (this.Frame.YSplitOperator.IgnoreYValue) ignoreYValue = this.Frame.YSplitOperator.IgnoreYValue;
  10743. }
  10744. this.Frame.YSplitOperator = new FrameSplitY();
  10745. this.Frame.YSplitOperator.FloatPrecision = floatPrecision; //实例化纵坐标分割后 赋给备份的值
  10746. this.Frame.YSplitOperator.IgnoreYValue = ignoreYValue;
  10747. this.Frame.YSplitOperator.SplitCount = this.YSplitCount;
  10748. this.Frame.YSplitOperator.FrameSplitData = this.FrameSplitData.get('double');
  10749. this.Frame.YSplitOperator.Frame = this.Frame;
  10750. this.Frame.YSplitOperator.ChartBorder = this.Frame.ChartBorder;
  10751. this.Frame.XSplitOperator = new FrameSplitXData();
  10752. this.Frame.XSplitOperator.Frame = this.Frame;
  10753. this.Frame.XSplitOperator.ChartBorder = this.Frame.ChartBorder;
  10754. // this.TitlePaint[0]=new DynamicKLineTitlePainting();
  10755. // this.TitlePaint[0].Frame=this.Frame.SubFrame[0].Frame;
  10756. // this.TitlePaint[0].Canvas=this.Canvas;
  10757. }
  10758. this.RequestData = function () {
  10759. if (!this.MainDataControl) return;
  10760. this.MainDataControl.JSChartContainer = this;
  10761. this.MainDataControl.RequestData();
  10762. }
  10763. this.UpdateMainData = function (dataControl) {
  10764. let lCount = 0;
  10765. for (let i in dataControl.Data) {
  10766. let itemData = new ChartData();
  10767. itemData.Data = dataControl.Data[i];
  10768. this.ChartPaint[i].Data = itemData;
  10769. if (lCount < itemData.Data.length) lCount = itemData.Data.length;
  10770. }
  10771. this.Frame.XPointCount = lCount;
  10772. this.Frame.Data = this.ChartPaint[0].Data;
  10773. this.Frame.XData = dataControl.XData;
  10774. this.UpdateFrameMaxMin(); //调整坐标最大 最小值
  10775. this.Frame.SetSizeChage(true);
  10776. this.Draw();
  10777. }
  10778. }
  10779. ////////////////////////////////////////////////////////////////////////////////
  10780. // 饼图图形框架
  10781. //
  10782. function PieChartContainer(uielement) {
  10783. this.Radius; //半径
  10784. this.newMethod = JSChartContainer; //派生
  10785. this.newMethod(uielement);
  10786. delete this.newMethod;
  10787. this.MainDataControl; //主数据类(对外的接口类)
  10788. //鼠标移动
  10789. this.OnMouseMove = function (x, y, e) { }
  10790. //创建
  10791. this.Create = function () {
  10792. this.UIElement.JSChartContainer = this;
  10793. //创建等待提示
  10794. this.ChartSplashPaint = new ChartSplashPaint();
  10795. this.ChartSplashPaint.Canvas = this.Canvas;
  10796. //创建框架容器
  10797. this.Frame = new NoneFrame();
  10798. this.Frame.ChartBorder = new ChartBorder();
  10799. this.Frame.ChartBorder.UIElement = this.UIElement;
  10800. this.Frame.ChartBorder.Top = 30;
  10801. this.Frame.ChartBorder.Left = 5;
  10802. this.Frame.ChartBorder.Bottom = 20;
  10803. this.Frame.Canvas = this.Canvas;
  10804. this.ChartSplashPaint.Frame = this.Frame;
  10805. this.CreateMainChart();
  10806. }
  10807. this.SetMainDataConotrl = function (dataControl) {
  10808. if (!dataControl) return;
  10809. this.MainDataControl = dataControl;
  10810. this.ChartPaint = []; //图形
  10811. this.CreateMainChart();
  10812. this.Draw();
  10813. this.RequestData();
  10814. }
  10815. //创建主数据画法
  10816. this.CreateMainChart = function ()
  10817. {
  10818. if (!this.MainDataControl) return;
  10819. for (let i in this.MainDataControl.DataType)
  10820. {
  10821. let item = this.MainDataControl.DataType[i];
  10822. if (item.Type == "PIE")
  10823. {
  10824. var chartItem = new ChartPie();
  10825. chartItem.Canvas = this.Canvas;
  10826. chartItem.ChartBorder = this.Frame.ChartBorder;
  10827. chartItem.ChartFrame = this.Frame;
  10828. chartItem.Name = item.Name;
  10829. this.ChartPaint.push(chartItem);
  10830. }
  10831. else if (item.Type == 'CIRCLE')
  10832. {
  10833. var chartItem = new ChartCircle();
  10834. chartItem.Canvas = this.Canvas;
  10835. chartItem.ChartBorder = this.Frame.ChartBorder;
  10836. chartItem.ChartFrame = this.Frame;
  10837. chartItem.Name = item.Name;
  10838. this.ChartPaint.push(chartItem);
  10839. }
  10840. else if (item.Type == 'RADAR') //雷达图
  10841. {
  10842. var chartItem = new ChartRadar();
  10843. chartItem.Canvas = this.Canvas;
  10844. chartItem.ChartBorder = this.Frame.ChartBorder;
  10845. chartItem.ChartFrame = this.Frame;
  10846. chartItem.Name = item.Name;
  10847. if (item.StartAngle) chartItem.StartAngle = item.StartAngle;
  10848. if (item.TitleFont) chartItem.TitleFont = item.TitleFont;
  10849. this.ChartPaint.push(chartItem);
  10850. }
  10851. }
  10852. // this.TitlePaint[0]=new DynamicKLineTitlePainting();
  10853. // this.TitlePaint[0].Frame=this.Frame.SubFrame[0].Frame;
  10854. // this.TitlePaint[0].Canvas=this.Canvas;
  10855. }
  10856. this.RequestData = function () {
  10857. if (!this.MainDataControl) return;
  10858. this.MainDataControl.JSChartContainer = this;
  10859. this.MainDataControl.RequestData();
  10860. }
  10861. this.UpdateMainData = function (dataControl) {
  10862. for (let i in dataControl.Data) {
  10863. let itemData = new ChartData();
  10864. itemData.Data = dataControl.Data[i];
  10865. this.ChartPaint[i].Data = itemData;
  10866. }
  10867. this.Frame.SetSizeChage(true);
  10868. this.Draw();
  10869. }
  10870. }
  10871. //地图
  10872. function MapChartContainer(uielement) {
  10873. this.newMethod = JSChartContainer; //派生
  10874. this.newMethod(uielement);
  10875. delete this.newMethod;
  10876. this.MainDataControl; //主数据类(对外的接口类)
  10877. //鼠标移动
  10878. this.OnMouseMove = function (x, y, e) {
  10879. }
  10880. //创建
  10881. this.Create = function () {
  10882. this.UIElement.JSChartContainer = this;
  10883. //创建等待提示
  10884. this.ChartSplashPaint = new ChartSplashPaint();
  10885. this.ChartSplashPaint.Canvas = this.Canvas;
  10886. //创建框架容器
  10887. this.Frame = new NoneFrame();
  10888. this.Frame.ChartBorder = new ChartBorder();
  10889. this.Frame.ChartBorder.UIElement = this.UIElement;
  10890. this.Frame.ChartBorder.Top = 30;
  10891. this.Frame.ChartBorder.Left = 5;
  10892. this.Frame.ChartBorder.Bottom = 20;
  10893. this.Frame.Canvas = this.Canvas;
  10894. this.ChartSplashPaint.Frame = this.Frame;
  10895. this.CreateMainChart();
  10896. }
  10897. this.SetMainDataConotrl = function (dataControl) {
  10898. if (!dataControl) return;
  10899. this.MainDataControl = dataControl;
  10900. this.ChartPaint = []; //图形
  10901. this.CreateMainChart();
  10902. this.Draw();
  10903. this.RequestData();
  10904. }
  10905. //创建主数据画法
  10906. this.CreateMainChart = function () {
  10907. if (!this.MainDataControl) return;
  10908. let chartItem = new ChartChinaMap();
  10909. chartItem.Canvas = this.Canvas;
  10910. chartItem.ChartBorder = this.Frame.ChartBorder;
  10911. chartItem.ChartFrame = this.Frame;
  10912. chartItem.Name = this.MainDataControl.DataType[0].Name;
  10913. if (this.Radius) chartItem.Radius = this.Radius;
  10914. this.ChartPaint.push(chartItem);
  10915. // this.TitlePaint[0]=new DynamicKLineTitlePainting();
  10916. // this.TitlePaint[0].Frame=this.Frame.SubFrame[0].Frame;
  10917. // this.TitlePaint[0].Canvas=this.Canvas;
  10918. }
  10919. this.RequestData = function () {
  10920. if (!this.MainDataControl) return;
  10921. this.MainDataControl.JSChartContainer = this;
  10922. this.MainDataControl.RequestData();
  10923. }
  10924. this.UpdateMainData = function (dataControl) {
  10925. this.ChartPaint[0].Data = dataControl.Data[0];
  10926. this.Frame.SetSizeChage(true);
  10927. this.Draw();
  10928. }
  10929. }
  10930. var HQ_DATA_TYPE =
  10931. {
  10932. KLINE_ID: 0, //K线
  10933. MINUTE_ID: 2, //当日走势图
  10934. HISTORY_MINUTE_ID: 3,//历史分钟走势图
  10935. MULTIDAY_MINUTE_ID: 4,//多日走势图
  10936. };
  10937. function APIScriptIndex(name, script, args, option) //后台执行指标
  10938. {
  10939. this.newMethod = ScriptIndex; //派生
  10940. this.newMethod(name, script, args, option);
  10941. delete this.newMethod;
  10942. this.ApiUrl; //指标执行api地址
  10943. this.HQDataType;
  10944. if (option.API)
  10945. {
  10946. if (option.API.Url) this.ApiUrl = option.API.Url;
  10947. if (option.API.Name) this.Name = this.ID = option.API.Name;
  10948. if (option.API.ID) this.ID = option.API.ID;
  10949. }
  10950. this.ExecuteScript = function (hqChart, windowIndex, hisData)
  10951. {
  10952. JSConsole.Chart.Log('[APIScriptIndex::ExecuteScript] name, Arguments ', this.Name, this.Arguments);
  10953. //数据类型
  10954. let hqDataType = HQ_DATA_TYPE.KLINE_ID; //默认K线
  10955. if (hqChart.ClassName === 'MinuteChartContainer' || hqChart.ClassName === 'MinuteChartHScreenContainer')
  10956. {
  10957. if (hqChart.DayCount > 1) hqDataType = HQ_DATA_TYPE.MULTIDAY_MINUTE_ID; //多日分钟
  10958. else hqDataType = HQ_DATA_TYPE.MINUTE_ID; //分钟数据
  10959. }
  10960. else if (hqChart.ClassName === 'HistoryMinuteChartContainer')
  10961. {
  10962. hqDataType = HQ_DATA_TYPE.HISTORY_MINUTE_ID; //历史分钟
  10963. }
  10964. var args = [];
  10965. if (this.Arguments)
  10966. {
  10967. for (var i in this.Arguments)
  10968. {
  10969. var item = this.Arguments[i];
  10970. args.push({ name: item.Name, value: item.Value });
  10971. }
  10972. }
  10973. var requestCount = hqChart.GetRequestDataCount();
  10974. var self = this;
  10975. var postData =
  10976. {
  10977. indexname: this.ID, symbol: hqChart.Symbol, script: this.Script, args: args,
  10978. period: hqChart.Period, right: hqChart.Right, maxdatacount: requestCount.MaxRequestDataCount, maxminutedaycount: requestCount.MaxRequestMinuteDayCount, hqdatatype: hqDataType
  10979. };
  10980. if (hqDataType == HQ_DATA_TYPE.MULTIDAY_MINUTE_ID || hqDataType == HQ_DATA_TYPE.MINUTE_ID) postData.daycount = hqChart.DayCount;
  10981. this.HQDataType = hqDataType;
  10982. if (hqChart.NetworkFilter)
  10983. {
  10984. var obj =
  10985. {
  10986. Name: 'APIScriptIndex::ExecuteScript', //类名::
  10987. Explain: '指标计算',
  10988. Request: { Url: self.ApiUrl, Type: 'POST', Data: postData },
  10989. Self: this,
  10990. HQChart: hqChart,
  10991. PreventDefault: false
  10992. };
  10993. hqChart.NetworkFilter(obj, function (data)
  10994. {
  10995. self.RecvAPIData(data, hqChart, windowIndex, hisData);
  10996. });
  10997. if (obj.PreventDefault == true) return; //已被上层替换,不调用默认的网络请求
  10998. }
  10999. wx.request({
  11000. url: self.ApiUrl,
  11001. data: postData,
  11002. method: 'POST',
  11003. dataType: "json",
  11004. async: true,
  11005. success: function (recvData)
  11006. {
  11007. self.RecvAPIData(recvData, hqChart, windowIndex, hisData);
  11008. },
  11009. error: function (request)
  11010. {
  11011. self.RecvError(request);
  11012. }
  11013. });
  11014. }
  11015. this.RecvAPIData = function (recvData, hqChart, windowIndex, hisData)
  11016. {
  11017. var data=recvData.data;
  11018. JSConsole.Chart.Log('[APIScriptIndex::RecvAPIData] recv data ', this.Name, data);
  11019. if (data.code != 0) return;
  11020. if (data.outdata && data.outdata.name) this.Name = data.outdata.name;
  11021. if (data.outdata.args) //外部修改显示参数
  11022. {
  11023. this.Arguments = [];
  11024. for (var i in data.outdata.args)
  11025. {
  11026. var item = data.outdata.args[i];
  11027. this.Arguments.push({ Name: item.name, Value: item.value });
  11028. }
  11029. }
  11030. if (this.HQDataType == HQ_DATA_TYPE.KLINE_ID)
  11031. {
  11032. this.OutVar = this.FittingData(data.outdata, hqChart);
  11033. JSConsole.Chart.Log('[APIScriptIndex::RecvAPIData] conver to OutVar ', this.OutVar);
  11034. }
  11035. else
  11036. {
  11037. this.OutVar = this.FittingMinuteData(data.outdata, hqChart); //走势图数据
  11038. }
  11039. this.BindData(hqChart, windowIndex, hisData);
  11040. if (this.IsLocked == false) //不上锁
  11041. {
  11042. hqChart.Frame.SubFrame[windowIndex].Frame.SetLock(null);
  11043. }
  11044. else //上锁
  11045. {
  11046. let lockData =
  11047. {
  11048. IsLocked: true, Callback: this.LockCallback, IndexName: this.Name, ID: this.LockID,
  11049. BG: this.LockBG, Text: this.LockText, TextColor: this.LockTextColor, Font: this.LockFont, Count: this.LockCount, MinWidth: this.LockMinWidth
  11050. };
  11051. hqChart.Frame.SubFrame[windowIndex].Frame.SetLock(lockData);
  11052. }
  11053. hqChart.UpdataDataoffset(); //更新数据偏移
  11054. hqChart.UpdateFrameMaxMin(); //调整坐标最大 最小值
  11055. hqChart.Draw();
  11056. if (hqChart.GetIndexEvent)
  11057. {
  11058. var event = hqChart.GetIndexEvent(); //指标计算完成回调
  11059. if (event)
  11060. {
  11061. var data =
  11062. {
  11063. OutVar: this.OutVar, WindowIndex: windowIndex, Name: this.Name, Arguments: this.Arguments, HistoryData: hisData,
  11064. Stock: { Symbol: hqChart.Symbol, Name: hqChart.Name }
  11065. };
  11066. event.Callback(event, data, this);
  11067. }
  11068. }
  11069. }
  11070. this.FittingData = function (jsonData, hqChart)
  11071. {
  11072. var outVar = jsonData.outvar;
  11073. var date = jsonData.date;
  11074. var time = jsonData.time;
  11075. var kdata = hqChart.ChartPaint[0].Data;
  11076. //把数据拟合到kdata上
  11077. var result = [];
  11078. for (var i in outVar)
  11079. {
  11080. var item = outVar[i];
  11081. var indexData = [];
  11082. var outVarItem = { Name: item.name, Type: item.type };
  11083. if (item.color) outVarItem.Color = item.color;
  11084. if (item.data)
  11085. {
  11086. outVarItem.Data = this.FittingArray(item.data, date, time, hqChart);
  11087. if (item.color) outVarItem.Color = item.color;
  11088. if (item.linewidth >= 1) outVarItem.LineWidth = item.linewidth;
  11089. if (item.isshow == false) outVarItem.IsShow = false;
  11090. if (item.isexdata == true) outVarItem.IsExData = true;
  11091. result.push(outVarItem);
  11092. }
  11093. else if (item.Draw)
  11094. {
  11095. var draw = item.Draw;
  11096. var drawItem = {};
  11097. if (draw.DrawType == 'DRAWICON') //图标
  11098. {
  11099. drawItem.Icon = draw.Icon;
  11100. drawItem.Name = draw.Name;
  11101. drawItem.DrawType = draw.DrawType;
  11102. drawItem.DrawData = this.FittingArray(draw.DrawData, date, time, hqChart);
  11103. outVarItem.Draw = drawItem;
  11104. result.push(outVarItem);
  11105. }
  11106. else if (draw.DrawType == 'DRAWTEXT') //文本
  11107. {
  11108. drawItem.Text = draw.Text;
  11109. drawItem.Name = draw.Name;
  11110. drawItem.DrawType = draw.DrawType;
  11111. drawItem.DrawData = this.FittingArray(draw.DrawData, date, time, hqChart);
  11112. outVarItem.Draw = drawItem;
  11113. result.push(outVarItem);
  11114. }
  11115. else if (draw.DrawType == 'STICKLINE') //柱子
  11116. {
  11117. drawItem.Name = draw.Name;
  11118. drawItem.Type = draw.Type;
  11119. drawItem.Width = draw.Width;
  11120. drawItem.DrawType = draw.DrawType;
  11121. drawItem.DrawData = this.FittingArray(draw.DrawData, date, time, hqChart, 1);
  11122. outVarItem.Draw = drawItem;
  11123. result.push(outVarItem);
  11124. }
  11125. else if (draw.DrawType == 'MULTI_LINE')
  11126. {
  11127. drawItem.Text = draw.Text;
  11128. drawItem.Name = draw.Name;
  11129. drawItem.DrawType = draw.DrawType;
  11130. drawItem.DrawData = this.FittingMultiLine(draw.DrawData, date, time, hqChart);
  11131. outVarItem.Draw = drawItem;
  11132. if (draw.LineDash) drawItem.LineDash=draw.LineDash;
  11133. //if (draw.Arrow) drawItem.Arrow=draw.Arrow;
  11134. if (IFrameSplitOperator.IsNumber(draw.LineWidth)) drawItem.LineWidth=draw.LineWidth;
  11135. result.push(outVarItem);
  11136. }
  11137. else if (draw.DrawType == 'MULTI_BAR')
  11138. {
  11139. drawItem.Text = draw.Text;
  11140. drawItem.Name = draw.Name;
  11141. drawItem.DrawType = draw.DrawType;
  11142. drawItem.DrawData = this.FittingMultiLine(draw.DrawData, date, time, hqChart);
  11143. outVarItem.Draw = drawItem;
  11144. result.push(outVarItem);
  11145. }
  11146. else if (draw.DrawType == 'MULTI_TEXT')
  11147. {
  11148. drawItem.Text = draw.Text;
  11149. drawItem.Name = draw.Name;
  11150. drawItem.DrawType = draw.DrawType;
  11151. drawItem.DrawData = this.FittingMultiText(draw.DrawData, date, time, hqChart);
  11152. this.GetKLineData(drawItem.DrawData, hqChart);
  11153. outVarItem.Draw = drawItem;
  11154. result.push(outVarItem);
  11155. }
  11156. else if (draw.DrawType=="MULTI_HTMLDOM") //外部自己创建dom
  11157. {
  11158. drawItem.Text=draw.Text;
  11159. drawItem.Name=draw.Name;
  11160. drawItem.DrawType=draw.DrawType;
  11161. drawItem.Callback=draw.Callback;
  11162. drawItem.DrawData=this.FittingMultiText(draw.DrawData,date,time,hqChart);
  11163. this.GetKLineData(drawItem.DrawData, hqChart);
  11164. outVarItem.Draw=drawItem;
  11165. result.push(outVarItem);
  11166. }
  11167. else if (draw.DrawType=="KLINE_BG")
  11168. {
  11169. drawItem.Name=draw.Name;
  11170. drawItem.DrawType=draw.DrawType;
  11171. drawItem.DrawData={ Color:draw.Color, Angle:draw.Angle };
  11172. drawItem.DrawData.Data=this.FittingKLineBG(draw.DrawData, hqChart);
  11173. outVarItem.Draw=drawItem;
  11174. outVarItem.Name=draw.DrawType;
  11175. result.push(outVarItem);
  11176. }
  11177. }
  11178. }
  11179. return result;
  11180. }
  11181. // h, high, low l.
  11182. this.GetKLineData=function(data,hqChart)
  11183. {
  11184. if (!data) return;
  11185. if (!Array.isArray(data)) return;
  11186. var kData=hqChart.ChartPaint[0].Data; //K线
  11187. for(var i in data)
  11188. {
  11189. var item=data[i];
  11190. if (!IFrameSplitOperator.IsString(item.Value)) continue;
  11191. if(!IFrameSplitOperator.IsNumber(item.Index)) continue;
  11192. if (item.Index<0 || item.Index>=kData.Data.length) continue;
  11193. var valueName=item.Value.toUpperCase();
  11194. var kItem=kData.Data[item.Index];
  11195. switch(valueName)
  11196. {
  11197. case "HIGH":
  11198. case "H":
  11199. item.Value=kItem.High;
  11200. break;
  11201. case "L":
  11202. case "LOW":
  11203. item.Value=kItem.Low;
  11204. break;
  11205. }
  11206. }
  11207. }
  11208. this.FittingKLineBG=function(data, hqChart)
  11209. {
  11210. var kData=hqChart.ChartPaint[0].Data; //K线
  11211. var result=[];
  11212. if (ChartData.IsDayPeriod(hqChart.Period,true)) //日线
  11213. {
  11214. var bFill=false;
  11215. for(var i=0,j=0;i<kData.Data.length;)
  11216. {
  11217. result[i]=0;
  11218. var kItem=kData.Data[i];
  11219. if (j>=data.length)
  11220. {
  11221. ++i;
  11222. continue;
  11223. }
  11224. var dataItem=data[j];
  11225. if (dataItem.Date<kItem.Date)
  11226. {
  11227. ++j;
  11228. }
  11229. else if (dataItem.Date>kItem.Date)
  11230. {
  11231. ++i;
  11232. }
  11233. else
  11234. {
  11235. bFill=true;
  11236. result[i]=1;
  11237. ++j;
  11238. ++i;
  11239. }
  11240. }
  11241. if (bFill) return result;
  11242. }
  11243. else if (ChartData.IsMinutePeriod(hqChart.Period,true)) //分钟线
  11244. {
  11245. var bFill=false;
  11246. for(var i=0,j=0;i<kData.Data.length;)
  11247. {
  11248. result[i]=0;
  11249. var kItem=kData.Data[i];
  11250. if (j>=data.length)
  11251. {
  11252. ++i;
  11253. continue;
  11254. }
  11255. var dataItem=data[j];
  11256. if (dataItem.Date<kItem.Date || (dataItem.Date==kItem.Date && dataItem.Time<kItem.Time))
  11257. {
  11258. ++j;
  11259. }
  11260. else if (dataItem.Date>kItem.Date || (dataItem.Date==kItem.Date && dataItem.Time>kItem.Time))
  11261. {
  11262. ++i;
  11263. }
  11264. else
  11265. {
  11266. bFill=true;
  11267. result[i]=1;
  11268. ++j;
  11269. ++i;
  11270. }
  11271. }
  11272. if (bFill) return result;
  11273. }
  11274. return null;
  11275. }
  11276. this.FittingArray = function (sourceData, date, time, hqChart, arrayType) //arrayType 0=单值数组 1=结构体
  11277. {
  11278. var kdata = hqChart.ChartPaint[0].Data; //K线
  11279. var arySingleData = [];
  11280. for (var i in sourceData)
  11281. {
  11282. var value = sourceData[i];
  11283. var indexItem = new SingleData(); //单列指标数据
  11284. indexItem.Date = date[i];
  11285. if (time && i < time.length) indexItem.Time = time[i];
  11286. indexItem.Value = value;
  11287. arySingleData.push(indexItem);
  11288. }
  11289. var aryFittingData;
  11290. if (ChartData.IsDayPeriod(hqChart.Period,true))
  11291. aryFittingData = kdata.GetFittingData(arySingleData); //数据和主图K线拟合
  11292. else
  11293. aryFittingData = kdata.GetMinuteFittingData(arySingleData); //数据和主图K线拟合
  11294. var bindData = new ChartData();
  11295. bindData.Data = aryFittingData;
  11296. var result;
  11297. if (arrayType == 1) result = bindData.GetObject();
  11298. else result = bindData.GetValue();
  11299. return result;
  11300. }
  11301. this.FittingMultiLine = function (sourceData, date, time, hqChart)
  11302. {
  11303. var kdata = hqChart.ChartPaint[0].Data; //K线
  11304. if (ChartData.IsDayPeriod(hqChart.Period, true)) //日线
  11305. {
  11306. var aryPoint = [];
  11307. for (var i in sourceData)
  11308. {
  11309. var item = sourceData[i];
  11310. for (var j in item.Point)
  11311. {
  11312. var point = item.Point[j];
  11313. aryPoint.push(point);
  11314. }
  11315. }
  11316. aryPoint.sort(function (a, b) { return a.Date - b.Date; });
  11317. kdata.GetDateIndex(aryPoint);
  11318. return sourceData;
  11319. }
  11320. else if (ChartData.IsMinutePeriod(hqChart.Period, true)) //分钟线
  11321. {
  11322. var aryPoint = [];
  11323. for (var i in sourceData)
  11324. {
  11325. var item = sourceData[i];
  11326. for (var j in item.Point)
  11327. {
  11328. var point = item.Point[j];
  11329. aryPoint.push(point);
  11330. }
  11331. }
  11332. aryPoint.sort(function (a, b) {
  11333. if (a.Date == b.Date) return a.Time - b.Time;
  11334. return a.Date - b.Date;
  11335. });
  11336. kdata.GetDateTimeIndex(aryPoint);
  11337. return sourceData;
  11338. }
  11339. return null;
  11340. }
  11341. this.FittingMultiText = function (sourceData, date, time, hqChart)
  11342. {
  11343. var kdata = hqChart.ChartPaint[0].Data; //K线
  11344. if (ChartData.IsDayPeriod(hqChart.Period, true)) //日线
  11345. {
  11346. sourceData.sort(function (a, b) { return a.Date - b.Date; });
  11347. kdata.GetDateIndex(sourceData);
  11348. return sourceData;
  11349. }
  11350. else if (ChartData.IsMinutePeriod(hqChart.Period, true)) //分钟线
  11351. {
  11352. sourceData.sort(function (a, b) {
  11353. if (a.Date == b.Date) return a.Time - b.Time;
  11354. return a.Date - b.Date;
  11355. }
  11356. );
  11357. kdata.GetDateTimeIndex(sourceData);
  11358. return sourceData;
  11359. }
  11360. return null;
  11361. }
  11362. }
  11363. //市场多空
  11364. function MarketLongShortIndex() {
  11365. this.newMethod = BaseIndex; //派生
  11366. this.newMethod('市场多空');
  11367. delete this.newMethod;
  11368. this.Index = new Array(
  11369. new IndexInfo("多空指标", null),
  11370. new IndexInfo("多头区域", null),
  11371. new IndexInfo("空头区域", null)
  11372. );
  11373. this.Index[0].LineColor = g_JSChartResource.Index.LineColor[0];
  11374. this.Index[1].LineColor = g_JSChartResource.UpBarColor;
  11375. this.Index[2].LineColor = g_JSChartResource.DownBarColor;
  11376. this.LongShortData; //多空数据
  11377. this.Create = function (hqChart, windowIndex) {
  11378. for (var i in this.Index) {
  11379. var paint = null;
  11380. if (i == 0)
  11381. paint = new ChartLine();
  11382. else
  11383. paint = new ChartStraightLine();
  11384. paint.Color = this.Index[i].LineColor;
  11385. paint.Canvas = hqChart.Canvas;
  11386. paint.Name = this.Name + "-" + i.toString();
  11387. paint.ChartBorder = hqChart.Frame.SubFrame[windowIndex].Frame.ChartBorder;
  11388. paint.ChartFrame = hqChart.Frame.SubFrame[windowIndex].Frame;
  11389. hqChart.ChartPaint.push(paint);
  11390. }
  11391. }
  11392. //请求数据
  11393. this.RequestData = function (hqChart, windowIndex, hisData) {
  11394. var self = this;
  11395. var param =
  11396. {
  11397. HQChart: hqChart,
  11398. WindowIndex: windowIndex,
  11399. HistoryData: hisData
  11400. };
  11401. this.LongShortData = [];
  11402. if (param.HQChart.Period > 0) //周期数据
  11403. {
  11404. this.NotSupport(param.HQChart, param.WindowIndex, "不支持周期切换");
  11405. param.HQChart.Draw();
  11406. return false;
  11407. }
  11408. //请求数据
  11409. wx.request({
  11410. url: g_JSChartResource.Index.MarketLongShortApiUrl,
  11411. data:
  11412. {
  11413. },
  11414. method: 'POST',
  11415. dataType: "json",
  11416. async: true,
  11417. success: function (recvData) {
  11418. self.RecvData(recvData, param);
  11419. }
  11420. });
  11421. return true;
  11422. }
  11423. this.RecvData = function (recvData, param) {
  11424. if (recvData.data.data.length <= 0) return;
  11425. var aryData = new Array();
  11426. for (var i in recvData.data.data) {
  11427. var item = recvData.data.data[i];
  11428. var indexData = new SingleData();
  11429. indexData.Date = item[0];
  11430. indexData.Value = item[1];
  11431. aryData.push(indexData);
  11432. }
  11433. var aryFittingData = param.HistoryData.GetFittingData(aryData);
  11434. var bindData = new ChartData();
  11435. bindData.Data = aryFittingData;
  11436. bindData.Period = param.HQChart.Period; //周期
  11437. bindData.Right = param.HQChart.Right; //复权
  11438. this.LongShortData = bindData.GetValue();
  11439. this.BindData(param.HQChart, param.WindowIndex, param.HistoryData);
  11440. param.HQChart.UpdataDataoffset(); //更新数据偏移
  11441. param.HQChart.UpdateFrameMaxMin(); //调整坐标最大 最小值
  11442. param.HQChart.Draw();
  11443. }
  11444. this.BindData = function (hqChart, windowIndex, hisData) {
  11445. var paint = hqChart.GetChartPaint(windowIndex);
  11446. if (paint.length != this.Index.length) return false;
  11447. //paint[0].Data.Data=SWLData;
  11448. paint[0].Data.Data = this.LongShortData;
  11449. paint[0].NotSupportMessage = null;
  11450. paint[1].Data.Data[0] = 8;
  11451. paint[2].Data.Data[0] = 1;
  11452. //指定[0,9]
  11453. hqChart.Frame.SubFrame[windowIndex].Frame.YSpecificMaxMin = { Max: 9, Min: 0, Count: 3 };
  11454. var titleIndex = windowIndex + 1;
  11455. for (var i in paint) {
  11456. hqChart.TitlePaint[titleIndex].Data[i] = new DynamicTitleData(paint[i].Data, this.Index[i].Name, this.Index[i].LineColor);
  11457. if (i > 0) hqChart.TitlePaint[titleIndex].Data[i].DataType = "StraightLine";
  11458. }
  11459. hqChart.TitlePaint[titleIndex].Title = this.FormatIndexTitle();
  11460. if (hqChart.UpdateUICallback) hqChart.UpdateUICallback('MarketLongShortIndex', paint, { WindowIndex: windowIndex, HistoryData: hisData }); //通知上层回调
  11461. return true;
  11462. }
  11463. }
  11464. //市场择时
  11465. function MarketTimingIndex() {
  11466. this.newMethod = BaseIndex; //派生
  11467. this.newMethod('市场择时');
  11468. delete this.newMethod;
  11469. this.Index = new Array(
  11470. new IndexInfo("因子择时", null)
  11471. );
  11472. this.TimingData; //择时数据
  11473. this.TitleColor = g_JSChartResource.FrameSplitTextColor
  11474. this.Create = function (hqChart, windowIndex) {
  11475. for (var i in this.Index) {
  11476. var paint = new ChartMACD();
  11477. paint.Canvas = hqChart.Canvas;
  11478. paint.Name = this.Name + "-" + i.toString();
  11479. paint.ChartBorder = hqChart.Frame.SubFrame[windowIndex].Frame.ChartBorder;
  11480. paint.ChartFrame = hqChart.Frame.SubFrame[windowIndex].Frame;
  11481. hqChart.ChartPaint.push(paint);
  11482. }
  11483. }
  11484. //请求数据
  11485. this.RequestData = function (hqChart, windowIndex, hisData) {
  11486. var self = this;
  11487. var param =
  11488. {
  11489. HQChart: hqChart,
  11490. WindowIndex: windowIndex,
  11491. HistoryData: hisData
  11492. };
  11493. this.LongShortData = [];
  11494. if (param.HQChart.Period > 0) //周期数据
  11495. {
  11496. this.NotSupport(param.HQChart, param.WindowIndex, "不支持周期切换");
  11497. param.HQChart.Draw();
  11498. return false;
  11499. }
  11500. //请求数据
  11501. wx.request({
  11502. url: g_JSChartResource.Index.MarketLongShortApiUrl,
  11503. data:
  11504. {
  11505. },
  11506. method: 'POST',
  11507. dataType: "json",
  11508. async: true,
  11509. success: function (recvData) {
  11510. self.RecvData(recvData, param);
  11511. }
  11512. });
  11513. return true;
  11514. }
  11515. this.RecvData = function (recvData, param) {
  11516. if (recvData.data.data.length <= 0) return;
  11517. var aryData = new Array();
  11518. for (var i in recvData.data.data) {
  11519. var item = recvData.data.data[i];
  11520. var indexData = new SingleData();
  11521. indexData.Date = item[0];
  11522. indexData.Value = item[2];
  11523. aryData.push(indexData);
  11524. }
  11525. var aryFittingData = param.HistoryData.GetFittingData(aryData);
  11526. var bindData = new ChartData();
  11527. bindData.Data = aryFittingData;
  11528. bindData.Period = param.HQChart.Period; //周期
  11529. bindData.Right = param.HQChart.Right; //复权
  11530. this.TimingData = bindData.GetValue();
  11531. this.BindData(param.HQChart, param.WindowIndex, param.HistoryData);
  11532. param.HQChart.UpdataDataoffset(); //更新数据偏移
  11533. param.HQChart.UpdateFrameMaxMin(); //调整坐标最大 最小值
  11534. param.HQChart.Draw();
  11535. }
  11536. this.BindData = function (hqChart, windowIndex, hisData) {
  11537. var paint = hqChart.GetChartPaint(windowIndex);
  11538. if (paint.length != this.Index.length) return false;
  11539. //paint[0].Data.Data=SWLData;
  11540. paint[0].Data.Data = this.TimingData;
  11541. paint[0].NotSupportMessage = null;
  11542. var titleIndex = windowIndex + 1;
  11543. for (var i in paint) {
  11544. hqChart.TitlePaint[titleIndex].Data[i] = new DynamicTitleData(paint[i].Data, this.Index[i].Name, this.TitleColor);
  11545. hqChart.TitlePaint[titleIndex].Data[i].StringFormat = STRING_FORMAT_TYPE.THOUSANDS;
  11546. hqChart.TitlePaint[titleIndex].Data[i].FloatPrecision = 0;
  11547. }
  11548. hqChart.TitlePaint[titleIndex].Title = this.FormatIndexTitle();
  11549. if (hqChart.UpdateUICallback) hqChart.UpdateUICallback('MarketTimingIndex', paint, { WindowIndex: windowIndex, HistoryData: hisData }); //通知上层回调
  11550. return true;
  11551. }
  11552. }
  11553. //市场关注度
  11554. function MarketAttentionIndex() {
  11555. this.newMethod = BaseIndex; //派生
  11556. this.newMethod('市场关注度');
  11557. delete this.newMethod;
  11558. this.Index = new Array(
  11559. new IndexInfo("市场关注度指数", null)
  11560. );
  11561. this.Data; //关注度数据
  11562. this.TitleColor = g_JSChartResource.FrameSplitTextColor;
  11563. this.ApiUrl = g_JSChartResource.Index.MarketAttentionApiUrl;
  11564. this.Create = function (hqChart, windowIndex) {
  11565. for (var i in this.Index) {
  11566. var paint = new ChartBar(); //柱子
  11567. paint.Canvas = hqChart.Canvas;
  11568. paint.Name = this.Name + "-" + i.toString();
  11569. paint.ChartBorder = hqChart.Frame.SubFrame[windowIndex].Frame.ChartBorder;
  11570. paint.ChartFrame = hqChart.Frame.SubFrame[windowIndex].Frame;
  11571. paint.UpBarColor = paint.DownBarColor = 'rgb(243,152,0)';
  11572. hqChart.ChartPaint.push(paint);
  11573. }
  11574. }
  11575. //调整框架
  11576. this.SetFrame = function (hqChart, windowIndex, hisData) {
  11577. hqChart.Frame.SubFrame[windowIndex].Frame.YSpecificMaxMin = { Max: 6, Min: 0, Count: 3 };
  11578. }
  11579. //请求数据
  11580. this.RequestData = function (hqChart, windowIndex, hisData) {
  11581. var self = this;
  11582. var param =
  11583. {
  11584. HQChart: hqChart,
  11585. WindowIndex: windowIndex,
  11586. HistoryData: hisData
  11587. };
  11588. this.Data = [];
  11589. if (param.HQChart.Period > 0) //周期数据
  11590. {
  11591. this.NotSupport(param.HQChart, param.WindowIndex, "不支持周期切换");
  11592. param.HQChart.Draw();
  11593. return false;
  11594. }
  11595. //请求数据
  11596. wx.request({
  11597. url: this.ApiUrl,
  11598. data:
  11599. {
  11600. "symbol": param.HQChart.Symbol,
  11601. "startdate": 20100101,
  11602. },
  11603. method: 'POST',
  11604. dataType: "json",
  11605. success: function (recvData) {
  11606. self.RecvData(recvData.data, param);
  11607. }
  11608. });
  11609. return true;
  11610. }
  11611. this.RecvData = function (recvData, param) {
  11612. if (recvData.date.length < 0) return;
  11613. var aryData = new Array();
  11614. for (var i in recvData.date) {
  11615. var indexData = new SingleData();
  11616. indexData.Date = recvData.date[i];
  11617. indexData.Value = recvData.value[i];
  11618. aryData.push(indexData);
  11619. }
  11620. var aryFittingData = param.HistoryData.GetFittingData(aryData);
  11621. var bindData = new ChartData();
  11622. bindData.Data = aryFittingData;
  11623. bindData.Period = param.HQChart.Period; //周期
  11624. bindData.Right = param.HQChart.Right; //复权
  11625. this.Data = bindData.GetValue();
  11626. this.BindData(param.HQChart, param.WindowIndex, param.HistoryData);
  11627. this.SetFrame(param.HQChart, param.WindowIndex, param.HistoryData);
  11628. param.HQChart.UpdataDataoffset(); //更新数据偏移
  11629. param.HQChart.UpdateFrameMaxMin(); //调整坐标最大 最小值
  11630. param.HQChart.Draw();
  11631. // if (typeof (this.UpdateUICallback) == 'function') this.UpdateUICallback('RecvHistoryData', this);
  11632. }
  11633. this.BindData = function (hqChart, windowIndex, hisData) {
  11634. var paint = hqChart.GetChartPaint(windowIndex);
  11635. if (paint.length != this.Index.length) return false;
  11636. //paint[0].Data.Data=SWLData;
  11637. paint[0].Data.Data = this.Data;
  11638. paint[0].NotSupportMessage = null;
  11639. var titleIndex = windowIndex + 1;
  11640. for (var i in paint) {
  11641. hqChart.TitlePaint[titleIndex].Data[i] = new DynamicTitleData(paint[i].Data, this.Index[i].Name, this.TitleColor);
  11642. hqChart.TitlePaint[titleIndex].Data[i].StringFormat = STRING_FORMAT_TYPE.THOUSANDS;
  11643. hqChart.TitlePaint[titleIndex].Data[i].FloatPrecision = 0;
  11644. }
  11645. hqChart.TitlePaint[titleIndex].Title = this.FormatIndexTitle();
  11646. return true;
  11647. }
  11648. }
  11649. /*
  11650. 行业,指数热度
  11651. */
  11652. function MarketHeatIndex() {
  11653. this.newMethod = BaseIndex; //派生
  11654. this.newMethod('指数/行业热度');
  11655. delete this.newMethod;
  11656. this.Index = new Array(
  11657. new IndexInfo("热度指数", 5),
  11658. new IndexInfo('MA', 10),
  11659. new IndexInfo('MA', null)
  11660. );
  11661. this.Data; //关注度数据
  11662. this.ApiUrl = g_JSChartResource.Index.MarketHeatApiUrl;
  11663. this.Index[0].LineColor = g_JSChartResource.FrameSplitTextColor;
  11664. this.Index[1].LineColor = g_JSChartResource.Index.LineColor[0];
  11665. this.Index[2].LineColor = g_JSChartResource.Index.LineColor[1];
  11666. this.Create = function (hqChart, windowIndex) {
  11667. for (var i in this.Index) {
  11668. var paint = null;
  11669. if (i == 0) {
  11670. paint = new ChartMACD(); //柱子
  11671. }
  11672. else {
  11673. paint = new ChartLine();
  11674. paint.Color = this.Index[i].LineColor;
  11675. }
  11676. paint.Canvas = hqChart.Canvas;
  11677. paint.Name = this.Name + "-" + i.toString();
  11678. paint.ChartBorder = hqChart.Frame.SubFrame[windowIndex].Frame.ChartBorder;
  11679. paint.ChartFrame = hqChart.Frame.SubFrame[windowIndex].Frame;
  11680. hqChart.ChartPaint.push(paint);
  11681. }
  11682. }
  11683. //请求数据
  11684. this.RequestData = function (hqChart, windowIndex, hisData) {
  11685. var self = this;
  11686. var param =
  11687. {
  11688. HQChart: hqChart,
  11689. WindowIndex: windowIndex,
  11690. HistoryData: hisData
  11691. };
  11692. this.Data = [];
  11693. if (param.HQChart.Period > 0) //周期数据
  11694. {
  11695. this.NotSupport(param.HQChart, param.WindowIndex, "不支持周期切换");
  11696. param.HQChart.Draw();
  11697. return false;
  11698. }
  11699. //请求数据
  11700. wx.request({
  11701. url: this.ApiUrl,
  11702. data:
  11703. {
  11704. "symbol": param.HQChart.Symbol,
  11705. "startdate": 20100101,
  11706. },
  11707. method: 'POST',
  11708. dataType: "json",
  11709. success: function (recvData) {
  11710. self.RecvData(recvData.data, param);
  11711. }
  11712. });
  11713. return true;
  11714. }
  11715. this.RecvData = function (recvData, param) {
  11716. if (recvData.date.length < 0) return;
  11717. var aryData = new Array();
  11718. for (var i in recvData.date) {
  11719. var indexData = new SingleData();
  11720. indexData.Date = recvData.date[i];
  11721. indexData.Value = recvData.value[i];
  11722. aryData.push(indexData);
  11723. }
  11724. var aryFittingData = param.HistoryData.GetFittingData(aryData);
  11725. var bindData = new ChartData();
  11726. bindData.Data = aryFittingData;
  11727. bindData.Period = param.HQChart.Period; //周期
  11728. bindData.Right = param.HQChart.Right; //复权
  11729. this.Data = bindData.GetValue();
  11730. this.BindData(param.HQChart, param.WindowIndex, param.HistoryData);
  11731. param.HQChart.UpdataDataoffset(); //更新数据偏移
  11732. param.HQChart.UpdateFrameMaxMin(); //调整坐标最大 最小值
  11733. param.HQChart.Draw();
  11734. }
  11735. this.BindData = function (hqChart, windowIndex, hisData) {
  11736. var paint = hqChart.GetChartPaint(windowIndex);
  11737. if (paint.length != this.Index.length) return false;
  11738. paint[0].Data.Data = this.Data;
  11739. paint[0].NotSupportMessage = null;
  11740. var MA = HQIndexFormula.MA(this.Data, this.Index[0].Param);
  11741. paint[1].Data.Data = MA;
  11742. var MA2 = HQIndexFormula.MA(this.Data, this.Index[1].Param);
  11743. paint[2].Data.Data = MA2;
  11744. var titleIndex = windowIndex + 1;
  11745. for (var i in paint) {
  11746. var name = ""; //显示的名字特殊处理
  11747. if (i == 0)
  11748. name = hqChart.Name + this.Index[i].Name;
  11749. else
  11750. name = "MA" + this.Index[i - 1].Param;
  11751. hqChart.TitlePaint[titleIndex].Data[i] = new DynamicTitleData(paint[i].Data, name, this.Index[i].LineColor);
  11752. hqChart.TitlePaint[titleIndex].Data[i].StringFormat = STRING_FORMAT_TYPE.DEFAULT;
  11753. hqChart.TitlePaint[titleIndex].Data[i].FloatPrecision = 2;
  11754. }
  11755. hqChart.TitlePaint[titleIndex].Title = this.FormatIndexTitle();
  11756. return true;
  11757. }
  11758. }
  11759. //自定义指数热度
  11760. function CustonIndexHeatIndex() {
  11761. this.newMethod = BaseIndex; //派生
  11762. this.newMethod('Market-Heat');
  11763. delete this.newMethod;
  11764. this.Index = new Array(
  11765. new IndexInfo('区域', 3),
  11766. new IndexInfo("热度指数", 10),
  11767. new IndexInfo('MA', 5),
  11768. new IndexInfo('MA', 10)
  11769. );
  11770. this.Data; //热度数据
  11771. this.ApiUrl = g_JSChartResource.Index.CustomIndexHeatApiUrl;
  11772. this.Index[1].LineColor = g_JSChartResource.Index.LineColor[1];
  11773. this.Index[2].LineColor = g_JSChartResource.Index.LineColor[2];
  11774. this.Index[3].LineColor = g_JSChartResource.Index.LineColor[3];
  11775. this.Create = function (hqChart, windowIndex) {
  11776. for (var i in this.Index) {
  11777. var paint = null;
  11778. if (i == 0) {
  11779. paint = new ChartStraightArea();
  11780. }
  11781. else {
  11782. paint = new ChartLine();
  11783. paint.Color = this.Index[i].LineColor;
  11784. }
  11785. paint.Canvas = hqChart.Canvas;
  11786. paint.Name = this.Name + "-" + i.toString();
  11787. paint.ChartBorder = hqChart.Frame.SubFrame[windowIndex].Frame.ChartBorder;
  11788. paint.ChartFrame = hqChart.Frame.SubFrame[windowIndex].Frame;
  11789. hqChart.ChartPaint.push(paint);
  11790. }
  11791. }
  11792. //请求数据
  11793. this.RequestData = function (hqChart, windowIndex, hisData) {
  11794. var self = this;
  11795. var param =
  11796. {
  11797. HQChart: hqChart,
  11798. WindowIndex: windowIndex,
  11799. HistoryData: hisData
  11800. };
  11801. this.Data = [];
  11802. if (param.HQChart.Period > 0) //周期数据
  11803. {
  11804. this.NotSupport(param.HQChart, param.WindowIndex, "不支持周期切换");
  11805. param.HQChart.Draw();
  11806. return false;
  11807. }
  11808. //请求数据
  11809. wx.request({
  11810. url: this.ApiUrl,
  11811. data:
  11812. {
  11813. "stock": param.HQChart.CustomStock,
  11814. "date": { "startdate": param.HQChart.QueryDate.Start, "enddate": param.HQChart.QueryDate.End },
  11815. "day": [this.Index[0].Param, this.Index[1].Param],
  11816. },
  11817. method: 'POST',
  11818. dataType: "json",
  11819. success: function (recvData) {
  11820. self.RecvData(recvData, param);
  11821. }
  11822. });
  11823. return true;
  11824. }
  11825. this.RecvData = function (recvData, param) {
  11826. let data = recvData.data;
  11827. if (data.data == null || data.data.length < 0) return;
  11828. //JSConsole.Chart.Log(recvData.data);
  11829. let aryData = new Array();
  11830. for (let i in data.data) {
  11831. let item = data.data[i];
  11832. let indexData = new SingleData();
  11833. indexData.Date = item[0];
  11834. indexData.Value = item[1];
  11835. aryData.push(indexData);
  11836. }
  11837. var aryFittingData = param.HistoryData.GetFittingData(aryData);
  11838. var bindData = new ChartData();
  11839. bindData.Data = aryFittingData;
  11840. bindData.Period = param.HQChart.Period; //周期
  11841. bindData.Right = param.HQChart.Right; //复权
  11842. this.Data = bindData.GetValue();
  11843. this.BindData(param.HQChart, param.WindowIndex, param.HistoryData);
  11844. param.HQChart.UpdataDataoffset(); //更新数据偏移
  11845. param.HQChart.UpdateFrameMaxMin(); //调整坐标最大 最小值
  11846. param.HQChart.Draw();
  11847. }
  11848. this.BindData = function (hqChart, windowIndex, hisData) {
  11849. let paint = hqChart.GetChartPaint(windowIndex);
  11850. if (paint.length != this.Index.length) return false;
  11851. paint[0].NotSupportMessage = null;
  11852. paint[0].Data.Data =
  11853. [
  11854. { Value: 0, Value2: 0.2, Color: 'rgb(46,139,87)', Title: '较差区', TitleColor: 'rgb(245,255 ,250)' },
  11855. { Value: 0.19, Value2: 0.4, Color: 'rgb(255,140,0)', Title: '变热区', TitleColor: 'rgb(245,255 ,250)' },
  11856. { Value: 0.39, Value2: 0.8, Color: 'rgb(255,106,106)', Title: '较好区', TitleColor: 'rgb(245,255 ,250)' },
  11857. { Value: 0.79, Value2: 1, Color: 'rgb(255,69,0)', Title: '过热区', TitleColor: 'rgb(245,255 ,250)' }
  11858. ];
  11859. paint[1].Data.Data = this.Data;
  11860. let MA = HQIndexFormula.MA(this.Data, this.Index[2].Param);
  11861. paint[2].Data.Data = MA;
  11862. let MA2 = HQIndexFormula.MA(this.Data, this.Index[3].Param);
  11863. paint[3].Data.Data = MA2;
  11864. //指定框架最大最小[0,1]
  11865. hqChart.Frame.SubFrame[windowIndex].Frame.YSpecificMaxMin = { Max: 1, Min: 0, Count: 3 };
  11866. let titleIndex = windowIndex + 1;
  11867. for (let i = 1; i < paint.length; ++i) {
  11868. let name = this.Index[i].Name; //显示的名字特殊处理
  11869. if (name == 'MA') name = "MA" + this.Index[i].Param;
  11870. hqChart.TitlePaint[titleIndex].Data[i] = new DynamicTitleData(paint[i].Data, name, this.Index[i].LineColor);
  11871. hqChart.TitlePaint[titleIndex].Data[i].StringFormat = STRING_FORMAT_TYPE.DEFAULT;
  11872. hqChart.TitlePaint[titleIndex].Data[i].FloatPrecision = 2;
  11873. }
  11874. hqChart.TitlePaint[titleIndex].Title = '热度' + '(' + this.Index[0].Param + ',' + this.Index[1].Param + ',' + this.Index[2].Param + ',' + this.Index[3].Param + ')';
  11875. return true;
  11876. }
  11877. }
  11878. /*
  11879. 本福特系数(财务粉饰)
  11880. */
  11881. function BenfordIndex() {
  11882. this.newMethod = BaseIndex; //派生
  11883. this.newMethod('财务风险');
  11884. delete this.newMethod;
  11885. this.Index = new Array(
  11886. new IndexInfo('区域', null),
  11887. new IndexInfo("系数", null),
  11888. );
  11889. this.Data; //财务数据
  11890. this.ApiUrl = g_JSChartResource.Index.StockHistoryDayApiUrl;
  11891. this.Index[0].LineColor = g_JSChartResource.Index.LineColor[0];
  11892. this.Index[1].LineColor = 'rgb(105,105,105)';
  11893. this.Create = function (hqChart, windowIndex) {
  11894. for (var i in this.Index) {
  11895. var paint = null;
  11896. if (i == 0)
  11897. paint = new ChartStraightArea();
  11898. else if (i == 1)
  11899. paint = new ChartLineMultiData();
  11900. if (paint) {
  11901. paint.Color = this.Index[i].LineColor;
  11902. paint.Canvas = hqChart.Canvas;
  11903. paint.Name = this.Name + "-" + i.toString();
  11904. paint.ChartBorder = hqChart.Frame.SubFrame[windowIndex].Frame.ChartBorder;
  11905. paint.ChartFrame = hqChart.Frame.SubFrame[windowIndex].Frame;
  11906. hqChart.ChartPaint.push(paint);
  11907. }
  11908. }
  11909. }
  11910. //请求数据
  11911. this.RequestData = function (hqChart, windowIndex, hisData) {
  11912. var self = this;
  11913. var param =
  11914. {
  11915. HQChart: hqChart,
  11916. WindowIndex: windowIndex,
  11917. HistoryData: hisData
  11918. };
  11919. this.Data = [];
  11920. if (param.HQChart.Period != 2) //周期数据
  11921. {
  11922. this.NotSupport(param.HQChart, param.WindowIndex, "只支持月线");
  11923. param.HQChart.Draw();
  11924. return false;
  11925. }
  11926. var aryField = ["finance.benford", "announcement2.quarter", "announcement1.quarter", "announcement3.quarter", "announcement4.quarter"];
  11927. var aryCondition =
  11928. [
  11929. { item: ["date", "int32", "gte", "20130101"] },
  11930. {
  11931. item: ["announcement1.year", "int32", "gte", 0,
  11932. "announcement2.year", "int32", "gte", 0,
  11933. "announcement3.year", "int32", "gte", 0,
  11934. "announcement4.year", "int32", "gte", 0,
  11935. "or"]
  11936. }
  11937. ];
  11938. //请求数据
  11939. wx.request({
  11940. url: this.ApiUrl,
  11941. data:
  11942. {
  11943. "symbol": [param.HQChart.Symbol],
  11944. "field": aryField,
  11945. "condition": aryCondition
  11946. },
  11947. method: 'POST',
  11948. dataType: "json",
  11949. success: function (recvData) {
  11950. self.RecvData(recvData, param);
  11951. }
  11952. });
  11953. return true;
  11954. }
  11955. this.JsonDataToMapSingleData = function (recvData) {
  11956. var stockData = recvData.stock[0].stockday;
  11957. var mapData = new Map();
  11958. for (var i in stockData) {
  11959. var item = stockData[i];
  11960. var indexData = new SingleData();
  11961. indexData.Date = item.date;
  11962. indexData.Value = new Array();
  11963. if (item.finance1 != null && item.announcement1 != null) {
  11964. let year = item.announcement1.year;
  11965. let quarter = item.announcement1.quarter;
  11966. let value = item.finance1.benford;
  11967. indexData.Value.push({ Year: year, Quarter: quarter, Value: value });
  11968. }
  11969. if (item.finance2 != null && item.announcement2 != null) {
  11970. let year = item.announcement2.year;
  11971. let quarter = item.announcement2.quarter;
  11972. let value = item.finance2.benford;
  11973. indexData.Value.push({ Year: year, Quarter: quarter, Value: value });
  11974. }
  11975. if (item.finance3 != null && item.announcement3 != null) {
  11976. let year = item.announcement3.year;
  11977. let quarter = item.announcement3.quarter;
  11978. let value = item.finance3.benford;
  11979. indexData.Value.push({ Year: year, Quarter: quarter, Value: value });
  11980. }
  11981. if (item.finance4 != null && item.announcement4 != null) {
  11982. let year = item.announcement4.year;
  11983. let quarter = item.announcement4.quarter;
  11984. let value = item.finance4.benford;
  11985. indexData.Value.push({ Year: year, Quarter: quarter, Value: value });
  11986. }
  11987. mapData.set(indexData.Date, indexData);
  11988. }
  11989. var aryData = new Array();
  11990. for (var item of mapData) {
  11991. aryData.push(item[1]);
  11992. }
  11993. return aryData;
  11994. }
  11995. this.RecvData = function (recvData, param) {
  11996. JSConsole.Chart.Log(recvData);
  11997. if (recvData.data.stock == null || recvData.data.stock.length <= 0) return;
  11998. var aryData = this.JsonDataToMapSingleData(recvData.data);
  11999. var aryFittingData = param.HistoryData.GetFittingMonthData(aryData);
  12000. var bindData = new ChartData();
  12001. bindData.Data = aryFittingData;
  12002. bindData.Period = param.HQChart.Period; //周期
  12003. bindData.Right = param.HQChart.Right; //复权
  12004. this.Data = bindData.GetValue();
  12005. this.BindData(param.HQChart, param.WindowIndex, param.HistoryData);
  12006. param.HQChart.UpdataDataoffset(); //更新数据偏移
  12007. param.HQChart.UpdateFrameMaxMin(); //调整坐标最大 最小值
  12008. param.HQChart.Draw();
  12009. }
  12010. this.BindData = function (hqChart, windowIndex, hisData) {
  12011. var paint = hqChart.GetChartPaint(windowIndex);
  12012. if (paint.length != this.Index.length) return false;
  12013. paint[0].NotSupportMessage = null;
  12014. paint[0].Data.Data =
  12015. [
  12016. // { Value: 0, Value2: 0.2, Color: 'rgb(50,205,50)', Title: '安全区', TitleColor: 'rgb(245,255 ,250)' },
  12017. // { Value: 0.2, Value2: 0.4, Color: 'rgb(255,140,0)', Title: '预警区', TitleColor: 'rgb(245,255 ,250)' },
  12018. // { Value: 0.4, Value2: 1, Color: 'rgb(255,106,106)', Title: '警示区', TitleColor: 'rgb(245,255 ,250)' }
  12019. { Value: 0, Value2: 0.2, Color: 'rgb(219,255,193)', Title: '安全区', TitleColor: 'rgb(66,192,99)' },
  12020. { Value: 0.2, Value2: 0.4, Color: 'rgb(255,228,170)', Title: '预警区', TitleColor: 'rgb(255,124,3)' },
  12021. { Value: 0.4, Value2: 1, Color: 'rgb(254,219,212)', Title: '警示区', TitleColor: 'rgb(255,0,0)' }
  12022. ];
  12023. paint[1].Data.Data = this.Data;
  12024. //指定框架最大最小[0,1]
  12025. hqChart.Frame.SubFrame[windowIndex].Frame.YSpecificMaxMin = { Max: 1, Min: 0, Count: 3 };
  12026. hqChart.Frame.SubFrame[windowIndex].Frame.YSplitScale = [0.2,0.4];
  12027. var titleIndex = windowIndex + 1;
  12028. hqChart.TitlePaint[titleIndex].Data[1] = new DynamicTitleData(paint[1].Data, this.Index[1].Name, this.Index[1].LineColor);
  12029. hqChart.TitlePaint[titleIndex].Data[1].DataType = "MultiReport";
  12030. hqChart.TitlePaint[titleIndex].Title = this.FormatIndexTitle();
  12031. return true;
  12032. }
  12033. }
  12034. //是否是指数代码
  12035. function IsIndexSymbol(symbol) {
  12036. var upperSymbol = symbol.toUpperCase();
  12037. if (upperSymbol.indexOf('.SH') > 0) {
  12038. upperSymbol = upperSymbol.replace('.SH', '');
  12039. if (upperSymbol.charAt(0) == '0' && parseInt(upperSymbol) <= 3000) return true;
  12040. }
  12041. else if (upperSymbol.indexOf('.SZ') > 0) {
  12042. upperSymbol = upperSymbol.replace('.SZ', '');
  12043. if (upperSymbol.charAt(0) == '3' && upperSymbol.charAt(1) == '9') return true;
  12044. }
  12045. else if (upperSymbol.indexOf('.CI') > 0) //自定义指数
  12046. {
  12047. return true;
  12048. }
  12049. return false;
  12050. }
  12051. //导出统一使用JSCommon命名空间名
  12052. module.exports =
  12053. {
  12054. JSCommon:
  12055. {
  12056. JSCanvasElement: JSCanvasElement,
  12057. JSChart: JSChart,
  12058. Guid: Guid,
  12059. IFrameSplitOperator: IFrameSplitOperator,
  12060. ChartData: ChartData,
  12061. DataPlus: DataPlus,
  12062. KLineTooltipPaint: KLineTooltipPaint,
  12063. MARKET_SUFFIX_NAME: MARKET_SUFFIX_NAME,
  12064. JSCommonCoordinateData:JSCommonCoordinateData,
  12065. FrameSplitKLineX:FrameSplitKLineX,
  12066. FrameSplitKLinePriceY:FrameSplitKLinePriceY,
  12067. JSCHART_EVENT_ID:JSCHART_EVENT_ID
  12068. },
  12069. };