umychart.chartpaint.wechat.js 219 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167
  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
  10. {
  11. JSCommon_ChartData as ChartData, JSCommon_HistoryData as HistoryData,
  12. JSCommon_SingleData as SingleData, JSCommon_MinuteData as MinuteData,
  13. JSCommon_Rect as Rect,
  14. } from "./umychart.data.wechat.js";
  15. import
  16. {
  17. JSCommonResource_Global_JSChartResource as g_JSChartResource,
  18. } from './umychart.resource.wechat.js'
  19. import
  20. {
  21. JSCommonSplit_IFrameSplitOperator as IFrameSplitOperator,
  22. } from './umychart.framesplit.wechat.js'
  23. import
  24. {
  25. JSCommonCoordinateData as JSCommonCoordinateData,
  26. JSCommonCoordinateData_MARKET_SUFFIX_NAME as MARKET_SUFFIX_NAME
  27. } from "./umychart.coordinatedata.wechat.js";
  28. //配色
  29. function JSChartPaintResource()
  30. {
  31. //指标不支持信息
  32. this.Index=
  33. {
  34. NotSupport : { Font: "12px 微软雅黑", TextColor: "rgb(52,52,52)" }
  35. }
  36. }
  37. var g_JSChartPaintResource = new JSChartPaintResource();
  38. //图新画法接口类
  39. function IChartPainting()
  40. {
  41. this.Canvas; //画布
  42. this.ChartBorder; //边框信息
  43. this.ChartFrame; //框架画法
  44. this.Name; //名称
  45. this.ClassName = 'IChartPainting'; //类名
  46. this.Data = new ChartData(); //数据区
  47. this.NotSupportMessage = null;
  48. this.MessageFont = g_JSChartPaintResource.Index.NotSupport.Font;
  49. this.MessageColor = g_JSChartPaintResource.Index.NotSupport.TextColor;
  50. this.IsDrawFirst = false; //是否比K线先画
  51. this.IsShow = true; //是否显示
  52. this.Draw = function () { }
  53. this.IsMinuteFrame=function()
  54. {
  55. var isMinute=(this.ChartFrame.ClassName=="MinuteFrame" || this.ChartFrame.ClassName=="MinuteHScreenFrame");
  56. return isMinute
  57. }
  58. this.DrawNotSupportmessage = function ()
  59. {
  60. this.Canvas.font = this.MessageFont;
  61. this.Canvas.setFillStyle(this.MessageColor);
  62. var left = this.ChartBorder.GetLeft();
  63. var width = this.ChartBorder.GetWidth();
  64. var top = this.ChartBorder.GetTopEx();
  65. var height = this.ChartBorder.GetHeightEx();
  66. var x = left + width / 2;
  67. var y = top + height / 2;
  68. this.Canvas.textAlign = "center";
  69. this.Canvas.textBaseline = "middle";
  70. this.Canvas.fillText(this.NotSupportMessage, x, y);
  71. }
  72. this.GetTooltipData = function (x, y, tooltip)
  73. {
  74. return false;
  75. }
  76. this.GetMaxMin = function ()
  77. {
  78. var xPointCount = this.ChartFrame.XPointCount;
  79. var range = {};
  80. range.Min = null;
  81. range.Max = null;
  82. if (!this.Data || !this.Data.Data) return range;
  83. for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j)
  84. {
  85. var value = this.Data.Data[i];
  86. if (value == null || isNaN(value)) continue;
  87. if (range.Max == null) range.Max = value;
  88. if (range.Min == null) range.Min = value;
  89. if (range.Max < value) range.Max = value;
  90. if (range.Min > value) range.Min = value;
  91. }
  92. return range;
  93. }
  94. this.GetDynamicFont = function (dataWidth) //根据宽度自动获取对应字体
  95. {
  96. var font;
  97. if (dataWidth < 5) font = '4px Arial'; //字体根据数据宽度动态调整
  98. else if (dataWidth < 7) font = '6px Arial';
  99. else if (dataWidth < 9) font = '8px Arial';
  100. else if (dataWidth < 11) font = '10px Arial';
  101. else if (dataWidth < 13) font = '12px Arial';
  102. else if (dataWidth < 15) font = '14px Arial';
  103. else font = '16px Arial';
  104. console.log(dataWidth);
  105. return font;
  106. }
  107. this.GetDynamicFontEx=function(dataWidth, distanceWidth, maxSize, minSize, zoom, fontname) //根据宽度自动获取对应字体
  108. {
  109. if (maxSize==minSize)
  110. {
  111. var font=`${maxSize.toFixed(0)}px ${fontname}` ;
  112. return font;
  113. }
  114. var fontSize=(dataWidth+distanceWidth);
  115. if (zoom)
  116. {
  117. if (zoom.Type==0)
  118. {
  119. if (zoom.Value>0) fontSize=(dataWidth*zoom.Value);
  120. }
  121. else if (zoom.Type==1)
  122. {
  123. if (zoom.Value>0) fontSize=(dataWidth+distanceWidth)*zoom.Value;
  124. }
  125. else if (zoom.Type==2)
  126. {
  127. if (IFrameSplitOperator.IsNumber(zoom.Value))
  128. fontSize=(dataWidth+distanceWidth) + (2*zoom.Value);
  129. }
  130. }
  131. if (fontSize<minSize) fontSize=minSize;
  132. else if (fontSize>maxSize) fontSize=maxSize;
  133. var font=`${fontSize.toFixed(0)}px ${fontname}` ;
  134. return font;
  135. }
  136. this.SetFillStyle = function (color, x0, y0, x1, y1)
  137. {
  138. if (Array.isArray(color))
  139. {
  140. let gradient = this.Canvas.createLinearGradient(x0, y0, x1, y1);
  141. var offset = 1 / (color.length);
  142. for (var i in color)
  143. {
  144. gradient.addColorStop(i * offset, color[i]);
  145. }
  146. this.Canvas.setFillStyle(gradient);
  147. }
  148. else
  149. {
  150. this.Canvas.setFillStyle(color);
  151. }
  152. }
  153. }
  154. //K线画法
  155. function ChartKLine()
  156. {
  157. this.newMethod = IChartPainting; //派生
  158. this.newMethod();
  159. delete this.newMethod;
  160. this.ClassName = 'ChartKLine';
  161. this.Symbol; //股票代码
  162. this.DrawType = 0; // 0=K线 1=收盘价线 2=美国线 3=空心K线柱子 4=收盘价面积
  163. this.CloseLineColor = g_JSChartResource.CloseLineColor;
  164. this.CloseLineAreaColor = g_JSChartResource.CloseLineAreaColor;
  165. this.UpColor = g_JSChartResource.UpBarColor;
  166. this.DownColor = g_JSChartResource.DownBarColor;
  167. this.UnchagneColor = g_JSChartResource.UnchagneBarColor; //平盘
  168. this.ColorData; //五彩K线颜色 >0 UpColor 其他 DownColor
  169. this.TradeData; //交易系统 包含买卖数据{Buy:, Sell:}
  170. this.IsShowMaxMinPrice = true; //是否显示最大最小值
  171. this.TextFont = g_JSChartResource.KLine.MaxMin.Font;
  172. this.TextColor = g_JSChartResource.KLine.MaxMin.Color;
  173. this.InfoPointColor = g_JSChartResource.KLine.Info.Color;
  174. this.InfoPointColor2 = g_JSChartResource.KLine.Info.Color2;
  175. this.InfoDrawType = 0; //0=在底部画远点 1=在最低价画三角
  176. this.PtMax; //最大值的位置
  177. this.PtMin; //最小值的位置
  178. this.MinBarWidth=g_JSChartResource.MinKLineBarWidth; //最小的柱子宽度
  179. this.DrawAKLine = function () //美国线
  180. {
  181. var isHScreen = (this.ChartFrame.IsHScreen === true);
  182. var dataWidth = this.ChartFrame.DataWidth;
  183. var distanceWidth = this.ChartFrame.DistanceWidth;
  184. var xOffset = this.ChartBorder.GetLeft() + distanceWidth / 2.0 + g_JSChartResource.FrameLeftMargin;
  185. if (isHScreen) xOffset = this.ChartBorder.GetTop() + distanceWidth / 2.0 + g_JSChartResource.FrameLeftMargin;
  186. var chartright = this.ChartBorder.GetRight();
  187. if (isHScreen) chartright = this.ChartBorder.GetBottom();
  188. var xPointCount = this.ChartFrame.XPointCount;
  189. var ptMax = { X: null, Y: null, Value: null, Align: 'left' };
  190. var ptMin = { X: null, Y: null, Value: null, Align: 'left' };
  191. for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j, xOffset += (dataWidth + distanceWidth))
  192. {
  193. var data = this.Data.Data[i];
  194. if (data.Open == null || data.High == null || data.Low == null || data.Close == null) continue;
  195. var left = xOffset;
  196. var right = xOffset + dataWidth;
  197. if (right > chartright) break;
  198. var x = left + (right - left) / 2;
  199. var yLow = this.ChartFrame.GetYFromData(data.Low);
  200. var yHigh = this.ChartFrame.GetYFromData(data.High);
  201. var yOpen = this.ChartFrame.GetYFromData(data.Open);
  202. var yClose = this.ChartFrame.GetYFromData(data.Close);
  203. if (ptMax.Value == null || ptMax.Value < data.High) //求最大值
  204. {
  205. ptMax.X = x;
  206. ptMax.Y = yHigh;
  207. ptMax.Value = data.High;
  208. ptMax.Align = j < xPointCount / 2 ? 'left' : 'right';
  209. }
  210. if (ptMin.Value == null || ptMin.Value > data.Low) //求最小值
  211. {
  212. ptMin.X = x;
  213. ptMin.Y = yLow;
  214. ptMin.Value = data.Low;
  215. ptMin.Align = j < xPointCount / 2 ? 'left' : 'right';
  216. }
  217. if (data.Open < data.Close) this.Canvas.setStrokeStyle(this.UpColor); //阳线
  218. else if (data.Open > data.Close) this.Canvas.setStrokeStyle(this.DownColor); //阳线
  219. else this.Canvas.setStrokeStyle(this.UnchagneColor); //平线
  220. this.Canvas.beginPath(); //最高-最低
  221. if (isHScreen) {
  222. this.Canvas.moveTo(yHigh, ToFixedPoint(x));
  223. this.Canvas.lineTo(yLow, ToFixedPoint(x));
  224. }
  225. else {
  226. this.Canvas.moveTo(ToFixedPoint(x), yHigh);
  227. this.Canvas.lineTo(ToFixedPoint(x), yLow);
  228. }
  229. this.Canvas.stroke();
  230. if (dataWidth >= this.MinBarWidth) {
  231. this.Canvas.beginPath(); //开盘
  232. if (isHScreen) {
  233. this.Canvas.moveTo(ToFixedPoint(yOpen), left);
  234. this.Canvas.lineTo(ToFixedPoint(yOpen), x);
  235. }
  236. else {
  237. this.Canvas.moveTo(left, ToFixedPoint(yOpen));
  238. this.Canvas.lineTo(x, ToFixedPoint(yOpen));
  239. }
  240. this.Canvas.stroke();
  241. this.Canvas.beginPath(); //收盘
  242. if (isHScreen) {
  243. this.Canvas.moveTo(ToFixedPoint(yClose), right);
  244. this.Canvas.lineTo(ToFixedPoint(yClose), x);
  245. }
  246. else {
  247. this.Canvas.moveTo(right, ToFixedPoint(yClose));
  248. this.Canvas.lineTo(x, ToFixedPoint(yClose));
  249. }
  250. this.Canvas.stroke();
  251. }
  252. if (this.Data.DataType == 0 && ChartData.IsDayPeriod(this.Data.Period,true)) //信息地雷
  253. {
  254. var infoItem = { X: x, Xleft: left, XRight: right, YMax: yHigh, YMin: yLow, DayData: data, Index: j };
  255. this.DrawInfoDiv(infoItem);
  256. }
  257. }
  258. this.PtMax = ptMax;
  259. this.PtMin = ptMin;
  260. }
  261. this.DrawCloseLine = function () //收盘价线
  262. {
  263. var isHScreen = (this.ChartFrame.IsHScreen === true);
  264. var dataWidth = this.ChartFrame.DataWidth;
  265. var distanceWidth = this.ChartFrame.DistanceWidth;
  266. var xOffset = this.ChartBorder.GetLeft() + distanceWidth / 2.0 + 2.0;
  267. if (isHScreen) xOffset = this.ChartBorder.GetTop() + distanceWidth / 2.0 + 2.0;
  268. var chartright = this.ChartBorder.GetRight();
  269. if (isHScreen) chartright = this.ChartBorder.GetBottom();
  270. var xPointCount = this.ChartFrame.XPointCount;
  271. var bFirstPoint = true;
  272. this.Canvas.beginPath();
  273. this.Canvas.setStrokeStyle(this.CloseLineColor);
  274. for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j, xOffset += (dataWidth + distanceWidth)) {
  275. var data = this.Data.Data[i];
  276. if (data.Open == null || data.High == null || data.Low == null || data.Close == null) continue;
  277. var left = xOffset;
  278. var right = xOffset + dataWidth;
  279. if (right > chartright) break;
  280. var x = left + (right - left) / 2;
  281. var yClose = this.ChartFrame.GetYFromData(data.Close);
  282. if (bFirstPoint) {
  283. if (isHScreen) this.Canvas.moveTo(yClose, x);
  284. else this.Canvas.moveTo(x, yClose);
  285. bFirstPoint = false;
  286. }
  287. else {
  288. if (isHScreen) this.Canvas.lineTo(yClose, x);
  289. else this.Canvas.lineTo(x, yClose);
  290. }
  291. }
  292. if (bFirstPoint == false) this.Canvas.stroke();
  293. }
  294. this.DrawCloseArea = function () //收盘价面积
  295. {
  296. var isHScreen = (this.ChartFrame.IsHScreen === true);
  297. var dataWidth = this.ChartFrame.DataWidth;
  298. var distanceWidth = this.ChartFrame.DistanceWidth;
  299. var xOffset = this.ChartBorder.GetLeft() + distanceWidth / 2.0 + 2.0;
  300. if (isHScreen) xOffset = this.ChartBorder.GetTop() + distanceWidth / 2.0 + 2.0;
  301. var chartright = this.ChartBorder.GetRight();
  302. if (isHScreen) chartright = this.ChartBorder.GetBottom();
  303. var xPointCount = this.ChartFrame.XPointCount;
  304. var bFirstPoint = true;
  305. var firstPoint = null;
  306. this.Canvas.beginPath();
  307. this.Canvas.setStrokeStyle(this.CloseLineColor);
  308. for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j, xOffset += (dataWidth + distanceWidth)) {
  309. var data = this.Data.Data[i];
  310. if (data.Open == null || data.High == null || data.Low == null || data.Close == null) continue;
  311. var left = xOffset;
  312. var right = xOffset + dataWidth;
  313. if (right > chartright) break;
  314. var x = left + (right - left) / 2;
  315. var yClose = this.ChartFrame.GetYFromData(data.Close);
  316. if (bFirstPoint) {
  317. if (isHScreen) {
  318. this.Canvas.moveTo(yClose, x);
  319. firstPoint = { X: yClose, Y: x };
  320. }
  321. else {
  322. this.Canvas.moveTo(x, yClose);
  323. firstPoint = { X: x, Y: yClose };
  324. }
  325. bFirstPoint = false;
  326. }
  327. else {
  328. if (isHScreen) this.Canvas.lineTo(yClose, x);
  329. else this.Canvas.lineTo(x, yClose);
  330. }
  331. }
  332. if (bFirstPoint) return;
  333. this.Canvas.stroke();
  334. //画面积
  335. if (isHScreen) {
  336. this.Canvas.lineTo(this.ChartBorder.GetLeft(), x);
  337. this.Canvas.lineTo(this.ChartBorder.GetLeft(), firstPoint.Y);
  338. }
  339. else {
  340. this.Canvas.lineTo(x, this.ChartBorder.GetBottom());
  341. this.Canvas.lineTo(firstPoint.X, this.ChartBorder.GetBottom());
  342. }
  343. this.Canvas.closePath();
  344. if (Array.isArray(this.CloseLineAreaColor)) {
  345. if (isHScreen) {
  346. let gradient = this.Canvas.createLinearGradient(this.ChartBorder.GetRightEx(), this.ChartBorder.GetTop(), this.ChartBorder.GetLeft(), this.ChartBorder.GetTop());
  347. gradient.addColorStop(0, this.CloseLineAreaColor[0]);
  348. gradient.addColorStop(1, this.CloseLineAreaColor[1]);
  349. this.Canvas.setFillStyle(gradient);
  350. }
  351. else {
  352. let gradient = this.Canvas.createLinearGradient(firstPoint.X, this.ChartBorder.GetTopEx(), firstPoint.X, this.ChartBorder.GetBottom());
  353. gradient.addColorStop(0, this.CloseLineAreaColor[0]);
  354. gradient.addColorStop(1, this.CloseLineAreaColor[1]);
  355. this.Canvas.setFillStyle(gradient);
  356. }
  357. }
  358. else {
  359. this.Canvas.setFillStyle(this.CloseLineAreaColor);
  360. }
  361. this.Canvas.fill();
  362. }
  363. this.DrawKBar = function ()
  364. {
  365. var isHScreen = (this.ChartFrame.IsHScreen === true);
  366. var dataWidth = this.ChartFrame.DataWidth;
  367. var distanceWidth = this.ChartFrame.DistanceWidth;
  368. var xOffset = this.ChartBorder.GetLeft() + distanceWidth / 2.0 + 2.0;
  369. var chartright = this.ChartBorder.GetRight();
  370. var xPointCount = this.ChartFrame.XPointCount;
  371. if (isHScreen) {
  372. xOffset = this.ChartBorder.GetTop() + distanceWidth / 2.0 + 2.0;
  373. chartright = this.ChartBorder.GetBottom();
  374. }
  375. var ptMax = { X: null, Y: null, Value: null, Align: 'left' };
  376. var ptMin = { X: null, Y: null, Value: null, Align: 'left' };
  377. var upColor = this.UpColor;
  378. var downColor = this.DownColor;
  379. var unchagneColor = this.UnchagneColor;
  380. for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j, xOffset += (dataWidth + distanceWidth))
  381. {
  382. var data = this.Data.Data[i];
  383. if (data.Open == null || data.High == null || data.Low == null || data.Close == null) continue;
  384. var left = xOffset;
  385. var right = xOffset + dataWidth;
  386. if (right > chartright)
  387. break;
  388. var x = left + (right - left) / 2;
  389. var yLow = this.ChartFrame.GetYFromData(data.Low);
  390. var yHigh = this.ChartFrame.GetYFromData(data.High);
  391. var yOpen = this.ChartFrame.GetYFromData(data.Open);
  392. var yClose = this.ChartFrame.GetYFromData(data.Close);
  393. var y = yHigh;
  394. if (ptMax.Value == null || ptMax.Value < data.High) //求最大值
  395. {
  396. ptMax.X = x;
  397. ptMax.Y = yHigh;
  398. ptMax.Value = data.High;
  399. ptMax.Align = j < xPointCount / 2 ? 'left' : 'right';
  400. }
  401. if (ptMin.Value == null || ptMin.Value > data.Low) //求最小值
  402. {
  403. ptMin.X = x;
  404. ptMin.Y = yLow;
  405. ptMin.Value = data.Low;
  406. ptMin.Align = j < xPointCount / 2 ? 'left' : 'right';
  407. }
  408. if (this.ColorData) ///五彩K线颜色设置
  409. {
  410. if (i < this.ColorData.length)
  411. upColor = downColor = unchagneColor = (this.ColorData[i] > 0 ? this.UpColor : this.DownColor);
  412. else
  413. upColor = downColor = unchagneColor = this.DownColor;
  414. }
  415. if (data.Open < data.Close) //阳线
  416. {
  417. if (dataWidth >= this.MinBarWidth)
  418. {
  419. this.Canvas.setStrokeStyle(upColor);
  420. if (data.High > data.Close) //上影线
  421. {
  422. this.Canvas.beginPath();
  423. if (isHScreen)
  424. {
  425. this.Canvas.moveTo(ToFixedPoint(y), ToFixedPoint(x));
  426. this.Canvas.lineTo(ToFixedPoint(this.DrawType == 3 ? Math.max(yClose, yOpen) : yClose), ToFixedPoint(x));
  427. }
  428. else
  429. {
  430. this.Canvas.moveTo(ToFixedPoint(x), ToFixedPoint(y));
  431. this.Canvas.lineTo(ToFixedPoint(x), ToFixedPoint(this.DrawType == 3 ? Math.min(yClose, yOpen) : yClose));
  432. }
  433. this.Canvas.stroke();
  434. y = yClose;
  435. }
  436. else
  437. {
  438. y = yClose;
  439. }
  440. this.Canvas.setFillStyle(upColor);
  441. if (isHScreen)
  442. {
  443. if (Math.abs(yOpen - y) < 1)
  444. {
  445. this.Canvas.fillRect(ToFixedRect(y), ToFixedRect(left), 1, ToFixedRect(dataWidth)); //高度小于1,统一使用高度1
  446. }
  447. else
  448. {
  449. if (this.DrawType == 3) //空心柱
  450. {
  451. this.Canvas.beginPath();
  452. this.Canvas.rect(ToFixedPoint(y), ToFixedPoint(left), ToFixedRect(yOpen - y), ToFixedRect(dataWidth));
  453. this.Canvas.stroke();
  454. }
  455. else
  456. {
  457. //宽度是负数竟然不会画, h5就可以
  458. //this.Canvas.fillRect(ToFixedRect(y), ToFixedRect(left), ToFixedRect(yOpen - y), ToFixedRect(dataWidth));
  459. this.Canvas.fillRect(ToFixedRect(Math.min(yOpen, y)), ToFixedRect(left), ToFixedRect(Math.abs(yOpen - y)), ToFixedRect(dataWidth));
  460. }
  461. }
  462. }
  463. else
  464. {
  465. if (Math.abs(yOpen - y) < 1)
  466. {
  467. this.Canvas.fillRect(ToFixedRect(left), ToFixedRect(y), ToFixedRect(dataWidth), 1); //高度小于1,统一使用高度1
  468. }
  469. else
  470. {
  471. if (this.DrawType == 3) //空心柱
  472. {
  473. this.Canvas.beginPath();
  474. this.Canvas.rect(ToFixedPoint(left), ToFixedPoint(y), ToFixedRect(dataWidth), ToFixedRect(yOpen - y));
  475. this.Canvas.stroke();
  476. }
  477. else
  478. {
  479. this.Canvas.fillRect(ToFixedRect(left), ToFixedRect(y), ToFixedRect(dataWidth), ToFixedRect(yOpen - y));
  480. }
  481. }
  482. }
  483. if (data.Open > data.Low) //下影线
  484. {
  485. this.Canvas.beginPath();
  486. if (isHScreen)
  487. {
  488. this.Canvas.moveTo(ToFixedPoint(this.DrawType == 3 ? Math.min(yClose, yOpen) : y), ToFixedPoint(x));
  489. this.Canvas.lineTo(ToFixedPoint(yLow), ToFixedPoint(x));
  490. }
  491. else
  492. {
  493. this.Canvas.moveTo(ToFixedPoint(x), ToFixedPoint(this.DrawType == 3 ? Math.max(yClose, yOpen) : y));
  494. this.Canvas.lineTo(ToFixedPoint(x), ToFixedPoint(yLow));
  495. }
  496. this.Canvas.stroke();
  497. }
  498. }
  499. else
  500. {
  501. this.Canvas.beginPath();
  502. if (isHScreen)
  503. {
  504. this.Canvas.moveTo(yHigh, ToFixedPoint(x));
  505. this.Canvas.lineTo(yLow, ToFixedPoint(x));
  506. }
  507. else
  508. {
  509. this.Canvas.moveTo(ToFixedPoint(x), yHigh);
  510. this.Canvas.lineTo(ToFixedPoint(x), yLow);
  511. }
  512. this.Canvas.setStrokeStyle(upColor);
  513. this.Canvas.stroke();
  514. }
  515. }
  516. else if (data.Open > data.Close) //阴线
  517. {
  518. if (dataWidth >= this.MinBarWidth)
  519. {
  520. this.Canvas.setStrokeStyle(downColor);
  521. if (data.High > data.Close) //上影线
  522. {
  523. this.Canvas.beginPath();
  524. if (isHScreen)
  525. {
  526. this.Canvas.moveTo(ToFixedPoint(y), ToFixedPoint(x));
  527. this.Canvas.lineTo(ToFixedPoint(yOpen), ToFixedPoint(x));
  528. }
  529. else
  530. {
  531. this.Canvas.moveTo(ToFixedPoint(x), ToFixedPoint(y));
  532. this.Canvas.lineTo(ToFixedPoint(x), ToFixedPoint(yOpen));
  533. }
  534. this.Canvas.stroke();
  535. y = yOpen;
  536. }
  537. else
  538. {
  539. y = yOpen
  540. }
  541. this.Canvas.setFillStyle(downColor);
  542. if (isHScreen)
  543. {
  544. if (Math.abs(yClose - y) < 1)
  545. {
  546. this.Canvas.fillRect(ToFixedRect(y), ToFixedRect(left), 1, ToFixedRect(dataWidth)); //高度小于1,统一使用高度1
  547. }
  548. else
  549. {
  550. //宽度是负数竟然不会画, h5就可以
  551. this.Canvas.fillRect(ToFixedRect(Math.min(yClose, y)), ToFixedRect(left), ToFixedRect(Math.abs(yClose - y)), ToFixedRect(dataWidth));
  552. }
  553. }
  554. else
  555. {
  556. if (Math.abs(yClose - y) < 1) this.Canvas.fillRect(ToFixedRect(left), ToFixedRect(y), ToFixedRect(dataWidth), 1); //高度小于1,统一使用高度1
  557. else this.Canvas.fillRect(ToFixedRect(left), ToFixedRect(y), ToFixedRect(dataWidth), ToFixedRect(yClose - y));
  558. }
  559. if (data.Open > data.Low) //下影线
  560. {
  561. this.Canvas.beginPath();
  562. if (isHScreen)
  563. {
  564. this.Canvas.moveTo(ToFixedPoint(y), ToFixedPoint(x));
  565. this.Canvas.lineTo(ToFixedPoint(yLow), ToFixedPoint(x));
  566. }
  567. else
  568. {
  569. this.Canvas.moveTo(ToFixedPoint(x), ToFixedPoint(y));
  570. this.Canvas.lineTo(ToFixedPoint(x), ToFixedPoint(yLow));
  571. }
  572. this.Canvas.stroke();
  573. }
  574. }
  575. else
  576. {
  577. this.Canvas.beginPath();
  578. if (isHScreen)
  579. {
  580. this.Canvas.moveTo(yHigh, ToFixedPoint(x));
  581. this.Canvas.lineTo(yLow, ToFixedPoint(x));
  582. }
  583. else
  584. {
  585. this.Canvas.moveTo(ToFixedPoint(x), yHigh);
  586. this.Canvas.lineTo(ToFixedPoint(x), yLow);
  587. }
  588. this.Canvas.setStrokeStyle(downColor);
  589. this.Canvas.stroke();
  590. }
  591. }
  592. else // 平线
  593. {
  594. if (dataWidth >= this.MinBarWidth)
  595. {
  596. this.Canvas.setStrokeStyle(unchagneColor);
  597. this.Canvas.beginPath();
  598. if (data.High > data.Close) //上影线
  599. {
  600. if (isHScreen)
  601. {
  602. this.Canvas.moveTo(y, ToFixedPoint(x));
  603. this.Canvas.lineTo(yOpen, ToFixedPoint(x));
  604. }
  605. else
  606. {
  607. this.Canvas.moveTo(ToFixedPoint(x), y);
  608. this.Canvas.lineTo(ToFixedPoint(x), yOpen);
  609. }
  610. y = yOpen;
  611. }
  612. else
  613. {
  614. y = yOpen;
  615. }
  616. if (isHScreen)
  617. {
  618. this.Canvas.moveTo(ToFixedPoint(y), ToFixedPoint(left));
  619. this.Canvas.lineTo(ToFixedPoint(y), ToFixedPoint(right));
  620. }
  621. else
  622. {
  623. this.Canvas.moveTo(ToFixedPoint(left), ToFixedPoint(y));
  624. this.Canvas.lineTo(ToFixedPoint(right), ToFixedPoint(y));
  625. }
  626. if (data.Open > data.Low) //下影线
  627. {
  628. if (isHScreen)
  629. {
  630. this.Canvas.moveTo(ToFixedPoint(y), ToFixedPoint(x));
  631. this.Canvas.lineTo(ToFixedPoint(yLow), ToFixedPoint(x));
  632. }
  633. else
  634. {
  635. this.Canvas.moveTo(ToFixedPoint(x), ToFixedPoint(y));
  636. this.Canvas.lineTo(ToFixedPoint(x), ToFixedPoint(yLow));
  637. }
  638. }
  639. this.Canvas.stroke();
  640. }
  641. else
  642. {
  643. this.Canvas.beginPath();
  644. if (isHScreen)
  645. {
  646. this.Canvas.moveTo(yHigh, ToFixedPoint(x));
  647. this.Canvas.lineTo(yLow, ToFixedPoint(x));
  648. }
  649. else
  650. {
  651. this.Canvas.moveTo(ToFixedPoint(x), yHigh);
  652. this.Canvas.lineTo(ToFixedPoint(x), yLow);
  653. }
  654. this.Canvas.setStrokeStyle(unchagneColor);
  655. this.Canvas.stroke();
  656. }
  657. }
  658. if (this.Data.DataType == 0 && ChartData.IsDayPeriod(this.Data.Period,true)) //信息地雷
  659. {
  660. var infoItem = { X: x, Xleft: left, XRight: right, YMax: yHigh, YMin: yLow, DayData: data, Index: j };
  661. this.DrawInfoDiv(infoItem);
  662. }
  663. }
  664. this.PtMax = ptMax;
  665. this.PtMin = ptMin;
  666. }
  667. this.DrawTrade = function () //交易系统
  668. {
  669. if (!this.TradeData) return;
  670. var isHScreen = (this.ChartFrame.IsHScreen === true);
  671. var dataWidth = this.ChartFrame.DataWidth;
  672. var distanceWidth = this.ChartFrame.DistanceWidth;
  673. var xOffset = this.ChartBorder.GetLeft() + distanceWidth / 2.0 + 2.0;
  674. var chartright = this.ChartBorder.GetRight();
  675. var xPointCount = this.ChartFrame.XPointCount;
  676. if (isHScreen) {
  677. xOffset = this.ChartBorder.GetTop() + distanceWidth / 2.0 + 2.0;
  678. chartright = this.ChartBorder.GetBottom();
  679. }
  680. var sellData = this.TradeData.Sell;
  681. var buyData = this.TradeData.Buy;
  682. var arrowWidth = dataWidth;
  683. if (arrowWidth > 10) arrowWidth = 10;
  684. for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j, xOffset += (dataWidth + distanceWidth)) {
  685. var data = this.Data.Data[i];
  686. if (data.Open == null || data.High == null || data.Low == null || data.Close == null) continue;
  687. var buy = false, sell = false;
  688. if (sellData && i < sellData.length) sell = sellData[i] > 0;
  689. if (buyData && i < buyData.length) buy = buyData[i] > 0;
  690. if (!sell && !buy) continue;
  691. var left = xOffset;
  692. var right = xOffset + dataWidth;
  693. if (right > chartright) break;
  694. var x = left + (right - left) / 2;
  695. var yLow = this.ChartFrame.GetYFromData(data.Low);
  696. var yHigh = this.ChartFrame.GetYFromData(data.High);
  697. var yOpen = this.ChartFrame.GetYFromData(data.Open);
  698. var yClose = this.ChartFrame.GetYFromData(data.Close);
  699. var y = yHigh;
  700. if (buy) {
  701. this.Canvas.setFillStyle(this.UpColor);
  702. this.Canvas.setStrokeStyle(this.UnchagneColor);
  703. this.Canvas.beginPath();
  704. if (isHScreen) {
  705. this.Canvas.moveTo(yLow - 1, x);
  706. this.Canvas.lineTo(yLow - arrowWidth - 1, x - arrowWidth / 2);
  707. this.Canvas.lineTo(yLow - arrowWidth - 1, x + arrowWidth / 2);
  708. }
  709. else {
  710. this.Canvas.moveTo(x, yLow + 1);
  711. this.Canvas.lineTo(x - arrowWidth / 2, yLow + arrowWidth + 1);
  712. this.Canvas.lineTo(x + arrowWidth / 2, yLow + arrowWidth + 1);
  713. }
  714. this.Canvas.closePath();
  715. this.Canvas.fill();
  716. this.Canvas.stroke();
  717. }
  718. if (sell) {
  719. this.Canvas.setFillStyle(this.DownColor);
  720. this.Canvas.setStrokeStyle(this.UnchagneColor);
  721. this.Canvas.beginPath();
  722. if (isHScreen) {
  723. this.Canvas.moveTo(yHigh + 1, x);
  724. this.Canvas.lineTo(yHigh + arrowWidth + 1, x - arrowWidth / 2);
  725. this.Canvas.lineTo(yHigh + arrowWidth + 1, x + arrowWidth / 2);
  726. }
  727. else {
  728. this.Canvas.moveTo(x, yHigh - 1);
  729. this.Canvas.lineTo(x - arrowWidth / 2, yHigh - arrowWidth - 1);
  730. this.Canvas.lineTo(x + arrowWidth / 2, yHigh - arrowWidth - 1);
  731. }
  732. this.Canvas.closePath();
  733. this.Canvas.fill();
  734. this.Canvas.stroke();
  735. }
  736. }
  737. }
  738. this.Draw = function () {
  739. this.PtMax = { X: null, Y: null, Value: null, Align: 'left' }; //清空最大
  740. this.PtMin = { X: null, Y: null, Value: null, Align: 'left' }; //清空最小
  741. this.ChartFrame.ChartKLine = { Max: null, Min: null }; //保存K线上 显示最大最小值坐标
  742. if (this.IsShow == false) return;
  743. if (this.DrawType == 1) {
  744. this.DrawCloseLine();
  745. return;
  746. }
  747. else if (this.DrawType == 2) {
  748. this.DrawAKLine();
  749. }
  750. else if (this.DrawType == 4) {
  751. this.DrawCloseArea();
  752. }
  753. else {
  754. this.DrawKBar();
  755. }
  756. this.DrawTrade();
  757. if (this.IsShowMaxMinPrice) //标注最大值最小值
  758. {
  759. if (this.ChartFrame.IsHScreen === true) this.HScreenDrawMaxMinPrice(this.PtMax, this.PtMin);
  760. else this.DrawMaxMinPrice(this.PtMax, this.PtMin);
  761. }
  762. }
  763. this.DrawMaxMinPrice = function (ptMax, ptMin) {
  764. if (ptMax.X == null || ptMax.Y == null || ptMax.Value == null) return;
  765. if (ptMin.X == null || ptMin.Y == null || ptMin.Value == null) return;
  766. var leftArrow=g_JSChartResource.KLine.MaxMin.LeftArrow;
  767. var rightArrow=g_JSChartResource.KLine.MaxMin.RightArrow;
  768. var highYOffset=g_JSChartResource.KLine.MaxMin.HighYOffset;
  769. var lowYOffset=g_JSChartResource.KLine.MaxMin.LowYOffset;
  770. var defaultfloatPrecision = JSCommonCoordinateData.GetfloatPrecision(this.Symbol);
  771. this.Canvas.font = this.TextFont;
  772. this.Canvas.setFillStyle(this.TextColor);
  773. this.Canvas.textAlign = ptMax.Align;
  774. this.Canvas.textBaseline = 'bottom';
  775. var left = ptMax.X;
  776. if (IFrameSplitOperator.IsNumber(highYOffset)) ptMax.Y+=highYOffset;
  777. var text = ptMax.Value.toFixed(defaultfloatPrecision);
  778. if (ptMax.Align == 'left') text = leftArrow + text;
  779. else text = text + rightArrow;
  780. this.Canvas.fillText(text, left, ptMax.Y);
  781. this.ChartFrame.ChartKLine.Max = { X: left, Y: ptMax.Y, Text: { BaseLine: 'bottom' } };
  782. this.Canvas.textAlign = ptMin.Align;
  783. this.Canvas.textBaseline = 'top';
  784. var left = ptMin.X;
  785. if (IFrameSplitOperator.IsNumber(lowYOffset)) ptMin.Y+=lowYOffset;
  786. text = ptMin.Value.toFixed(defaultfloatPrecision);
  787. if (ptMin.Align == 'left') text = leftArrow + text;
  788. else text = text + rightArrow;
  789. this.Canvas.fillText(text, left, ptMin.Y);
  790. this.ChartFrame.ChartKLine.Min = { X: left, Y: ptMin.Y, Text: { BaseLine: 'top' } };
  791. }
  792. this.HScreenDrawMaxMinPrice = function (ptMax, ptMin) //横屏模式下显示最大最小值
  793. {
  794. if (ptMax.X == null || ptMax.Y == null || ptMax.Value == null) return;
  795. if (ptMin.X == null || ptMin.Y == null || ptMin.Value == null) return;
  796. var leftArrow=g_JSChartResource.KLine.MaxMin.LeftArrow;
  797. var rightArrow=g_JSChartResource.KLine.MaxMin.RightArrow;
  798. var highYOffset=g_JSChartResource.KLine.MaxMin.HighYOffset;
  799. var lowYOffset=g_JSChartResource.KLine.MaxMin.LowYOffset;
  800. var defaultfloatPrecision = JSCommonCoordinateData.GetfloatPrecision(this.Symbol);
  801. var xText = ptMax.Y;
  802. var yText = ptMax.X;
  803. if (IFrameSplitOperator.IsNumber(highYOffset)) xText+=highYOffset;
  804. this.Canvas.save();
  805. this.Canvas.translate(xText, yText);
  806. this.Canvas.rotate(90 * Math.PI / 180);
  807. this.Canvas.font = this.TextFont;
  808. this.Canvas.setFillStyle(this.TextColor);
  809. this.Canvas.textAlign = ptMax.Align;
  810. this.Canvas.textBaseline = 'bottom';
  811. var text = ptMax.Value.toFixed(defaultfloatPrecision);
  812. if (ptMax.Align == 'left') text = leftArrow + text;
  813. else text = text + rightArrow;
  814. this.Canvas.fillText(text, 0, 0);
  815. this.Canvas.restore();
  816. var xText = ptMin.Y;
  817. var yText = ptMin.X;
  818. if (IFrameSplitOperator.IsNumber(lowYOffset)) xText+=lowYOffset;
  819. this.Canvas.save();
  820. this.Canvas.translate(xText, yText);
  821. this.Canvas.rotate(90 * Math.PI / 180);
  822. this.Canvas.font = this.TextFont;
  823. this.Canvas.setFillStyle(this.TextColor);
  824. this.Canvas.textAlign = ptMin.Align;
  825. this.Canvas.textBaseline = 'top';
  826. var text = ptMin.Value.toFixed(defaultfloatPrecision);
  827. if (ptMin.Align == 'left') text = leftArrow + text;
  828. else text = text + rightArrow;
  829. this.Canvas.fillText(text, 0, 0);
  830. this.Canvas.restore();
  831. }
  832. //画某一天的信息地雷 画在底部
  833. this.DrawInfoDiv = function (item) {
  834. if (!this.InfoData || this.InfoData.length <= 0) return;
  835. var dataWidth = this.ChartFrame.DataWidth;
  836. var distanceWidth = this.ChartFrame.DistanceWidth;
  837. var infoData = this.InfoData.get(item.DayData.Date.toString());
  838. if (!infoData || infoData.Data.length <= 0) return;
  839. var bHScreen = (this.ChartFrame.IsHScreen === true);
  840. if (this.InfoDrawType === 1) {
  841. this.Canvas.font = this.GetDynamicFont(dataWidth);
  842. this.Canvas.setFillStyle(this.InfoPointColor2);
  843. this.Canvas.textAlign = 'center';
  844. this.Canvas.textBaseline = 'top';
  845. if (bHScreen) {
  846. var xText = item.YMin;
  847. var yText = item.X;
  848. this.Canvas.save();
  849. this.Canvas.translate(xText, yText);
  850. this.Canvas.rotate(90 * Math.PI / 180);
  851. this.Canvas.fillText('▲', 0, 0);
  852. this.Canvas.restore();
  853. }
  854. else {
  855. var left = ToFixedPoint(item.X);
  856. this.Canvas.fillText('▲', left, item.YMin);
  857. }
  858. }
  859. else {
  860. var dataWidth = this.ChartFrame.DataWidth;
  861. var radius = dataWidth / 2;
  862. if (radius > 3) radius = 3;
  863. var x = item.X;
  864. var y = this.ChartFrame.ChartBorder.GetBottom() - 2 - radius;
  865. if (bHScreen) y = this.ChartFrame.ChartBorder.GetLeft() + 2 + radius;
  866. this.Canvas.setFillStyle(this.InfoPointColor);
  867. this.Canvas.beginPath();
  868. if (bHScreen) this.Canvas.arc(y, x, radius, 0, Math.PI * 2, true);
  869. else this.Canvas.arc(ToFixedPoint(x), y, radius, 0, Math.PI * 2, true);
  870. this.Canvas.closePath();
  871. this.Canvas.fill();
  872. }
  873. }
  874. this.GetTooltipData = function (x, y, tooltip) {
  875. return false;
  876. }
  877. this.GetMaxMin = function () //计算当天显示数据的最大最小值
  878. {
  879. var xPointCount = this.ChartFrame.XPointCount;
  880. var range = {};
  881. range.Max = null;
  882. range.Min = null;
  883. if (this.IsShow == false) return range;
  884. if (this.DrawType==1 || this.DrawType==4 ) // 1=收盘价线 4=收盘价面积图
  885. {
  886. for(var i=this.Data.DataOffset,j=0;i<this.Data.Data.length && j<xPointCount;++i,++j)
  887. {
  888. var data=this.Data.Data[i];
  889. if (!IFrameSplitOperator.IsNumber(data.Close)) continue;
  890. if (range.Max==null) range.Max=data.Close;
  891. if (range.Min==null) range.Min=data.Close;
  892. if (range.Max<data.Close) range.Max=data.Close;
  893. if (range.Min>data.Close) range.Min=data.Close;
  894. }
  895. }
  896. else
  897. {
  898. for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j)
  899. {
  900. var data = this.Data.Data[i];
  901. if (data.Open == null || data.High == null || data.Low == null || data.Close == null) continue;
  902. if (range.Max == null) range.Max = data.High;
  903. if (range.Min == null) range.Min = data.Low;
  904. if (range.Max < data.High) range.Max = data.High;
  905. if (range.Min > data.Low) range.Min = data.Low;
  906. }
  907. }
  908. return range;
  909. }
  910. }
  911. /*
  912. 文字输出 支持横屏
  913. 数组不为null的数据中输出 this.Text文本
  914. */
  915. function ChartSingleText()
  916. {
  917. this.newMethod = IChartPainting; //派生
  918. this.newMethod();
  919. delete this.newMethod;
  920. this.Color = "rgb(255,193,37)"; //线段颜色
  921. this.TextFont = "12px 微软雅黑"; //字体
  922. this.Text;
  923. this.TextAlign = 'left';
  924. this.Direction = 0; //0=middle 1=bottom 2=top
  925. this.YOffset = 0;
  926. this.Position; //指定输出位置
  927. this.TextSize=
  928. {
  929. Max: g_JSChartResource.DRAWICON.Text.MaxSize, Min:g_JSChartResource.DRAWICON.Text.MinSize, //字体的最大最小值
  930. Zoom:{ Type:g_JSChartResource.DRAWICON.Text.Zoom.Type , Value:g_JSChartResource.DRAWICON.Text.Zoom.Value }, //放大倍数
  931. FontName:g_JSChartResource.DRAWICON.Text.FontName
  932. }
  933. this.ReloadResource=function(resource)
  934. {
  935. if (this.Name=="DRAWTEXT")
  936. {
  937. this.TextSize=
  938. {
  939. Max: g_JSChartResource.DRAWTEXT.MaxSize, Min:g_JSChartResource.DRAWTEXT.MinSize, //字体的最大最小值
  940. Zoom:{ Type:g_JSChartResource.DRAWTEXT.Zoom.Type , Value:g_JSChartResource.DRAWTEXT.Zoom.Value }, //放大倍数
  941. FontName:g_JSChartResource.DRAWTEXT.FontName
  942. }
  943. }
  944. else if (this.Name=="DRAWNUMBER")
  945. {
  946. this.TextSize=
  947. {
  948. Max: g_JSChartResource.DRAWNUMBER.MaxSize, Min:g_JSChartResource.DRAWNUMBER.MinSize, //字体的最大最小值
  949. Zoom:{ Type:g_JSChartResource.DRAWNUMBER.Zoom.Type , Value:g_JSChartResource.DRAWNUMBER.Zoom.Value }, //放大倍数
  950. FontName:g_JSChartResource.DRAWNUMBER.FontName
  951. }
  952. }
  953. }
  954. this.Draw = function ()
  955. {
  956. if (!this.IsShow || this.ChartFrame.IsMinSize) return;
  957. if (this.NotSupportMessage)
  958. {
  959. this.DrawNotSupportmessage();
  960. return;
  961. }
  962. if (this.Position)
  963. {
  964. this.DrawPosition();
  965. return;
  966. }
  967. if (!this.Data || !this.Data.Data) return;
  968. var isHScreen = (this.ChartFrame.IsHScreen === true)
  969. var dataWidth = this.ChartFrame.DataWidth;
  970. var distanceWidth = this.ChartFrame.DistanceWidth;
  971. var chartright = this.ChartBorder.GetRight();
  972. var top = this.ChartBorder.GetTopEx();
  973. var bottom = this.ChartBorder.GetBottomEx();
  974. if (isHScreen)
  975. {
  976. chartright = this.ChartBorder.GetBottom();
  977. top = this.ChartBorder.GetRightEx();
  978. bottom = this.ChartBorder.GetLeftEx();
  979. }
  980. var xPointCount = this.ChartFrame.XPointCount;
  981. var isArrayText = Array.isArray(this.Text);
  982. var text;
  983. if (this.Direction == 1) this.Canvas.textBaseline = 'bottom';
  984. else if (this.Direction == 2) this.Canvas.textBaseline = 'top';
  985. else this.Canvas.textBaseline = 'middle';
  986. this.TextFont = this.GetDynamicFontEx(dataWidth,distanceWidth,this.TextSize.Max,this.TextSize.Min,this.TextSize.Zoom,this.TextSize.FontName);
  987. for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j)
  988. {
  989. var value = this.Data.Data[i];
  990. if (value == null) continue;
  991. var x = this.ChartFrame.GetXFromIndex(j);
  992. var y = this.ChartFrame.GetYFromData(value);
  993. if (x > chartright) break;
  994. this.Canvas.textAlign = this.TextAlign;
  995. this.Canvas.setFillStyle(this.Color);
  996. this.Canvas.font = this.TextFont;
  997. if (this.YOffset > 0 && this.Direction > 0)
  998. {
  999. var yPrice = y;
  1000. this.Canvas.save();
  1001. this.Canvas.setLineDash([5, 10]);
  1002. this.Canvas.setStrokeStyle(this.Color);
  1003. this.Canvas.beginPath();
  1004. if (isHScreen)
  1005. {
  1006. if (this.Direction == 1)
  1007. {
  1008. y = top - this.YOffset;
  1009. yPrice += 5;
  1010. }
  1011. else
  1012. {
  1013. y = bottom + this.YOffset;
  1014. yPrice -= 5;
  1015. }
  1016. this.Canvas.moveTo(ToFixedPoint(yPrice), ToFixedPoint(x));
  1017. this.Canvas.lineTo(ToFixedPoint(y), ToFixedPoint(x));
  1018. }
  1019. else
  1020. {
  1021. if (this.Direction == 1)
  1022. {
  1023. y = top + this.YOffset;
  1024. yPrice += 5;
  1025. }
  1026. else
  1027. {
  1028. y = bottom - this.YOffset;
  1029. yPrice -= 5;
  1030. }
  1031. this.Canvas.moveTo(ToFixedPoint(x), ToFixedPoint(yPrice));
  1032. this.Canvas.lineTo(ToFixedPoint(x), ToFixedPoint(y));
  1033. }
  1034. this.Canvas.stroke();
  1035. this.Canvas.restore();
  1036. }
  1037. if (isArrayText)
  1038. {
  1039. text = this.Text[i];
  1040. if (!text) continue;
  1041. if (isHScreen)
  1042. {
  1043. if (this.Name=='DRAWNUMBER')
  1044. {
  1045. if (this.Direction==1) y+=g_JSChartResource.DRAWABOVE.YOffset;
  1046. else if (this.Direction==2) y-=4;
  1047. }
  1048. }
  1049. else
  1050. {
  1051. if (this.Name=='DRAWNUMBER')
  1052. {
  1053. if (this.Direction==1) y-=g_JSChartResource.DRAWABOVE.YOffset;
  1054. else if (this.Direction==2) y+=4;
  1055. }
  1056. }
  1057. this.DrawText(text, x, y, isHScreen);
  1058. }
  1059. else
  1060. {
  1061. this.DrawText(this.Text, x, y, isHScreen);
  1062. }
  1063. }
  1064. }
  1065. this.DrawPosition=function() //绘制在指定位置上
  1066. {
  1067. if (!this.Text) return;
  1068. var isHScreen=(this.ChartFrame.IsHScreen===true)
  1069. if (isHScreen)
  1070. {
  1071. var y=this.ChartBorder.GetRightEx()-this.ChartBorder.GetWidthEx()*this.Position.Y;
  1072. var x=this.ChartBorder.GetTop()+this.ChartBorder.GetHeight()*this.Position.X;
  1073. }
  1074. else
  1075. {
  1076. var x=this.ChartBorder.GetLeft()+this.ChartBorder.GetWidth()*this.Position.X;
  1077. var y=this.ChartBorder.GetTopEx()+this.ChartBorder.GetHeight()*this.Position.Y;
  1078. }
  1079. this.Canvas.fillStyle=this.Color;
  1080. //TYPE:0为左对齐,1为右对齐.
  1081. if (this.Position.Type==0) this.Canvas.textAlign='left';
  1082. else if (this.Position.Type==1) this.Canvas.textAlign='right';
  1083. else this.Canvas.textAlign='center';
  1084. if (this.Direction==1) this.Canvas.textBaseline='bottom';
  1085. else if (this.Direction==2) this.Canvas.textBaseline='top';
  1086. else this.Canvas.textBaseline='middle';
  1087. this.DrawText(this.Text,x,y,isHScreen);
  1088. }
  1089. this.DrawText = function (text, x, y, isHScreen)
  1090. {
  1091. if(text.length<=2){
  1092. this.Canvas.font="18px Arial";
  1093. }else{
  1094. this.Canvas.font="12px Arial";
  1095. }
  1096. // console.log(text);
  1097. // console.log(text.length);
  1098. // console.log(this.Canvas.font);
  1099. if (isHScreen)
  1100. {
  1101. this.Canvas.save();
  1102. this.Canvas.translate(y, x);
  1103. this.Canvas.rotate(90 * Math.PI / 180);
  1104. this.Canvas.fillText(text, 0, 0);
  1105. this.Canvas.restore();
  1106. }
  1107. else
  1108. {
  1109. this.Canvas.fillText(text, x, y);
  1110. }
  1111. }
  1112. }
  1113. //线段
  1114. function ChartLine()
  1115. {
  1116. this.newMethod = IChartPainting; //派生
  1117. this.newMethod();
  1118. delete this.newMethod;
  1119. this.ClassName ='ChartLine';
  1120. this.Color = "rgb(255,193,37)"; //线段颜色
  1121. this.LineWidth; //线段宽度
  1122. this.DrawType = 0; //画图方式 0=无效数平滑 1=无效数不画断开
  1123. this.IsDotLine = false; //虚线
  1124. this.Draw = function ()
  1125. {
  1126. if (!this.IsShow || this.ChartFrame.IsMinSize) return;
  1127. if (this.NotSupportMessage)
  1128. {
  1129. this.DrawNotSupportmessage();
  1130. return;
  1131. }
  1132. if (!this.Data || !this.Data.Data) return;
  1133. switch (this.DrawType)
  1134. {
  1135. case 0:
  1136. return this.DrawLine();
  1137. case 1:
  1138. return this.DrawStraightLine();
  1139. }
  1140. }
  1141. this.DrawLine = function ()
  1142. {
  1143. var bHScreen = (this.ChartFrame.IsHScreen === true);
  1144. var dataWidth = this.ChartFrame.DataWidth;
  1145. var distanceWidth = this.ChartFrame.DistanceWidth;
  1146. var chartright = this.ChartBorder.GetRight();
  1147. if (bHScreen) chartright = this.ChartBorder.GetBottom();
  1148. var xPointCount = this.ChartFrame.XPointCount;
  1149. this.Canvas.save();
  1150. if (this.LineWidth > 0) this.Canvas.lineWidth = this.LineWidth;
  1151. var bFirstPoint = true;
  1152. var drawCount = 0;
  1153. for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j)
  1154. {
  1155. var value = this.Data.Data[i];
  1156. if (value == null) continue;
  1157. var x = this.ChartFrame.GetXFromIndex(j);
  1158. var y = this.GetYFromData(value);
  1159. if (x > chartright) break;
  1160. if (bFirstPoint)
  1161. {
  1162. this.Canvas.setStrokeStyle(this.Color);
  1163. this.Canvas.beginPath();
  1164. if (bHScreen) this.Canvas.moveTo(y, x); //横屏坐标轴对调
  1165. else this.Canvas.moveTo(x, y);
  1166. bFirstPoint = false;
  1167. }
  1168. else
  1169. {
  1170. if (bHScreen) this.Canvas.lineTo(y, x);
  1171. else this.Canvas.lineTo(x, y);
  1172. }
  1173. ++drawCount;
  1174. }
  1175. if (drawCount > 0) this.Canvas.stroke();
  1176. this.Canvas.restore();
  1177. }
  1178. //无效数不画
  1179. this.DrawStraightLine = function ()
  1180. {
  1181. var bHScreen = (this.ChartFrame.IsHScreen === true);
  1182. var isMinute=this.IsMinuteFrame();
  1183. var dataWidth = this.ChartFrame.DataWidth;
  1184. var distanceWidth = this.ChartFrame.DistanceWidth;
  1185. var xOffset=this.ChartBorder.GetLeft()+distanceWidth/2.0+g_JSChartResource.FrameLeftMargin;
  1186. var chartright = this.ChartBorder.GetRight();
  1187. if (bHScreen) chartright = this.ChartBorder.GetBottom();
  1188. if (bHScreen) xOffset=this.ChartBorder.GetTop()+distanceWidth/2.0+g_JSChartResource.FrameLeftMargin;
  1189. var xPointCount = this.ChartFrame.XPointCount;
  1190. this.Canvas.save();
  1191. if (this.LineWidth > 0) this.Canvas.lineWidth = this.LineWidth;
  1192. this.Canvas.setStrokeStyle(this.Color);
  1193. if (this.IsDotLine) this.Canvas.setLineDash([3, 5]); //画虚线
  1194. var bFirstPoint = true;
  1195. var drawCount = 0;
  1196. for(var i=this.Data.DataOffset,j=0;i<this.Data.Data.length && j<xPointCount;++i,++j,xOffset+=(dataWidth+distanceWidth))
  1197. //for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j)
  1198. {
  1199. var value = this.Data.Data[i];
  1200. if (value == null)
  1201. {
  1202. if (drawCount > 0) this.Canvas.stroke();
  1203. bFirstPoint = true;
  1204. drawCount = 0;
  1205. continue;
  1206. }
  1207. if (isMinute)
  1208. {
  1209. var x = this.ChartFrame.GetXFromIndex(j);
  1210. }
  1211. else
  1212. {
  1213. var left=xOffset;
  1214. var right=xOffset+dataWidth;
  1215. if (right>chartright) break;
  1216. var x=left+(right-left)/2;
  1217. }
  1218. var y = this.GetYFromData(value);
  1219. if (x > chartright) break;
  1220. if (bFirstPoint)
  1221. {
  1222. this.Canvas.beginPath();
  1223. if (bHScreen) this.Canvas.moveTo(y, x); //横屏坐标轴对调
  1224. else this.Canvas.moveTo(x, y);
  1225. bFirstPoint = false;
  1226. }
  1227. else
  1228. {
  1229. if (bHScreen) this.Canvas.lineTo(y, x);
  1230. else this.Canvas.lineTo(x, y);
  1231. }
  1232. ++drawCount;
  1233. }
  1234. if (drawCount > 0) this.Canvas.stroke();
  1235. this.Canvas.restore();
  1236. }
  1237. this.GetYFromData = function (value)
  1238. {
  1239. return this.ChartFrame.GetYFromData(value);
  1240. }
  1241. }
  1242. //子线段
  1243. function ChartSubLine()
  1244. {
  1245. this.newMethod = ChartLine; //派生
  1246. this.newMethod();
  1247. delete this.newMethod;
  1248. this.ClassName = 'ChartSubLine'; //类名
  1249. this.Color = "rgb(255,193,37)"; //线段颜色
  1250. this.LineWidth; //线段宽度
  1251. this.DrawType = 0; //画图方式 0=无效数平滑 1=无效数不画断开
  1252. this.IsDotLine = false; //虚线
  1253. this.SubFrame = { Max: null, Min: null };
  1254. this.Draw = function ()
  1255. {
  1256. if (!this.IsShow) return;
  1257. if (!this.Data || !this.Data.Data) return;
  1258. this.CalculateDataMaxMin();
  1259. switch (this.DrawType)
  1260. {
  1261. case 0:
  1262. return this.DrawLine();
  1263. case 1:
  1264. return this.DrawStraightLine();
  1265. }
  1266. }
  1267. this.GetYFromData = function (value)
  1268. {
  1269. var bHScreen = (this.ChartFrame.IsHScreen === true);
  1270. if (bHScreen)
  1271. {
  1272. if (value <= this.SubFrame.Min) return this.ChartBorder.GetLeftEx();
  1273. if (value >= this.SubFrame.Max) return this.ChartBorder.GetRightEx();
  1274. var width = this.ChartBorder.GetWidthEx() * (value - this.SubFrame.Min) / (this.SubFrame.Max - this.SubFrame.Min);
  1275. return this.ChartBorder.GetLeftEx() + width;
  1276. }
  1277. else
  1278. {
  1279. if (value <= this.SubFrame.Min) return this.ChartBorder.GetBottomEx();
  1280. if (value >= this.SubFrame.Max) return this.ChartBorder.GetTopEx();
  1281. var height = this.ChartBorder.GetHeightEx() * (value - this.SubFrame.Min) / (this.SubFrame.Max - this.SubFrame.Min);
  1282. return this.ChartBorder.GetBottomEx() - height;
  1283. }
  1284. }
  1285. this.CalculateDataMaxMin = function ()
  1286. {
  1287. this.SubFrame = { Max: null, Min: null };
  1288. var bHScreen = (this.ChartFrame.IsHScreen === true);
  1289. var chartright = this.ChartBorder.GetRight();
  1290. if (bHScreen) chartright = this.ChartBorder.GetBottom();
  1291. var xPointCount = this.ChartFrame.XPointCount;
  1292. for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j)
  1293. {
  1294. var value = this.Data.Data[i];
  1295. if (value == null) continue;
  1296. var x = this.ChartFrame.GetXFromIndex(j);
  1297. if (x > chartright) break;
  1298. if (this.SubFrame.Min == null || this.SubFrame.Min > value) this.SubFrame.Min = value;
  1299. if (this.SubFrame.Max == null || this.SubFrame.Max < value) this.SubFrame.Max = value;
  1300. }
  1301. }
  1302. this.GetMaxMin = function () //数据不参与坐标轴最大最小值计算
  1303. {
  1304. var range = { Min: null, Max: null };
  1305. return range;
  1306. }
  1307. }
  1308. //POINTDOT 圆点 支持横屏
  1309. function ChartPointDot()
  1310. {
  1311. this.newMethod = IChartPainting; //派生
  1312. this.newMethod();
  1313. delete this.newMethod;
  1314. this.Color = "rgb(255,193,37)"; //线段颜色
  1315. this.Radius = 1; //点半径
  1316. this.ClassName = 'ChartPointDot';
  1317. this.Draw = function ()
  1318. {
  1319. if (!this.IsShow || this.ChartFrame.IsMinSize) return;
  1320. if (this.NotSupportMessage)
  1321. {
  1322. this.DrawNotSupportmessage();
  1323. return;
  1324. }
  1325. if (!this.Data || !this.Data.Data) return;
  1326. var bHScreen = (this.ChartFrame.IsHScreen === true);
  1327. var dataWidth = this.ChartFrame.DataWidth;
  1328. var distanceWidth = this.ChartFrame.DistanceWidth;
  1329. var chartright = this.ChartBorder.GetRight();
  1330. if (bHScreen === true) chartright = this.ChartBorder.GetBottom();
  1331. var xPointCount = this.ChartFrame.XPointCount;
  1332. this.Canvas.save();
  1333. this.Canvas.setFillStyle(this.Color);
  1334. for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j)
  1335. {
  1336. var value = this.Data.Data[i];
  1337. if (value == null) continue;
  1338. var x = this.ChartFrame.GetXFromIndex(j);
  1339. var y = this.ChartFrame.GetYFromData(value);
  1340. if (x > chartright) break;
  1341. this.Canvas.beginPath();
  1342. if (bHScreen) this.Canvas.arc(y, x, this.Radius, 0, Math.PI * 2, true);
  1343. else this.Canvas.arc(x, y, this.Radius, 0, Math.PI * 2, true);
  1344. this.Canvas.closePath();
  1345. this.Canvas.fill();
  1346. }
  1347. this.Canvas.restore();
  1348. }
  1349. }
  1350. //通达信语法 STICK 支持横屏
  1351. function ChartStick()
  1352. {
  1353. this.newMethod = IChartPainting; //派生
  1354. this.newMethod();
  1355. delete this.newMethod;
  1356. this.Color = "rgb(255,193,37)"; //线段颜色
  1357. this.LineWidth; //线段宽度
  1358. this.ClassName = 'ChartStick';
  1359. this.DrawLine = function ()
  1360. {
  1361. if (this.ChartFrame.IsMinSize) return;
  1362. if (!this.Data || !this.Data.Data) return;
  1363. var isHScreen = (this.ChartFrame.IsHScreen === true);
  1364. var dataWidth = this.ChartFrame.DataWidth;
  1365. var distanceWidth = this.ChartFrame.DistanceWidth;
  1366. var chartright = this.ChartBorder.GetRight();
  1367. if (isHScreen === true) chartright = this.ChartBorder.GetBottom();
  1368. var xPointCount = this.ChartFrame.XPointCount;
  1369. this.Canvas.save();
  1370. if (this.LineWidth > 0) this.Canvas.lineWidth = this.LineWidth;
  1371. var bFirstPoint = true;
  1372. var drawCount = 0;
  1373. for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j)
  1374. {
  1375. var value = this.Data.Data[i];
  1376. if (value == null) continue;
  1377. var x = this.ChartFrame.GetXFromIndex(j);
  1378. var y = this.ChartFrame.GetYFromData(value);
  1379. if (x > chartright) break;
  1380. if (bFirstPoint)
  1381. {
  1382. this.Canvas.setStrokeStyle(this.Color);
  1383. this.Canvas.beginPath();
  1384. if (isHScreen) this.Canvas.moveTo(y, x);
  1385. else this.Canvas.moveTo(x, y);
  1386. bFirstPoint = false;
  1387. }
  1388. else
  1389. {
  1390. if (isHScreen) this.Canvas.lineTo(y, x);
  1391. else this.Canvas.lineTo(x, y);
  1392. }
  1393. ++drawCount;
  1394. }
  1395. if (drawCount > 0) this.Canvas.stroke();
  1396. this.Canvas.restore();
  1397. }
  1398. this.DrawStick = function ()
  1399. {
  1400. if (!this.Data || !this.Data.Data) return;
  1401. var bHScreen = (this.ChartFrame.IsHScreen === true);
  1402. var chartright = this.ChartBorder.GetRight();
  1403. if (bHScreen) chartright = this.ChartBorder.GetBottom();
  1404. var xPointCount = this.ChartFrame.XPointCount;
  1405. var yBottom = this.ChartBorder.GetBottom();
  1406. var xLeft = this.ChartBorder.GetLeft();
  1407. this.Canvas.save();
  1408. this.Canvas.setStrokeStyle(this.Color);
  1409. if (this.LineWidth) this.Canvas.lineWidth = this.LineWidth;
  1410. for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j)
  1411. {
  1412. var value = this.Data.Data[i];
  1413. if (value == null) continue;
  1414. var x = this.ChartFrame.GetXFromIndex(j);
  1415. var y = this.ChartFrame.GetYFromData(value);
  1416. if (x > chartright) break;
  1417. this.Canvas.beginPath();
  1418. if (bHScreen)
  1419. {
  1420. this.Canvas.moveTo(xLeft, x);
  1421. this.Canvas.lineTo(y, x);
  1422. this.Canvas.stroke();
  1423. }
  1424. else
  1425. {
  1426. var xFix = parseInt(x.toString()) + 0.5;
  1427. this.Canvas.moveTo(xFix, y);
  1428. this.Canvas.lineTo(xFix, yBottom);
  1429. }
  1430. this.Canvas.stroke();
  1431. }
  1432. this.Canvas.restore();
  1433. }
  1434. this.Draw = function ()
  1435. {
  1436. if (!this.IsShow) return;
  1437. if (this.NotSupportMessage)
  1438. {
  1439. this.DrawNotSupportmessage();
  1440. return;
  1441. }
  1442. this.DrawStick();
  1443. }
  1444. }
  1445. //通达信语法 LINESTICK 支持横屏
  1446. function ChartLineStick()
  1447. {
  1448. this.newMethod = ChartStick; //派生
  1449. this.newMethod();
  1450. delete this.newMethod;
  1451. this.ClassName = 'ChartLineStick';
  1452. this.Draw = function ()
  1453. {
  1454. if (!this.IsShow || this.ChartFrame.IsMinSize) return;
  1455. if (this.NotSupportMessage)
  1456. {
  1457. this.DrawNotSupportmessage();
  1458. return;
  1459. }
  1460. this.DrawStick();
  1461. this.DrawLine();
  1462. }
  1463. }
  1464. //柱子 支持横屏
  1465. function ChartStickLine()
  1466. {
  1467. this.newMethod = IChartPainting; //派生
  1468. this.newMethod();
  1469. delete this.newMethod;
  1470. this.ClassName ='ChartStickLine';
  1471. this.Color = "rgb(255,193,37)"; //线段颜色
  1472. this.LineWidth = 2; //线段宽度
  1473. this.BarType = 0; //柱子类型 0=实心 1=空心
  1474. this.MinBarWidth=g_JSChartResource.MinKLineBarWidth; //最小的柱子宽度
  1475. this.Draw = function ()
  1476. {
  1477. if (this.ChartFrame.IsMinSize) return;
  1478. if (this.NotSupportMessage)
  1479. {
  1480. this.DrawNotSupportmessage();
  1481. return;
  1482. }
  1483. if (!this.Data || !this.Data.Data) return;
  1484. var isHScreen = (this.ChartFrame.IsHScreen === true);
  1485. var dataWidth = this.ChartFrame.DataWidth;
  1486. var distanceWidth = this.ChartFrame.DistanceWidth;
  1487. var chartright = this.ChartBorder.GetRight();
  1488. if (isHScreen) chartright = this.ChartBorder.GetBottom();
  1489. var xPointCount = this.ChartFrame.XPointCount;
  1490. var xOffset = this.ChartBorder.GetLeft() + distanceWidth / 2.0 + 2.0;
  1491. if (isHScreen) xOffset = this.ChartBorder.GetTop() + distanceWidth / 2.0 + 2.0;
  1492. var isMinute=this.IsMinuteFrame();
  1493. this.Canvas.save();
  1494. var bFillBar = false;
  1495. var bFillKLine = false;
  1496. if (isMinute)
  1497. {
  1498. if (this.LineWidth>1) this.Canvas.lineWidth=2;
  1499. else this.Canvas.lineWidth=1;
  1500. this.Canvas.strokeStyle=this.Color;
  1501. }
  1502. else if (this.LineWidth==50)
  1503. {
  1504. if (dataWidth >= this.MinBarWidth)
  1505. {
  1506. bFillKLine = true;
  1507. this.Canvas.setFillStyle(this.Color);
  1508. this.Canvas.setStrokeStyle(this.Color);
  1509. }
  1510. else //太细了 画竖线
  1511. {
  1512. this.Canvas.lineWidth = 1;
  1513. this.Canvas.setStrokeStyle(this.Color);
  1514. }
  1515. }
  1516. else if (this.LineWidth < 100)
  1517. {
  1518. var LineWidth = this.LineWidth;
  1519. if (dataWidth <= 4) LineWidth = 1;
  1520. else if (dataWidth < LineWidth) LineWidth = parseInt(dataWidth);
  1521. this.Canvas.lineWidth = LineWidth;
  1522. this.Canvas.setStrokeStyle(this.Color);
  1523. }
  1524. else
  1525. {
  1526. bFillBar = true;
  1527. this.Canvas.setFillStyle(this.Color);
  1528. var fixedWidth = 2;
  1529. }
  1530. for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j, xOffset += (dataWidth + distanceWidth))
  1531. {
  1532. var value = this.Data.Data[i];
  1533. if (value == null) continue;
  1534. var price = value.Value;
  1535. var price2 = value.Value2;
  1536. if (price2 == null) price2 = 0;
  1537. var x = this.ChartFrame.GetXFromIndex(j);
  1538. var y = this.ChartFrame.GetYFromData(price);
  1539. var y2 = this.ChartFrame.GetYFromData(price2);
  1540. if (x > chartright) break;
  1541. if (bFillBar)
  1542. {
  1543. var left = xOffset - fixedWidth;
  1544. if (isHScreen)
  1545. {
  1546. this.Canvas.fillRect(Math.min(y, y2), left, Math.abs(y - y2), dataWidth + distanceWidth + fixedWidth * 2);
  1547. }
  1548. else
  1549. {
  1550. var barWidth = dataWidth + distanceWidth + fixedWidth * 2;
  1551. if (left + barWidth > chartright) barWidth = chartright - left; //不要超过右边框子
  1552. this.Canvas.fillRect(left, ToFixedRect(Math.min(y, y2)), barWidth, ToFixedRect(Math.abs(y - y2)));
  1553. }
  1554. }
  1555. else if (bFillKLine)
  1556. {
  1557. if (this.BarType == 1) //实心
  1558. {
  1559. if (isHScreen)
  1560. {
  1561. this.Canvas.beginPath();
  1562. this.Canvas.fillRect(ToFixedRect(Math.min(y, y2)), ToFixedRect(xOffset), ToFixedRect(Math.abs(y - y2)), ToFixedRect(dataWidth));
  1563. this.Canvas.stroke();
  1564. }
  1565. else
  1566. {
  1567. this.Canvas.beginPath();
  1568. this.Canvas.rect(ToFixedRect(xOffset), ToFixedRect(Math.min(y, y2)), ToFixedRect(dataWidth), ToFixedRect(Math.abs(y - y2)));
  1569. this.Canvas.stroke();
  1570. }
  1571. }
  1572. else
  1573. {
  1574. if (isHScreen)
  1575. this.Canvas.fillRect(ToFixedRect(Math.min(y, y2)), ToFixedRect(xOffset), ToFixedRect(Math.abs(y - y2)), ToFixedRect(dataWidth));
  1576. else
  1577. this.Canvas.fillRect(ToFixedRect(xOffset), ToFixedRect(Math.min(y, y2)), ToFixedRect(dataWidth), ToFixedRect(Math.abs(y - y2)));
  1578. }
  1579. }
  1580. else
  1581. {
  1582. if (isHScreen)
  1583. {
  1584. this.Canvas.beginPath();
  1585. this.Canvas.moveTo(y, ToFixedPoint(x));
  1586. this.Canvas.lineTo(y2, ToFixedPoint(x));
  1587. this.Canvas.stroke();
  1588. }
  1589. else
  1590. {
  1591. var xFix = parseInt(x.toString()) + 0.5;
  1592. this.Canvas.beginPath();
  1593. this.Canvas.moveTo(xFix, y);
  1594. this.Canvas.lineTo(xFix, y2);
  1595. this.Canvas.stroke();
  1596. }
  1597. }
  1598. }
  1599. this.Canvas.restore();
  1600. }
  1601. this.GetMaxMin = function ()
  1602. {
  1603. var xPointCount = this.ChartFrame.XPointCount;
  1604. var range = {};
  1605. range.Min = null;
  1606. range.Max = null;
  1607. if (!this.Data || !this.Data.Data) return range;
  1608. for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j)
  1609. {
  1610. var data = this.Data.Data[i];
  1611. if (data == null) continue;
  1612. var value2 = data.Value2;
  1613. if (value2 == null) value2 = 0;
  1614. if (data == null || isNaN(data.Value) || isNaN(value2)) continue;
  1615. var valueMax = Math.max(data.Value, value2);
  1616. var valueMin = Math.min(data.Value, value2);
  1617. if (range.Max == null) range.Max = valueMax;
  1618. if (range.Min == null) range.Min = valueMin;
  1619. if (range.Max < valueMax) range.Max = valueMax;
  1620. if (range.Min > valueMin) range.Min = valueMin;
  1621. }
  1622. return range;
  1623. }
  1624. }
  1625. //画矩形
  1626. function ChartRectangle()
  1627. {
  1628. this.newMethod = IChartPainting; //派生
  1629. this.newMethod();
  1630. delete this.newMethod;
  1631. this.ClassName ='ChartRectangle';
  1632. this.Color = [];
  1633. this.Rect;
  1634. this.BorderColor = g_JSChartResource.FrameBorderPen;
  1635. this.Draw = function ()
  1636. {
  1637. if (!this.IsShow || this.ChartFrame.IsMinSize) return;
  1638. if (!this.Color || !this.Rect) return;
  1639. if (this.Color.length <= 0) return;
  1640. this.Canvas.setStrokeStyle(this.BorderColor);
  1641. var bFill = false;
  1642. if (this.Color.length == 2)
  1643. {
  1644. /* TODO 渐变下次做吧
  1645. if (this.ColorAngle==0)
  1646. {
  1647. var ptStart={ X:this.ChartBorder.GetLeft(), Y:this.ChartBorder.GetTopEx() };
  1648. var ptEnd={ X:this.ChartBorder.GetLeft(), Y:this.ChartBorder.GetBottomEx() };
  1649. }
  1650. else
  1651. {
  1652. var ptStart={ X:this.ChartBorder.GetLeft(), Y:this.ChartBorder.GetTopEx() };
  1653. var ptEnd={ X:this.ChartBorder.GetRight(), Y:this.ChartBorder.GetTopEx() };
  1654. }
  1655. let gradient = this.Canvas.createLinearGradient(ptStart.X,ptStart.Y, ptEnd.X,ptEnd.Y);
  1656. gradient.addColorStop(0, this.Color[0]);
  1657. gradient.addColorStop(1, this.Color[1]);
  1658. this.Canvas.fillStyle=gradient;
  1659. */
  1660. this.Canvas.setFillStyle(this.Color[0]);
  1661. bFill = true;
  1662. }
  1663. else if (this.Color.length == 1)
  1664. {
  1665. if (this.Color[0])
  1666. {
  1667. this.Canvas.setFillStyle(this.Color[0]);
  1668. bFill = true;
  1669. }
  1670. }
  1671. else
  1672. {
  1673. return;
  1674. }
  1675. var chartWidth = this.ChartBorder.GetWidth();
  1676. var chartHeight = this.ChartBorder.GetHeightEx();
  1677. var left = this.Rect.Left / 1000 * chartWidth;
  1678. var top = this.Rect.Top / 1000 * chartHeight;
  1679. var right = this.Rect.Right / 1000 * chartWidth;
  1680. var bottom = this.Rect.Bottom / 1000 * chartHeight;
  1681. left = this.ChartBorder.GetLeft() + left
  1682. top = this.ChartBorder.GetTopEx() + top;
  1683. right = this.ChartBorder.GetLeft() + right;
  1684. bottom = this.ChartBorder.GetTopEx() + bottom;
  1685. var width = Math.abs(left - right);
  1686. var height = Math.abs(top - bottom);
  1687. if (bFill) this.Canvas.fillRect(left, top, width, height);
  1688. this.Canvas.rect(ToFixedPoint(left), ToFixedPoint(top), ToFixedRect(width), ToFixedRect(height));
  1689. this.Canvas.stroke();
  1690. }
  1691. }
  1692. //K线叠加
  1693. function ChartOverlayKLine()
  1694. {
  1695. this.newMethod = IChartPainting; //派生
  1696. this.newMethod();
  1697. delete this.newMethod;
  1698. this.Color = "rgb(65,105,225)";
  1699. this.MainData; //主图K线数据
  1700. this.SourceData; //叠加的原始数据
  1701. this.Name = "ChartOverlayKLine";
  1702. this.Title;
  1703. this.DrawType = 0;
  1704. this.ClassName ='ChartOverlayKLine';
  1705. this.CustomDrawType = null; //图形类型
  1706. this.SetOption = function (option)
  1707. {
  1708. if (!option) return;
  1709. if (IFrameSplitOperator.IsNumber(option.DrawType)) this.CustomDrawType = option.DrawType;
  1710. }
  1711. this.DrawKBar = function (firstOpen) //firstOpen 当前屏第1个显示数据
  1712. {
  1713. var isHScreen = (this.ChartFrame.IsHScreen === true);
  1714. var dataWidth = this.ChartFrame.DataWidth;
  1715. var distanceWidth = this.ChartFrame.DistanceWidth;
  1716. var xOffset = this.ChartBorder.GetLeft() + distanceWidth / 2.0 + 2.0;
  1717. if (isHScreen) xOffset = this.ChartBorder.GetTop() + distanceWidth / 2.0 + 2.0;
  1718. var chartright = this.ChartBorder.GetRight();
  1719. if (isHScreen) chartright = this.ChartBorder.GetBottom();
  1720. var xPointCount = this.ChartFrame.XPointCount;
  1721. var isFristDraw = true;
  1722. var firstOverlayOpen = null;
  1723. for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j, xOffset += (dataWidth + distanceWidth))
  1724. {
  1725. var data = this.Data.Data[i];
  1726. if (!data || data.Open == null || data.High == null || data.Low == null || data.Close == null) continue;
  1727. if (firstOverlayOpen == null) firstOverlayOpen = data.Open;
  1728. if (isFristDraw)
  1729. {
  1730. this.Canvas.setStrokeStyle(this.Color);
  1731. this.Canvas.setFillStyle(this.Color);
  1732. this.Canvas.beginPath();
  1733. isFristDraw = false;
  1734. }
  1735. var left = xOffset;
  1736. var right = xOffset + dataWidth;
  1737. if (right > chartright) break;
  1738. var x = left + (right - left) / 2;
  1739. var yLow = this.ChartFrame.GetYFromData(data.Low / firstOverlayOpen * firstOpen);
  1740. var yHigh = this.ChartFrame.GetYFromData(data.High / firstOverlayOpen * firstOpen);
  1741. var yOpen = this.ChartFrame.GetYFromData(data.Open / firstOverlayOpen * firstOpen);
  1742. var yClose = this.ChartFrame.GetYFromData(data.Close / firstOverlayOpen * firstOpen);
  1743. var y = yHigh;
  1744. if (data.Open < data.Close) //阳线
  1745. {
  1746. if (dataWidth >= 4)
  1747. {
  1748. if (data.High > data.Close) //上影线
  1749. {
  1750. if (isHScreen)
  1751. {
  1752. this.Canvas.moveTo(ToFixedPoint(y), ToFixedPoint(x));
  1753. this.Canvas.lineTo(ToFixedPoint(this.DrawType == 3 ? Math.max(yClose, yOpen) : yClose), ToFixedPoint(x));
  1754. }
  1755. else
  1756. {
  1757. this.Canvas.moveTo(ToFixedPoint(x), ToFixedPoint(y));
  1758. this.Canvas.lineTo(ToFixedPoint(x), ToFixedPoint(this.DrawType == 3 ? Math.min(yClose, yOpen) : yClose));
  1759. }
  1760. y = yClose;
  1761. }
  1762. else
  1763. {
  1764. y = yClose;
  1765. }
  1766. if (isHScreen) {
  1767. if (Math.abs(yOpen - y) < 1)
  1768. {
  1769. this.Canvas.fillRect(ToFixedRect(y), ToFixedRect(left), 1, ToFixedRect(dataWidth)); //高度小于1,统一使用高度1
  1770. }
  1771. else
  1772. {
  1773. if (this.DrawType == 3) this.Canvas.rect(ToFixedPoint(y), ToFixedPoint(left), ToFixedRect(yOpen - y), ToFixedRect(dataWidth)); //空心柱
  1774. else this.Canvas.fillRect(ToFixedRect(y), ToFixedRect(left), ToFixedRect(yOpen - y), ToFixedRect(dataWidth));
  1775. }
  1776. }
  1777. else
  1778. {
  1779. if (Math.abs(yOpen - y) < 1)
  1780. {
  1781. this.Canvas.fillRect(ToFixedRect(left), ToFixedRect(y), ToFixedRect(dataWidth), 1); //高度小于1,统一使用高度1
  1782. }
  1783. else
  1784. {
  1785. if (this.DrawType == 3) this.Canvas.rect(ToFixedPoint(left), ToFixedPoint(y), ToFixedRect(dataWidth), ToFixedRect(yOpen - y)); //空心柱
  1786. else this.Canvas.fillRect(ToFixedRect(left), ToFixedRect(y), ToFixedRect(dataWidth), ToFixedRect(yOpen - y));
  1787. }
  1788. }
  1789. if (data.Open > data.Low)
  1790. {
  1791. if (isHScreen)
  1792. {
  1793. this.Canvas.moveTo(ToFixedPoint(this.DrawType == 3 ? Math.min(yClose, yOpen) : y), ToFixedPoint(x));
  1794. this.Canvas.lineTo(ToFixedPoint(yLow), ToFixedPoint(x));
  1795. }
  1796. else
  1797. {
  1798. this.Canvas.moveTo(ToFixedPoint(x), ToFixedPoint(this.DrawType == 3 ? Math.max(yClose, yOpen) : y));
  1799. this.Canvas.lineTo(ToFixedPoint(x), ToFixedPoint(yLow));
  1800. }
  1801. }
  1802. }
  1803. else
  1804. {
  1805. if (isHScreen)
  1806. {
  1807. this.Canvas.moveTo(yHigh, ToFixedPoint(x));
  1808. this.Canvas.lineTo(yLow, ToFixedPoint(x));
  1809. }
  1810. else
  1811. {
  1812. this.Canvas.moveTo(ToFixedPoint(x), yHigh);
  1813. this.Canvas.lineTo(ToFixedPoint(x), yLow);
  1814. }
  1815. }
  1816. }
  1817. else if (data.Open > data.Close) //阴线
  1818. {
  1819. if (dataWidth >= 4)
  1820. {
  1821. if (data.High > data.Close) //上影线
  1822. {
  1823. if (isHScreen)
  1824. {
  1825. this.Canvas.moveTo(ToFixedPoint(y), ToFixedPoint(x));
  1826. this.Canvas.lineTo(ToFixedPoint(yOpen), ToFixedPoint(x));
  1827. }
  1828. else
  1829. {
  1830. this.Canvas.moveTo(ToFixedPoint(x), ToFixedPoint(y));
  1831. this.Canvas.lineTo(ToFixedPoint(x), ToFixedPoint(yOpen));
  1832. }
  1833. y = yOpen;
  1834. }
  1835. else
  1836. {
  1837. y = yOpen
  1838. }
  1839. if (isHScreen)
  1840. {
  1841. if (Math.abs(yClose - y) < 1) this.Canvas.fillRect(ToFixedRect(y), ToFixedRect(left), 1, ToFixedRect(dataWidth)); //高度小于1,统一使用高度1
  1842. else this.Canvas.fillRect(ToFixedRect(y), ToFixedRect(left), ToFixedRect(yClose - y), ToFixedRect(dataWidth));
  1843. }
  1844. else
  1845. {
  1846. if (Math.abs(yClose - y) < 1) this.Canvas.fillRect(ToFixedRect(left), ToFixedRect(y), ToFixedRect(dataWidth), 1); //高度小于1,统一使用高度1
  1847. else this.Canvas.fillRect(ToFixedRect(left), ToFixedRect(y), ToFixedRect(dataWidth), ToFixedRect(yClose - y));
  1848. }
  1849. if (data.Open > data.Low) //下影线
  1850. {
  1851. if (isHScreen)
  1852. {
  1853. this.Canvas.moveTo(ToFixedPoint(y), ToFixedPoint(x));
  1854. this.Canvas.lineTo(ToFixedPoint(yLow), ToFixedPoint(x));
  1855. }
  1856. else
  1857. {
  1858. this.Canvas.moveTo(ToFixedPoint(x), ToFixedPoint(y));
  1859. this.Canvas.lineTo(ToFixedPoint(x), ToFixedPoint(yLow));
  1860. }
  1861. }
  1862. }
  1863. else
  1864. {
  1865. if (isHScreen)
  1866. {
  1867. this.Canvas.moveTo(yHigh, ToFixedPoint(x));
  1868. this.Canvas.lineTo(yLow, ToFixedPoint(x));
  1869. }
  1870. else
  1871. {
  1872. this.Canvas.moveTo(ToFixedPoint(x), yHigh);
  1873. this.Canvas.lineTo(ToFixedPoint(x), yLow);
  1874. }
  1875. }
  1876. }
  1877. else // 平线
  1878. {
  1879. if (dataWidth >= 4)
  1880. {
  1881. if (data.High > data.Close) //上影线
  1882. {
  1883. if (isHScreen)
  1884. {
  1885. this.Canvas.moveTo(y, ToFixedPoint(x));
  1886. this.Canvas.lineTo(yOpen, ToFixedPoint(x));
  1887. }
  1888. else
  1889. {
  1890. this.Canvas.moveTo(ToFixedPoint(x), y);
  1891. this.Canvas.lineTo(ToFixedPoint(x), yOpen);
  1892. }
  1893. y = yOpen;
  1894. }
  1895. else
  1896. {
  1897. y = yOpen;
  1898. }
  1899. if (isHScreen)
  1900. {
  1901. this.Canvas.moveTo(ToFixedPoint(y), ToFixedPoint(left));
  1902. this.Canvas.lineTo(ToFixedPoint(y), ToFixedPoint(right));
  1903. }
  1904. else
  1905. {
  1906. this.Canvas.moveTo(ToFixedPoint(left), ToFixedPoint(y));
  1907. this.Canvas.lineTo(ToFixedPoint(right), ToFixedPoint(y));
  1908. }
  1909. if (data.Open > data.Low) //下影线
  1910. {
  1911. if (isHScreen)
  1912. {
  1913. this.Canvas.moveTo(ToFixedPoint(y), ToFixedPoint(x));
  1914. this.Canvas.lineTo(ToFixedPoint(yLow), ToFixedPoint(x));
  1915. }
  1916. else
  1917. {
  1918. this.Canvas.moveTo(ToFixedPoint(x), ToFixedPoint(y));
  1919. this.Canvas.lineTo(ToFixedPoint(x), ToFixedPoint(yLow));
  1920. }
  1921. }
  1922. }
  1923. else
  1924. {
  1925. if (isHScreen)
  1926. {
  1927. this.Canvas.moveTo(yHigh, ToFixedPoint(x));
  1928. this.Canvas.lineTo(yLow, ToFixedPoint(x));
  1929. }
  1930. else
  1931. {
  1932. this.Canvas.moveTo(ToFixedPoint(x), yHigh);
  1933. this.Canvas.lineTo(ToFixedPoint(x), yLow);
  1934. }
  1935. }
  1936. }
  1937. }
  1938. if (isFristDraw == false) this.Canvas.stroke();
  1939. }
  1940. this.DrawAKLine = function (firstOpen) //美国线
  1941. {
  1942. var isHScreen = (this.ChartFrame.IsHScreen === true);
  1943. var dataWidth = this.ChartFrame.DataWidth;
  1944. var distanceWidth = this.ChartFrame.DistanceWidth;
  1945. var xOffset = this.ChartBorder.GetLeft() + distanceWidth / 2.0 + 2.0;
  1946. if (isHScreen) xOffset = this.ChartBorder.GetTop() + distanceWidth / 2.0 + 2.0;
  1947. var chartright = this.ChartBorder.GetRight();
  1948. if (isHScreen) chartright = this.ChartBorder.GetBottom();
  1949. var xPointCount = this.ChartFrame.XPointCount;
  1950. var firstOverlayOpen = null;
  1951. this.Canvas.setStrokeStyle(this.Color);
  1952. for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j, xOffset += (dataWidth + distanceWidth))
  1953. {
  1954. var data = this.Data.Data[i];
  1955. if (data.Open == null || data.High == null || data.Low == null || data.Close == null) continue;
  1956. if (firstOverlayOpen == null) firstOverlayOpen = data.Open;
  1957. var left = xOffset;
  1958. var right = xOffset + dataWidth;
  1959. if (right > chartright) break;
  1960. var x = left + (right - left) / 2;
  1961. var yLow = this.ChartFrame.GetYFromData(data.Low / firstOverlayOpen * firstOpen);
  1962. var yHigh = this.ChartFrame.GetYFromData(data.High / firstOverlayOpen * firstOpen);
  1963. var yOpen = this.ChartFrame.GetYFromData(data.Open / firstOverlayOpen * firstOpen);
  1964. var yClose = this.ChartFrame.GetYFromData(data.Close / firstOverlayOpen * firstOpen);
  1965. this.Canvas.beginPath(); //最高-最低
  1966. if (isHScreen)
  1967. {
  1968. this.Canvas.moveTo(yHigh, ToFixedPoint(x));
  1969. this.Canvas.lineTo(yLow, ToFixedPoint(x));
  1970. }
  1971. else
  1972. {
  1973. this.Canvas.moveTo(ToFixedPoint(x), yHigh);
  1974. this.Canvas.lineTo(ToFixedPoint(x), yLow);
  1975. }
  1976. this.Canvas.stroke();
  1977. if (dataWidth >= 4)
  1978. {
  1979. this.Canvas.beginPath(); //开盘
  1980. if (isHScreen)
  1981. {
  1982. this.Canvas.moveTo(ToFixedPoint(yOpen), left);
  1983. this.Canvas.lineTo(ToFixedPoint(yOpen), x);
  1984. }
  1985. else
  1986. {
  1987. this.Canvas.moveTo(left, ToFixedPoint(yOpen));
  1988. this.Canvas.lineTo(x, ToFixedPoint(yOpen));
  1989. }
  1990. this.Canvas.stroke();
  1991. this.Canvas.beginPath(); //收盘
  1992. if (isHScreen)
  1993. {
  1994. this.Canvas.moveTo(ToFixedPoint(yClose), right);
  1995. this.Canvas.lineTo(ToFixedPoint(yClose), x);
  1996. }
  1997. else
  1998. {
  1999. this.Canvas.moveTo(right, ToFixedPoint(yClose));
  2000. this.Canvas.lineTo(x, ToFixedPoint(yClose));
  2001. }
  2002. this.Canvas.stroke();
  2003. }
  2004. }
  2005. }
  2006. this.DrawCloseLine = function (firstOpen) //收盘价线
  2007. {
  2008. var isHScreen = (this.ChartFrame.IsHScreen === true);
  2009. var dataWidth = this.ChartFrame.DataWidth;
  2010. var distanceWidth = this.ChartFrame.DistanceWidth;
  2011. var xOffset = this.ChartBorder.GetLeft() + distanceWidth / 2.0 + 2.0;
  2012. if (isHScreen) xOffset = this.ChartBorder.GetTop() + distanceWidth / 2.0 + 2.0;
  2013. var chartright = this.ChartBorder.GetRight();
  2014. if (isHScreen) chartright = this.ChartBorder.GetBottom();
  2015. var xPointCount = this.ChartFrame.XPointCount;
  2016. var firstOverlayOpen = null;
  2017. var bFirstPoint = true;
  2018. this.Canvas.setStrokeStyle(this.Color);
  2019. this.Canvas.beginPath();
  2020. for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j, xOffset += (dataWidth + distanceWidth))
  2021. {
  2022. var data = this.Data.Data[i];
  2023. if (data.Open == null || data.High == null || data.Low == null || data.Close == null) continue;
  2024. if (firstOverlayOpen == null) firstOverlayOpen = data.Open;
  2025. var left = xOffset;
  2026. var right = xOffset + dataWidth;
  2027. if (right > chartright) break;
  2028. var x = left + (right - left) / 2;
  2029. var yClose = this.ChartFrame.GetYFromData(data.Close / firstOverlayOpen * firstOpen);
  2030. if (bFirstPoint)
  2031. {
  2032. if (isHScreen) this.Canvas.moveTo(yClose, x);
  2033. else this.Canvas.moveTo(x, yClose);
  2034. bFirstPoint = false;
  2035. }
  2036. else
  2037. {
  2038. if (isHScreen) this.Canvas.lineTo(yClose, x);
  2039. else this.Canvas.lineTo(x, yClose);
  2040. }
  2041. }
  2042. if (bFirstPoint == false) this.Canvas.stroke();
  2043. }
  2044. this.Draw = function ()
  2045. {
  2046. this.TooltipRect = [];
  2047. if (!this.MainData || !this.Data) return;
  2048. var xPointCount = this.ChartFrame.XPointCount;
  2049. var firstOpen = null; //主线数据第1个开盘价
  2050. for (var i = this.Data.DataOffset, j = 0; i < this.MainData.Data.length && j < xPointCount; ++i, ++j)
  2051. {
  2052. var data = this.MainData.Data[i];
  2053. if (data.Open == null || data.High == null || data.Low == null || data.Close == null) continue;
  2054. firstOpen = data.Open;
  2055. break;
  2056. }
  2057. if (firstOpen == null) return;
  2058. var drawTypeBackup = this.DrawType; //备份下线段类型
  2059. if (this.CustomDrawType != null) this.DrawType = this.CustomDrawType;
  2060. if (this.DrawType == 1) this.DrawCloseLine(firstOpen);
  2061. else if (this.DrawType == 2) this.DrawAKLine(firstOpen);
  2062. else this.DrawKBar(firstOpen);
  2063. this.DrawType = drawTypeBackup; //还原线段类型
  2064. }
  2065. this.GetMaxMin = function ()
  2066. {
  2067. var xPointCount = this.ChartFrame.XPointCount;
  2068. var range = {};
  2069. range.Max = null;
  2070. range.Min = null;
  2071. if (!this.MainData || !this.Data) return range;
  2072. var firstOpen = null; //主线数据第1个收盘价
  2073. for (var i = this.Data.DataOffset, j = 0; i < this.MainData.Data.length && j < xPointCount; ++i, ++j)
  2074. {
  2075. var data = this.MainData.Data[i];
  2076. if (data.Open == null || data.High == null || data.Low == null || data.Close == null) continue;
  2077. firstOpen = data.Close;
  2078. break;
  2079. }
  2080. if (firstOpen == null) return range;
  2081. var firstOverlayOpen = null;
  2082. var high, low;
  2083. for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j)
  2084. {
  2085. var data = this.Data.Data[i];
  2086. if (!data || data.Open == null || data.High == null || data.Low == null || data.Close == null) continue;
  2087. if (firstOverlayOpen == null) firstOverlayOpen = data.Open;
  2088. high = data.High / firstOverlayOpen * firstOpen;
  2089. low = data.Low / firstOverlayOpen * firstOpen;
  2090. if (range.Max == null) range.Max = high;
  2091. if (range.Min == null) range.Min = low;
  2092. if (range.Max < high) range.Max = high;
  2093. if (range.Min > low) range.Min = low;
  2094. }
  2095. return range;
  2096. }
  2097. }
  2098. // 多文本集合 支持横屏
  2099. function ChartMultiText()
  2100. {
  2101. this.newMethod = IChartPainting; //派生
  2102. this.newMethod();
  2103. delete this.newMethod;
  2104. this.ClassName ='ChartMultiText';
  2105. this.Texts = []; //[ {Index:, Value:, Text:, Color:, Font: , Baseline:, Line:{ Color:, Dash:[虚线点], KData:"H/L", Offset:[5,10], Width:线粗细 } } ]
  2106. this.Font = g_JSChartResource.DefaultTextFont;
  2107. this.Color = g_JSChartResource.DefaultTextColor;
  2108. this.IsHScreen = false; //是否横屏
  2109. this.Draw = function ()
  2110. {
  2111. if (!this.IsShow || this.ChartFrame.IsMinSize) return;
  2112. if (!this.Data || this.Data.length <= 0) return;
  2113. if (!this.Texts) return;
  2114. this.IsHScreen = (this.ChartFrame.IsHScreen === true);
  2115. var xPointCount = this.ChartFrame.XPointCount;
  2116. var offset = this.Data.DataOffset;
  2117. var left = this.ChartBorder.GetLeft();
  2118. var right = this.ChartBorder.GetRight();
  2119. if (this.IsHScreen)
  2120. {
  2121. left = this.ChartBorder.GetTop();
  2122. right = this.ChartBorder.GetBottom();
  2123. }
  2124. for (var i in this.Texts)
  2125. {
  2126. var item = this.Texts[i];
  2127. if (!item.Text) continue;
  2128. if (!IFrameSplitOperator.IsNumber(item.Index)) continue;
  2129. var index = item.Index - offset;
  2130. if (index >= 0 && index < xPointCount)
  2131. {
  2132. var x = this.ChartFrame.GetXFromIndex(index);
  2133. var y = this.ChartFrame.GetYFromData(item.Value);
  2134. if (item.Color) this.Canvas.setFillStyle(item.Color);
  2135. else this.Canvas.setFillStyle(this.Color);
  2136. if (item.Font) this.Canvas.font = item.Font;
  2137. else this.Canvas.font = this.Font;
  2138. var textWidth = this.Canvas.measureText(item.Text).width;
  2139. this.Canvas.textAlign = 'center';
  2140. if (x + textWidth / 2 >= right)
  2141. {
  2142. this.Canvas.textAlign = 'right';
  2143. x = right;
  2144. }
  2145. else if (x - textWidth / 2 < left)
  2146. {
  2147. this.Canvas.textAlign = 'left';
  2148. x = left;
  2149. }
  2150. if (item.Baseline == 1) this.Canvas.textBaseline = 'top';
  2151. else if (item.Baseline == 2) this.Canvas.textBaseline = 'bottom';
  2152. else this.Canvas.textBaseline = 'middle';
  2153. if (this.IsHScreen) //横屏旋转
  2154. {
  2155. this.Canvas.save();
  2156. this.Canvas.translate(y, x);
  2157. this.Canvas.rotate(90 * Math.PI / 180);
  2158. this.Canvas.fillText(item.Text, 0, 0);
  2159. this.Canvas.restore();
  2160. }
  2161. else
  2162. {
  2163. this.Canvas.fillText(item.Text, x, y);
  2164. }
  2165. if (item.Line)
  2166. {
  2167. var kItem=this.Data.Data[item.Index];
  2168. var price=item.Line.KData=="H"? kItem.High:kItem.Low;
  2169. var yPrice=this.ChartFrame.GetYFromData(price);
  2170. var yText=y;
  2171. if (Array.isArray(item.Line.Offset) && item.Line.Offset.length==2)
  2172. {
  2173. if (yText>yPrice) //文字在下方
  2174. {
  2175. yText-=item.Line.Offset[1];
  2176. yPrice+=item.Line.Offset[0]
  2177. }
  2178. else if (yText<yPrice)
  2179. {
  2180. yText+=item.Line.Offset[1];
  2181. yPrice-=item.Line.Offset[0]
  2182. }
  2183. }
  2184. this.Canvas.save();
  2185. if (item.Line.Dash) this.Canvas.setLineDash(item.Line.Dash); //虚线
  2186. if (item.Line.Width>0) this.Canvas.lineWidth=item.Line.Width; //线宽
  2187. this.Canvas.setStrokeStyle(item.Line.Color);
  2188. this.Canvas.beginPath();
  2189. if (this.IsHScreen)
  2190. {
  2191. this.Canvas.moveTo(yText,ToFixedPoint(x));
  2192. this.Canvas.lineTo(yPrice,ToFixedPoint(x));
  2193. }
  2194. else
  2195. {
  2196. this.Canvas.moveTo(ToFixedPoint(x),yText);
  2197. this.Canvas.lineTo(ToFixedPoint(x),yPrice);
  2198. }
  2199. this.Canvas.stroke();
  2200. this.Canvas.restore();
  2201. }
  2202. }
  2203. }
  2204. }
  2205. this.GetMaxMin = function ()
  2206. {
  2207. var range = { Min: null, Max: null };
  2208. if (!this.Texts) return range;
  2209. var xPointCount = this.ChartFrame.XPointCount;
  2210. var start = this.Data.DataOffset;
  2211. var end = start + xPointCount;
  2212. for (var i in this.Texts)
  2213. {
  2214. var item = this.Texts[i];
  2215. if (item.Index >= start && item.Index < end)
  2216. {
  2217. if (range.Max == null) range.Max = item.Value;
  2218. else if (range.Max < item.Value) range.Max = item.Value;
  2219. if (range.Min == null) range.Min = item.Value;
  2220. else if (range.Min > item.Value) range.Min = item.Value;
  2221. }
  2222. }
  2223. return range;
  2224. }
  2225. }
  2226. // 多dom节点
  2227. function ChartMultiHtmlDom()
  2228. {
  2229. this.newMethod=IChartPainting; //派生
  2230. this.newMethod();
  2231. delete this.newMethod;
  2232. this.ClassName="ChartMultiHtmlDom";
  2233. this.Texts=[]; //[ {Index:, Value:, Text: ] Text=dom内容
  2234. this.IsHScreen=false; //是否横屏
  2235. this.DrawCallback; //function(op, obj) op:1=开始 2=结束 3=绘制单个数据
  2236. this.DrawItem=[];
  2237. this.Draw=function()
  2238. {
  2239. this.DrawItem=[];
  2240. if (this.DrawCallback) this.DrawCallback(1, {Self:this} );
  2241. this.DrawDom();
  2242. if (this.DrawCallback) this.DrawCallback(2, { Self:this, Draw:this.DrawItem } );
  2243. }
  2244. this.DrawDom=function()
  2245. {
  2246. if (!this.IsShow || this.ChartFrame.IsMinSize) return;
  2247. if (!this.Data || this.Data.length<=0) return;
  2248. this.IsHScreen=(this.ChartFrame.IsHScreen===true);
  2249. var xPointCount=this.ChartFrame.XPointCount;
  2250. var offset=this.Data.DataOffset;
  2251. for(var i in this.Texts)
  2252. {
  2253. var item=this.Texts[i];
  2254. if (!item.Text) continue;
  2255. if (!IFrameSplitOperator.IsNumber(item.Index)) continue;
  2256. var index=item.Index-offset;
  2257. var kItem=this.Data.Data[item.Index]; //K线数据
  2258. var obj={ KData:kItem, Item:item, IsShow:false, Self:this };
  2259. if (index>=0 && index<xPointCount)
  2260. {
  2261. var x=this.ChartFrame.GetXFromIndex(index);
  2262. var y=this.ChartFrame.GetYFromData(item.Value);
  2263. obj.X=x;
  2264. obj.Y=y;
  2265. obj.IsShow=true;
  2266. }
  2267. this.DrawItem.push(obj);
  2268. if (this.DrawCallback) this.DrawCallback(3, obj);
  2269. }
  2270. }
  2271. this.GetMaxMin=function()
  2272. {
  2273. var range={ Min:null, Max:null };
  2274. var xPointCount=this.ChartFrame.XPointCount;
  2275. var start=this.Data.DataOffset;
  2276. var end=start+xPointCount;
  2277. for(var i in this.Texts)
  2278. {
  2279. var item=this.Texts[i];
  2280. if (!IFrameSplitOperator.IsNumber(item.Index)) continue;
  2281. if (item.Index>=start && item.Index<end)
  2282. {
  2283. if (range.Max==null) range.Max=item.Value;
  2284. else if (range.Max<item.Value) range.Max=item.Value;
  2285. if (range.Min==null) range.Min=item.Value;
  2286. else if (range.Min>item.Value) range.Min=item.Value;
  2287. }
  2288. }
  2289. return range;
  2290. }
  2291. }
  2292. // 线段集合 支持横屏
  2293. function ChartMultiLine()
  2294. {
  2295. this.newMethod = IChartPainting; //派生
  2296. this.newMethod();
  2297. delete this.newMethod;
  2298. this.Lines = []; // [ {Point:[ {Index, Value }, ], Color: }, ]
  2299. this.IsHScreen = false;
  2300. this.LineWidth=1;
  2301. this.LineDash;
  2302. this.Draw = function ()
  2303. {
  2304. if (!this.IsShow || this.ChartFrame.IsMinSize) return;
  2305. if (!this.Data || this.Data.length <= 0) return;
  2306. this.IsHScreen = (this.ChartFrame.IsHScreen === true);
  2307. var xPointCount = this.ChartFrame.XPointCount;
  2308. var offset = this.Data.DataOffset;
  2309. var drawLines = [];
  2310. for (var i in this.Lines)
  2311. {
  2312. var line = this.Lines[i];
  2313. var drawPoints = { Point: [], Color: line.Color };
  2314. for (var j in line.Point)
  2315. {
  2316. var point = line.Point[j];
  2317. if (!IFrameSplitOperator.IsNumber(point.Index)) continue;
  2318. var index = point.Index - offset;
  2319. if (index >= 0 && index < xPointCount)
  2320. {
  2321. var x = this.ChartFrame.GetXFromIndex(index);
  2322. var y = this.ChartFrame.GetYFromData(point.Value);
  2323. drawPoints.Point.push({ X: x, Y: y });
  2324. }
  2325. }
  2326. if (drawPoints.Point.length >= 2) drawLines.push(drawPoints)
  2327. }
  2328. this.Canvas.save();
  2329. for (var i in drawLines)
  2330. {
  2331. if (this.LineDash) this.Canvas.setLineDash(this.LineDash);
  2332. if (IFrameSplitOperator.IsPlusNumber(this.LineWidth)) this.Canvas.lineWidth=this.LineWidth;
  2333. else this.Canvas.lineWidth=1;
  2334. var item = drawLines[i];
  2335. this.DrawLine(item);
  2336. }
  2337. this.Canvas.restore();
  2338. }
  2339. this.DrawLine = function (line)
  2340. {
  2341. this.Canvas.setStrokeStyle(line.Color);
  2342. for (var i in line.Point)
  2343. {
  2344. var item = line.Point[i];
  2345. if (i == 0)
  2346. {
  2347. this.Canvas.beginPath();
  2348. if (this.IsHScreen) this.Canvas.moveTo(item.Y, item.X);
  2349. else this.Canvas.moveTo(item.X, item.Y);
  2350. }
  2351. else
  2352. {
  2353. if (this.IsHScreen) this.Canvas.lineTo(item.Y, item.X);
  2354. else this.Canvas.lineTo(item.X, item.Y);
  2355. }
  2356. }
  2357. this.Canvas.stroke();
  2358. }
  2359. this.GetMaxMin = function ()
  2360. {
  2361. var range = { Min: null, Max: null };
  2362. var xPointCount = this.ChartFrame.XPointCount;
  2363. var start = this.Data.DataOffset;
  2364. var end = start + xPointCount;
  2365. for (var i in this.Lines)
  2366. {
  2367. var line = this.Lines[i];
  2368. for (var j in line.Point)
  2369. {
  2370. var point = line.Point[j];
  2371. if (point.Index >= start && point.Index < end)
  2372. {
  2373. if (range.Max == null) range.Max = point.Value;
  2374. else if (range.Max < point.Value) range.Max = point.Value;
  2375. if (range.Min == null) range.Min = point.Value;
  2376. else if (range.Min > point.Value) range.Min = point.Value;
  2377. }
  2378. }
  2379. }
  2380. return range;
  2381. }
  2382. }
  2383. // 柱子集合 支持横屏
  2384. function ChartMultiBar()
  2385. {
  2386. this.newMethod = IChartPainting; //派生
  2387. this.newMethod();
  2388. delete this.newMethod;
  2389. this.Bars = []; // [ {Point:[ {Index, Value, Value2 }, ], Color:, Width: , Type: 0 实心 1 空心 }, ]
  2390. this.IsHScreen = false;
  2391. this.Draw = function ()
  2392. {
  2393. if (!this.IsShow || this.ChartFrame.IsMinSize) return;
  2394. if (!this.Data || this.Data.length <= 0) return;
  2395. this.IsHScreen = (this.ChartFrame.IsHScreen === true);
  2396. var xPointCount = this.ChartFrame.XPointCount;
  2397. var offset = this.Data.DataOffset;
  2398. var dataWidth = this.ChartFrame.DataWidth;
  2399. var drawBars = [];
  2400. for (var i in this.Bars)
  2401. {
  2402. var item = this.Bars[i];
  2403. var drawPoints = { Point: [], Color: item.Color, Width: dataWidth, Type: 0 };
  2404. if (item.Type > 0) drawPoints.Type = item.Type;
  2405. if (item.Width > 0)
  2406. {
  2407. drawPoints.Width = item.Width;
  2408. if (drawPoints.Width > dataWidth) drawPoints.Width = dataWidth;
  2409. }
  2410. else
  2411. {
  2412. if (drawPoints.Width < 4) drawPoints.Width = 1;
  2413. }
  2414. for (var j in item.Point)
  2415. {
  2416. var point = item.Point[j];
  2417. if (!IFrameSplitOperator.IsNumber(point.Index)) continue;
  2418. var index = point.Index - offset;
  2419. if (index >= 0 && index < xPointCount)
  2420. {
  2421. var x = this.ChartFrame.GetXFromIndex(index);
  2422. var y = this.ChartFrame.GetYFromData(point.Value);
  2423. var y2 = this.ChartFrame.GetYFromData(point.Value2);
  2424. drawPoints.Point.push({ X: x, Y: y, Y2: y2 });
  2425. }
  2426. }
  2427. if (drawPoints.Point.length > 0) drawBars.push(drawPoints)
  2428. }
  2429. for (var i in drawBars)
  2430. {
  2431. var item = drawBars[i];
  2432. if (item.Width >= 4)
  2433. {
  2434. if (item.Type == 1) this.DrawHollowBar(item);
  2435. else this.DrawFillBar(item);
  2436. }
  2437. else
  2438. {
  2439. this.DrawLineBar(item);
  2440. }
  2441. }
  2442. }
  2443. this.DrawLineBar = function (bar)
  2444. {
  2445. this.Canvas.setStrokeStyle(bar.Color);
  2446. var backupLineWidth = this.Canvas.lineWidth;
  2447. this.Canvas.lineWidth = bar.Width;
  2448. for (var i in bar.Point)
  2449. {
  2450. var item = bar.Point[i];
  2451. this.Canvas.beginPath();
  2452. if (this.IsHScreen)
  2453. {
  2454. this.Canvas.moveTo(ToFixedPoint(item.Y), ToFixedPoint(item.X));
  2455. this.Canvas.lineTo(ToFixedPoint(item.Y2), ToFixedPoint(item.X));
  2456. }
  2457. else
  2458. {
  2459. this.Canvas.moveTo(ToFixedPoint(item.X), ToFixedPoint(item.Y));
  2460. this.Canvas.lineTo(ToFixedPoint(item.X), ToFixedPoint(item.Y2));
  2461. }
  2462. this.Canvas.stroke();
  2463. }
  2464. this.Canvas.lineWidth = backupLineWidth;
  2465. }
  2466. this.DrawFillBar = function (bar)
  2467. {
  2468. this.Canvas.setFillStyle(bar.Color);
  2469. for (var i in bar.Point)
  2470. {
  2471. var item = bar.Point[i];
  2472. var x = item.X - (bar.Width / 2);
  2473. var y = Math.min(item.Y, item.Y2);
  2474. var barWidth = bar.Width;
  2475. var barHeight = Math.abs(item.Y - item.Y2);
  2476. if (this.IsHScreen)
  2477. this.Canvas.fillRect(ToFixedRect(y), ToFixedRect(x), ToFixedRect(barHeight), ToFixedRect(barWidth));
  2478. else
  2479. this.Canvas.fillRect(ToFixedRect(x), ToFixedRect(y), ToFixedRect(barWidth), ToFixedRect(barHeight));
  2480. }
  2481. }
  2482. this.DrawHollowBar = function (bar) //空心柱子
  2483. {
  2484. this.Canvas.setStrokeStyle(bar.Color);
  2485. var backupLineWidth = 1;
  2486. for (var i in bar.Point)
  2487. {
  2488. var item = bar.Point[i];
  2489. var x = item.X - (bar.Width / 2);
  2490. var y = Math.min(item.Y, item.Y2);
  2491. var barWidth = bar.Width;
  2492. var barHeight = Math.abs(item.Y - item.Y2);
  2493. this.Canvas.beginPath();
  2494. if (this.IsHScreen)
  2495. this.Canvas.rect(ToFixedPoint(y), ToFixedPoint(x), ToFixedRect(barHeight), ToFixedRect(barWidth));
  2496. else
  2497. this.Canvas.rect(ToFixedPoint(x), ToFixedPoint(y), ToFixedRect(barWidth), ToFixedRect(barHeight));
  2498. this.Canvas.stroke();
  2499. }
  2500. this.Canvas.lineWidth = backupLineWidth;
  2501. }
  2502. this.GetMaxMin = function ()
  2503. {
  2504. var range = { Min: null, Max: null };
  2505. var xPointCount = this.ChartFrame.XPointCount;
  2506. var start = this.Data.DataOffset;
  2507. var end = start + xPointCount;
  2508. for (var i in this.Bars)
  2509. {
  2510. var item = this.Bars[i];
  2511. for (var j in item.Point)
  2512. {
  2513. var point = item.Point[j];
  2514. if (point.Index >= start && point.Index < end)
  2515. {
  2516. var minValue = Math.min(point.Value, point.Value2);
  2517. var maxValue = Math.max(point.Value, point.Value2);
  2518. if (range.Max == null) range.Max = maxValue;
  2519. else if (range.Max < maxValue) range.Max = maxValue;
  2520. if (range.Min == null) range.Min = minValue;
  2521. else if (range.Min > minValue) range.Min = minValue;
  2522. }
  2523. }
  2524. }
  2525. return range;
  2526. }
  2527. }
  2528. //分钟信息地雷 支持横屏
  2529. function ChartMinuteInfo()
  2530. {
  2531. this.newMethod = IChartPainting; //派生
  2532. this.newMethod();
  2533. delete this.newMethod;
  2534. this.ClassName = "ChartMinuteInfo";
  2535. this.Data = new Map() //Map key=date-time, value=[{Date, Time, Title, Type, ID:}]
  2536. this.SourceData;
  2537. this.ChartMinutePrice;
  2538. this.YClose;
  2539. this.TextColor = g_JSChartResource.MinuteInfo.TextColor;
  2540. this.Font = g_JSChartResource.MinuteInfo.Font;
  2541. this.PointColor = g_JSChartResource.MinuteInfo.PointColor;
  2542. this.LineColor = g_JSChartResource.MinuteInfo.LineColor;
  2543. this.TextBGColor = g_JSChartResource.MinuteInfo.TextBGColor;
  2544. this.TextHeight = 18;
  2545. this.TextRectCache = [];
  2546. this.InfoDrawCache = [];
  2547. this.FrameBottom;
  2548. this.FrameTop;
  2549. this.FrameLeft;
  2550. this.FrameRight;
  2551. this.YOffset = 5;
  2552. this.IsHScreen = false;
  2553. this.SetOption = function (option)
  2554. {
  2555. if (option.TextColor) this.TextColor = option.TextColor;
  2556. if (option.TextBGColor) this.TextBGColor = option.TextBGColor;
  2557. if (option.Font) this.Font = option.Font;
  2558. if (option.PointColor) this.PointColor = option.PointColor;
  2559. if (option.LineColor) this.LineColor = option.LineColor;
  2560. if (option.TextHeight > 0) this.TextHeight = option.TextHeight;
  2561. }
  2562. this.Draw = function ()
  2563. {
  2564. if (!this.ChartMinutePrice) return;
  2565. if (!this.Data || this.Data.size <= 0) return;
  2566. this.TextRectCache = [];
  2567. this.InfoDrawCache = [];
  2568. this.IsHScreen = (this.ChartFrame.IsHScreen === true);
  2569. var xPointCount = this.ChartFrame.XPointCount;
  2570. var minuteCount = this.ChartFrame.MinuteCount;
  2571. this.FrameBottom = this.ChartBorder.GetBottom();
  2572. this.FrameTop = this.ChartBorder.GetTop();
  2573. this.FrameLeft = this.ChartBorder.GetLeft();
  2574. this.FrameRight = this.ChartBorder.GetRight();
  2575. if (this.IsHScreen)
  2576. {
  2577. this.FrameRight = this.ChartBorder.GetBottom();
  2578. this.FrameLeft = this.ChartBorder.GetTop();
  2579. this.FrameBottom = this.ChartBorder.GetLeft();
  2580. this.FrameTop = this.ChartBorder.GetRight();
  2581. }
  2582. this.YClose = this.ChartMinutePrice.YClose;
  2583. var data = this.ChartMinutePrice.Data;
  2584. var isBeforeData = false;
  2585. if (this.ChartMinutePrice.SourceData)
  2586. {
  2587. data = this.ChartMinutePrice.SourceData;
  2588. isBeforeData = true;
  2589. }
  2590. this.Canvas.font = this.Font;
  2591. for (var i = data.DataOffset, j = 0; i < data.Data.length && j < xPointCount; ++i, ++j)
  2592. {
  2593. var item = this.SourceData.Data[i];
  2594. if (isBeforeData && item.Before) continue;
  2595. if (!item) continue;
  2596. var dateTime = item.DateTime;
  2597. if (!this.Data.has(dateTime)) continue;
  2598. if (this.IsHScreen)
  2599. this.CalcuateInfoHScreenPosition(this.Data.get(dateTime), j, item);
  2600. else
  2601. this.CalcuateInfoPosition(this.Data.get(dateTime), j, item);
  2602. }
  2603. for (var i in this.InfoDrawCache)
  2604. {
  2605. var item = this.InfoDrawCache[i];
  2606. this.DrawInfoLines(item);
  2607. }
  2608. for (var i in this.InfoDrawCache)
  2609. {
  2610. var item = this.InfoDrawCache[i];
  2611. this.DrawInfoText(item);
  2612. }
  2613. this.TextRectCache = [];
  2614. this.InfoDrawCache = [];
  2615. }
  2616. this.CalcuateInfoPosition = function (infoItem, index, minuteItem)
  2617. {
  2618. if (!infoItem || !infoItem.Data || infoItem.Data.length <= 0) return;
  2619. var showItem = infoItem.Data[0];
  2620. var textWidth = this.Canvas.measureText(showItem.Title).width + 4;
  2621. var textHeight = this.TextHeight;
  2622. var x = this.ChartFrame.GetXFromIndex(index);
  2623. var y = this.ChartFrame.GetYFromData(minuteItem.Close);
  2624. x = ToFixedPoint(x);
  2625. var isDrawLeft = x < (this.FrameLeft + Math.abs(this.FrameLeft - this.FrameRight) / 2);
  2626. var ARRAY_OFFSET = [2, 4, 3, 2, 3, 3, 2];
  2627. var offset = textHeight + ARRAY_OFFSET[index % ARRAY_OFFSET.length];
  2628. var yData =
  2629. {
  2630. Y:
  2631. [
  2632. { Value: y + (textHeight + this.YOffset), Offset: offset },
  2633. { Value: y - (2 * textHeight + this.YOffset), Offset: -offset }
  2634. ]
  2635. };
  2636. if (minuteItem.Close < this.YClose)
  2637. yData.Y = yData.Y.reverse();
  2638. var rtBorder = { X: x, Y: null, Width: textWidth, Height: textHeight };
  2639. if (!isDrawLeft) rtBorder.X -= rtBorder.Width;
  2640. this.FixTextRect(rtBorder, yData);
  2641. var InfoDrawItem = { Border: rtBorder, Start: { X: x, Y: y }, IsLeft: isDrawLeft, Title: showItem.Title };
  2642. this.InfoDrawCache.push(InfoDrawItem);
  2643. this.TextRectCache.push(rtBorder);
  2644. }
  2645. this.CalcuateInfoHScreenPosition = function (infoItem, index, minuteItem)
  2646. {
  2647. if (!infoItem || !infoItem.Data || infoItem.Data.length <= 0) return;
  2648. var showItem = infoItem.Data[0];
  2649. var textHeight = this.Canvas.measureText(showItem.Title).width + 4;
  2650. var textWidth = this.TextHeight;
  2651. var y = this.ChartFrame.GetXFromIndex(index);
  2652. var x = this.ChartFrame.GetYFromData(minuteItem.Close);
  2653. y = ToFixedPoint(y);
  2654. var isDrawLeft = y < (this.FrameLeft + Math.abs(this.FrameLeft - this.FrameRight) / 2);
  2655. var ARRAY_OFFSET = [2, 4, 3, 2, 3, 3, 2];
  2656. var offset = textWidth + ARRAY_OFFSET[index % ARRAY_OFFSET.length];
  2657. var xData =
  2658. {
  2659. X:
  2660. [
  2661. { Value: x + (textWidth + this.YOffset), Offset: offset },
  2662. { Value: x - (2 * textWidth + this.YOffset), Offset: -offset }
  2663. ]
  2664. };
  2665. if (minuteItem.Close > this.YClose)
  2666. xData.X = xData.X.reverse();
  2667. var rtBorder = { X: null, Y: y, Width: textWidth, Height: textHeight };
  2668. if (!isDrawLeft) rtBorder.Y -= rtBorder.Height;
  2669. this.FixHScreenTextRect(rtBorder, xData);
  2670. var InfoDrawItem = { Border: rtBorder, Start: { X: x, Y: y }, IsLeft: isDrawLeft, Title: showItem.Title };
  2671. this.InfoDrawCache.push(InfoDrawItem);
  2672. this.TextRectCache.push(rtBorder);
  2673. }
  2674. this.DrawInfoLines = function (item)
  2675. {
  2676. var rtBorder = item.Border;
  2677. var isDrawLeft = item.IsLeft;
  2678. this.Canvas.setStrokeStyle(this.LineColor);
  2679. this.Canvas.beginPath();
  2680. this.Canvas.moveTo(item.Start.X, item.Start.Y);
  2681. if (isDrawLeft)
  2682. {
  2683. this.Canvas.lineTo(rtBorder.X, rtBorder.Y);
  2684. }
  2685. else
  2686. {
  2687. if (this.IsHScreen) this.Canvas.lineTo(rtBorder.X, rtBorder.Y + rtBorder.Height);
  2688. else this.Canvas.lineTo(rtBorder.X + rtBorder.Width, rtBorder.Y);
  2689. }
  2690. this.Canvas.stroke();
  2691. this.Canvas.setFillStyle(this.PointColor);
  2692. this.Canvas.beginPath();
  2693. this.Canvas.arc(item.Start.X, item.Start.Y, 5, 0, 2 * Math.PI);
  2694. this.Canvas.closePath();
  2695. this.Canvas.fill();
  2696. }
  2697. this.DrawInfoText = function (item)
  2698. {
  2699. var rtBorder = item.Border;
  2700. var x = rtBorder.X, y = rtBorder.Y;
  2701. this.Canvas.setFillStyle(this.TextBGColor);
  2702. this.Canvas.fillRect(x, y, rtBorder.Width, rtBorder.Height);
  2703. this.Canvas.setStrokeStyle(this.LineColor);
  2704. this.Canvas.beginPath();
  2705. this.Canvas.rect(x, y, rtBorder.Width, rtBorder.Height);
  2706. this.Canvas.stroke();
  2707. if (this.IsHScreen)
  2708. {
  2709. this.Canvas.save();
  2710. this.Canvas.translate(rtBorder.X, rtBorder.Y);
  2711. this.Canvas.rotate(90 * Math.PI / 180);
  2712. x = 0; y = 0;
  2713. }
  2714. this.Canvas.textAlign = 'left'
  2715. this.Canvas.textBaseline = 'middle';
  2716. this.Canvas.setFillStyle(this.TextColor);
  2717. this.Canvas.font = this.Font;
  2718. if (this.IsHScreen) this.Canvas.fillText(item.Title, x + 2, y - rtBorder.Width / 2);
  2719. else this.Canvas.fillText(item.Title, x+2, y + rtBorder.Height / 2);
  2720. if (this.IsHScreen) this.Canvas.restore();
  2721. }
  2722. this.FixTextRect = function (rect, yData)
  2723. {
  2724. for (var k in yData.Y)
  2725. {
  2726. var yItem = yData.Y[k];
  2727. rect.Y = yItem.Value;
  2728. var y;
  2729. for (var j = 0; j < 10; ++j)
  2730. {
  2731. var isOverlap = false;
  2732. for (var i in this.TextRectCache)
  2733. {
  2734. var item = this.TextRectCache[i];
  2735. if (this.IsOverlap(item, rect))
  2736. {
  2737. isOverlap = true;
  2738. break;
  2739. }
  2740. }
  2741. if (isOverlap == false) return;
  2742. y = rect.Y;
  2743. y += yItem.Offset;
  2744. if (y + rect.Height > this.FrameBottom || y < this.FrameTop) break;
  2745. rect.Y = y;
  2746. }
  2747. }
  2748. }
  2749. this.FixHScreenTextRect = function (rect, xData)
  2750. {
  2751. for (var k in xData.X)
  2752. {
  2753. var xItem = xData.X[k];
  2754. rect.X = xItem.Value;
  2755. var x;
  2756. for (var j = 0; j < 10; ++j)
  2757. {
  2758. var isOverlap = false;
  2759. for (var i in this.TextRectCache)
  2760. {
  2761. var item = this.TextRectCache[i];
  2762. if (this.IsOverlap(item, rect))
  2763. {
  2764. isOverlap = true;
  2765. break;
  2766. }
  2767. }
  2768. if (isOverlap == false) return;
  2769. x = rect.X;
  2770. x += xItem.Offset;
  2771. if (x + rect.Width < this.FrameBottom || x > this.FrameTop) break;
  2772. rect.X = x;
  2773. }
  2774. }
  2775. }
  2776. this.IsOverlap = function (rc1, rc2)
  2777. {
  2778. if (rc1.X + rc1.Width > rc2.X && rc2.X + rc2.Width > rc1.X && rc1.Y + rc1.Height > rc2.Y && rc2.Y + rc2.Height > rc1.Y)
  2779. return true;
  2780. else
  2781. return false;
  2782. }
  2783. this.GetMaxMin = function ()
  2784. {
  2785. var range = { Min: null, Max: null };
  2786. return range;
  2787. }
  2788. }
  2789. //买卖盘
  2790. function ChartBuySell()
  2791. {
  2792. this.newMethod = ChartSingleText; //派生
  2793. this.newMethod();
  2794. delete this.newMethod;
  2795. this.ClassName = "ChartBuySell";
  2796. this.TextFont = g_JSChartResource.KLineTrain.Font; //"bold 14px arial"; //买卖信息字体
  2797. this.LastDataIcon = g_JSChartResource.KLineTrain.LastDataIcon; //{Color:'rgb(0,0,205)',Text:'↓'};
  2798. this.BuyIcon = g_JSChartResource.KLineTrain.BuyIcon; //{Color:'rgb(0,0,205)',Text:'B'};
  2799. this.SellIcon = g_JSChartResource.KLineTrain.SellIcon; //{Color:'rgb(0,0,205)',Text:'S'};
  2800. this.BuySellData = new Map(); //Key=数据索引index Value:Data:[ { Op: 买/卖 0=buy 1=sell, Date:, Time, Price: Vol:}, ]
  2801. this.AddTradeItem = function (tradeItem)
  2802. {
  2803. if (this.BuySellData.has(tradeItem.Key))
  2804. {
  2805. var Trade = this.BuySellData.get(tradeItem.Key);
  2806. Trade.Data.push(tradeItem);
  2807. }
  2808. else
  2809. {
  2810. this.BuySellData.set(tradeItem.Key, { Data: [tradeItem] });
  2811. }
  2812. }
  2813. this.ClearTradeData = function ()
  2814. {
  2815. this.BuySellData = new Map();
  2816. }
  2817. this.Draw = function ()
  2818. {
  2819. if (!this.Data || !this.Data.Data) return;
  2820. var isHScreen = (this.ChartFrame.IsHScreen === true);
  2821. var dataWidth = this.ChartFrame.DataWidth;
  2822. var distanceWidth = this.ChartFrame.DistanceWidth;
  2823. var chartright = this.ChartBorder.GetRight();
  2824. if (isHScreen === true) chartright = this.ChartBorder.GetBottom();
  2825. var xPointCount = this.ChartFrame.XPointCount;
  2826. var bottom = this.ChartBorder.GetBottomEx();
  2827. var top = this.ChartBorder.GetTopEx();
  2828. var height = this.ChartBorder.GetHeightEx();
  2829. if (isHScreen)
  2830. {
  2831. top = this.ChartBorder.GetRightEx();
  2832. bottom = this.ChartBorder.GetLeftEx();
  2833. height = this.ChartBorder.GetWidthEx();
  2834. }
  2835. this.Canvas.font = this.TextFont;
  2836. for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j)
  2837. {
  2838. var value = this.Data.Data[i];
  2839. if (value == null) continue;
  2840. if (x > chartright) break;
  2841. if (i == this.Data.Data.length - 1)
  2842. {
  2843. var x = this.ChartFrame.GetXFromIndex(j);
  2844. var yHigh = this.ChartFrame.GetYFromData(value.High);
  2845. if (this.LastDataIcon.Text)
  2846. {
  2847. this.Canvas.textAlign = 'center';
  2848. this.Canvas.textBaseline = 'bottom';
  2849. this.Canvas.setFillStyle(this.LastDataIcon.Color);
  2850. this.Canvas.font = this.TextFont;
  2851. this.DrawText(this.LastDataIcon.Text, x, yHigh, isHScreen);
  2852. }
  2853. else
  2854. {
  2855. var obj =
  2856. {
  2857. X: x, Top: top, Bottom: bottom, Height: height,
  2858. DataWidth: dataWidth, Color: this.LastDataIcon.Color, IsHScreen: isHScreen,
  2859. };
  2860. this.DrawLastData(obj);
  2861. }
  2862. }
  2863. var key = i;
  2864. if (!this.BuySellData.has(key)) continue;
  2865. var trade = this.BuySellData.get(key);
  2866. var x = this.ChartFrame.GetXFromIndex(j);
  2867. var yHigh = this.ChartFrame.GetYFromData(value.High);
  2868. var yLow = this.ChartFrame.GetYFromData(value.Low);
  2869. var drawInfo = [false, false]; //0=buy 1=sell
  2870. for (var k in trade.Data)
  2871. {
  2872. if (drawInfo[0] == true && drawInfo[1] == true) break; //买卖图标只画一次
  2873. var bsItem = trade.Data[k];
  2874. if (bsItem.Op == 0 && drawInfo[0] == false) //买 标识在最低价上
  2875. {
  2876. this.Canvas.textAlign = 'center';
  2877. this.Canvas.textBaseline = 'top';
  2878. this.Canvas.setFillStyle(this.BuyIcon.Color);
  2879. this.DrawText(this.BuyIcon.Text, x, yLow, isHScreen);
  2880. drawInfo[0] = true;
  2881. }
  2882. else if (bsItem.Op == 1 && drawInfo[1] == false) //卖 标识在最高价上
  2883. {
  2884. this.Canvas.textAlign = 'center';
  2885. this.Canvas.textBaseline = 'bottom';
  2886. this.Canvas.setFillStyle(this.SellIcon.Color);
  2887. this.DrawText(this.SellIcon.Text, x, yHigh, isHScreen);
  2888. drawInfo[1] = true;
  2889. }
  2890. }
  2891. }
  2892. }
  2893. this.DrawLastData=function(obj)
  2894. {
  2895. this.Canvas.setFillStyle(obj.Color);
  2896. var width = obj.DataWidth;
  2897. if (this.LastDataIcon.Width >= 2 && this.LastDataIcon.Width < obj.DataWidth)
  2898. width = this.LastDataIcon.Width;
  2899. var left = obj.X - width / 2;
  2900. if (obj.IsHScreen)
  2901. {
  2902. this.Canvas.fillRect(ToFixedRect(obj.Bottom), ToFixedRect(left), ToFixedRect(obj.Height), ToFixedRect(width));
  2903. }
  2904. else
  2905. {
  2906. var left = obj.X - width/2;
  2907. this.Canvas.fillRect(ToFixedRect(left), ToFixedRect(obj.Top), ToFixedRect(width), ToFixedRect(obj.Height));
  2908. }
  2909. }
  2910. }
  2911. //分钟成交量
  2912. function ChartMinuteVolumBar()
  2913. {
  2914. this.newMethod = IChartPainting; //派生
  2915. this.newMethod();
  2916. delete this.newMethod;
  2917. this.UpColor = g_JSChartResource.UpBarColor;
  2918. this.DownColor = g_JSChartResource.DownBarColor;
  2919. this.CustomColor=g_JSChartResource.Minute.VolBarColor;
  2920. this.YClose; //前收盘
  2921. this.Draw = function ()
  2922. {
  2923. var isHScreen = (this.ChartFrame.IsHScreen === true)
  2924. var chartright = this.ChartBorder.GetRight();
  2925. if (isHScreen) chartright = this.ChartBorder.GetBottom();
  2926. var xPointCount = this.ChartFrame.XPointCount;
  2927. var yBottom = this.ChartFrame.GetYFromData(0);
  2928. var yPrice = this.YClose; //上一分钟的价格
  2929. if (this.CustomColor) this.Canvas.strokeStyle=this.CustomColor;
  2930. for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j)
  2931. {
  2932. var item = this.Data.Data[i];
  2933. if (!item || !item.Vol) continue;
  2934. var y = this.ChartFrame.GetYFromData(item.Vol);
  2935. var x = this.ChartFrame.GetXFromIndex(i);
  2936. if (x > chartright) break;
  2937. //价格>=上一分钟价格 红色 否则绿色
  2938. if (!this.CustomColor) this.Canvas.setStrokeStyle(item.Close >= yPrice ? this.UpColor : this.DownColor);
  2939. this.Canvas.beginPath();
  2940. if (isHScreen)
  2941. {
  2942. this.Canvas.moveTo(y, ToFixedPoint(x));
  2943. this.Canvas.lineTo(yBottom, ToFixedPoint(x));
  2944. }
  2945. else
  2946. {
  2947. this.Canvas.moveTo(ToFixedPoint(x), y);
  2948. this.Canvas.lineTo(ToFixedPoint(x), yBottom);
  2949. }
  2950. this.Canvas.stroke();
  2951. yPrice = item.Close;
  2952. }
  2953. }
  2954. this.GetMaxMin = function ()
  2955. {
  2956. var xPointCount = this.ChartFrame.XPointCount;
  2957. var range = {};
  2958. range.Min = 0;
  2959. range.Max = null;
  2960. for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j)
  2961. {
  2962. var item = this.Data.Data[i];
  2963. if (!item || !item.Vol) continue;
  2964. if (range.Max == null) range.Max = item.Vol;
  2965. if (range.Max < item.Vol) range.Max = item.Vol;
  2966. }
  2967. return range;
  2968. }
  2969. }
  2970. //MACD森林线 支持横屏
  2971. function ChartMACD()
  2972. {
  2973. this.newMethod = IChartPainting; //派生
  2974. this.newMethod();
  2975. delete this.newMethod;
  2976. this.ClassName ='ChartMACD';
  2977. this.UpColor = g_JSChartResource.UpBarColor;
  2978. this.DownColor = g_JSChartResource.DownBarColor;
  2979. this.LineWidth=1;
  2980. this.Draw = function ()
  2981. {
  2982. if (this.ChartFrame.IsMinSize) return;
  2983. if (this.NotSupportMessage)
  2984. {
  2985. this.DrawNotSupportmessage();
  2986. return;
  2987. }
  2988. if (this.ChartFrame.IsHScreen === true)
  2989. {
  2990. this.HScreenDraw();
  2991. return;
  2992. }
  2993. var isMinute=this.IsMinuteFrame();
  2994. var dataWidth = this.ChartFrame.DataWidth;
  2995. var distanceWidth = this.ChartFrame.DistanceWidth;
  2996. var xOffset=this.ChartBorder.GetLeft()+distanceWidth/2.0+g_JSChartResource.FrameLeftMargin;
  2997. var chartright = this.ChartBorder.GetRight();
  2998. var xPointCount = this.ChartFrame.XPointCount;
  2999. var lineWidth=this.LineWidth;
  3000. if (this.LineWidth==50) lineWidth=dataWidth;
  3001. else if (lineWidth>dataWidth) lineWidth=dataWidth;
  3002. this.Canvas.save();
  3003. this.Canvas.lineWidth=lineWidth;
  3004. var bFirstPoint = true;
  3005. var drawCount = 0;
  3006. var yBottom = this.ChartFrame.GetYFromData(0);
  3007. for(var i=this.Data.DataOffset,j=0;i<this.Data.Data.length && j<xPointCount;++i,++j,xOffset+=(dataWidth+distanceWidth))
  3008. //for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j)
  3009. {
  3010. var value = this.Data.Data[i];
  3011. if (value == null) continue;
  3012. if (isMinute)
  3013. {
  3014. var x = this.ChartFrame.GetXFromIndex(j);
  3015. }
  3016. else
  3017. {
  3018. var left=xOffset;
  3019. var right=xOffset+dataWidth;
  3020. if (right>chartright) break;
  3021. var x=left+(right-left)/2;
  3022. }
  3023. var y = this.ChartFrame.GetYFromData(value);
  3024. if (x > chartright) break;
  3025. var xFix = parseInt(x.toString()) + 0.5; //毛边修正
  3026. this.Canvas.beginPath();
  3027. this.Canvas.moveTo(xFix, yBottom);
  3028. this.Canvas.lineTo(xFix, y);
  3029. if (value >= 0) this.Canvas.setStrokeStyle(this.UpColor);
  3030. else this.Canvas.setStrokeStyle(this.DownColor);
  3031. this.Canvas.stroke();
  3032. this.Canvas.closePath();
  3033. }
  3034. this.Canvas.restore();
  3035. }
  3036. this.HScreenDraw = function ()
  3037. {
  3038. var isMinute=this.IsMinuteFrame();
  3039. var dataWidth = this.ChartFrame.DataWidth;
  3040. var distanceWidth = this.ChartFrame.DistanceWidth;
  3041. var xOffset=this.ChartBorder.GetTop()+distanceWidth/2.0+g_JSChartResource.FrameLeftMargin;
  3042. var chartright = this.ChartBorder.GetBottom();
  3043. var xPointCount = this.ChartFrame.XPointCount;
  3044. var yBottom = this.ChartFrame.GetYFromData(0);
  3045. var lineWidth=this.LineWidth;
  3046. if (this.LineWidth==50) lineWidth=dataWidth;
  3047. else if (lineWidth>dataWidth) lineWidth=dataWidth;
  3048. this.Canvas.save();
  3049. this.Canvas.lineWidth=lineWidth;
  3050. for(var i=this.Data.DataOffset,j=0;i<this.Data.Data.length && j<xPointCount;++i,++j,xOffset+=(dataWidth+distanceWidth))
  3051. //for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j)
  3052. {
  3053. var value = this.Data.Data[i];
  3054. if (value == null) continue;
  3055. if (isMinute)
  3056. {
  3057. var x = this.ChartFrame.GetXFromIndex(j);
  3058. }
  3059. else
  3060. {
  3061. var left=xOffset;
  3062. var right=xOffset+dataWidth;
  3063. if (right>chartright) break;
  3064. var x=left+(right-left)/2;
  3065. }
  3066. var y = this.ChartFrame.GetYFromData(value);
  3067. if (x > chartright) break;
  3068. this.Canvas.beginPath();
  3069. this.Canvas.moveTo(yBottom, ToFixedPoint(x));
  3070. this.Canvas.lineTo(y, ToFixedPoint(x));
  3071. if (value >= 0) this.Canvas.setStrokeStyle(this.UpColor);
  3072. else this.Canvas.setStrokeStyle(this.DownColor);
  3073. this.Canvas.stroke();
  3074. this.Canvas.closePath();
  3075. }
  3076. this.Canvas.restore();
  3077. }
  3078. }
  3079. ////////////////////////////////////////////////////////////////////////////////
  3080. // 等待提示
  3081. function ChartSplashPaint()
  3082. {
  3083. this.newMethod = IChartPainting; //派生
  3084. this.newMethod();
  3085. delete this.newMethod;
  3086. this.Font = g_JSChartResource.DefaultTextFont; //字体
  3087. this.TextColor = g_JSChartResource.DefaultTextColor; //文本颜色
  3088. this.IsEnableSplash = false;
  3089. this.SplashTitle = '数据加载中.....';
  3090. this.HQChart;
  3091. this.EnableSplash=function(bEnable)
  3092. {
  3093. this.IsEnableSplash=bEnable;
  3094. if (this.HQChart)
  3095. {
  3096. var event=this.HQChart.GetEnableSplashEvent();
  3097. if (event)
  3098. {
  3099. var data={ Enable:bEnable };
  3100. event.Callback(event,data,this);
  3101. }
  3102. }
  3103. }
  3104. this.SetTitle=function(title)
  3105. {
  3106. this.SplashTitle=title;
  3107. }
  3108. this.Draw = function ()
  3109. {
  3110. if (!this.IsEnableSplash) return;
  3111. if (this.Frame.IsHScreen === true)
  3112. {
  3113. this.HScreenDraw();
  3114. return;
  3115. }
  3116. var xCenter = (this.Frame.ChartBorder.GetLeft() + this.Frame.ChartBorder.GetRight()) / 2;
  3117. var yCenter = (this.Frame.ChartBorder.GetTop() + this.Frame.ChartBorder.GetBottom()) / 2;
  3118. this.Canvas.textAlign = 'center';
  3119. this.Canvas.textBaseline = 'middle';
  3120. this.Canvas.setFillStyle(this.TextColor);
  3121. this.Canvas.font = this.Font;
  3122. this.Canvas.fillText(this.SplashTitle, xCenter, yCenter);
  3123. }
  3124. this.HScreenDraw = function () //横屏
  3125. {
  3126. var xCenter = (this.Frame.ChartBorder.GetLeft() + this.Frame.ChartBorder.GetRight()) / 2;
  3127. var yCenter = (this.Frame.ChartBorder.GetTop() + this.Frame.ChartBorder.GetBottom()) / 2;
  3128. this.Canvas.save();
  3129. this.Canvas.translate(xCenter, yCenter);
  3130. this.Canvas.rotate(90 * Math.PI / 180); //数据和框子旋转180度
  3131. this.Canvas.textAlign = 'center';
  3132. this.Canvas.textBaseline = 'middle';
  3133. this.Canvas.setFillStyle(this.TextColor);
  3134. this.Canvas.font = this.Font;
  3135. this.Canvas.fillText(this.SplashTitle, 0, 0);
  3136. this.Canvas.restore();
  3137. }
  3138. }
  3139. //填充背景 支持横屏
  3140. function ChartBackground()
  3141. {
  3142. this.newMethod=IChartPainting; //派生
  3143. this.newMethod();
  3144. delete this.newMethod;
  3145. this.ClassName="ChartBackground";
  3146. this.Color=null;
  3147. this.ColorAngle=0; //0 竖向 1 横向
  3148. this.IsDrawFirst = true; //面积图在K线前面画,否则回挡住K线的
  3149. this.IsHScreen=false;
  3150. this.Draw=function()
  3151. {
  3152. if (!this.IsShow || this.ChartFrame.IsMinSize) return;
  3153. if (!this.Color) return;
  3154. if (this.Color.length<=0) return;
  3155. this.IsHScreen=(this.ChartFrame.IsHScreen===true);
  3156. if (this.Color.length==2)
  3157. {
  3158. if (this.IsHScreen)
  3159. {
  3160. if (this.ColorAngle==0)
  3161. {
  3162. var ptStart={ X:this.ChartBorder.GetRight(), Y:this.ChartBorder.GetTopEx() };
  3163. var ptEnd={ X:this.ChartBorder.GetLeft(), Y:this.ChartBorder.GetTopEx() };
  3164. }
  3165. else
  3166. {
  3167. var ptStart={ X:this.ChartBorder.GetLeft(), Y:this.ChartBorder.GetTopEx() };
  3168. var ptEnd={ X:this.ChartBorder.GetLeft(), Y:this.ChartBorder.GetBottomEx() };
  3169. }
  3170. }
  3171. else
  3172. {
  3173. if (this.ColorAngle==0)
  3174. {
  3175. var ptStart={ X:this.ChartBorder.GetLeft(), Y:this.ChartBorder.GetTopEx() };
  3176. var ptEnd={ X:this.ChartBorder.GetLeft(), Y:this.ChartBorder.GetBottomEx() };
  3177. }
  3178. else
  3179. {
  3180. var ptStart={ X:this.ChartBorder.GetLeft(), Y:this.ChartBorder.GetTopEx() };
  3181. var ptEnd={ X:this.ChartBorder.GetRight(), Y:this.ChartBorder.GetTopEx() };
  3182. }
  3183. }
  3184. let gradient = this.Canvas.createLinearGradient(ptStart.X,ptStart.Y, ptEnd.X,ptEnd.Y);
  3185. gradient.addColorStop(0, this.Color[0]);
  3186. gradient.addColorStop(1, this.Color[1]);
  3187. this.Canvas.fillStyle=gradient;
  3188. }
  3189. else if (this.Color.length==1)
  3190. {
  3191. this.Canvas.fillStyle=this.Color[0];
  3192. }
  3193. else
  3194. {
  3195. return;
  3196. }
  3197. if (this.Name=="DRAWGBK2" || this.Name=="KLINE_BG")
  3198. {
  3199. this.DrawRegion();
  3200. return;
  3201. }
  3202. if (this.IsHScreen)
  3203. {
  3204. var left=this.ChartBorder.GetLeftEx();
  3205. var top=this.ChartBorder.GetTop();
  3206. var width=this.ChartBorder.GetWidthEx();
  3207. var height=this.ChartBorder.GetHeight();
  3208. }
  3209. else
  3210. {
  3211. var left=this.ChartBorder.GetLeft();
  3212. var top=this.ChartBorder.GetTopEx();
  3213. var width=this.ChartBorder.GetWidth();
  3214. var height=this.ChartBorder.GetHeightEx();
  3215. }
  3216. this.Canvas.fillRect(left, top,width, height);
  3217. }
  3218. this.DrawRegion=function()
  3219. {
  3220. var xPointCount=this.ChartFrame.XPointCount;
  3221. var xOffset=this.ChartBorder.GetLeft()+distanceWidth/2.0+g_JSChartResource.FrameLeftMargin;
  3222. var dataWidth=this.ChartFrame.DataWidth;
  3223. var distanceWidth=this.ChartFrame.DistanceWidth;
  3224. var top=this.ChartBorder.GetTopEx();
  3225. var bottom=this.ChartBorder.GetBottomEx();
  3226. if (this.IsHScreen)
  3227. {
  3228. top=this.ChartBorder.GetRightEx();
  3229. bottom=this.ChartBorder.GetLeftEx();
  3230. }
  3231. var aryPoint=[]; //点坐标
  3232. for(var i=this.Data.DataOffset,j=0;i<this.Data.Data.length && j<xPointCount;++i,++j,xOffset+=(dataWidth+distanceWidth))
  3233. {
  3234. var value=this.Data.Data[i];
  3235. aryPoint[i]=null;
  3236. if (!IFrameSplitOperator.IsNumber(value) || value<=0) continue;
  3237. var x=this.ChartFrame.GetXFromIndex(j);
  3238. var y=this.ChartFrame.GetYFromData(value.Value);
  3239. if (this.IsHScreen)
  3240. aryPoint[i]={ Line:{ X:bottom, Y:x }, Line2:{ X:top, Y:x } };
  3241. else
  3242. aryPoint[i]={ Line:{ X:x, Y:top }, Line2:{ X:x, Y:bottom } };
  3243. }
  3244. this.DrawBG(aryPoint);
  3245. }
  3246. this.DrawBG=function(aryPoint)
  3247. {
  3248. var dataWidth=this.ChartFrame.DataWidth;
  3249. var distanceWidth=this.ChartFrame.DistanceWidth;
  3250. var halfWidth=(distanceWidth+dataWidth)/2;
  3251. var firstPoint=true;
  3252. var pointCount=0;
  3253. var aryLine2=[];
  3254. var color=null;
  3255. for(var i in aryPoint)
  3256. {
  3257. var item=aryPoint[i];
  3258. if (!item || (color && item.Color!=color) )
  3259. {
  3260. if (pointCount>0)
  3261. {
  3262. for(var j=aryLine2.length-1; j>=0; --j)
  3263. {
  3264. var item2=aryLine2[j];
  3265. if (this.IsHScreen)
  3266. {
  3267. this.Canvas.lineTo(item2.Line2.X, item2.Line2.Y+halfWidth);
  3268. this.Canvas.lineTo(item2.Line2.X, item2.Line2.Y-halfWidth);
  3269. }
  3270. else
  3271. {
  3272. this.Canvas.lineTo(item2.Line2.X+halfWidth, item2.Line2.Y);
  3273. this.Canvas.lineTo(item2.Line2.X-halfWidth, item2.Line2.Y);
  3274. }
  3275. }
  3276. this.Canvas.closePath();
  3277. this.Canvas.fill();
  3278. }
  3279. firstPoint=true;
  3280. pointCount=0;
  3281. aryLine2=[];
  3282. color=null;
  3283. }
  3284. if (!item) continue;
  3285. if (firstPoint)
  3286. {
  3287. this.Canvas.beginPath();
  3288. if (this.IsHScreen)
  3289. {
  3290. this.Canvas.moveTo(item.Line.X, item.Line.Y-halfWidth);
  3291. this.Canvas.lineTo(item.Line.X, item.Line.Y+halfWidth);
  3292. }
  3293. else
  3294. {
  3295. this.Canvas.moveTo(item.Line.X-halfWidth, item.Line.Y);
  3296. this.Canvas.lineTo(item.Line.X+halfWidth, item.Line.Y);
  3297. }
  3298. firstPoint=false;
  3299. color=item.Color;
  3300. }
  3301. else
  3302. {
  3303. if (this.IsHScreen)
  3304. {
  3305. this.Canvas.lineTo(item.Line.X, item.Line.Y-halfWidth);
  3306. this.Canvas.lineTo(item.Line.X, item.Line.Y+halfWidth);
  3307. }
  3308. else
  3309. {
  3310. this.Canvas.lineTo(item.Line.X-halfWidth, item.Line.Y);
  3311. this.Canvas.lineTo(item.Line.X+halfWidth, item.Line.Y);
  3312. }
  3313. }
  3314. aryLine2.push(item);
  3315. ++pointCount;
  3316. }
  3317. if (pointCount>0)
  3318. {
  3319. for(var j=aryLine2.length-1; j>=0; --j)
  3320. {
  3321. var item2=aryLine2[j];
  3322. if (this.IsHScreen)
  3323. {
  3324. this.Canvas.lineTo(item2.Line2.X, item2.Line2.Y+halfWidth);
  3325. this.Canvas.lineTo(item2.Line2.X, item2.Line2.Y-halfWidth);
  3326. }
  3327. else
  3328. {
  3329. this.Canvas.lineTo(item2.Line2.X+halfWidth, item2.Line2.Y);
  3330. this.Canvas.lineTo(item2.Line2.X-halfWidth, item2.Line2.Y);
  3331. }
  3332. }
  3333. this.Canvas.closePath();
  3334. this.Canvas.fill();
  3335. }
  3336. }
  3337. this.GetMaxMin=function()
  3338. {
  3339. return { Min:null, Max:null };
  3340. }
  3341. }
  3342. //锁 支持横屏
  3343. function ChartLock()
  3344. {
  3345. this.newMethod = IChartPainting; //派生
  3346. this.newMethod();
  3347. delete this.newMethod;
  3348. this.WidthDiv = 0.2; // 框子宽度占比
  3349. this.LockCount = 10; // 锁最新的几个数据
  3350. this.BGColor = g_JSChartResource.LockBGColor;
  3351. this.TextColor = g_JSChartResource.LockTextColor;
  3352. this.Font = g_JSChartResource.DefaultTextFont;
  3353. this.Title = '🔒开通权限';
  3354. this.LockRect = null; //上锁区域
  3355. this.LockID; //锁ID
  3356. this.Callback; //回调
  3357. this.IndexName; //指标名字
  3358. this.Draw = function ()
  3359. {
  3360. this.LockRect = null;
  3361. if (this.ChartFrame.IsMinSize) return;
  3362. if (this.NotSupportMessage)
  3363. {
  3364. this.DrawNotSupportmessage();
  3365. return;
  3366. }
  3367. if (this.ChartFrame.IsHScreen === true)
  3368. {
  3369. this.HScreenDraw();
  3370. return;
  3371. }
  3372. var xOffset = this.ChartBorder.GetRight();
  3373. var lOffsetWidth = 0;
  3374. if (this.ChartFrame.Data != null)
  3375. {
  3376. var dataWidth = this.ChartFrame.DataWidth;
  3377. var distanceWidth = this.ChartFrame.DistanceWidth;
  3378. xOffset = this.ChartBorder.GetLeft() + distanceWidth / 2.0 + 2.0;
  3379. var chartright = this.ChartBorder.GetRight();
  3380. var xPointCount = this.ChartFrame.XPointCount;
  3381. for (var i = this.ChartFrame.Data.DataOffset, j = 0; i < this.ChartFrame.Data.Data.length && j < xPointCount; ++i, ++j, xOffset += (dataWidth + distanceWidth))
  3382. {
  3383. var data = this.ChartFrame.Data.Data[i];
  3384. if (data.Open == null || data.High == null || data.Low == null || data.Close == null) continue;
  3385. var left = xOffset;
  3386. var right = xOffset + dataWidth;
  3387. if (right > chartright) break;
  3388. }
  3389. lOffsetWidth = (dataWidth + distanceWidth) * this.LockCount;
  3390. }
  3391. if (lOffsetWidth == 0)
  3392. {
  3393. lOffsetWidth = (xOffset - this.ChartBorder.GetLeft()) * this.WidthDiv;
  3394. }
  3395. var lLeft = xOffset - lOffsetWidth;
  3396. if (lLeft < this.ChartBorder.GetLeft())
  3397. lLeft = this.ChartBorder.GetLeft();
  3398. var lHeight = this.ChartBorder.GetBottom() - this.ChartBorder.GetTop();
  3399. var lWidth = this.ChartBorder.GetRight() - lLeft;
  3400. this.Canvas.setFillStyle(this.BGColor);
  3401. this.Canvas.fillRect(lLeft, this.ChartBorder.GetTop(), lWidth, lHeight);
  3402. var xCenter = lLeft + lWidth / 2;
  3403. var yCenter = this.ChartBorder.GetTop() + lHeight / 2;
  3404. this.Canvas.textAlign = 'center';
  3405. this.Canvas.textBaseline = 'middle';
  3406. this.Canvas.setFillStyle(this.TextColor);
  3407. this.Canvas.font = this.Font;
  3408. this.Canvas.fillText(this.Title, xCenter, yCenter);
  3409. this.LockRect = { Left: lLeft, Top: this.ChartBorder.GetTop(), Width: lWidth, Heigh: lHeight }; //保存上锁区域
  3410. }
  3411. this.HScreenDraw = function ()
  3412. {
  3413. var xOffset = this.ChartBorder.GetBottom();
  3414. var lOffsetWidth = 0;
  3415. if (this.ChartFrame.Data != null)
  3416. {
  3417. var dataWidth = this.ChartFrame.DataWidth;
  3418. var distanceWidth = this.ChartFrame.DistanceWidth;
  3419. xOffset = this.ChartBorder.GetTop() + distanceWidth / 2.0 + 2.0;
  3420. var chartright = this.ChartBorder.GetBottom();
  3421. var xPointCount = this.ChartFrame.XPointCount;
  3422. //求最后1个数据的位置
  3423. for (var i = this.ChartFrame.Data.DataOffset, j = 0; i < this.ChartFrame.Data.Data.length && j < xPointCount; ++i, ++j, xOffset += (dataWidth + distanceWidth))
  3424. {
  3425. var data = this.ChartFrame.Data.Data[i];
  3426. if (data.Open == null || data.High == null || data.Low == null || data.Close == null) continue;
  3427. var left = xOffset;
  3428. var right = xOffset + dataWidth;
  3429. if (right > chartright) break;
  3430. }
  3431. lOffsetWidth = (dataWidth + distanceWidth) * this.LockCount;
  3432. }
  3433. if (lOffsetWidth == 0)
  3434. {
  3435. lOffsetWidth = (xOffset - this.ChartBorder.GetTop()) * this.WidthDiv;
  3436. }
  3437. var lLeft = xOffset - lOffsetWidth;
  3438. if (lLeft < this.ChartBorder.GetTop()) lLeft = this.ChartBorder.GetTop();
  3439. var lHeight = this.ChartBorder.GetRight() - this.ChartBorder.GetLeft();
  3440. var lWidth = this.ChartBorder.GetBottom() - lLeft;
  3441. this.Canvas.setFillStyle(this.BGColor);
  3442. this.Canvas.fillRect(this.ChartBorder.GetLeft(), lLeft, lHeight, lWidth);
  3443. var xCenter = this.ChartBorder.GetLeft() + lHeight / 2;
  3444. var yCenter = lLeft + lWidth / 2;
  3445. this.Canvas.save();
  3446. this.Canvas.translate(xCenter, yCenter);
  3447. this.Canvas.rotate(90 * Math.PI / 180);
  3448. this.Canvas.textAlign = 'center';
  3449. this.Canvas.textBaseline = 'middle';
  3450. this.Canvas.setFillStyle(this.TextColor);
  3451. this.Canvas.font = this.Font;
  3452. this.Canvas.fillText(this.Title, 0, 0);
  3453. this.Canvas.restore();
  3454. this.LockRect = { Left: this.ChartBorder.GetLeft(), Top: lLeft, Width: lHeight, Heigh: lWidth }; //保存上锁区域
  3455. }
  3456. //x,y是否在上锁区域
  3457. this.GetTooltipData = function (x, y, tooltip)
  3458. {
  3459. if (this.LockRect == null) return false;
  3460. if (this.IsPointInRect(x, y, this.LockRect.Left, this.LockRect.Top, this.LockRect.Width, this.LockRect.Heigh))
  3461. {
  3462. tooltip.Data = { ID: this.LockID, Callback: this.Callback, IndexName: this.IndexName };
  3463. tooltip.ChartPaint = this;
  3464. return true;
  3465. }
  3466. return false;
  3467. }
  3468. this.IsPointInRect = function (x, y, left, top, width, heigh)
  3469. {
  3470. if (x > left && x < left + width && y > top && y < top + heigh) return true;
  3471. return false;
  3472. }
  3473. }
  3474. //通达信语法 VOLSTICK 支持横屏
  3475. function ChartVolStick()
  3476. {
  3477. this.newMethod = IChartPainting; //派生
  3478. this.newMethod();
  3479. delete this.newMethod;
  3480. this.UpColor = g_JSChartResource.UpBarColor;
  3481. this.DownColor = g_JSChartResource.DownBarColor;
  3482. this.HistoryData; //历史数据
  3483. this.KLineDrawType = 0;
  3484. this.ClassName = 'ChartVolStick';
  3485. this.MinBarWidth=g_JSChartResource.MinKLineBarWidth; //最小的柱子宽度
  3486. this.Draw = function ()
  3487. {
  3488. if (this.ChartFrame.IsMinSize) return;
  3489. if (this.ChartFrame.IsHScreen === true)
  3490. {
  3491. this.HScreenDraw();
  3492. return;
  3493. }
  3494. var dataWidth = this.ChartFrame.DataWidth;
  3495. var distanceWidth = this.ChartFrame.DistanceWidth;
  3496. var xOffset = this.ChartBorder.GetLeft() + distanceWidth / 2.0 + 2.0;
  3497. var chartright = this.ChartBorder.GetRight();
  3498. var xPointCount = this.ChartFrame.XPointCount;
  3499. var yBottom = this.ChartFrame.GetYFromData(0);
  3500. var isMinute=this.IsMinuteFrame();
  3501. if (dataWidth >= this.MinBarWidth)
  3502. { //只有K线, 分时图dataWidth=1
  3503. yBottom = ToFixedRect(yBottom);
  3504. for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j, xOffset += (dataWidth + distanceWidth))
  3505. {
  3506. var value = this.Data.Data[i];
  3507. var kItem = this.HistoryData.Data[i];
  3508. if (value == null || kItem == null) continue;
  3509. var left = xOffset;
  3510. var right = xOffset + dataWidth;
  3511. if (right > chartright) break;
  3512. var y = this.ChartFrame.GetYFromData(value);
  3513. var bUp = false;
  3514. if (kItem.Close >= kItem.Open)
  3515. {
  3516. this.Canvas.setFillStyle(this.UpColor);
  3517. bUp = true;
  3518. }
  3519. else
  3520. {
  3521. this.Canvas.setFillStyle(this.DownColor);
  3522. }
  3523. //高度调整为整数
  3524. var height = ToFixedRect(Math.abs(yBottom - y)>=1 ? yBottom - y : 1);
  3525. y = yBottom - height;
  3526. if (bUp && (this.KLineDrawType == 1 || this.KLineDrawType == 2 || this.KLineDrawType == 3)) //空心柱子
  3527. {
  3528. this.Canvas.setStrokeStyle(this.UpColor);
  3529. this.Canvas.beginPath();
  3530. this.Canvas.rect(ToFixedPoint(left), ToFixedPoint(y), ToFixedRect(dataWidth), height);
  3531. this.Canvas.stroke();
  3532. }
  3533. else
  3534. {
  3535. this.Canvas.fillRect(ToFixedRect(left), y, ToFixedRect(dataWidth), height);
  3536. }
  3537. }
  3538. }
  3539. else //太细了直接话线
  3540. {
  3541. for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j, xOffset += (dataWidth + distanceWidth))
  3542. {
  3543. var value = this.Data.Data[i];
  3544. var kItem = this.HistoryData.Data[i];
  3545. if (value == null || kItem == null) continue;
  3546. var y = this.ChartFrame.GetYFromData(value);
  3547. if (isMinute)
  3548. {
  3549. var x=this.ChartFrame.GetXFromIndex(j);
  3550. }
  3551. else
  3552. {
  3553. var left=xOffset;
  3554. var right=xOffset+dataWidth;
  3555. var x=left+(right-left)/2;
  3556. }
  3557. if (x > chartright) break;
  3558. if (kItem.Close > kItem.Open)
  3559. this.Canvas.setStrokeStyle(this.UpColor);
  3560. else
  3561. this.Canvas.setStrokeStyle(this.DownColor);
  3562. var x = this.ChartFrame.GetXFromIndex(j);
  3563. this.Canvas.beginPath();
  3564. this.Canvas.moveTo(ToFixedPoint(x), y);
  3565. this.Canvas.lineTo(ToFixedPoint(x), yBottom);
  3566. this.Canvas.stroke();
  3567. }
  3568. }
  3569. }
  3570. this.HScreenDraw = function () //横屏画法
  3571. {
  3572. var dataWidth = this.ChartFrame.DataWidth;
  3573. var distanceWidth = this.ChartFrame.DistanceWidth;
  3574. var xOffset = this.ChartBorder.GetTop() + distanceWidth / 2.0 + 2.0;
  3575. var chartBottom = this.ChartBorder.GetBottom();
  3576. var xPointCount = this.ChartFrame.XPointCount;
  3577. var yBottom = this.ChartFrame.GetYFromData(0);
  3578. if (dataWidth >= this.MinBarWidth)
  3579. {
  3580. yBottom = ToFixedRect(yBottom);
  3581. for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j, xOffset += (dataWidth + distanceWidth))
  3582. {
  3583. var value = this.Data.Data[i];
  3584. var kItem = this.HistoryData.Data[i];
  3585. if (value == null || kItem == null) continue;
  3586. var left = xOffset;
  3587. var right = xOffset + dataWidth;
  3588. if (right > chartBottom) break;
  3589. var y = this.ChartFrame.GetYFromData(value);
  3590. var bUp = false;
  3591. if (kItem.Close >= kItem.Open)
  3592. {
  3593. bUp = true;
  3594. this.Canvas.setFillStyle(this.UpColor);
  3595. }
  3596. else
  3597. {
  3598. this.Canvas.setFillStyle(this.DownColor);
  3599. }
  3600. //高度调整为整数
  3601. var height = ToFixedRect(y - yBottom);
  3602. if (bUp && (this.KLineDrawType == 1 || this.KLineDrawType == 2 || this.KLineDrawType == 3)) //空心柱子
  3603. {
  3604. this.Canvas.setStrokeStyle(this.UpColor);
  3605. this.Canvas.beginPath();
  3606. this.Canvas.rect(ToFixedPoint(yBottom), ToFixedPoint(left), height, ToFixedRect(dataWidth));
  3607. this.Canvas.stroke();
  3608. }
  3609. else
  3610. {
  3611. this.Canvas.fillRect(yBottom, ToFixedRect(left), height, ToFixedRect(dataWidth));
  3612. }
  3613. }
  3614. }
  3615. else //太细了直接话线
  3616. {
  3617. for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j, xOffset += (dataWidth + distanceWidth))
  3618. {
  3619. var value = this.Data.Data[i];
  3620. var kItem = this.HistoryData.Data[i];
  3621. if (value == null || kItem == null) continue;
  3622. var y = this.ChartFrame.GetYFromData(value);
  3623. var x = this.ChartFrame.GetXFromIndex(j);
  3624. if (x > chartBottom) break;
  3625. if (kItem.Close > kItem.Open)
  3626. this.Canvas.setStrokeStyle(this.UpColor);
  3627. else
  3628. this.Canvas.setStrokeStyle(this.DownColor);
  3629. var x = this.ChartFrame.GetXFromIndex(j);
  3630. this.Canvas.beginPath();
  3631. this.Canvas.moveTo(y, ToFixedPoint(x));
  3632. this.Canvas.lineTo(yBottom, ToFixedPoint(x));
  3633. this.Canvas.stroke();
  3634. }
  3635. }
  3636. }
  3637. this.GetMaxMin = function ()
  3638. {
  3639. var xPointCount = this.ChartFrame.XPointCount;
  3640. var range = {};
  3641. range.Min = 0;
  3642. range.Max = null;
  3643. for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j)
  3644. {
  3645. var value = this.Data.Data[i];
  3646. if (range.Max == null) range.Max = value;
  3647. if (range.Max < value) range.Max = value;
  3648. }
  3649. return range;
  3650. }
  3651. }
  3652. function ChartText()
  3653. {
  3654. this.newMethod = IChartPainting; //派生
  3655. this.newMethod();
  3656. delete this.newMethod;
  3657. this.TextFont = "12px 微软雅黑";
  3658. this.Draw = function ()
  3659. {
  3660. if (this.ChartFrame.IsMinSize) return;
  3661. if (this.NotSupportMessage)
  3662. {
  3663. this.DrawNotSupportmessage();
  3664. return;
  3665. }
  3666. if (!this.Data || !this.Data.Data) return;
  3667. var dataWidth = this.ChartFrame.DataWidth;
  3668. var distanceWidth = this.ChartFrame.DistanceWidth;
  3669. var chartright = this.ChartBorder.GetRight();
  3670. var xPointCount = this.ChartFrame.XPointCount;
  3671. for (var i in this.Data.Data)
  3672. {
  3673. var value = this.Data.Data[i];
  3674. if (value == null) continue;
  3675. var price = value.Value;
  3676. var position = value.Position;
  3677. if (position == 'Left') {
  3678. var x = this.ChartFrame.GetXFromIndex(0);
  3679. var y = this.ChartFrame.GetYFromData(price);
  3680. if (x > chartright) continue;
  3681. this.Canvas.textAlign = 'left';
  3682. this.Canvas.textBaseline = 'middle';
  3683. this.Canvas.setFillStyle(value.Color);
  3684. this.Canvas.font = this.TextFont;
  3685. this.Canvas.fillText(value.Message, x, y);
  3686. }
  3687. }
  3688. }
  3689. this.GetMaxMin = function ()
  3690. {
  3691. var xPointCount = this.ChartFrame.XPointCount;
  3692. var range = {};
  3693. range.Min = null;
  3694. range.Max = null;
  3695. if (!this.Data || !this.Data.Data) return range;
  3696. for (var i in this.Data.Data)
  3697. {
  3698. var data = this.Data.Data[i];
  3699. if (data == null || isNaN(data.Value)) continue;
  3700. var value = data.Value;
  3701. if (range.Max == null) range.Max = value;
  3702. if (range.Min == null) range.Min = value;
  3703. if (range.Max < value) range.Max = value;
  3704. if (range.Min > value) range.Min = value;
  3705. }
  3706. return range;
  3707. }
  3708. }
  3709. /* 水平面积 只有1个数据
  3710. Data 数据结构
  3711. Value, Value2 区间最大最小值
  3712. Color=面积的颜色
  3713. Title=标题 TitleColor=标题颜色
  3714. 支持横屏
  3715. */
  3716. function ChartStraightArea()
  3717. {
  3718. this.newMethod = IChartPainting; //派生
  3719. this.newMethod();
  3720. delete this.newMethod;
  3721. this.Color = "rgb(255,193,37)"; //线段颜色
  3722. this.Font = '11px 微软雅黑';
  3723. this.Draw = function ()
  3724. {
  3725. if (this.ChartFrame.IsMinSize) return;
  3726. if (this.NotSupportMessage)
  3727. {
  3728. this.DrawNotSupportmessage();
  3729. return;
  3730. }
  3731. if (!this.Data || !this.Data.Data) return;
  3732. if (this.ChartFrame.IsHScreen === true)
  3733. {
  3734. this.HScreenDraw();
  3735. return;
  3736. }
  3737. var dataWidth = this.ChartFrame.DataWidth;
  3738. var distanceWidth = this.ChartFrame.DistanceWidth;
  3739. var chartright = this.ChartBorder.GetRight();
  3740. var bottom = this.ChartBorder.GetBottom();
  3741. var left = this.ChartBorder.GetLeft();
  3742. var xPointCount = this.ChartFrame.XPointCount;
  3743. var xRight = this.ChartFrame.GetXFromIndex(xPointCount - 1);
  3744. //画背景
  3745. for (let i in this.Data.Data)
  3746. {
  3747. let item = this.Data.Data[i];
  3748. if (item == null || isNaN(item.Value) || isNaN(item.Value2)) continue;
  3749. if (item.Color == null) continue;
  3750. let valueMax = Math.max(item.Value, item.Value2);
  3751. let valueMin = Math.min(item.Value, item.Value2);
  3752. let yTop = this.ChartFrame.GetYFromData(valueMax);
  3753. let yBottom = this.ChartFrame.GetYFromData(valueMin);
  3754. this.Canvas.setFillStyle(item.Color);
  3755. this.Canvas.fillRect(ToFixedRect(left), ToFixedRect(yTop), ToFixedRect(xRight - left), ToFixedRect(yBottom - yTop));
  3756. }
  3757. for (let i in this.Data.Data)
  3758. {
  3759. let item = this.Data.Data[i];
  3760. if (item == null || isNaN(item.Value) || isNaN(item.Value2)) continue;
  3761. if (item.Color == null) continue;
  3762. let valueMax = Math.max(item.Value, item.Value2);
  3763. let valueMin = Math.min(item.Value, item.Value2);
  3764. let yTop = this.ChartFrame.GetYFromData(valueMax);
  3765. let yBottom = this.ChartFrame.GetYFromData(valueMin);
  3766. if (item.Title && item.TitleColor)
  3767. {
  3768. let x = xRight;
  3769. if (item.Align == 'left')
  3770. {
  3771. this.Canvas.textAlign = 'left';
  3772. x = left;
  3773. }
  3774. else
  3775. {
  3776. this.Canvas.textAlign = 'right';
  3777. x = xRight;
  3778. }
  3779. this.Canvas.textBaseline = 'middle';
  3780. this.Canvas.setFillStyle(item.TitleColor);
  3781. this.Canvas.font = this.Font;
  3782. let y = yTop + (yBottom - yTop) / 2;
  3783. this.Canvas.fillText(item.Title, x, y);
  3784. }
  3785. }
  3786. }
  3787. this.HScreenDraw = function ()
  3788. {
  3789. var bottom = this.ChartBorder.GetBottom();
  3790. var top = this.ChartBorder.GetTop();
  3791. var height = this.ChartBorder.GetHeight();
  3792. for (let i in this.Data.Data)
  3793. {
  3794. let item = this.Data.Data[i];
  3795. if (item == null || isNaN(item.Value) || isNaN(item.Value2)) continue;
  3796. if (item.Color == null) continue;
  3797. let valueMax = Math.max(item.Value, item.Value2);
  3798. let valueMin = Math.min(item.Value, item.Value2);
  3799. var yTop = this.ChartFrame.GetYFromData(valueMax);
  3800. var yBottom = this.ChartFrame.GetYFromData(valueMin);
  3801. this.Canvas.setFillStyle(item.Color);
  3802. this.Canvas.fillRect(ToFixedRect(yBottom), ToFixedRect(top), ToFixedRect(yTop - yBottom), ToFixedRect(height));
  3803. if (item.Title && item.TitleColor)
  3804. {
  3805. var xText = yTop + (yBottom - yTop) / 2;
  3806. var yText = bottom;
  3807. this.Canvas.save();
  3808. this.Canvas.translate(xText, yText);
  3809. this.Canvas.rotate(90 * Math.PI / 180);
  3810. this.Canvas.textAlign = 'right';
  3811. this.Canvas.textBaseline = 'middle';
  3812. this.Canvas.setFillStyle(item.TitleColor);
  3813. this.Canvas.font = this.Font;
  3814. this.Canvas.fillText(item.Title, 0, -2);
  3815. this.Canvas.restore();
  3816. }
  3817. }
  3818. }
  3819. this.GetMaxMin = function ()
  3820. {
  3821. var xPointCount = this.ChartFrame.XPointCount;
  3822. var range = {};
  3823. range.Min = null;
  3824. range.Max = null;
  3825. if (!this.Data || !this.Data.Data) return range;
  3826. for (let i in this.Data.Data)
  3827. {
  3828. let item = this.Data.Data[i];
  3829. if (item == null || isNaN(item.Value) || isNaN(item.Value2)) continue;
  3830. let valueMax = Math.max(item.Value, item.Value2);
  3831. let valueMin = Math.min(item.Value, item.Value2);
  3832. if (range.Max == null) range.Max = valueMax;
  3833. if (range.Min == null) range.Min = valueMin;
  3834. if (range.Max < valueMax) range.Max = valueMax;
  3835. if (range.Min > valueMin) range.Min = valueMin;
  3836. }
  3837. return range;
  3838. }
  3839. }
  3840. // 面积图
  3841. function ChartBand() {
  3842. this.newMethod = IChartPainting; //派生
  3843. this.newMethod();
  3844. delete this.newMethod;
  3845. this.IsDrawFirst = true;
  3846. this.FirstColor = g_JSChartResource.Index.LineColor[0];
  3847. this.SecondColor = g_JSChartResource.Index.LineColor[1];
  3848. this.Draw = function ()
  3849. {
  3850. if (this.ChartFrame.IsMinSize) return;
  3851. if (this.NotSupportMessage)
  3852. {
  3853. this.DrawNotSupportmessage();
  3854. return;
  3855. }
  3856. var dataWidth = this.ChartFrame.DataWidth;
  3857. var distanceWidth = this.ChartFrame.DistanceWidth;
  3858. var xPointCount = this.ChartFrame.XPointCount;
  3859. var xOffset = this.ChartBorder.GetLeft() + distanceWidth / 2.0 + 2.0;
  3860. var x = 0;
  3861. var y = 0;
  3862. var y2 = 0;
  3863. var firstlinePoints = [];
  3864. var secondlinePoints = [];
  3865. var lIndex = 0;
  3866. for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j, xOffset += (dataWidth + distanceWidth))
  3867. {
  3868. var value = this.Data.Data[i];
  3869. if (value == null || value.Value == null || value.Value2 == null) continue;
  3870. x = this.ChartFrame.GetXFromIndex(j);
  3871. y = this.ChartFrame.GetYFromData(value.Value);
  3872. y2 = this.ChartFrame.GetYFromData(value.Value2);
  3873. firstlinePoints[lIndex] = { x: x, y: y };
  3874. secondlinePoints[lIndex] = { x: x, y: y2 };
  3875. lIndex++;
  3876. }
  3877. if (firstlinePoints.length > 1)
  3878. {
  3879. this.Canvas.save();
  3880. this.Canvas.beginPath();
  3881. for (var i = 0; i < firstlinePoints.length; ++i)
  3882. {
  3883. if (i == 0)
  3884. this.Canvas.moveTo(firstlinePoints[i].x, firstlinePoints[i].y);
  3885. else
  3886. this.Canvas.lineTo(firstlinePoints[i].x, firstlinePoints[i].y);
  3887. }
  3888. for (var j = secondlinePoints.length - 1; j >= 0; --j)
  3889. {
  3890. this.Canvas.lineTo(secondlinePoints[j].x, secondlinePoints[j].y);
  3891. }
  3892. this.Canvas.closePath();
  3893. this.Canvas.setStrokeStyle("rgba(255,255,255,0)");
  3894. this.Canvas.stroke();
  3895. this.Canvas.clip();
  3896. this.Canvas.beginPath();
  3897. this.Canvas.moveTo(firstlinePoints[0].x, this.ChartBorder.GetBottom());
  3898. for (var i = 0; i < firstlinePoints.length; ++i)
  3899. {
  3900. this.Canvas.lineTo(firstlinePoints[i].x, firstlinePoints[i].y);
  3901. }
  3902. this.Canvas.lineTo(firstlinePoints[firstlinePoints.length - 1].x, this.ChartBorder.GetBottom());
  3903. this.Canvas.closePath();
  3904. this.Canvas.setFillStyle(this.FirstColor);
  3905. this.Canvas.fill();
  3906. this.Canvas.beginPath();
  3907. this.Canvas.moveTo(secondlinePoints[0].x, this.ChartBorder.GetBottom());
  3908. for (var i = 0; i < secondlinePoints.length; ++i)
  3909. {
  3910. this.Canvas.lineTo(secondlinePoints[i].x, secondlinePoints[i].y);
  3911. }
  3912. this.Canvas.lineTo(secondlinePoints[secondlinePoints.length - 1].x, this.ChartBorder.GetBottom());
  3913. this.Canvas.closePath();
  3914. this.Canvas.setFillStyle(this.SecondColor);
  3915. this.Canvas.fill();
  3916. this.Canvas.restore();
  3917. }
  3918. }
  3919. this.GetMaxMin = function ()
  3920. {
  3921. var xPointCount = this.ChartFrame.XPointCount;
  3922. var range = {};
  3923. range.Min = null;
  3924. range.Max = null;
  3925. for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j)
  3926. {
  3927. var value = this.Data.Data[i];
  3928. if (value == null || value.Value == null || value.Value2 == null) continue;
  3929. var maxData = value.Value > value.Value2 ? value.Value : value.Value2;
  3930. var minData = value.Value < value.Value2 ? value.Value : value.Value2;
  3931. if (range.Max == null)
  3932. range.Max = maxData;
  3933. else if (range.Max < maxData)
  3934. range.Max = maxData;
  3935. if (range.Min == null)
  3936. range.Min = minData;
  3937. else if (range.Min > minData)
  3938. range.Min = minData;
  3939. }
  3940. return range;
  3941. }
  3942. }
  3943. ////////////////////////////////////////////////////////////////////////////////////////////////////
  3944. // 其他图形
  3945. //
  3946. //
  3947. ////////////////////////////////////////////////////////////////////////////////////////////////////
  3948. /*
  3949. 饼图
  3950. */
  3951. function ChartPie()
  3952. {
  3953. this.newMethod = IChartPainting; //派生
  3954. this.newMethod();
  3955. delete this.newMethod;
  3956. this.Draw = function ()
  3957. {
  3958. if (!this.Data || !this.Data.Data || !(this.Data.Data.length > 0)) return this.DrawEmptyData();
  3959. let left = this.ChartBorder.GetLeft();
  3960. let right = this.ChartBorder.GetRight();
  3961. let top = this.ChartBorder.GetTop();
  3962. let bottom = this.ChartBorder.GetBottom();
  3963. let width = this.ChartBorder.GetWidth();
  3964. let height = this.ChartBorder.GetHeight();
  3965. //圆半径
  3966. let radius = width / 4 * 0.8;
  3967. this.Canvas.save();
  3968. this.Canvas.translate(left + radius, top + height / 2);
  3969. let totalValue = 0; //求和
  3970. for (let i in this.Data.Data) {
  3971. totalValue += this.Data.Data[i].Value;
  3972. }
  3973. let startAngle = Math.PI * 1.5;
  3974. let start = startAngle;
  3975. let end = startAngle;
  3976. //画饼图
  3977. for (let i in this.Data.Data)
  3978. {
  3979. let item = this.Data.Data[i];
  3980. let rate = item.Value / totalValue; //占比
  3981. // 绘制扇形
  3982. this.Canvas.beginPath();
  3983. this.Canvas.moveTo(0, 0);
  3984. end += rate * 2 * Math.PI;//终止角度
  3985. this.Canvas.setStrokeStyle("white");
  3986. this.Canvas.setFillStyle(item.Color);
  3987. this.Canvas.arc(0, 0, radius, start, end);
  3988. this.Canvas.fill();
  3989. this.Canvas.closePath();
  3990. this.Canvas.stroke();
  3991. start += rate * 2 * Math.PI;//起始角度
  3992. }
  3993. //画文字
  3994. this.Canvas.restore();
  3995. let textLeft = left + width / 2 + 5;
  3996. // let textTop = top + height / 2 + 20;
  3997. let textTop = top;
  3998. this.Canvas.textBaseline = "bottom";
  3999. this.Canvas.font = "12px 微软雅黑";
  4000. for (let i = 0, j = 0; i < this.Data.Data.length; ++i)
  4001. {
  4002. let item = this.Data.Data[i];
  4003. if (!item.Text) continue;
  4004. this.Canvas.setFillStyle(item.Color);
  4005. this.Canvas.fillRect(textLeft, textTop - 15, 13, 13);
  4006. this.Canvas.setFillStyle('rgb(102,102,102)');
  4007. this.Canvas.fillText(item.Text, textLeft + 16, textTop);
  4008. // textTop += 20;
  4009. textTop += 17;
  4010. if (textTop > top + height / 2 + radius) {
  4011. ++j;
  4012. if (j >= 2) break;
  4013. // textTop = top + height / 2 + 20;
  4014. textTop = top;
  4015. textLeft = right - (width / 4) + 5;
  4016. }
  4017. }
  4018. }
  4019. //空数据
  4020. this.DrawEmptyData = function ()
  4021. {
  4022. console.log('[ChartPie::DrawEmptyData]')
  4023. let left = this.ChartBorder.GetLeft();
  4024. let right = this.ChartBorder.GetRight();
  4025. let top = this.ChartBorder.GetTop();
  4026. let bottom = this.ChartBorder.GetBottom();
  4027. let width = this.ChartBorder.GetWidth();
  4028. let height = this.ChartBorder.GetHeight();
  4029. //圆半径
  4030. let radius = width / 4 * 0.8;
  4031. this.Canvas.save();
  4032. this.Canvas.translate(left + radius, top + height / 2);
  4033. this.Canvas.beginPath();
  4034. this.Canvas.setFillStyle('rgb(211,211,211)');
  4035. this.Canvas.setStrokeStyle("white");
  4036. this.Canvas.arc(0, 0, radius * 0.8, 0, 2 * Math.PI);
  4037. this.Canvas.fill();
  4038. this.Canvas.closePath();
  4039. this.Canvas.stroke();
  4040. this.Canvas.restore();
  4041. }
  4042. }
  4043. /*
  4044. 圆环
  4045. */
  4046. function ChartCircle()
  4047. {
  4048. this.newMethod = IChartPainting; //派生
  4049. this.newMethod();
  4050. delete this.newMethod;
  4051. this.BGColor = 'white'; //背景色
  4052. this.TextHeight = 25;
  4053. //空数据
  4054. this.DrawEmptyData = function ()
  4055. {
  4056. console.log('[ChartCircle::DrawEmptyData]')
  4057. }
  4058. this.Draw = function ()
  4059. {
  4060. if (!this.Data || !this.Data.Data || !(this.Data.Data.length > 0)) return this.DrawEmptyData();
  4061. let left = this.ChartBorder.GetLeft();
  4062. let right = this.ChartBorder.GetRight();
  4063. let top = this.ChartBorder.GetTop();
  4064. let bottom = this.ChartBorder.GetBottom();
  4065. let width = this.ChartBorder.GetWidth();
  4066. let height = this.ChartBorder.GetHeight();
  4067. //圆半径
  4068. let lTextHeight = this.TextHeight;
  4069. let size = width - lTextHeight;
  4070. if (size > height - lTextHeight) size = height - lTextHeight;
  4071. let radius = (size - lTextHeight) / 2;
  4072. this.Canvas.save();
  4073. this.Canvas.translate(left + width / 2, top + height / 2 - lTextHeight / 2);
  4074. let totalValue = 0; //求和
  4075. for (let i in this.Data.Data)
  4076. {
  4077. totalValue += this.Data.Data[i].Value;
  4078. }
  4079. let startAngle = Math.PI * 1.5;
  4080. let start = startAngle;
  4081. let end = startAngle;
  4082. //画饼图
  4083. for (let i in this.Data.Data)
  4084. {
  4085. let item = this.Data.Data[i];
  4086. let rate = item.Value / totalValue; //占比
  4087. //console.log('[ChartPie::Draw]', i, rate, item);
  4088. // 绘制扇形
  4089. this.Canvas.beginPath();
  4090. this.Canvas.moveTo(0, 0);
  4091. end += rate * 2 * Math.PI;//终止角度
  4092. this.Canvas.setStrokeStyle("white");
  4093. this.Canvas.setFillStyle(item.Color);
  4094. this.Canvas.arc(0, 0, radius, start, end);
  4095. this.Canvas.fill();
  4096. this.Canvas.closePath();
  4097. this.Canvas.stroke();
  4098. start += rate * 2 * Math.PI;//起始角度
  4099. }
  4100. //中心画一个背景色的圆
  4101. this.Canvas.beginPath();
  4102. this.Canvas.setFillStyle(this.BGColor);
  4103. this.Canvas.arc(0, 0, radius * 0.5, 0, 2 * Math.PI);
  4104. this.Canvas.fill();
  4105. this.Canvas.closePath();
  4106. this.Canvas.stroke();
  4107. this.Canvas.restore();
  4108. //画文字
  4109. this.Canvas.restore();
  4110. let textLeft = left;
  4111. let textTop = top + height / 2 - lTextHeight / 2 + radius + 5 + 20;
  4112. this.Canvas.textBaseline = "bottom";
  4113. this.Canvas.textAlign = 'left';
  4114. this.Canvas.font = "12px 微软雅黑";
  4115. let textWidth = 0;
  4116. //以圆心左右显示
  4117. for (let i = 0, j = 0; i < this.Data.Data.length; ++i)
  4118. {
  4119. let item = this.Data.Data[i];
  4120. if (!item.Text) continue;
  4121. this.Canvas.setFillStyle(item.Color);
  4122. if (j % 2 == 0)
  4123. {
  4124. textLeft = left + width / 2 - 10;
  4125. textWidth = this.Canvas.measureText(item.Text).width;
  4126. textLeft = textLeft - textWidth - 16;
  4127. this.Canvas.fillRect(textLeft, textTop - 15, 13, 13);
  4128. this.Canvas.setFillStyle('rgb(102,102,102)');
  4129. this.Canvas.fillText(item.Text, textLeft + 16, textTop);
  4130. }
  4131. else
  4132. {
  4133. textLeft = left + width / 2 + 10 + 10;
  4134. this.Canvas.fillRect(textLeft, textTop - 15, 13, 13);
  4135. this.Canvas.setFillStyle('rgb(102,102,102)');
  4136. this.Canvas.fillText(item.Text, textLeft + 16, textTop);
  4137. textTop += 20;
  4138. }
  4139. if (textTop > bottom) break;
  4140. ++j;
  4141. }
  4142. }
  4143. }
  4144. // 中国地图
  4145. function ChartChinaMap()
  4146. {
  4147. this.newMethod = IChartPainting; //派生
  4148. this.newMethod();
  4149. delete this.newMethod;
  4150. this.ImageData = null;
  4151. this.Left;
  4152. this.Top;
  4153. this.Width;
  4154. this.Height;
  4155. this.ImageWidth;
  4156. this.ImageHeight;
  4157. this.DefaultColor = [217, 222, 239];
  4158. this.Color =
  4159. [
  4160. { Name: '海南', Color: 'rgb(217,222,223)' },
  4161. { Name: '内蒙古', Color: 'rgb(217,222,225)' },
  4162. { Name: '新疆', Color: 'rgb(217,222,226)' },
  4163. { Name: '青海', Color: 'rgb(217,222,227)' },
  4164. { Name: '西藏', Color: 'rgb(217,222,228)' },
  4165. { Name: '云南', Color: 'rgb(217,222,229)' },
  4166. { Name: '黑龙江', Color: 'rgb(217,222,230)' },
  4167. { Name: '吉林', Color: 'rgb(217,222,231)' },
  4168. { Name: '辽宁', Color: 'rgb(217,222,232)' },
  4169. { Name: '河北', Color: 'rgb(217,222,233)' },
  4170. { Name: '山东', Color: 'rgb(217,222,234)' },
  4171. { Name: '江苏', Color: 'rgb(217,222,235)' },
  4172. { Name: '浙江', Color: 'rgb(217,222,236)' },
  4173. { Name: '福建', Color: 'rgb(217,222,237)' },
  4174. { Name: '广东', Color: 'rgb(217,222,238)' },
  4175. { Name: '广西', Color: 'rgb(217,222,239)' },
  4176. { Name: '贵州', Color: 'rgb(217,222,240)' },
  4177. { Name: '湖南', Color: 'rgb(217,222,241)' },
  4178. { Name: '江西', Color: 'rgb(217,222,242)' },
  4179. { Name: '安徽', Color: 'rgb(217,222,243)' },
  4180. { Name: '湖北', Color: 'rgb(217,222,244)' },
  4181. { Name: '重庆', Color: 'rgb(217,222,245)' },
  4182. { Name: '四川', Color: 'rgb(217,222,246)' },
  4183. { Name: '甘肃', Color: 'rgb(217,222,247)' },
  4184. { Name: '陕西', Color: 'rgb(217,222,248)' },
  4185. { Name: '山西', Color: 'rgb(217,222,249)' },
  4186. { Name: '河南', Color: 'rgb(217,222,250)' }
  4187. ];
  4188. this.Draw = function ()
  4189. {
  4190. let left = this.ChartBorder.GetLeft() + 1;
  4191. let right = this.ChartBorder.GetRight() - 1;
  4192. let top = this.ChartBorder.GetTop() + 1;
  4193. let bottom = this.ChartBorder.GetBottom() - 1;
  4194. let width = this.ChartBorder.GetWidth() - 2;
  4195. let height = this.ChartBorder.GetHeight() - 2;
  4196. let imageWidth = CHINA_MAP_IMAGE.width;
  4197. let imageHeight = CHINA_MAP_IMAGE.height;
  4198. let drawImageWidth = imageWidth;
  4199. let drawImageHeight = imageHeight;
  4200. if (height < drawImageHeight || width < drawImageWidth)
  4201. {
  4202. this.ImageData = null;
  4203. return;
  4204. }
  4205. if (this.Left != left || this.Top != top || this.Width != width || this.Height != height || this.ImageWidth != imageWidth || this.ImageHeight != imageHeight)
  4206. {
  4207. this.ImageData = null;
  4208. this.ImageWidth = imageWidth;
  4209. this.ImageHeight = imageHeight;
  4210. this.Left = left;
  4211. this.Top = top;
  4212. this.Width = width;
  4213. this.Height = height;
  4214. console.log(imageWidth, imageHeight);
  4215. }
  4216. if (this.ImageData == null)
  4217. {
  4218. this.Canvas.drawImage(CHINA_MAP_IMAGE, 0, 0, imageWidth, imageHeight, left, top, drawImageWidth, drawImageHeight);
  4219. this.ImageData = this.Canvas.getImageData(left, top, drawImageWidth, drawImageHeight);
  4220. let defaultColorSet = new Set(); //默认颜色填充的色块
  4221. let colorMap = new Map(); //定义颜色填充的色块
  4222. let nameMap = new Map();
  4223. if (this.Data.length > 0)
  4224. {
  4225. for (let i in this.Data)
  4226. {
  4227. let item = this.Data[i];
  4228. nameMap.set(item.Name, item.Color)
  4229. }
  4230. }
  4231. console.log(this.Data);
  4232. for (let i in this.Color)
  4233. {
  4234. let item = this.Color[i];
  4235. if (nameMap.has(item.Name))
  4236. {
  4237. colorMap.set(item.Color, nameMap.get(item.Name));
  4238. }
  4239. else
  4240. {
  4241. defaultColorSet.add(item.Color);
  4242. }
  4243. }
  4244. var color;
  4245. for (let i = 0; i < this.ImageData.data.length; i += 4)
  4246. {
  4247. color = 'rgb(' + this.ImageData.data[i] + ',' + this.ImageData.data[i + 1] + ',' + this.ImageData.data[i + 2] + ')';
  4248. if (defaultColorSet.has(color))
  4249. {
  4250. this.ImageData.data[i] = this.DefaultColor[0];
  4251. this.ImageData.data[i + 1] = this.DefaultColor[1];
  4252. this.ImageData.data[i + 2] = this.DefaultColor[2];
  4253. }
  4254. else if (colorMap.has(color))
  4255. {
  4256. let colorValue = colorMap.get(color);
  4257. this.ImageData.data[i] = colorValue[0];
  4258. this.ImageData.data[i + 1] = colorValue[1];
  4259. this.ImageData.data[i + 2] = colorValue[2];
  4260. }
  4261. }
  4262. this.Canvas.clearRect(left, top, drawImageWidth, drawImageHeight);
  4263. this.Canvas.putImageData(this.ImageData, left, top, 0, 0, drawImageWidth, drawImageHeight);
  4264. }
  4265. else
  4266. {
  4267. this.Canvas.putImageData(this.ImageData, left, top, 0, 0, drawImageWidth, drawImageHeight);
  4268. }
  4269. }
  4270. }
  4271. // 雷达图
  4272. function ChartRadar()
  4273. {
  4274. this.newMethod = IChartPainting; //派生
  4275. this.newMethod();
  4276. delete this.newMethod;
  4277. this.BorderPoint = []; //边框点
  4278. this.DataPoint = []; //数据点
  4279. this.CenterPoint = {};
  4280. this.StartAngle = 0;
  4281. this.Color = 'rgb(198,198,198)';
  4282. this.AreaColor = 'rgba(242,154,118,0.4)'; //面积图颜色
  4283. this.AreaLineColor = 'rgb(242,154,118)';
  4284. this.TitleFont = '24px 微软雅黑';
  4285. this.TitleColor = 'rgb(102,102,102)';
  4286. this.BGColor = ['rgb(255,255,255)', 'rgb(224,224,224)']//背景色
  4287. this.DrawBorder = function () //画边框
  4288. {
  4289. if (this.BorderPoint.length <= 0) return;
  4290. this.Canvas.font = this.TitleFont;
  4291. this.Canvas.setStrokeStyle(this.Color);
  4292. const aryBorder = [1, 0.8, 0.6, 0.4, 0.2];
  4293. for (let j in aryBorder)
  4294. {
  4295. var rate = aryBorder[j];
  4296. var isFirstDraw = true;
  4297. for (let i in this.BorderPoint)
  4298. {
  4299. var item = this.BorderPoint[i];
  4300. item.X = this.CenterPoint.X + item.Radius * Math.cos(item.Angle * Math.PI / 180) * rate;
  4301. item.Y = this.CenterPoint.Y + item.Radius * Math.sin(item.Angle * Math.PI / 180) * rate;
  4302. if (isFirstDraw)
  4303. {
  4304. this.Canvas.beginPath();
  4305. this.Canvas.moveTo(item.X, item.Y);
  4306. isFirstDraw = false;
  4307. }
  4308. else
  4309. {
  4310. this.Canvas.lineTo(item.X, item.Y);
  4311. }
  4312. if (j == 0) this.DrawText(item);
  4313. }
  4314. this.Canvas.closePath();
  4315. this.Canvas.stroke();
  4316. this.Canvas.setFillStyle(this.BGColor[j % 2 == 0 ? 0 : 1]);
  4317. this.Canvas.fill();
  4318. }
  4319. this.Canvas.beginPath();
  4320. for (let i in this.BorderPoint)
  4321. {
  4322. var item = this.BorderPoint[i];
  4323. item.X = this.CenterPoint.X + item.Radius * Math.cos(item.Angle * Math.PI / 180);
  4324. item.Y = this.CenterPoint.Y + item.Radius * Math.sin(item.Angle * Math.PI / 180);
  4325. this.Canvas.moveTo(this.CenterPoint.X, this.CenterPoint.Y);
  4326. this.Canvas.lineTo(item.X, item.Y);
  4327. }
  4328. this.Canvas.stroke();
  4329. }
  4330. this.DrawArea = function ()
  4331. {
  4332. if (!this.DataPoint || this.DataPoint.length <= 0) return;
  4333. this.Canvas.setFillStyle(this.AreaColor);
  4334. this.Canvas.setStrokeStyle(this.AreaLineColor);
  4335. this.Canvas.beginPath();
  4336. var isFirstDraw = true;
  4337. for (let i in this.DataPoint)
  4338. {
  4339. var item = this.DataPoint[i];
  4340. if (isFirstDraw)
  4341. {
  4342. this.Canvas.beginPath();
  4343. this.Canvas.moveTo(item.X, item.Y);
  4344. isFirstDraw = false;
  4345. }
  4346. else
  4347. {
  4348. this.Canvas.lineTo(item.X, item.Y);
  4349. }
  4350. }
  4351. this.Canvas.closePath();
  4352. this.Canvas.fill();
  4353. this.Canvas.stroke();
  4354. }
  4355. this.DrawText = function (item)
  4356. {
  4357. if (!item.Text) return;
  4358. //console.log(item.Text, item.Angle);
  4359. this.Canvas.setFillStyle(this.TitleColor);
  4360. var xText = item.X, yText = item.Y;
  4361. //显示每个角度的位置
  4362. if (item.Angle > 0 && item.Angle < 45)
  4363. {
  4364. this.Canvas.textAlign = 'left';
  4365. this.Canvas.textBaseline = 'middle';
  4366. xText += 2;
  4367. }
  4368. else if (item.Angle >= 0 && item.Angle < 90) {
  4369. this.Canvas.textAlign = 'left';
  4370. this.Canvas.textBaseline = 'top';
  4371. xText += 2;
  4372. }
  4373. else if (item.Angle >= 90 && item.Angle < 135)
  4374. {
  4375. this.Canvas.textAlign = 'right';
  4376. this.Canvas.textBaseline = 'top';
  4377. xText -= 2;
  4378. }
  4379. else if (item.Angle >= 135 && item.Angle < 180)
  4380. {
  4381. this.Canvas.textAlign = 'right';
  4382. this.Canvas.textBaseline = 'top';
  4383. xText -= 2;
  4384. }
  4385. else if (item.Angle >= 180 && item.Angle < 225) {
  4386. this.Canvas.textAlign = 'right';
  4387. this.Canvas.textBaseline = 'middle';
  4388. xText -= 2;
  4389. }
  4390. else if (item.Angle >= 225 && item.Angle <= 270) {
  4391. this.Canvas.textAlign = 'center';
  4392. this.Canvas.textBaseline = 'bottom';
  4393. }
  4394. else if (item.Angle > 270 && item.Angle < 315)
  4395. {
  4396. this.Canvas.textAlign = 'left';
  4397. this.Canvas.textBaseline = 'bottom';
  4398. xText += 2;
  4399. }
  4400. else
  4401. {
  4402. this.Canvas.textAlign = 'left';
  4403. this.Canvas.textBaseline = 'middle';
  4404. xText += 2;
  4405. }
  4406. this.Canvas.fillText(item.Text, xText, yText);
  4407. }
  4408. this.Draw = function ()
  4409. {
  4410. this.BorderPoint = [];
  4411. this.DataPoint = [];
  4412. this.InternalBorderPoint = [];
  4413. this.CenterPoint = {};
  4414. if (!this.Data || !this.Data.Data || !(this.Data.Data.length > 0))
  4415. this.CalculatePoints(null);
  4416. else
  4417. this.CalculatePoints(this.Data.Data);
  4418. this.DrawBorder();
  4419. this.DrawArea();
  4420. }
  4421. this.CalculatePoints = function (data)
  4422. {
  4423. let left = this.ChartBorder.GetLeft();
  4424. let right = this.ChartBorder.GetRight();
  4425. let top = this.ChartBorder.GetTop();
  4426. let bottom = this.ChartBorder.GetBottom();
  4427. let width = this.ChartBorder.GetWidth();
  4428. let height = this.ChartBorder.GetHeight();
  4429. let ptCenter = { X: left + width / 2, Y: top + height / 2 }; //中心点
  4430. let radius = Math.min(width / 2, height / 2) - 2 //半径
  4431. let count = Math.max(5, data ? data.length : 0);
  4432. let averageAngle = 360 / count;
  4433. for (let i = 0; i < count; ++i)
  4434. {
  4435. let ptBorder = { Index: i, Radius: radius, Angle: i * averageAngle + this.StartAngle };
  4436. let angle = ptBorder.Angle;
  4437. if (data && i < data.length)
  4438. {
  4439. var item = data[i];
  4440. let ptData = { Index: i, Text: item.Text };
  4441. ptBorder.Text = item.Name;
  4442. if (!item.Value)
  4443. {
  4444. ptData.X = ptCenter.X;
  4445. ptData.Y = ptCenter.Y;
  4446. }
  4447. else
  4448. {
  4449. var value = item.Value;
  4450. if (value >= 1) value = 1;
  4451. var dataRadius = radius * value;
  4452. ptData.X = ptCenter.X + dataRadius * Math.cos(angle * Math.PI / 180);
  4453. ptData.Y = ptCenter.Y + dataRadius * Math.sin(angle * Math.PI / 180);
  4454. }
  4455. this.DataPoint.push(ptData);
  4456. }
  4457. this.BorderPoint.push(ptBorder);
  4458. }
  4459. this.CenterPoint = ptCenter;
  4460. }
  4461. }
  4462. ///////////////////////////////////////////////////////////////////////////////////////////////////
  4463. //十字光标
  4464. function ChartCorssCursor()
  4465. {
  4466. this.Frame;
  4467. this.Canvas; //画布
  4468. this.HPenColor = g_JSChartResource.CorssCursorHPenColor; //水平线颜色
  4469. this.HPenType = 0; //水平线样式 0=虚线 1=实线
  4470. this.VPenColor = g_JSChartResource.CorssCursorVPenColor; //垂直线颜色
  4471. this.VPenType = 0; //垂直线颜色 0=虚线 1=实线 2=K线宽度
  4472. this.Font = g_JSChartResource.CorssCursorTextFont; //字体
  4473. this.TextColor = g_JSChartResource.CorssCursorTextColor; //文本颜色
  4474. this.TextBGColor = g_JSChartResource.CorssCursorBGColor; //文本背景色
  4475. this.TextHeight = 15; //文本字体高度
  4476. this.LastPoint;
  4477. this.CursorIndex; //当前数据的位置
  4478. this.PointX;
  4479. this.PointY;
  4480. this.StringFormatX;
  4481. this.StringFormatY;
  4482. this.IsShow = true; //是否显示
  4483. this.ShowTextMode = { Left: 1, Right: 1, Bottom: 1 }; //0=不显示 1=显示在框架外 2=显示在框架内
  4484. this.IsShowCorss = true; //是否显示十字光标
  4485. this.IsShowClose = false; //Y轴始终显示收盘价
  4486. this.IsFixXLastTime=false; //是否修正X轴,超出当前时间的,X轴调整到当前最后的时间.
  4487. //内部使用
  4488. this.Close = null; //收盘价格
  4489. this.GetCloseYPoint = function (index)
  4490. {
  4491. this.Close = null;
  4492. if (!this.StringFormatX.Data) return null;
  4493. var data = this.StringFormatX.Data;
  4494. if (!data.Data || data.Data.length <= 0) return null;
  4495. var dataIndex = data.DataOffset + index;
  4496. if (dataIndex >= data.Data.length) dataIndex = data.Data.length - 1;
  4497. if (dataIndex < 0) return null;
  4498. var klineData = data.Data[dataIndex];
  4499. if (!klineData) return null;
  4500. this.Close = klineData.Close;
  4501. var yPoint = this.Frame.GetYFromData(this.Close);
  4502. return yPoint;
  4503. }
  4504. this.FixMinuteLastTimeXPoint=function(index)
  4505. {
  4506. if (!IFrameSplitOperator.IsNumber(index)) return null;
  4507. index=parseInt(index);
  4508. if (!this.StringFormatX.Data) return null;
  4509. var data = this.StringFormatX.Data;
  4510. if (!data.Data || data.Data.length <= 0) return null;
  4511. var dataIndex = data.DataOffset + index;
  4512. if (dataIndex<data.Data.length) return null;
  4513. dataIndex=data.Data.length - 1;
  4514. dataIndex-=data.DataOffset;
  4515. var xPoint=this.Frame.GetXFromIndex(dataIndex);
  4516. return { X:xPoint, Index:dataIndex };
  4517. }
  4518. this.Draw = function ()
  4519. {
  4520. if (!this.LastPoint) return;
  4521. var x = this.LastPoint.X;
  4522. var y = this.LastPoint.Y;
  4523. var isInClient = false;
  4524. var rtClient = new Rect(this.Frame.ChartBorder.GetLeft(), this.Frame.ChartBorder.GetTop(), this.Frame.ChartBorder.GetWidth(), this.Frame.ChartBorder.GetHeight());
  4525. isInClient = rtClient.IsPointIn(x, y);
  4526. this.PointY = null;
  4527. this.PointY == null;
  4528. if (!isInClient) return;
  4529. if (this.Frame.IsHScreen === true)
  4530. {
  4531. this.HScreenDraw();
  4532. return;
  4533. }
  4534. var left = this.Frame.ChartBorder.GetLeft();
  4535. var right = this.Frame.ChartBorder.GetRight();
  4536. var top = this.Frame.ChartBorder.GetTopTitle();
  4537. var bottom = this.Frame.ChartBorder.GetBottom();
  4538. var rightWidth = this.Frame.ChartBorder.Right;
  4539. var chartRight = this.Frame.ChartBorder.GetChartWidth();
  4540. x = this.Frame.GetXFromIndex(this.CursorIndex); //手机端 十字只能画在K线上
  4541. if (this.IsShowClose)
  4542. {
  4543. var yPoint = this.GetCloseYPoint(this.CursorIndex);
  4544. if (yPoint != null) y = yPoint;
  4545. }
  4546. if (this.IsFixXLastTime)
  4547. {
  4548. var value=this.FixMinuteLastTimeXPoint(this.CursorIndex)
  4549. if (value)
  4550. {
  4551. x=value.X;
  4552. this.CursorIndex=value.Index;
  4553. }
  4554. }
  4555. this.PointY = [[left, y], [right, y]];
  4556. this.PointX = [[x, top], [x, bottom]];
  4557. if (this.IsShowCorss) //十字线
  4558. {
  4559. if (this.HPenType==1 || this.HPenType==0)
  4560. {
  4561. this.Canvas.setStrokeStyle(this.HPenColor);
  4562. if (this.HPenType == 0) this.Canvas.setLineDash([3, 2]); //虚线
  4563. //this.Canvas.lineWidth=0.5
  4564. this.Canvas.beginPath();
  4565. this.Canvas.moveTo(left, ToFixedPoint(y));
  4566. this.Canvas.lineTo(right, ToFixedPoint(y));
  4567. this.Canvas.stroke();
  4568. this.Canvas.setLineDash([]);
  4569. }
  4570. this.Canvas.save();
  4571. this.Canvas.setStrokeStyle(this.VPenColor);
  4572. if (this.VPenType == 0)
  4573. {
  4574. this.Canvas.setLineDash([3, 2]); //虚线
  4575. }
  4576. else if (this.VPenType == 2)
  4577. {
  4578. let barWidth = this.Frame.SubFrame[0].Frame.DataWidth; //和K线一样宽度
  4579. if (barWidth > 2) this.Canvas.lineWidth = barWidth;
  4580. }
  4581. this.Canvas.beginPath();
  4582. if (this.Frame.SubFrame.length > 0)
  4583. {
  4584. for (var i in this.Frame.SubFrame)
  4585. {
  4586. var frame = this.Frame.SubFrame[i].Frame;
  4587. top = frame.ChartBorder.GetTopTitle();
  4588. bottom = frame.ChartBorder.GetBottom();
  4589. this.Canvas.moveTo(ToFixedPoint(x), top);
  4590. this.Canvas.lineTo(ToFixedPoint(x), bottom);
  4591. }
  4592. }
  4593. else
  4594. {
  4595. this.Canvas.moveTo(ToFixedPoint(x), top);
  4596. this.Canvas.lineTo(ToFixedPoint(x), bottom);
  4597. }
  4598. this.Canvas.stroke();
  4599. this.Canvas.restore();
  4600. }
  4601. var xValue = this.Frame.GetXData(x);
  4602. var yValueExtend = {};
  4603. var yValue = this.Frame.GetYData(y, yValueExtend);
  4604. this.StringFormatY.RValue = yValueExtend.RightYValue; //右侧子坐标
  4605. if (this.IsShowClose && this.Close != null) yValue = this.Close;
  4606. this.StringFormatX.Value = this.CursorIndex;
  4607. this.StringFormatY.Value = yValue;
  4608. this.StringFormatY.FrameID = yValueExtend.FrameID;
  4609. if (((this.ShowTextMode.Left == 1 && this.Frame.ChartBorder.Left >= 30) || this.ShowTextMode.Left == 2 ||
  4610. (this.ShowTextMode.Right == 1 && this.Frame.ChartBorder.Right >= 30) || this.ShowTextMode.Right == 2) && this.StringFormatY.Operator())
  4611. {
  4612. var text = this.StringFormatY.Text;
  4613. this.Canvas.font = this.Font;
  4614. var textWidth = this.Canvas.measureText(text).width + 4; //前后各空2个像素
  4615. if (this.Frame.ChartBorder.Left >= 30 && this.ShowTextMode.Left == 1)
  4616. {
  4617. this.Canvas.setFillStyle(this.TextBGColor);
  4618. if (left < textWidth) //左边空白的地方太少了画布下
  4619. {
  4620. this.Canvas.fillRect(2, y - this.TextHeight / 2, textWidth, this.TextHeight);
  4621. this.Canvas.textAlign = "left";
  4622. this.Canvas.textBaseline = "middle";
  4623. this.Canvas.setFillStyle(this.TextColor);
  4624. this.Canvas.fillText(text, 2 + 2, y, textWidth);
  4625. }
  4626. else
  4627. {
  4628. this.Canvas.fillRect(left - 2, y - this.TextHeight / 2, -textWidth, this.TextHeight);
  4629. this.Canvas.textAlign = "right";
  4630. this.Canvas.textBaseline = "middle";
  4631. this.Canvas.setFillStyle(this.TextColor);
  4632. this.Canvas.fillText(text, left - 4, y, textWidth);
  4633. }
  4634. }
  4635. else if (this.ShowTextMode.Left == 2)
  4636. {
  4637. this.Canvas.setFillStyle(this.TextBGColor);
  4638. this.Canvas.fillRect(left, y - this.TextHeight / 2, textWidth, this.TextHeight);
  4639. this.Canvas.textAlign = "left";
  4640. this.Canvas.textBaseline = "middle";
  4641. this.Canvas.setFillStyle(this.TextColor);
  4642. this.Canvas.fillText(text, left + 2, y, textWidth);
  4643. }
  4644. if (this.StringFormatY.RText)
  4645. {
  4646. text = this.StringFormatY.RText;
  4647. var textWidth = this.Canvas.measureText(text).width + 4; //前后各空2个像素
  4648. }
  4649. if (this.Frame.ChartBorder.Right >= 30 && this.ShowTextMode.Right == 1)
  4650. {
  4651. this.Canvas.setFillStyle(this.TextBGColor);
  4652. if (rightWidth > textWidth) //右边不够就不画
  4653. {
  4654. this.Canvas.fillRect(right + 2, y - this.TextHeight / 2, textWidth, this.TextHeight);
  4655. this.Canvas.textAlign = "left";
  4656. this.Canvas.textBaseline = "middle";
  4657. this.Canvas.setFillStyle(this.TextColor);
  4658. this.Canvas.fillText(text, right + 4, y, textWidth);
  4659. }
  4660. else
  4661. {
  4662. this.Canvas.fillRect(chartRight - 2 - textWidth, y - this.TextHeight / 2, textWidth, this.TextHeight);
  4663. this.Canvas.textAlign = "right";
  4664. this.Canvas.textBaseline = "middle";
  4665. this.Canvas.setFillStyle(this.TextColor);
  4666. this.Canvas.fillText(text, chartRight - 4, y, textWidth);
  4667. }
  4668. }
  4669. else if (this.ShowTextMode.Right == 2)
  4670. {
  4671. this.Canvas.setFillStyle(this.TextBGColor);
  4672. var showLeft = right - textWidth;
  4673. this.Canvas.fillRect(showLeft, y - this.TextHeight / 2, textWidth, this.TextHeight);
  4674. this.Canvas.textAlign = "left";
  4675. this.Canvas.textBaseline = "middle";
  4676. this.Canvas.setFillStyle(this.TextColor);
  4677. this.Canvas.fillText(text, showLeft + 2, y, textWidth);
  4678. }
  4679. }
  4680. if (this.ShowTextMode.Bottom == 1 && this.StringFormatX.Operator())
  4681. {
  4682. var text = this.StringFormatX.Text;
  4683. this.Canvas.font = this.Font;
  4684. //这个地方是显示十字光标下的日期
  4685. this.Canvas.setFillStyle(this.TextBGColor);
  4686. var textWidth = this.Canvas.measureText(text).width + 4; //前后各空2个像素
  4687. if (x - textWidth / 2 < 3) //左边位置不够了, 顶着左边画
  4688. {
  4689. this.Canvas.fillRect(x - 1, bottom + 2, textWidth, this.TextHeight);
  4690. this.Canvas.textAlign = "left";
  4691. this.Canvas.textBaseline = "top";
  4692. this.Canvas.setFillStyle(this.TextColor);
  4693. var textBottom=bottom;
  4694. var textLeft=x;
  4695. //#ifdef MP-TOUTIAO
  4696. textBottom=textBottom+10;
  4697. textLeft=textLeft-25;
  4698. //#endif
  4699. this.Canvas.fillText(text, textLeft + 1, textBottom + 2, textWidth);
  4700. }
  4701. else if ((right - left) - x < textWidth)
  4702. { //右边位置不够用,顶着右边画
  4703. this.Canvas.fillRect(x - textWidth, bottom + 2, textWidth, this.TextHeight);
  4704. this.Canvas.textAlign = "right";
  4705. this.Canvas.textBaseline = "top";
  4706. this.Canvas.setFillStyle(this.TextColor);
  4707. var textBottom=bottom;
  4708. var textLeft=x;
  4709. //#ifdef MP-TOUTIAO
  4710. textBottom=textBottom+10;
  4711. textLeft=textLeft-25;
  4712. //#endif
  4713. this.Canvas.fillText(text, textLeft + 1, textBottom + 2, textWidth);
  4714. }
  4715. else
  4716. {
  4717. this.Canvas.fillRect(x - textWidth / 2, bottom + 2, textWidth, this.TextHeight);
  4718. this.Canvas.textAlign = "center";
  4719. this.Canvas.textBaseline = "top";
  4720. this.Canvas.setFillStyle(this.TextColor);
  4721. var textBottom=bottom;
  4722. var textLeft=x;
  4723. //#ifdef MP-TOUTIAO
  4724. textBottom=textBottom+10;
  4725. textLeft=textLeft-25;
  4726. //#endif
  4727. this.Canvas.fillText(text, textLeft + 1, textBottom + 2, textWidth);
  4728. }
  4729. }
  4730. }
  4731. this.HScreenDraw = function ()
  4732. {
  4733. var x = this.LastPoint.X;
  4734. var y = this.LastPoint.Y;
  4735. y = this.Frame.GetXFromIndex(this.CursorIndex); //手机端 十字只能画在K线上
  4736. var left = this.Frame.ChartBorder.GetLeft();
  4737. var right = this.Frame.ChartBorder.GetRightEx();
  4738. var top = this.Frame.ChartBorder.GetTop();
  4739. var bottom = this.Frame.ChartBorder.GetBottom();
  4740. var bottomWidth = this.Frame.ChartBorder.Bottom;
  4741. this.PointY = [[left, y], [right, y]];
  4742. this.PointX = [[x, top], [x, bottom]];
  4743. if (this.IsShowCorss) //十字线
  4744. {
  4745. this.Canvas.save();
  4746. this.Canvas.setStrokeStyle(this.HPenColor);
  4747. if (this.HPenType == 0) this.Canvas.setLineDash([3, 2]); //虚线
  4748. //画竖线
  4749. this.Canvas.beginPath();
  4750. this.Canvas.moveTo(ToFixedPoint(x), top);
  4751. this.Canvas.lineTo(ToFixedPoint(x), bottom);
  4752. this.Canvas.stroke();
  4753. this.Canvas.restore();
  4754. this.Canvas.save();
  4755. this.Canvas.setStrokeStyle(this.VPenColor);
  4756. if (this.VPenType == 0)
  4757. {
  4758. this.Canvas.setLineDash([3, 2]); //虚线
  4759. }
  4760. else if (this.VPenType == 2)
  4761. {
  4762. let barWidth = this.Frame.SubFrame[0].Frame.DataWidth; //和K线一样宽度
  4763. if (barWidth > 2) this.Canvas.lineWidth = barWidth;
  4764. }
  4765. this.Canvas.beginPath();
  4766. //画横线
  4767. if (this.Frame.SubFrame.length > 0)
  4768. {
  4769. for (var i in this.Frame.SubFrame)
  4770. {
  4771. var frame = this.Frame.SubFrame[i].Frame;
  4772. this.Canvas.moveTo(frame.ChartBorder.GetLeft(), ToFixedPoint(y));
  4773. this.Canvas.lineTo(frame.ChartBorder.GetRightTitle(), ToFixedPoint(y));
  4774. }
  4775. }
  4776. else
  4777. {
  4778. this.Canvas.moveTo(left, ToFixedPoint(y));
  4779. this.Canvas.lineTo(right, ToFixedPoint(y));
  4780. }
  4781. this.Canvas.stroke();
  4782. this.Canvas.restore();
  4783. }
  4784. var xValue = this.Frame.GetXData(y);
  4785. var yValueExtend = {};
  4786. var yValue = this.Frame.GetYData(x, yValueExtend);
  4787. this.StringFormatX.Value = xValue;
  4788. this.StringFormatY.Value = yValue;
  4789. this.StringFormatY.FrameID = yValueExtend.FrameID;
  4790. if (((this.ShowTextMode.Left == 1 && this.Frame.ChartBorder.Top >= 30) || this.ShowTextMode.Left == 2 ||
  4791. (this.ShowTextMode.Right == 1 && this.Frame.ChartBorder.Bottom >= 30) || this.ShowTextMode.Right == 2) && this.StringFormatY.Operator()) {
  4792. var text = this.StringFormatY.Text;
  4793. this.Canvas.font = this.Font;
  4794. var textWidth = this.Canvas.measureText(text).width + 4; //前后各空2个像素
  4795. if (this.Frame.ChartBorder.Top >= 30 && this.ShowTextMode.Left == 1) {
  4796. var xText = x, yText = top;
  4797. this.Canvas.save();
  4798. this.Canvas.translate(xText, yText);
  4799. this.Canvas.rotate(90 * Math.PI / 180); //数据和框子旋转180度
  4800. this.Canvas.setFillStyle(this.TextBGColor);
  4801. if (top >= textWidth) {
  4802. this.Canvas.fillRect(-textWidth, -(this.TextHeight / 2), textWidth, this.TextHeight);
  4803. this.Canvas.textAlign = "right";
  4804. this.Canvas.textBaseline = "middle";
  4805. this.Canvas.setFillStyle(this.TextColor);
  4806. this.Canvas.fillText(text, -2, 0, textWidth);
  4807. }
  4808. else {
  4809. this.Canvas.fillRect((textWidth - top), -(this.TextHeight / 2), -textWidth, this.TextHeight);
  4810. this.Canvas.textAlign = "right";
  4811. this.Canvas.textBaseline = "middle";
  4812. this.Canvas.setFillStyle(this.TextColor);
  4813. this.Canvas.fillText(text, (textWidth - top) - 2, 0, textWidth);
  4814. }
  4815. this.Canvas.restore();
  4816. }
  4817. else if (this.ShowTextMode.Left == 2) {
  4818. var xText = x;
  4819. var yText = top;
  4820. this.Canvas.save();
  4821. this.Canvas.translate(xText, yText);
  4822. this.Canvas.rotate(90 * Math.PI / 180); //数据和框子旋转180度
  4823. this.Canvas.setFillStyle(this.TextBGColor);
  4824. this.Canvas.fillRect(0, -(this.TextHeight / 2), textWidth, this.TextHeight);
  4825. this.Canvas.textAlign = "left";
  4826. this.Canvas.textBaseline = "middle";
  4827. this.Canvas.setFillStyle(this.TextColor);
  4828. this.Canvas.fillText(text, 2, 0, textWidth);
  4829. this.Canvas.restore();
  4830. }
  4831. if (this.Frame.ChartBorder.Bottom >= 30 && this.ShowTextMode.Right == 1) {
  4832. var xText = x, yText = bottom;
  4833. this.Canvas.save();
  4834. this.Canvas.translate(xText, yText);
  4835. this.Canvas.rotate(90 * Math.PI / 180); //数据和框子旋转180度
  4836. this.Canvas.setFillStyle(this.TextBGColor);
  4837. if (bottomWidth > textWidth) {
  4838. this.Canvas.fillRect(0, -(this.TextHeight / 2), textWidth, this.TextHeight);
  4839. this.Canvas.textAlign = "left";
  4840. this.Canvas.textBaseline = "middle";
  4841. this.Canvas.setFillStyle(this.TextColor);
  4842. this.Canvas.fillText(text, 2, 0, textWidth);
  4843. }
  4844. else {
  4845. this.Canvas.fillRect((bottomWidth - textWidth), -(this.TextHeight / 2), textWidth, this.TextHeight);
  4846. this.Canvas.textAlign = "left";
  4847. this.Canvas.textBaseline = "middle";
  4848. this.Canvas.setFillStyle(this.TextColor);
  4849. this.Canvas.fillText(text, (bottomWidth - textWidth) + 2, 0, textWidth);
  4850. }
  4851. this.Canvas.restore();
  4852. }
  4853. else if (this.ShowTextMode.Right == 2) {
  4854. var xText = x;
  4855. var yText = bottom;
  4856. this.Canvas.save();
  4857. this.Canvas.translate(xText, yText);
  4858. this.Canvas.rotate(90 * Math.PI / 180); //数据和框子旋转180度
  4859. this.Canvas.setFillStyle(this.TextBGColor);
  4860. this.Canvas.fillRect(0, -(this.TextHeight / 2), -textWidth, this.TextHeight);
  4861. this.Canvas.textAlign = "right";
  4862. this.Canvas.textBaseline = "middle";
  4863. this.Canvas.setFillStyle(this.TextColor);
  4864. this.Canvas.fillText(text, -2, 0, textWidth);
  4865. this.Canvas.restore();
  4866. }
  4867. }
  4868. if (this.ShowTextMode.Bottom === 1 && this.StringFormatX.Operator()) {
  4869. var text = this.StringFormatX.Text;
  4870. this.Canvas.font = this.Font;
  4871. this.Canvas.setFillStyle(this.TextBGColor);
  4872. var textWidth = this.Canvas.measureText(text).width + 4; //前后各空2个像素
  4873. if (y - textWidth / 2 < 3) //左边位置不够了, 顶着左边画
  4874. {
  4875. var xText = left;
  4876. var yText = y;
  4877. this.Canvas.save();
  4878. this.Canvas.translate(xText, yText);
  4879. this.Canvas.rotate(90 * Math.PI / 180); //数据和框子旋转180度
  4880. this.Canvas.fillRect(0, 0, textWidth, this.TextHeight);
  4881. this.Canvas.textAlign = "center";
  4882. this.Canvas.textBaseline = "top";
  4883. this.Canvas.setFillStyle(this.TextColor);
  4884. this.Canvas.fillText(text, 0, 0, textWidth);
  4885. this.Canvas.restore();
  4886. }
  4887. else {
  4888. var xText = left;
  4889. var yText = y;
  4890. this.Canvas.save();
  4891. this.Canvas.translate(xText, yText);
  4892. this.Canvas.rotate(90 * Math.PI / 180); //数据和框子旋转180度
  4893. this.Canvas.fillRect(-(textWidth / 2), 0, textWidth, this.TextHeight);
  4894. this.Canvas.textAlign = "center";
  4895. this.Canvas.textBaseline = "top";
  4896. this.Canvas.setFillStyle(this.TextColor);
  4897. this.Canvas.fillText(text, 0, 0, textWidth);
  4898. this.Canvas.restore();
  4899. }
  4900. }
  4901. }
  4902. }
  4903. //分钟线
  4904. function ChartMinutePriceLine()
  4905. {
  4906. this.newMethod = ChartLine; //派生
  4907. this.newMethod();
  4908. delete this.newMethod;
  4909. this.YClose;
  4910. this.IsDrawArea = true; //是否画价格面积图
  4911. this.AreaColor = 'rgba(0,191,255,0.1)';
  4912. this.Draw = function ()
  4913. {
  4914. if (this.NotSupportMessage)
  4915. {
  4916. this.DrawNotSupportmessage();
  4917. return;
  4918. }
  4919. if (!this.IsShow) return;
  4920. if (!this.Data) return;
  4921. var isHScreen = (this.ChartFrame.IsHScreen === true);
  4922. var dataWidth = this.ChartFrame.DataWidth;
  4923. var distanceWidth = this.ChartFrame.DistanceWidth;
  4924. var chartright = this.ChartBorder.GetRight();
  4925. if (isHScreen === true) chartright = this.ChartBorder.GetBottom();
  4926. var xPointCount = this.ChartFrame.XPointCount;
  4927. var minuteCount = this.ChartFrame.MinuteCount;
  4928. var bottom = this.ChartBorder.GetBottomEx();
  4929. var left = this.ChartBorder.GetLeftEx();
  4930. var bFirstPoint = true;
  4931. var ptFirst = {}; //第1个点
  4932. var drawCount = 0;
  4933. for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j)
  4934. {
  4935. var value = this.Data.Data[i];
  4936. if (value == null) continue;
  4937. var x = this.ChartFrame.GetXFromIndex(j);
  4938. var y = this.ChartFrame.GetYFromData(value);
  4939. if (bFirstPoint)
  4940. {
  4941. this.Canvas.setStrokeStyle(this.Color);
  4942. this.Canvas.beginPath();
  4943. if (isHScreen) this.Canvas.moveTo(y, x);
  4944. else this.Canvas.moveTo(x, y);
  4945. bFirstPoint = false;
  4946. ptFirst = { X: x, Y: y };
  4947. }
  4948. else
  4949. {
  4950. if (isHScreen) this.Canvas.lineTo(y, x);
  4951. else this.Canvas.lineTo(x, y);
  4952. }
  4953. ++drawCount;
  4954. if (drawCount >= minuteCount) //上一天的数据和这天地数据线段要断开
  4955. {
  4956. bFirstPoint = true;
  4957. this.Canvas.stroke();
  4958. if (this.IsDrawArea) //画面积
  4959. {
  4960. if (isHScreen)
  4961. {
  4962. this.Canvas.lineTo(left, x);
  4963. this.Canvas.lineTo(left, ptFirst.X);
  4964. this.SetFillStyle(this.AreaColor, this.ChartBorder.GetRightEx(), bottom, this.ChartBorder.GetLeftEx(), bottom);
  4965. }
  4966. else
  4967. {
  4968. this.Canvas.lineTo(x, bottom);
  4969. this.Canvas.lineTo(ptFirst.X, bottom);
  4970. this.SetFillStyle(this.AreaColor, left, this.ChartBorder.GetTopEx(), left, bottom);
  4971. }
  4972. this.Canvas.fill();
  4973. }
  4974. drawCount = 0;
  4975. }
  4976. }
  4977. if (drawCount > 0)
  4978. {
  4979. this.Canvas.stroke();
  4980. if (this.IsDrawArea) //画面积
  4981. {
  4982. if (isHScreen)
  4983. {
  4984. this.Canvas.lineTo(left, x);
  4985. this.Canvas.lineTo(left, ptFirst.X);
  4986. this.SetFillStyle(this.AreaColor, this.ChartBorder.GetRightEx(), bottom, this.ChartBorder.GetLeftEx(), bottom);
  4987. }
  4988. else
  4989. {
  4990. this.Canvas.lineTo(x, bottom);
  4991. this.Canvas.lineTo(ptFirst.X, bottom);
  4992. this.SetFillStyle(this.AreaColor, left, this.ChartBorder.GetTopEx(), left, bottom);
  4993. }
  4994. this.Canvas.fill();
  4995. }
  4996. }
  4997. }
  4998. this.GetMaxMin = function ()
  4999. {
  5000. var xPointCount = this.ChartFrame.XPointCount;
  5001. var range = {};
  5002. if (this.YClose == null) return range;
  5003. range.Min = this.YClose;
  5004. range.Max = this.YClose;
  5005. for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j)
  5006. {
  5007. var value = this.Data.Data[i];
  5008. if (!value) continue;
  5009. if (range.Max == null) range.Max = value;
  5010. if (range.Min == null) range.Min = value;
  5011. if (range.Max < value) range.Max = value;
  5012. if (range.Min > value) range.Min = value;
  5013. }
  5014. if (range.Max == this.YClose && range.Min == this.YClose)
  5015. {
  5016. range.Max = this.YClose + this.YClose * 0.1;
  5017. range.Min = this.YClose - this.YClose * 0.1;
  5018. return range;
  5019. }
  5020. var distance = Math.max(Math.abs(this.YClose - range.Max), Math.abs(this.YClose - range.Min));
  5021. range.Max = this.YClose + distance;
  5022. range.Min = this.YClose - distance;
  5023. return range;
  5024. }
  5025. }
  5026. ////////////////////////////////////////////////////////////////////////////////
  5027. //深度图十字光标
  5028. function DepthChartCorssCursor()
  5029. {
  5030. this.Frame;
  5031. this.Canvas; //画布
  5032. this.Data;
  5033. this.Symbol;
  5034. this.HQChart;
  5035. this.HPenType=0; //水平线样式 0=虚线 1=实线
  5036. this.VPenType=0; //垂直线颜色 0=虚线 1=实线
  5037. this.LineDash=g_JSChartResource.DepthCorss.LineDash;
  5038. this.AskColor=g_JSChartResource.DepthCorss.AskColor.Line; //卖
  5039. this.BidColor=g_JSChartResource.DepthCorss.BidColor.Line; //买
  5040. this.LineWidth=g_JSChartResource.DepthCorss.LineWidth;
  5041. this.IsShowTooltip=true;
  5042. this.Tooltip=
  5043. {
  5044. LineHeight:g_JSChartResource.DepthCorss.Tooltip.LineHeight,
  5045. Border:
  5046. {
  5047. Top:g_JSChartResource.DepthCorss.Tooltip.Border.Top,
  5048. Left:g_JSChartResource.DepthCorss.Tooltip.Border.Left,
  5049. Bottom:g_JSChartResource.DepthCorss.Tooltip.Border.Bottom,
  5050. Center: g_JSChartResource.DepthCorss.Tooltip.Border.Center
  5051. },
  5052. Font:g_JSChartResource.DepthCorss.Tooltip.Font,
  5053. TextColor:g_JSChartResource.DepthCorss.Tooltip.TextColor,
  5054. BGColor:g_JSChartResource.DepthCorss.Tooltip.BGColor
  5055. }; // Width: Height:
  5056. this.Font=g_JSChartResource.CorssCursorTextFont; //字体
  5057. this.TextColor=g_JSChartResource.CorssCursorTextColor; //文本颜色
  5058. this.TextBGColor=g_JSChartResource.CorssCursorBGColor; //文本背景色
  5059. this.TextHeight=20; //文本字体高度
  5060. this.LastPoint;
  5061. this.PointX;
  5062. this.PointY;
  5063. this.StringFormatX;
  5064. this.StringFormatY;
  5065. this.IsShowCorss=true; //是否显示十字光标
  5066. this.IsShow=true;
  5067. this.GetVol=function(price, isAsk)
  5068. {
  5069. if (!this.Data) return null;
  5070. var aryData=isAsk? this.Data.Asks:this.Data.Bids;
  5071. if (!aryData || !Array.isArray(aryData) || aryData.length<=0) return null;
  5072. for(var i in aryData)
  5073. {
  5074. var item=aryData[i];
  5075. if (item.Price==price) return item.Vol;
  5076. }
  5077. return null;
  5078. }
  5079. this.Draw=function()
  5080. {
  5081. this.Status=0;
  5082. if (!this.LastPoint) return;
  5083. if (!this.Data) return;
  5084. if (!this.IsShow) return;
  5085. var x=this.LastPoint.X;
  5086. var y=this.LastPoint.Y;
  5087. var isInClient=false;
  5088. var rtClient = new Rect(this.Frame.ChartBorder.GetLeft(), this.Frame.ChartBorder.GetTop(), this.Frame.ChartBorder.GetWidth(), this.Frame.ChartBorder.GetHeight());
  5089. isInClient = rtClient.IsPointIn(x, y);
  5090. this.PointY=null;
  5091. this.PointY==null;
  5092. if (!isInClient) return;
  5093. if (this.Frame.IsHScreen===true)
  5094. {
  5095. return;
  5096. }
  5097. var left=this.Frame.ChartBorder.GetLeft();
  5098. var right=this.Frame.ChartBorder.GetRight();
  5099. var top=this.Frame.ChartBorder.GetTopTitle();
  5100. var bottom=this.Frame.ChartBorder.GetBottom();
  5101. var rightWidth=this.Frame.ChartBorder.Right;
  5102. var chartRight=this.Frame.ChartBorder.GetChartWidth();
  5103. var xValue=this.Frame.GetXData(x);
  5104. var xInfo=this.Frame.GetXFromPrice(xValue); //调整价格到有数据的点上
  5105. if (!xInfo) return;
  5106. var yVol=this.GetVol(xInfo.Price, xInfo.IsAsk);
  5107. y=this.Frame.GetYFromData(yVol); //调整Y轴, 让它在线段上
  5108. xInfo.Vol=yVol;
  5109. xInfo.Y=y;
  5110. this.PointY=[[left,y],[right,y]];
  5111. this.PointX=[[x,top],[x,bottom]];
  5112. if (this.IsShowCorss)
  5113. {
  5114. if (xInfo.IsAsk) this.Canvas.strokeStyle=this.AskColor;
  5115. else this.Canvas.strokeStyle=this.BidColor;
  5116. this.Canvas.save();
  5117. this.Canvas.lineWidth=this.LineWidth;
  5118. var lineWidth=this.Canvas.lineWidth;
  5119. if (this.HPenType==1 || this.HPenType==0) //0=实线 1=虚线
  5120. {
  5121. if (this.HPenType==0) this.Canvas.setLineDash(this.LineDash); //虚线
  5122. var yFix=ToFixedPoint(y);
  5123. this.Canvas.beginPath();
  5124. this.Canvas.moveTo(left,yFix);
  5125. this.Canvas.lineTo(right,yFix);
  5126. this.Canvas.stroke();
  5127. if (this.HPenType==0) this.Canvas.setLineDash([]);
  5128. }
  5129. if (this.VPenType==0) this.Canvas.setLineDash(this.LineDash); //虚线
  5130. var xFix=ToFixedPoint(xInfo.X);
  5131. this.Canvas.beginPath();
  5132. this.Canvas.moveTo(xFix,top);
  5133. this.Canvas.lineTo(xFix,bottom);
  5134. this.Canvas.stroke();
  5135. if (this.VPenType==0) this.Canvas.setLineDash([]);
  5136. this.Canvas.restore();
  5137. }
  5138. if (this.HQChart)
  5139. {
  5140. //JSCHART_EVENT_ID.ON_DRAW_DEPTH_TOOLTIP
  5141. var event=this.HQChart.GetEvent(25);
  5142. if (event)
  5143. {
  5144. event.Callback(event,xInfo,this);
  5145. }
  5146. }
  5147. if (this.IsShowTooltip) this.DrawTooltip(xInfo);
  5148. }
  5149. this.DrawTooltip=function(data)
  5150. {
  5151. var price=data.Price;
  5152. var vol=data.Vol;
  5153. var border=this.Tooltip.Border;
  5154. this.Canvas.font=this.Tooltip.Font;
  5155. var floatPrecision=2;
  5156. if (this.Symbol) floatPrecision=JSCommonCoordinateData.GetfloatPrecision(this.Symbol);//价格小数位数
  5157. var maxText='擎擎: 9999.99亿 ';
  5158. if (floatPrecision>=5) maxText=`擎擎: ${99.99.toFixed(floatPrecision)} `; //小数位数太多了
  5159. this.Tooltip.Width=this.Canvas.measureText(maxText).width+border.Left;
  5160. this.Tooltip.Height=this.Tooltip.LineHeight*4+border.Top+border.Bottom+border.Center;
  5161. var chartRight=this.Frame.ChartBorder.GetRight();
  5162. var chartTop=this.Frame.ChartBorder.GetTop();
  5163. var left=data.X+2;
  5164. var top=data.Y-this.Tooltip.Height-2;
  5165. if (left+this.Tooltip.Width>=chartRight) left=data.X-this.Tooltip.Width-2;
  5166. if (top<chartTop) top=data.Y+2;
  5167. this.Canvas.fillStyle=this.Tooltip.BGColor;
  5168. this.Canvas.fillRect(left,top,this.Tooltip.Width,this.Tooltip.Height);
  5169. var x=border.Left+left;
  5170. var y=border.Top+top;
  5171. this.Canvas.textBaseline="top";
  5172. this.Canvas.textAlign="left";
  5173. this.Canvas.fillStyle=this.Tooltip.TextColor;
  5174. this.Canvas.fillText("委托价",x,y);
  5175. y+=this.Tooltip.LineHeight;
  5176. this.Canvas.fillText(data.Price.toFixed(floatPrecision),x,y);
  5177. y+=this.Tooltip.LineHeight;
  5178. y+=border.Center;
  5179. this.Canvas.fillText("累计",x,y);
  5180. y+=this.Tooltip.LineHeight;
  5181. this.Canvas.fillText(data.Vol.toFixed(4),x,y);
  5182. }
  5183. }
  5184. //深度图
  5185. function ChartOrderbookDepth()
  5186. {
  5187. this.newMethod=IChartPainting; //派生
  5188. this.newMethod();
  5189. delete this.newMethod;
  5190. this.ClassName="ChartOrderbookDepth";
  5191. this.Data=null;
  5192. this.AskColor={ Line:g_JSChartResource.DepthChart.AskColor.Line, Area:g_JSChartResource.DepthChart.AskColor.Area } //卖
  5193. this.BidColor={ Line:g_JSChartResource.DepthChart.BidColor.Line, Area:g_JSChartResource.DepthChart.BidColor.Area } //买
  5194. this.LineWidth=g_JSChartResource.DepthChart.LineWidth;
  5195. this.Draw=function()
  5196. {
  5197. if (!this.Data) return;
  5198. this.Canvas.save();
  5199. this.Canvas.lineWidth=this.LineWidth;
  5200. this.DrawArea(this.Data.Bids, this.BidColor.Line, this.BidColor.Area, true);
  5201. this.DrawArea(this.Data.Asks, this.AskColor.Line, this.AskColor.Area, false);
  5202. this.Canvas.restore();
  5203. }
  5204. this.DrawArea=function(aryData, colorLine, colorArea, isLeft)
  5205. {
  5206. var xRange=this.ChartFrame.VerticalRange;
  5207. var aryPoint=[];
  5208. for(var i in aryData)
  5209. {
  5210. var item=aryData[i];
  5211. if (isLeft)
  5212. {
  5213. if (item.Price<xRange.Min) break;
  5214. }
  5215. else
  5216. {
  5217. if (item.Price>xRange.Max) break;
  5218. }
  5219. var x=this.ChartFrame.GetXFromIndex(item.Price);
  5220. var y=this.ChartFrame.GetYFromData(item.Vol);
  5221. aryPoint.push({X:x,Y:y});
  5222. }
  5223. if (aryPoint.length<=1) return;
  5224. var left=this.ChartBorder.GetLeft();
  5225. var bottom=this.ChartBorder.GetBottom();
  5226. var right=this.ChartBorder.GetRight();
  5227. this.Canvas.beginPath();
  5228. this.Canvas.moveTo(aryPoint[0].X, bottom);
  5229. for(var i in aryPoint)
  5230. {
  5231. var item=aryPoint[i];
  5232. this.Canvas.lineTo(item.X,item.Y);
  5233. }
  5234. this.Canvas.lineTo(isLeft?left:right,aryPoint[aryPoint.length-1].Y);
  5235. this.Canvas.lineTo(isLeft?left:right,bottom);
  5236. this.Canvas.lineTo(aryPoint[0].X,bottom);
  5237. this.Canvas.closePath();
  5238. this.Canvas.setFillStyle(colorArea);
  5239. this.Canvas.fill();
  5240. this.Canvas.beginPath();
  5241. this.Canvas.moveTo(aryPoint[0].X, bottom);
  5242. for(var i in aryPoint)
  5243. {
  5244. var item=aryPoint[i];
  5245. this.Canvas.lineTo(item.X,item.Y);
  5246. }
  5247. this.Canvas.lineTo(isLeft?left:right,aryPoint[aryPoint.length-1].Y);
  5248. this.Canvas.strokeStyle=colorLine;
  5249. this.Canvas.stroke();
  5250. }
  5251. this.GetMaxMin=function()
  5252. {
  5253. var range={ Min:null, Max:null, XMin:null, XMax:null };
  5254. var xRange=this.ChartFrame.VerticalRange;
  5255. for(var i in this.Data.Asks)
  5256. {
  5257. var item=this.Data.Asks[i];
  5258. if (item.Price>xRange.Max) break;
  5259. if (range.XMin==null || range.XMin>item.Price) range.XMin=item.Price;
  5260. if (range.XMax==null || range.XMax<item.Price) range.XMax=item.Price;
  5261. if (range.Min==null || range.Min>item.Vol) range.Min=item.Vol;
  5262. if (range.Max==null || range.Max<item.Vol) range.Max=item.Vol;
  5263. }
  5264. for(var i in this.Data.Bids)
  5265. {
  5266. var item=this.Data.Bids[i];
  5267. if (item.Price<xRange.Min) break;
  5268. if (range.XMin==null || range.XMin>item.Price) range.XMin=item.Price;
  5269. if (range.XMax==null || range.XMax<item.Price) range.XMax=item.Price;
  5270. if (range.Min==null || range.Min>item.Vol) range.Min=item.Vol;
  5271. if (range.Max==null || range.Max<item.Vol) range.Max=item.Vol;
  5272. }
  5273. return range;
  5274. }
  5275. }
  5276. ///////////////////////////////////////////////////////////////////////////////////////
  5277. // 公共函数
  5278. //修正线段有毛刺
  5279. function ToFixedPoint(value)
  5280. {
  5281. //return value;
  5282. return parseInt(value) + 0.5;
  5283. }
  5284. function ToFixedRect(value)
  5285. {
  5286. var rounded;
  5287. return rounded = (0.5 + value) << 0;
  5288. }
  5289. //导出统一使用JSCommon命名空间名
  5290. module.exports =
  5291. {
  5292. JSCommonChartPaint:
  5293. {
  5294. IChartPaintin: IChartPainting,
  5295. ChartKLine: ChartKLine,
  5296. ChartLine: ChartLine,
  5297. ChartSubLine: ChartSubLine,
  5298. ChartSingleText: ChartSingleText,
  5299. ChartPointDot: ChartPointDot,
  5300. ChartStick: ChartStick,
  5301. ChartLineStick: ChartLineStick,
  5302. ChartStickLine: ChartStickLine,
  5303. ChartOverlayKLine: ChartOverlayKLine,
  5304. ChartMinuteInfo: ChartMinuteInfo,
  5305. ChartRectangle: ChartRectangle,
  5306. ChartMultiText: ChartMultiText,
  5307. ChartMultiHtmlDom:ChartMultiHtmlDom,
  5308. ChartMultiLine: ChartMultiLine,
  5309. ChartBackground:ChartBackground,
  5310. ChartBuySell: ChartBuySell,
  5311. ChartMultiBar: ChartMultiBar,
  5312. ChartMACD:ChartMACD,
  5313. ChartMinutePriceLine:ChartMinutePriceLine,
  5314. ChartLock:ChartLock,
  5315. ChartVolStick:ChartVolStick,
  5316. ChartBand:ChartBand,
  5317. ChartMinuteVolumBar:ChartMinuteVolumBar,
  5318. ChartText:ChartText,
  5319. ChartStraightArea:ChartStraightArea,
  5320. ChartSplashPaint:ChartSplashPaint,
  5321. ChartPie: ChartPie,
  5322. ChartCircle: ChartCircle,
  5323. ChartChinaMap: ChartChinaMap,
  5324. ChartRadar: ChartRadar,
  5325. ChartCorssCursor: ChartCorssCursor, //十字光标
  5326. DepthChartCorssCursor:DepthChartCorssCursor,
  5327. ChartOrderbookDepth:ChartOrderbookDepth,
  5328. },
  5329. //单个类导出
  5330. JSCommonChartPaint_IChartPainting: IChartPainting,
  5331. JSCommonChartPaint_ChartKLine: ChartKLine,
  5332. JSCommonChartPaint_ChartLine: ChartLine,
  5333. JSCommonChartPaint_ChartSubLine: ChartSubLine,
  5334. JSCommonChartPaint_ChartSingleText: ChartSingleText,
  5335. JSCommonChartPaint_ChartPointDot: ChartPointDot,
  5336. JSCommonChartPaint_ChartStick: ChartStick,
  5337. JSCommonChartPaint_ChartLineStick: ChartLineStick,
  5338. JSCommonChartPaint_ChartStickLine: ChartStickLine,
  5339. JSCommonChartPaint_ChartBackground:ChartBackground,
  5340. JSCommonChartPaint_ChartMinuteVolumBar:ChartMinuteVolumBar,
  5341. JSCommonChartPaint_ChartOverlayKLine: ChartOverlayKLine,
  5342. JSCommonChartPaint_ChartLock:ChartLock,
  5343. JSCommonChartPaint_ChartVolStick:ChartVolStick,
  5344. JSCommonChartPaint_ChartBand:ChartBand,
  5345. JSCommonChartPaint_ChartMinutePriceLine:ChartMinutePriceLine,
  5346. JSCommonChartPaint_ChartPie: ChartPie,
  5347. JSCommonChartPaint_ChartCircle: ChartCircle,
  5348. JSCommonChartPaint_ChartChinaMap: ChartChinaMap,
  5349. JSCommonChartPaint_ChartRadar: ChartRadar,
  5350. JSCommonChartPaint_ChartMinuteInfo: ChartMinuteInfo,
  5351. JSCommonChartPaint_ChartRectangle: ChartRectangle,
  5352. JSCommonChartPaint_ChartMultiText: ChartMultiText,
  5353. JSCommonChartPaint_ChartMultiLine: ChartMultiLine,
  5354. JSCommonChartPaint_ChartMultiHtmlDom: ChartMultiHtmlDom,
  5355. JSCommonChartPaint_ChartMultiBar: ChartMultiBar,
  5356. JSCommonChartPaint_ChartBuySell: ChartBuySell,
  5357. JSCommonChartPaint_ChartMACD: ChartMACD,
  5358. JSCommonChartPaint_ChartText:ChartText,
  5359. JSCommonChartPaint_ChartStraightArea:ChartStraightArea,
  5360. JSCommonChartPaint_ChartCorssCursor: ChartCorssCursor,
  5361. JSCommonChartPaint_DepthChartCorssCursor:DepthChartCorssCursor,
  5362. JSCommonChartPaint_ChartOrderbookDepth:ChartOrderbookDepth,
  5363. JSCommonChartPaint_ChartSplashPaint:ChartSplashPaint,
  5364. };