| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470847184728473847484758476847784788479848084818482848384848485848684878488848984908491849284938494849584968497849884998500850185028503850485058506850785088509851085118512851385148515851685178518851985208521852285238524852585268527852885298530853185328533853485358536853785388539854085418542854385448545854685478548854985508551855285538554855585568557855885598560856185628563856485658566856785688569857085718572857385748575857685778578857985808581858285838584858585868587858885898590859185928593859485958596859785988599860086018602860386048605860686078608860986108611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668866986708671867286738674867586768677867886798680868186828683868486858686868786888689869086918692869386948695869686978698869987008701870287038704870587068707870887098710871187128713871487158716871787188719872087218722872387248725872687278728872987308731873287338734873587368737873887398740874187428743874487458746874787488749875087518752875387548755875687578758875987608761876287638764876587668767876887698770877187728773877487758776877787788779878087818782878387848785878687878788878987908791879287938794879587968797879887998800880188028803880488058806880788088809881088118812881388148815881688178818881988208821882288238824882588268827882888298830883188328833883488358836883788388839884088418842884388448845884688478848884988508851885288538854885588568857885888598860886188628863886488658866886788688869887088718872887388748875887688778878887988808881888288838884888588868887888888898890889188928893889488958896889788988899890089018902890389048905890689078908890989108911891289138914891589168917891889198920892189228923892489258926892789288929893089318932893389348935893689378938893989408941894289438944894589468947894889498950895189528953895489558956895789588959896089618962896389648965896689678968896989708971897289738974897589768977897889798980898189828983898489858986898789888989899089918992899389948995899689978998899990009001900290039004900590069007900890099010901190129013901490159016901790189019902090219022902390249025902690279028902990309031903290339034903590369037903890399040904190429043904490459046904790489049905090519052905390549055905690579058905990609061906290639064906590669067906890699070907190729073907490759076907790789079908090819082908390849085908690879088908990909091909290939094909590969097909890999100910191029103910491059106910791089109911091119112911391149115911691179118911991209121912291239124912591269127912891299130913191329133913491359136913791389139914091419142914391449145914691479148914991509151915291539154915591569157915891599160916191629163916491659166916791689169917091719172917391749175917691779178917991809181918291839184918591869187918891899190919191929193919491959196919791989199920092019202920392049205920692079208920992109211921292139214921592169217921892199220922192229223922492259226922792289229923092319232923392349235923692379238923992409241924292439244924592469247924892499250925192529253925492559256925792589259926092619262926392649265926692679268926992709271927292739274927592769277927892799280928192829283928492859286928792889289929092919292929392949295929692979298929993009301930293039304930593069307930893099310931193129313931493159316931793189319932093219322932393249325932693279328932993309331933293339334933593369337933893399340934193429343934493459346934793489349935093519352935393549355935693579358935993609361936293639364936593669367936893699370937193729373937493759376937793789379938093819382938393849385938693879388938993909391939293939394939593969397939893999400940194029403940494059406940794089409941094119412941394149415941694179418941994209421942294239424942594269427942894299430943194329433943494359436943794389439944094419442944394449445944694479448944994509451945294539454945594569457945894599460946194629463946494659466946794689469947094719472947394749475947694779478947994809481948294839484948594869487948894899490949194929493949494959496949794989499950095019502950395049505950695079508950995109511951295139514951595169517951895199520952195229523952495259526952795289529953095319532953395349535953695379538953995409541954295439544954595469547954895499550955195529553955495559556955795589559956095619562956395649565956695679568956995709571957295739574957595769577957895799580958195829583958495859586958795889589959095919592959395949595959695979598959996009601960296039604960596069607960896099610961196129613961496159616961796189619962096219622962396249625962696279628962996309631963296339634963596369637963896399640964196429643964496459646964796489649965096519652965396549655965696579658965996609661966296639664966596669667966896699670967196729673967496759676967796789679968096819682968396849685968696879688968996909691969296939694969596969697969896999700970197029703970497059706970797089709971097119712971397149715971697179718971997209721972297239724972597269727972897299730973197329733973497359736973797389739974097419742974397449745974697479748974997509751975297539754975597569757975897599760976197629763976497659766976797689769977097719772977397749775977697779778977997809781978297839784978597869787978897899790979197929793979497959796979797989799980098019802980398049805980698079808980998109811981298139814981598169817981898199820982198229823982498259826982798289829983098319832983398349835983698379838983998409841984298439844984598469847984898499850985198529853985498559856985798589859986098619862986398649865986698679868986998709871987298739874987598769877987898799880988198829883988498859886988798889889989098919892989398949895989698979898989999009901990299039904990599069907990899099910991199129913991499159916991799189919992099219922992399249925992699279928992999309931993299339934993599369937993899399940994199429943994499459946994799489949995099519952995399549955995699579958995999609961996299639964996599669967996899699970997199729973997499759976997799789979998099819982998399849985998699879988998999909991999299939994999599969997999899991000010001100021000310004100051000610007100081000910010100111001210013100141001510016100171001810019100201002110022100231002410025100261002710028100291003010031100321003310034100351003610037100381003910040100411004210043100441004510046100471004810049100501005110052100531005410055100561005710058100591006010061100621006310064100651006610067100681006910070100711007210073100741007510076100771007810079100801008110082100831008410085100861008710088100891009010091100921009310094100951009610097100981009910100101011010210103101041010510106101071010810109101101011110112101131011410115101161011710118101191012010121101221012310124101251012610127101281012910130101311013210133101341013510136101371013810139101401014110142101431014410145101461014710148101491015010151101521015310154101551015610157101581015910160101611016210163101641016510166101671016810169101701017110172101731017410175101761017710178101791018010181101821018310184101851018610187101881018910190101911019210193101941019510196101971019810199102001020110202102031020410205102061020710208102091021010211102121021310214102151021610217102181021910220102211022210223102241022510226102271022810229102301023110232102331023410235102361023710238102391024010241102421024310244102451024610247102481024910250102511025210253102541025510256102571025810259102601026110262102631026410265102661026710268102691027010271102721027310274102751027610277102781027910280102811028210283102841028510286102871028810289102901029110292102931029410295102961029710298102991030010301103021030310304103051030610307103081030910310103111031210313103141031510316103171031810319103201032110322103231032410325103261032710328103291033010331103321033310334103351033610337103381033910340103411034210343103441034510346103471034810349103501035110352103531035410355103561035710358103591036010361103621036310364103651036610367103681036910370103711037210373103741037510376103771037810379103801038110382103831038410385103861038710388103891039010391103921039310394103951039610397103981039910400104011040210403104041040510406104071040810409104101041110412104131041410415104161041710418104191042010421104221042310424104251042610427104281042910430104311043210433104341043510436104371043810439104401044110442104431044410445104461044710448104491045010451104521045310454104551045610457104581045910460104611046210463104641046510466104671046810469104701047110472104731047410475104761047710478104791048010481104821048310484104851048610487104881048910490104911049210493104941049510496104971049810499105001050110502105031050410505105061050710508105091051010511105121051310514105151051610517105181051910520105211052210523105241052510526105271052810529105301053110532105331053410535105361053710538105391054010541105421054310544105451054610547105481054910550105511055210553105541055510556105571055810559105601056110562105631056410565105661056710568105691057010571105721057310574105751057610577105781057910580105811058210583105841058510586105871058810589105901059110592105931059410595105961059710598105991060010601106021060310604106051060610607106081060910610106111061210613106141061510616106171061810619106201062110622106231062410625106261062710628106291063010631106321063310634106351063610637106381063910640106411064210643106441064510646106471064810649106501065110652106531065410655106561065710658106591066010661106621066310664106651066610667106681066910670106711067210673106741067510676106771067810679106801068110682106831068410685106861068710688106891069010691106921069310694106951069610697106981069910700107011070210703107041070510706107071070810709107101071110712107131071410715107161071710718107191072010721107221072310724107251072610727107281072910730107311073210733107341073510736107371073810739107401074110742107431074410745107461074710748107491075010751107521075310754107551075610757107581075910760107611076210763107641076510766107671076810769107701077110772107731077410775107761077710778107791078010781107821078310784107851078610787107881078910790107911079210793107941079510796107971079810799108001080110802108031080410805108061080710808108091081010811108121081310814108151081610817108181081910820108211082210823108241082510826108271082810829108301083110832108331083410835108361083710838108391084010841108421084310844108451084610847108481084910850108511085210853108541085510856108571085810859108601086110862108631086410865108661086710868108691087010871108721087310874108751087610877108781087910880108811088210883108841088510886108871088810889108901089110892108931089410895108961089710898108991090010901109021090310904109051090610907109081090910910109111091210913109141091510916109171091810919109201092110922109231092410925109261092710928109291093010931109321093310934109351093610937109381093910940109411094210943109441094510946109471094810949109501095110952109531095410955109561095710958109591096010961109621096310964109651096610967109681096910970109711097210973109741097510976109771097810979109801098110982109831098410985109861098710988109891099010991109921099310994109951099610997109981099911000110011100211003110041100511006110071100811009110101101111012110131101411015110161101711018110191102011021110221102311024110251102611027110281102911030110311103211033110341103511036110371103811039110401104111042110431104411045110461104711048110491105011051110521105311054110551105611057110581105911060110611106211063110641106511066110671106811069110701107111072110731107411075110761107711078110791108011081110821108311084110851108611087110881108911090110911109211093110941109511096110971109811099111001110111102111031110411105111061110711108111091111011111111121111311114111151111611117111181111911120111211112211123111241112511126111271112811129111301113111132111331113411135111361113711138111391114011141111421114311144111451114611147111481114911150111511115211153111541115511156111571115811159111601116111162111631116411165111661116711168111691117011171111721117311174111751117611177111781117911180111811118211183111841118511186111871118811189111901119111192111931119411195111961119711198111991120011201112021120311204112051120611207112081120911210 |
- /*
- copyright (c) 2018 jones
- http://www.apache.org/licenses/LICENSE-2.0
- 开源项目 https://github.com/jones2000/HQChart
- jones_2000@163.com
- 小程序图形库
- */
- //行情数据结构体 及涉及到的行情算法(复权,周期等)
- import
- {
- ChartData, HistoryData,
- SingleData, MinuteData,
- Rect,RectV2,
- JSCHART_EVENT_ID,
- OVERLAY_STATUS_ID,
- JSCHART_CORSSCURSOR_STATUS_ID,
- CloneData
- } from "./umychart.data.wechat.js";
- import
- {
- g_JSChartResource,
- g_JSChartLocalization,
- JSChartResource,
- } from './umychart.resource.wechat.js'
- import
- {
- IFrameSplitOperator,
- } from './umychart.framesplit.wechat.js'
- import
- {
- JSCommonCoordinateData,
- MARKET_SUFFIX_NAME
- } from "./umychart.coordinatedata.wechat.js";
- import { JSConsole } from "./umychart.console.wechat.js";
- import { Path2DHelper } from "./umychart.data.wechat.js"
- //配色
- function JSChartPaintResource()
- {
- //指标不支持信息
- this.Index=
- {
- NotSupport : { Font: "14px 微软雅黑", TextColor: "rgb(52,52,52)" }
- }
- }
- var g_JSChartPaintResource = new JSChartPaintResource();
- function GetFontHeight(context, font, word)
- {
- if (!context) return null;
- if (font) context.font=font;
- var text='擎';
- if (IFrameSplitOperator.IsString(word)) text=word;
- var fontInfo=context.measureText(text);
- //var textHeight=fontInfo.fontBoundingBoxAscent + fontInfo.fontBoundingBoxDescent;
- var textHeight=fontInfo.width+2;
- return textHeight;
- }
- function ColorToRGBA(color,opacity)
- {
- var reg = /^(rgb|RGB)/;
- if (reg.test(color))
- {
- var strHex = "#";
- var colorArr = color.replace(/(?:\(|\)|rgb|RGB)*/g, "").split(","); // 把RGB的3个数值变成数组
- // 转成16进制
- for (var i = 0; i < colorArr.length; i++)
- {
- var hex = Number(colorArr[i]).toString(16);
- if (hex === "0") hex += hex;
- strHex += hex;
- }
- color=strHex;
- }
-
- return "rgba(" + parseInt("0x" + color.slice(1, 3)) + "," + parseInt("0x" + color.slice(3, 5)) + "," + parseInt("0x" + color.slice(5, 7)) + "," + opacity + ")";
- }
- //图新画法接口类
- function IChartPainting()
- {
- this.Canvas; //画布
- this.ChartBorder; //边框信息
- this.ChartFrame; //框架画法
- this.Name; //名称
- this.ClassName = 'IChartPainting'; //类名
- this.Data = new ChartData(); //数据区
- this.Script; //图形对应的指标脚本 (只有指标图形才有)
- this.NotSupportMessage = null;
- this.MessageFont = g_JSChartPaintResource.Index.NotSupport.Font;
- this.MessageColor = g_JSChartPaintResource.Index.NotSupport.TextColor;
- this.IsDrawFirst = false; //是否比K线先画
- this.IsShow = true; //是否显示
- this.IsVisible=true; //是否显示 (预留给外部单独设置线段显隐)
- this.GetEventCallback;
- this.Draw = function () { }
- this.BuildKey=function(item)
- {
- if (IFrameSplitOperator.IsNumber(item.Time)) return `${item.Date}-${item.Time}`;
- else return item.Date;
- }
- this.GetYFromData=function(value,isLimit)
- {
- return this.ChartFrame.GetYFromData(value,isLimit);
- }
- this.GetBorder=function()
- {
- if (this.ChartFrame.IsHScreen) return this.ChartBorder.GetHScreenBorder();
- return this.ChartBorder.GetBorder();
- }
-
- this.IsMinuteFrame=function()
- {
- var isMinute=(this.ChartFrame.ClassName=="MinuteFrame" || this.ChartFrame.ClassName=="MinuteHScreenFrame" ||
- this.ChartFrame.ClassName=="OverlayMinuteFrame" || this.ChartFrame.ClassName=="OverlayMinuteHScreenFrame");
- return isMinute
- }
- //是否隐藏指标
- this.IsHideScriptIndex=function()
- {
- if (this.Script && this.Script.IsShow==false) return true;
- return false;
- }
- this.DrawNotSupportmessage=function()
- {
- this.Canvas.font = this.MessageFont;
- this.Canvas.fillStyle = this.MessageColor;
- var left = this.ChartBorder.GetLeft();
- var width = this.ChartBorder.GetWidth();
- var top = this.ChartBorder.GetTopEx();
- var height = this.ChartBorder.GetHeightEx();
- var x = left + width / 2;
- var y = top + height / 2;
- var bHScreen=this.ChartFrame.IsHScreen;
- if (bHScreen)
- {
- this.Canvas.save();
- this.Canvas.translate(x, y);
- this.Canvas.rotate(90 * Math.PI / 180);
- x=0,y=0;
- }
- this.Canvas.textAlign = "center";
- this.Canvas.textBaseline = "middle";
- this.Canvas.fillText(this.NotSupportMessage, x, y);
- if (bHScreen) this.Canvas.restore();
- }
- this.GetTooltipData = function (x, y, tooltip)
- {
- return false;
- }
- this.GetMaxMin = function ()
- {
- var xPointCount = this.ChartFrame.XPointCount;
- var range = {};
- range.Min = null;
- range.Max = null;
- if (!this.Data || !this.Data.Data) return range;
- for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j)
- {
- var value = this.Data.Data[i];
- if (value == null || isNaN(value)) continue;
- if (range.Max == null) range.Max = value;
- if (range.Min == null) range.Min = value;
- if (range.Max < value) range.Max = value;
- if (range.Min > value) range.Min = value;
- }
- return range;
- }
- this.GetDynamicFont = function (dataWidth) //根据宽度自动获取对应字体
- {
- var font;
- if (dataWidth < 5) font = '4px Arial'; //字体根据数据宽度动态调整
- else if (dataWidth < 7) font = '6px Arial';
- else if (dataWidth < 9) font = '8px Arial';
- else if (dataWidth < 11) font = '10px Arial';
- else if (dataWidth < 13) font = '12px Arial';
- else if (dataWidth < 15) font = '14px Arial';
- else font = '16px Arial';
- return font;
- }
- this.GetDynamicFontEx=function(dataWidth, distanceWidth, maxSize, minSize, zoom, fontname) //根据宽度自动获取对应字体
- {
- if (maxSize==minSize)
- {
- var font=`${maxSize.toFixed(0)}px ${fontname}` ;
- return font;
- }
- var fontSize=(dataWidth+distanceWidth);
- if (zoom)
- {
- if (zoom.Type==0)
- {
- if (zoom.Value>0) fontSize=(dataWidth*zoom.Value);
- }
- else if (zoom.Type==1)
- {
- if (zoom.Value>0) fontSize=(dataWidth+distanceWidth)*zoom.Value;
- }
- else if (zoom.Type==2)
- {
- if (IFrameSplitOperator.IsNumber(zoom.Value))
- fontSize=(dataWidth+distanceWidth) + (2*zoom.Value);
- }
- }
- if (fontSize<minSize) fontSize=minSize;
- else if (fontSize>maxSize) fontSize=maxSize;
- var font=`${fontSize.toFixed(0)}px ${fontname}` ;
- return font;
- }
- this.SetFillStyle = function (color, x0, y0, x1, y1)
- {
- if (Array.isArray(color))
- {
- let gradient = this.Canvas.createLinearGradient(x0, y0, x1, y1);
- var offset = 1 / (color.length-1);
- for (var i=0;i<color.length;++i)
- {
- gradient.addColorStop(i * offset, color[i]);
- }
- this.Canvas.fillStyle = gradient;
- }
- else
- {
- this.Canvas.fillStyle = color;
- }
- }
- this.GetFontHeight=function(font)
- {
- return GetFontHeight(this.Canvas, font, "擎");
- }
- this.GetLockRect=function()
- {
- return this.ChartFrame.GetLockRect();
- }
- this.ClipClient=function(isHScreen) //裁剪客户端
- {
- if (isHScreen==true)
- {
- var left=this.ChartBorder.GetLeftEx();
- var right=this.ChartBorder.GetRightEx();
- var top=this.ChartBorder.GetTop();
- var bottom=this.ChartBorder.GetBottom();
- }
- else
- {
- var left=this.ChartBorder.GetLeft();
- var right=this.ChartBorder.GetRight();
- var top=this.ChartBorder.GetTopEx();
- var bottom=this.ChartBorder.GetBottomEx();
- }
- this.Canvas.beginPath();
- this.Canvas.rect(left,top,(right-left),(bottom-top));
- //this.Canvas.stroke(); //调试用
- this.Canvas.clip();
- }
- }
- //K线画法
- function ChartKLine()
- {
- this.newMethod = IChartPainting; //派生
- this.newMethod();
- delete this.newMethod;
- this.ClassName = 'ChartKLine';
- this.Symbol; //股票代码
- this.DrawType = 0; // 0=K线 1=收盘价线 2=美国线 3=空心K线柱子 4=收盘价面积 6=空心阴线阳线柱 9=自定义颜色K线
- this.CloseLineColor = g_JSChartResource.CloseLineColor;
- this.CloseLineAreaColor = g_JSChartResource.CloseLineAreaColor;
- this.UpColor = g_JSChartResource.UpBarColor;
- this.DownColor = g_JSChartResource.DownBarColor;
- this.UnchagneColor = g_JSChartResource.UnchagneBarColor; //平盘
- this.ColorData; //五彩K线颜色 >0 UpColor 其他 DownColor
- this.TradeData; //交易系统 包含买卖数据{Buy:, Sell:}
- this.IsShowMaxMinPrice = true; //是否显示最大最小值
- this.TextFont = g_JSChartResource.KLine.MaxMin.Font;
- this.TextColor = g_JSChartResource.KLine.MaxMin.Color;
- this.InfoPointColor = g_JSChartResource.KLine.Info.Color;
- this.InfoPointColor2 = g_JSChartResource.KLine.Info.Color2;
- this.InfoDrawType = 0; //0=在底部画远点 1=在最低价画三角
- this.PtMax; //最大值的位置
- this.PtMin; //最小值的位置
- this.MinBarWidth=g_JSChartResource.MinKLineBarWidth; //最小的柱子宽度
- this.MinColorBarWidth=g_JSChartResource.MinColorKBarWidth;
- this.CustomKLine; //自定义K线, key=date*1000000+time, key={ Color:, DrawType: }
- //当前屏显示K线信息
- this.ShowRange={ }; //K线显示范围 { Start:, End:, DataCount:, ShowCount: }
- this.DrawKRange={ Start:null, End:null }; //当前屏K线的索引{ Start: , End:}
- //未回补的价格缺口
- this.PriceGap={ Enable:false, Count:1 };
- this.PriceGapStyple=
- {
- Line:{ Color:g_JSChartResource.PriceGapStyple.Line.Color },
- Text:{ Color:g_JSChartResource.PriceGapStyple.Text.Color, Font: g_JSChartResource.PriceGapStyple.Text.Font }
- };
- this.AryPriceGapCache=[]; //缺口数据 { }
- this.OneLimitBarType=0; //一字板颜色类型 4个价格全部都在同一个价位上 0=使用平盘颜色 1=跟昨收比较
- this.EnableColorBar=false; //K线柱子是否支持自定义颜色
- this.DrawAKLine = function () //美国线
- {
- var isHScreen = (this.ChartFrame.IsHScreen === true);
- var dataWidth = this.ChartFrame.DataWidth;
- var distanceWidth = this.ChartFrame.DistanceWidth;
- var xOffset = this.ChartBorder.GetLeft() + distanceWidth / 2.0 + g_JSChartResource.FrameLeftMargin;
- if (isHScreen) xOffset = this.ChartBorder.GetTop() + distanceWidth / 2.0 + g_JSChartResource.FrameLeftMargin;
- var chartright = this.ChartBorder.GetRight();
- if (isHScreen) chartright = this.ChartBorder.GetBottom();
- var xPointCount = this.ChartFrame.XPointCount;
- this.ShowRange.Start=this.Data.DataOffset;
- this.ShowRange.End=this.ShowRange.Start;
- this.ShowRange.DataCount=0;
- this.ShowRange.ShowCount=xPointCount;
- this.DrawKRange.Start=this.Data.DataOffset;
- var eventUnchangeKLine=null; //定制平盘K线颜色事件
- if (this.GetEventCallback)
- {
- eventUnchangeKLine=this.GetEventCallback(JSCHART_EVENT_ID.ON_CUSTOM_UNCHANGE_KLINE_COLOR);
- }
- var upColor=this.UpColor;
- var downColor=this.DownColor;
- var unchagneColor=this.UnchagneColor;
- var ptMax = { X: null, Y: null, Value: null, Align: 'left' };
- var ptMin = { X: null, Y: null, Value: null, Align: 'left' };
- var preKItemInfo=null;
- for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j, xOffset += (dataWidth + distanceWidth),++this.ShowRange.DataCount)
- {
- var data = this.Data.Data[i];
- if (data.Open == null || data.High == null || data.Low == null || data.Close == null) continue;
- var left = xOffset;
- var right = xOffset + dataWidth;
- if (right > chartright) break;
- var x = left + (right - left) / 2;
- var yLow = this.ChartFrame.GetYFromData(data.Low);
- var yHigh = this.ChartFrame.GetYFromData(data.High);
- var yOpen = this.ChartFrame.GetYFromData(data.Open);
- var yClose = this.ChartFrame.GetYFromData(data.Close);
- this.DrawKRange.End=i;
- var kItemInfo={ Data:data, Coordinate:{ X:x, Low:yLow, High:yHigh, Close:yClose, Open:yOpen, Left:left, Right:right } };
- if (ptMax.Value == null || ptMax.Value < data.High) //求最大值
- {
- ptMax.X = x;
- ptMax.Y = yHigh;
- ptMax.Value = data.High;
- ptMax.Align = j < xPointCount / 2 ? 'left' : 'right';
- }
- if (ptMin.Value == null || ptMin.Value > data.Low) //求最小值
- {
- ptMin.X = x;
- ptMin.Y = yLow;
- ptMin.Value = data.Low;
- ptMin.Align = j < xPointCount / 2 ? 'left' : 'right';
- }
- if (data.Open < data.Close)
- {
- this.Canvas.strokeStyle =upColor; //阳线
- }
- else if (data.Open > data.Close)
- {
- this.Canvas.strokeStyle = downColor; //阴线
- }
- else
- {
- if (eventUnchangeKLine && eventUnchangeKLine.Callback)
- {
- var sendData={ KItem:data, DataIndex:i, DefaultColor:unchagneColor, BarColor:null };
- eventUnchangeKLine.Callback(eventUnchangeKLine, sendData, this);
- if (sendData.BarColor) unchagneColor=sendData.BarColor;
- }
- this.Canvas.strokeStyle =unchagneColor; //平线
- }
- this.Canvas.beginPath(); //最高-最低
- if (isHScreen)
- {
- if (data.High==data.Low && dataWidth < this.MinBarWidth)
- {
- this.Canvas.moveTo(yHigh, ToFixedPoint(x));
- this.Canvas.lineTo(yLow-1, ToFixedPoint(x));
- }
- else
- {
- this.Canvas.moveTo(yHigh, ToFixedPoint(x));
- this.Canvas.lineTo(yLow, ToFixedPoint(x));
- }
- }
- else
- {
- if (data.High==data.Low && dataWidth < this.MinBarWidth)
- {
- this.Canvas.moveTo(ToFixedPoint(x), yHigh);
- this.Canvas.lineTo(ToFixedPoint(x), yLow+1);
- }
- else
- {
- this.Canvas.moveTo(ToFixedPoint(x), yHigh);
- this.Canvas.lineTo(ToFixedPoint(x), yLow);
- }
- }
- this.Canvas.stroke();
- if (dataWidth >= this.MinBarWidth)
- {
- this.Canvas.beginPath(); //开盘
- if (isHScreen)
- {
- this.Canvas.moveTo(ToFixedPoint(yOpen), left);
- this.Canvas.lineTo(ToFixedPoint(yOpen), x);
- }
- else
- {
- this.Canvas.moveTo(left, ToFixedPoint(yOpen));
- this.Canvas.lineTo(x, ToFixedPoint(yOpen));
- }
- this.Canvas.stroke();
- this.Canvas.beginPath(); //收盘
- if (isHScreen)
- {
- this.Canvas.moveTo(ToFixedPoint(yClose), right);
- this.Canvas.lineTo(ToFixedPoint(yClose), x);
- }
- else
- {
- this.Canvas.moveTo(right, ToFixedPoint(yClose));
- this.Canvas.lineTo(x, ToFixedPoint(yClose));
- }
- this.Canvas.stroke();
- }
- if (this.Data.DataType == 0 && ChartData.IsDayPeriod(this.Data.Period,true)) //信息地雷
- {
- var infoItem = { X: x, Xleft: left, XRight: right, YMax: yHigh, YMin: yLow, DayData: data, Index: j };
- this.DrawInfoDiv(infoItem);
- }
- if (this.PriceGap.Enable && preKItemInfo)
- {
- this.CheckPriceGap(kItemInfo);
- var value=this.IsPriceGap(kItemInfo,preKItemInfo);
- if (value>0)
- this.AryPriceGapCache.push({ Data:[preKItemInfo, kItemInfo], Type:value });
- }
-
- preKItemInfo=kItemInfo;
- }
- this.PtMax = ptMax;
- this.PtMin = ptMin;
- }
- this.DrawCloseLine = function () //收盘价线
- {
- var isHScreen = (this.ChartFrame.IsHScreen === true);
- var dataWidth = this.ChartFrame.DataWidth;
- var distanceWidth = this.ChartFrame.DistanceWidth;
- var xOffset = this.ChartBorder.GetLeft() + distanceWidth / 2.0 + 2.0;
- if (isHScreen) xOffset = this.ChartBorder.GetTop() + distanceWidth / 2.0 + 2.0;
- var chartright = this.ChartBorder.GetRight();
- if (isHScreen) chartright = this.ChartBorder.GetBottom();
- var xPointCount = this.ChartFrame.XPointCount;
- this.ShowRange.Start=this.Data.DataOffset;
- this.ShowRange.End=this.ShowRange.Start;
- this.ShowRange.DataCount=0;
- this.ShowRange.ShowCount=xPointCount;
- this.DrawKRange.Start=this.Data.DataOffset;
- var bFirstPoint = true;
- this.Canvas.beginPath();
- this.Canvas.strokeStyle = this.CloseLineColor;
- var preKItemInfo=null;
- for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j, xOffset += (dataWidth + distanceWidth),++this.ShowRange.DataCount)
- {
- var data = this.Data.Data[i];
- if (data.Open == null || data.High == null || data.Low == null || data.Close == null) continue;
- var left = xOffset;
- var right = xOffset + dataWidth;
- if (right > chartright) break;
- var x = left + (right - left) / 2;
- var yClose = this.ChartFrame.GetYFromData(data.Close);
- this.DrawKRange.End=i;
- if (bFirstPoint) {
- if (isHScreen) this.Canvas.moveTo(yClose, x);
- else this.Canvas.moveTo(x, yClose);
- bFirstPoint = false;
- }
- else {
- if (isHScreen) this.Canvas.lineTo(yClose, x);
- else this.Canvas.lineTo(x, yClose);
- }
- if (this.PriceGap.Enable )
- {
- var yLow=this.GetYFromData(data.Low, false);
- var yHigh=this.GetYFromData(data.High, false);
- var yOpen=this.GetYFromData(data.Open, false);
- var kItemInfo={ Data:data, Coordinate:{ X:x, Low:yLow, High:yHigh, Close:yClose, Open:yOpen, Left:left, Right:right }};
- if (preKItemInfo)
- {
- this.CheckPriceGap(kItemInfo);
- var value=this.IsPriceGap(kItemInfo,preKItemInfo);
- if (value>0) this.AryPriceGapCache.push({ Data:[preKItemInfo, kItemInfo], Type:value });
- }
- preKItemInfo=kItemInfo;
- }
- }
- if (bFirstPoint == false) this.Canvas.stroke();
- }
- this.DrawCloseArea = function () //收盘价面积
- {
- var isHScreen = (this.ChartFrame.IsHScreen === true);
- var dataWidth = this.ChartFrame.DataWidth;
- var distanceWidth = this.ChartFrame.DistanceWidth;
- var xPointCount = this.ChartFrame.XPointCount;
- if (isHScreen)
- {
- var border=this.ChartBorder.GetHScreenBorder();
- var xOffset=border.TopEx+distanceWidth/2.0+g_JSChartResource.FrameLeftMargin;
- var chartright=border.BottomEx;
- var borderLeft=border.TopEx;
- }
- else
- {
- var border=this.ChartBorder.GetBorder();
- var xOffset=border.LeftEx+distanceWidth/2.0+g_JSChartResource.FrameLeftMargin;
- var chartright=border.RightEx;
- var borderLeft=border.LeftEx;
- }
- var bFirstPoint = true;
- var firstPoint = null;
- this.Canvas.beginPath();
- this.Canvas.strokeStyle = this.CloseLineColor;
- var ptLast=null;
- this.ShowRange.Start=this.Data.DataOffset;
- this.ShowRange.End=this.ShowRange.Start;
- this.ShowRange.DataCount=0;
- this.ShowRange.ShowCount=xPointCount;
- this.DrawKRange.Start=this.Data.DataOffset;
- if (this.Data.DataOffset>0) //把最左边的一个点连上
- {
- var data=this.Data.Data[this.Data.DataOffset-1];
- if (data && IFrameSplitOperator.IsNumber(data.Close))
- {
- var x=borderLeft;
- var yClose=this.GetYFromData(data.Close,false);
- if (isHScreen)
- {
- this.Canvas.moveTo(yClose,x);
- firstPoint={ X:yClose, Y:x };
- }
- else
- {
- this.Canvas.moveTo(x,yClose);
- firstPoint={ X:x, Y:yClose };
- }
- bFirstPoint=false;
- }
- }
- var preKItemInfo=null;
- for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j, xOffset += (dataWidth + distanceWidth),++this.ShowRange.DataCount)
- {
- var data = this.Data.Data[i];
- if (data.Open == null || data.High == null || data.Low == null || data.Close == null) continue;
- var left = xOffset;
- var right = xOffset + dataWidth;
- if (right > chartright) break;
- var x = left + (right - left) / 2;
- var yClose = this.ChartFrame.GetYFromData(data.Close);
- this.DrawKRange.End=i;
- if (bFirstPoint)
- {
- if (isHScreen)
- {
- this.Canvas.moveTo(yClose, x);
- firstPoint = { X: yClose, Y: x };
- }
- else
- {
- this.Canvas.moveTo(x, yClose);
- firstPoint = { X: x, Y: yClose };
- }
- bFirstPoint = false;
- }
- else
- {
- if (isHScreen) this.Canvas.lineTo(yClose, x);
- else this.Canvas.lineTo(x, yClose);
- }
- if (i==this.Data.Data.length-1)
- {
- ptLast={ X:x, Y:yClose, XLeft:left, XRight:right, KItem:data, ChartRight:chartright };
- }
- if (this.PriceGap.Enable )
- {
- var yLow=this.GetYFromData(data.Low, false);
- var yHigh=this.GetYFromData(data.High, false);
- var yOpen=this.GetYFromData(data.Open, false);
- var kItemInfo={ Data:data, Coordinate:{ X:x, Low:yLow, High:yHigh, Close:yClose, Open:yOpen, Left:left, Right:right }};
- if (preKItemInfo)
- {
- this.CheckPriceGap(kItemInfo);
- var value=this.IsPriceGap(kItemInfo,preKItemInfo);
- if (value>0) this.AryPriceGapCache.push({ Data:[preKItemInfo, kItemInfo], Type:value });
- }
- preKItemInfo=kItemInfo;
- }
- }
- this.DrawLastPointEvent(ptLast); //通知外部绘制最后一个点
- if (bFirstPoint) return;
- this.Canvas.stroke();
- //画面积
- if (isHScreen)
- {
- this.Canvas.lineTo(this.ChartBorder.GetLeft(), x);
- this.Canvas.lineTo(this.ChartBorder.GetLeft(), firstPoint.Y);
- }
- else
- {
- this.Canvas.lineTo(x, this.ChartBorder.GetBottom());
- this.Canvas.lineTo(firstPoint.X, this.ChartBorder.GetBottom());
- }
- this.Canvas.closePath();
- if (Array.isArray(this.CloseLineAreaColor))
- {
- if (isHScreen)
- {
- let gradient = this.Canvas.createLinearGradient(this.ChartBorder.GetRightEx(), this.ChartBorder.GetTop(), this.ChartBorder.GetLeft(), this.ChartBorder.GetTop());
- gradient.addColorStop(0, this.CloseLineAreaColor[0]);
- gradient.addColorStop(1, this.CloseLineAreaColor[1]);
- this.Canvas.fillStyle = gradient;
- }
- else
- {
- let gradient = this.Canvas.createLinearGradient(firstPoint.X, this.ChartBorder.GetTopEx(), firstPoint.X, this.ChartBorder.GetBottom());
- gradient.addColorStop(0, this.CloseLineAreaColor[0]);
- gradient.addColorStop(1, this.CloseLineAreaColor[1]);
- this.Canvas.fillStyle = gradient;
- }
- }
- else
- {
- this.Canvas.fillStyle = this.CloseLineAreaColor;
- }
- this.Canvas.fill();
- }
- this.DrawKBar = function ()
- {
- var isHScreen = (this.ChartFrame.IsHScreen === true);
- var dataWidth = this.ChartFrame.DataWidth;
- var distanceWidth = this.ChartFrame.DistanceWidth;
- var xOffset = this.ChartBorder.GetLeft() + distanceWidth / 2.0 + 2.0;
- var chartright = this.ChartBorder.GetRight();
- var xPointCount = this.ChartFrame.XPointCount;
- var border=this.ChartBorder.GetBorder();
-
- if (isHScreen)
- {
- xOffset = this.ChartBorder.GetTop() + distanceWidth / 2.0 + 2.0;
- chartright = this.ChartBorder.GetBottom();
- }
- var ptMax = { X: null, Y: null, Value: null, Align: 'left' };
- var ptMin = { X: null, Y: null, Value: null, Align: 'left' };
- var upColor = this.UpColor;
- var downColor = this.DownColor;
- var unchagneColor = this.UnchagneColor;
- var ptLast=null;
- this.ShowRange.Start=this.Data.DataOffset;
- this.ShowRange.End=this.ShowRange.Start;
- this.ShowRange.DataCount=0;
- this.ShowRange.ShowCount=xPointCount;
- this.DrawKRange.Start=this.Data.DataOffset;
- var eventUnchangeKLine=null; //定制平盘K线颜色事件
- if (this.GetEventCallback)
- {
- eventUnchangeKLine=this.GetEventCallback(JSCHART_EVENT_ID.ON_CUSTOM_UNCHANGE_KLINE_COLOR);
- }
- var preKItemInfo=null;
- for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j, xOffset += (dataWidth + distanceWidth), ++this.ShowRange.DataCount)
- {
- var data = this.Data.Data[i];
- if (data.Open == null || data.High == null || data.Low == null || data.Close == null) continue;
- var left = xOffset;
- var right = xOffset + dataWidth;
- if (right > chartright) break;
- this.DrawKRange.End=i;
- var x = left + (right - left) / 2;
- var yLow = this.ChartFrame.GetYFromData(data.Low);
- var yHigh = this.ChartFrame.GetYFromData(data.High);
- var yOpen = this.ChartFrame.GetYFromData(data.Open);
- var yClose = this.ChartFrame.GetYFromData(data.Close);
- var y = yHigh;
- var kItemInfo={ Data:data, Coordinate:{ X:x, Low:yLow, High:yHigh, Close:yClose, Open:yOpen, Left:left, Right:right }};
- if (ptMax.Value == null || ptMax.Value < data.High) //求最大值
- {
- ptMax.X = x;
- ptMax.Y = yHigh;
- ptMax.Value = data.High;
- ptMax.Align = j < xPointCount / 2 ? 'left' : 'right';
- }
- if (ptMin.Value == null || ptMin.Value > data.Low) //求最小值
- {
- ptMin.X = x;
- ptMin.Y = yLow;
- ptMin.Value = data.Low;
- ptMin.Align = j < xPointCount / 2 ? 'left' : 'right';
- }
- if (this.ColorData) ///五彩K线颜色设置
- {
- if (i < this.ColorData.length)
- upColor = downColor = unchagneColor = (this.ColorData[i] > 0 ? this.UpColor : this.DownColor);
- else
- upColor = downColor = unchagneColor = this.DownColor;
- }
- var kLineOption=this.GetCustomKLine(data);
- if (kLineOption)
- {
- var barColor=kLineOption.Color;
- if (!barColor)
- {
- if (data.Open<data.Close) barColor=upColor;
- else if (data.Open>data.Close) barColor=downColor;
- else barColor=unchagneColor;
- }
- var drawType=this.DrawType;
- if (IFrameSplitOperator.IsNumber(kLineOption.DrawType)) drawType=kLineOption.DrawType;
- this.DrawKBar_Custom(data, dataWidth, barColor, drawType, kLineOption, x, y, left, right, yLow, yHigh, yOpen, yClose, border, isHScreen);
- }
- else if ((this.DrawType==9 || this.EnableColorBar) && data.ColorData)
- {
- this.DrawColorKBar(data, data.ColorData, dataWidth, x, y, left, right, yLow, yHigh, yOpen, yClose, isHScreen);
- }
- else if (data.Open < data.Close) //阳线
- {
- this.DrawKBar_Up(data, dataWidth, upColor, this.DrawType, x, y, left, right, yLow, yHigh, yOpen, yClose, isHScreen);
- }
- else if (data.Open > data.Close) //阴线
- {
- this.DrawKBar_Down(data, dataWidth, downColor, this.DrawType, x, y, left, right, yLow, yHigh, yOpen, yClose, isHScreen);
- }
- else // 平线
- {
- var barColor=unchagneColor;
- if (eventUnchangeKLine && eventUnchangeKLine.Callback)
- {
- var sendData={ KItem:data, DataIndex:i, DefaultColor:barColor, BarColor:null };
- eventUnchangeKLine.Callback(eventUnchangeKLine, sendData, this);
- if (sendData.BarColor) barColor=sendData.BarColor;
- }
- this.DrawKBar_Unchagne(data, dataWidth, barColor, this.DrawType, x, y, left, right, yLow, yHigh, yOpen, yClose, isHScreen);
- }
- if (this.Data.DataType == 0 && ChartData.IsDayPeriod(this.Data.Period,true)) //信息地雷
- {
- var infoItem = { X: x, Xleft: left, XRight: right, YMax: yHigh, YMin: yLow, DayData: data, Index: j };
- this.DrawInfoDiv(infoItem);
- }
- if (i==this.Data.Data.length-1)
- {
- ptLast={ X:x, Y:yClose, XLeft:left, XRight:right, KItem:data, ChartRight:chartright };
- }
- if (this.PriceGap.Enable && preKItemInfo)
- {
- this.CheckPriceGap(kItemInfo);
- var value=this.IsPriceGap(kItemInfo,preKItemInfo);
- if (value>0) this.AryPriceGapCache.push({ Data:[preKItemInfo, kItemInfo], Type:value });
- }
-
- preKItemInfo=kItemInfo;
- }
- this.DrawLastPointEvent(ptLast); //通知外部绘制最后一个点
- this.PtMax = ptMax;
- this.PtMin = ptMin;
- }
- this.DrawKBar_Up = function(data, dataWidth, upColor, drawType, x, y, left, right, yLow, yHigh, yOpen, yClose, isHScreen) //阳线
- {
- var isEmptyBar=(drawType==3 || drawType==6);
- if (dataWidth >= this.MinBarWidth)
- {
- if (isEmptyBar)
- {
- if ((dataWidth%2)!=0) dataWidth-=1;
- }
- this.Canvas.strokeStyle = upColor;
- if (data.High > data.Close) //上影线
- {
- this.Canvas.beginPath();
- if (isHScreen)
- {
- this.Canvas.moveTo(ToFixedPoint(y), ToFixedPoint(x));
- this.Canvas.lineTo(ToFixedPoint(this.DrawType == 3 ? Math.max(yClose, yOpen) : yClose), ToFixedPoint(x));
- }
- else
- {
- if (isEmptyBar)
- {
- var xFixed=left+dataWidth/2;
- this.Canvas.moveTo(ToFixedPoint(xFixed),ToFixedPoint(y));
- this.Canvas.lineTo(ToFixedPoint(xFixed),ToFixedPoint(Math.min(yClose,yOpen)));
- }
- else
- {
- this.Canvas.moveTo(ToFixedPoint(x), ToFixedPoint(y));
- this.Canvas.lineTo(ToFixedPoint(x), ToFixedPoint(yClose));
- }
- }
- this.Canvas.stroke();
- y = yClose;
- }
- else
- {
- y = yClose;
- }
- this.Canvas.fillStyle = upColor;
- if (isHScreen)
- {
- if (Math.abs(yOpen - y) < 1)
- {
- this.Canvas.fillRect(ToFixedRect(y), ToFixedRect(left), 1, ToFixedRect(dataWidth)); //高度小于1,统一使用高度1
- }
- else
- {
- if (isEmptyBar) //空心柱
- {
- this.Canvas.beginPath();
- this.Canvas.rect(ToFixedPoint(y), ToFixedPoint(left), ToFixedRect(yOpen - y), ToFixedRect(dataWidth));
- this.Canvas.stroke();
- }
- else
- {
- //宽度是负数竟然不会画, h5就可以
- //this.Canvas.fillRect(ToFixedRect(y), ToFixedRect(left), ToFixedRect(yOpen - y), ToFixedRect(dataWidth));
- this.Canvas.fillRect(ToFixedRect(Math.min(yOpen, y)), ToFixedRect(left), ToFixedRect(Math.abs(yOpen - y)), ToFixedRect(dataWidth));
- }
- }
- }
- else
- {
- if (Math.abs(yOpen - y) < 1)
- {
- this.Canvas.fillRect(ToFixedRect(left), ToFixedRect(y), ToFixedRect(dataWidth), 1); //高度小于1,统一使用高度1
- }
- else
- {
- if (isEmptyBar) //空心柱
- {
- this.Canvas.beginPath();
- this.Canvas.rect(ToFixedPoint(left), ToFixedPoint(y), ToFixedRect(dataWidth), ToFixedRect(yOpen - y));
- this.Canvas.stroke();
- }
- else
- {
- this.Canvas.fillRect(ToFixedRect(left), ToFixedRect(y), ToFixedRect(dataWidth), ToFixedRect(yOpen - y));
- }
- }
- }
- if (data.Open > data.Low) //下影线
- {
- this.Canvas.beginPath();
- if (isHScreen)
- {
- this.Canvas.moveTo(ToFixedPoint(this.DrawType == 3 ? Math.min(yClose, yOpen) : y), ToFixedPoint(x));
- this.Canvas.lineTo(ToFixedPoint(yLow), ToFixedPoint(x));
- }
- else
- {
- if (isEmptyBar)
- {
- var xFixed=left+dataWidth/2;
- this.Canvas.moveTo(ToFixedPoint(xFixed),ToFixedPoint(Math.max(yClose,yOpen)));
- this.Canvas.lineTo(ToFixedPoint(xFixed),ToFixedPoint(yLow));
- }
- else
- {
- this.Canvas.moveTo(ToFixedPoint(x), ToFixedPoint(y));
- this.Canvas.lineTo(ToFixedPoint(x), ToFixedPoint(yLow));
- }
- }
- this.Canvas.stroke();
- }
- }
- else
- {
- this.Canvas.beginPath();
- if (isHScreen)
- {
- this.Canvas.moveTo(yHigh, ToFixedPoint(x));
- this.Canvas.lineTo(yLow, ToFixedPoint(x));
- }
- else
- {
- this.Canvas.moveTo(ToFixedPoint(x), yHigh);
- this.Canvas.lineTo(ToFixedPoint(x), yLow);
- }
- this.Canvas.strokeStyle = upColor;
- this.Canvas.stroke();
- }
- }
- this.DrawKBar_Down=function(data, dataWidth, downColor, drawType, x, y, left, right, yLow, yHigh, yOpen, yClose, isHScreen) //阴线
- {
- var isEmptyBar=(drawType==6);
- if (dataWidth >= this.MinBarWidth)
- {
- if (isEmptyBar)
- {
- if ((dataWidth%2)!=0) dataWidth-=1;
- }
- this.Canvas.strokeStyle = downColor;
- if (data.High > data.Close) //上影线
- {
- this.Canvas.beginPath();
- if (isHScreen)
- {
- this.Canvas.moveTo(ToFixedPoint(y), ToFixedPoint(x));
- this.Canvas.lineTo(ToFixedPoint(yOpen), ToFixedPoint(x));
- }
- else
- {
- if (isEmptyBar)
- {
- var xFixed=left+dataWidth/2;
- this.Canvas.moveTo(ToFixedPoint(xFixed),ToFixedPoint(y));
- this.Canvas.lineTo(ToFixedPoint(xFixed),ToFixedPoint(Math.min(yClose,yOpen)));
- }
- else
- {
- this.Canvas.moveTo(ToFixedPoint(x), ToFixedPoint(y));
- this.Canvas.lineTo(ToFixedPoint(x), ToFixedPoint(yOpen));
- }
-
- }
- this.Canvas.stroke();
- y = yOpen;
- }
- else
- {
- y = yOpen
- }
- this.Canvas.fillStyle = downColor;
- if (isHScreen)
- {
- if (Math.abs(yClose - y) < 1)
- {
- this.Canvas.fillRect(ToFixedRect(y), ToFixedRect(left), 1, ToFixedRect(dataWidth)); //高度小于1,统一使用高度1
- }
- else
- {
- //宽度是负数竟然不会画, h5就可以
- this.Canvas.fillRect(ToFixedRect(Math.min(yClose, y)), ToFixedRect(left), ToFixedRect(Math.abs(yClose - y)), ToFixedRect(dataWidth));
- }
- }
- else
- {
- if (Math.abs(yClose - y) < 1)
- {
- this.Canvas.fillRect(ToFixedRect(left), ToFixedRect(y), ToFixedRect(dataWidth), 1); //高度小于1,统一使用高度1
- }
- else
- {
- if (isEmptyBar) //空心柱
- {
- this.Canvas.beginPath();
- this.Canvas.rect(ToFixedPoint(left), ToFixedPoint(y), ToFixedRect(dataWidth), ToFixedRect(yClose - y));
- this.Canvas.stroke();
- }
- else
- {
- this.Canvas.fillRect(ToFixedRect(left), ToFixedRect(y), ToFixedRect(dataWidth), ToFixedRect(yClose - y));
- }
- }
- }
- if (data.Open > data.Low) //下影线
- {
- this.Canvas.beginPath();
- if (isHScreen)
- {
- this.Canvas.moveTo(ToFixedPoint(y), ToFixedPoint(x));
- this.Canvas.lineTo(ToFixedPoint(yLow), ToFixedPoint(x));
- }
- else
- {
- if (isEmptyBar)
- {
- var xFixed=left+dataWidth/2;
- this.Canvas.moveTo(ToFixedPoint(xFixed),ToFixedPoint(Math.max(yClose,yOpen)));
- this.Canvas.lineTo(ToFixedPoint(xFixed),ToFixedPoint(yLow));
- }
- else
- {
- this.Canvas.moveTo(ToFixedPoint(x), ToFixedPoint(y));
- this.Canvas.lineTo(ToFixedPoint(x), ToFixedPoint(yLow));
- }
- }
- this.Canvas.stroke();
- }
- }
- else
- {
- this.Canvas.beginPath();
- if (isHScreen)
- {
- this.Canvas.moveTo(yHigh, ToFixedPoint(x));
- this.Canvas.lineTo(yLow, ToFixedPoint(x));
- }
- else
- {
- this.Canvas.moveTo(ToFixedPoint(x), yHigh);
- this.Canvas.lineTo(ToFixedPoint(x), yLow);
- }
- this.Canvas.strokeStyle = downColor;
- this.Canvas.stroke();
- }
- }
- this.DrawKBar_Unchagne=function(data, dataWidth, unchagneColor, drawType, x, y, left, right, yLow, yHigh, yOpen, yClose, isHScreen) //平线
- {
- if (this.OneLimitBarType===1 && this.IsOneLimitBar(data)) //一字板
- {
- unchagneColor=this.GetOneLimitBarColor(data);
- }
- if (dataWidth >= this.MinBarWidth)
- {
- if ((dataWidth%2)!=0) dataWidth-=1;
- this.Canvas.strokeStyle = unchagneColor;
- this.Canvas.beginPath();
- if (data.High > data.Close) //上影线
- {
- if (isHScreen)
- {
- this.Canvas.moveTo(y, ToFixedPoint(x));
- this.Canvas.lineTo(yOpen, ToFixedPoint(x));
- }
- else
- {
- var xFixed=left+dataWidth/2;
- this.Canvas.moveTo(ToFixedPoint(xFixed), y);
- this.Canvas.lineTo(ToFixedPoint(xFixed), yOpen);
- }
- y = yOpen;
- }
- else
- {
- y = yOpen;
- }
- if (isHScreen)
- {
- this.Canvas.moveTo(ToFixedPoint(y), ToFixedPoint(left));
- this.Canvas.lineTo(ToFixedPoint(y), ToFixedPoint(right));
- }
- else
- {
- this.Canvas.moveTo(ToFixedPoint(left), ToFixedPoint(y));
- this.Canvas.lineTo(ToFixedPoint(left+dataWidth), ToFixedPoint(y));
- }
- if (data.Open > data.Low) //下影线
- {
- if (isHScreen)
- {
- this.Canvas.moveTo(ToFixedPoint(y), ToFixedPoint(x));
- this.Canvas.lineTo(ToFixedPoint(yLow), ToFixedPoint(x));
- }
- else
- {
- var xFixed=left+dataWidth/2;
- this.Canvas.moveTo(ToFixedPoint(xFixed), ToFixedPoint(y));
- this.Canvas.lineTo(ToFixedPoint(xFixed), ToFixedPoint(yLow));
- }
- }
- this.Canvas.stroke();
- }
- else
- {
- this.Canvas.beginPath();
- if (isHScreen)
- {
- if (data.High==data.Low)
- {
- this.Canvas.moveTo(yHigh,ToFixedPoint(x));
- this.Canvas.lineTo(yLow-1,ToFixedPoint(x));
- }
- else
- {
- this.Canvas.moveTo(yHigh, ToFixedPoint(x));
- this.Canvas.lineTo(yLow, ToFixedPoint(x));
- }
- }
- else
- {
- if (data.High==data.Low)
- {
- this.Canvas.moveTo(ToFixedPoint(x),yHigh);
- this.Canvas.lineTo(ToFixedPoint(x),yLow+1);
- }
- else
- {
- this.Canvas.moveTo(ToFixedPoint(x), yHigh);
- this.Canvas.lineTo(ToFixedPoint(x), yLow);
- }
-
- }
- this.Canvas.strokeStyle = unchagneColor;
- this.Canvas.stroke();
- }
- }
- //是否是一字板
- this.IsOneLimitBar=function(kItem)
- {
- if (kItem.Open==kItem.Close && kItem.High==kItem.Low && kItem.Open==kItem.High) return true;
- return false;
- }
-
- //一字板颜色 和昨收比较
- this.GetOneLimitBarColor=function(kItem)
- {
- if (!kItem || !IFrameSplitOperator.IsNumber(kItem.YClose)) return this.UnchagneColor;
- if (kItem.Close>kItem.YClose) return this.UpColor;
- else if (kItem.Close<kItem.YClose) return this.DownColor;
- else return this.UnchagneColor;
- }
- this.DrawKBar_Custom=function(data, dataWidth, barColor, drawType, option, x, y, left, right, yLow, yHigh, yOpen, yClose, border, isHScreen)
- {
- if (option.BGColor) //画背景色
- {
- this.Canvas.fillStyle=option.BGColor;
- var distanceWidth=this.ChartFrame.DistanceWidth;
- if (isHScreen)
- {
- var yLeft=left-(distanceWidth/2);
- var yRight=right+(distanceWidth/2);
- var xTop=border.RightEx;
- var xBottom=border.LeftEx;
- this.Canvas.fillRect(ToFixedRect(xBottom),ToFixedRect(yLeft),ToFixedRect(xTop-xBottom),ToFixedRect(yRight-yLeft));
- }
- else
- {
- var xLeft=left-(distanceWidth/2);
- var xRight=right+(distanceWidth/2);
- var yTop=border.TopEx;
- var yBottom=border.BottomEx;
-
- this.Canvas.fillRect(ToFixedRect(xLeft),ToFixedRect(yTop),ToFixedRect(xRight-xLeft),ToFixedRect(yBottom-yTop));
- }
- }
- if (dataWidth>=4)
- {
- this.Canvas.strokeStyle=barColor;
- if (data.High>data.Close) //上影线
- {
- this.Canvas.beginPath();
- if (isHScreen)
- {
- this.Canvas.moveTo(ToFixedPoint(y),ToFixedPoint(x));
- this.Canvas.lineTo(ToFixedPoint(drawType==3?Math.max(yClose,yOpen):yClose),ToFixedPoint(x));
- }
- else
- {
- this.Canvas.moveTo(ToFixedPoint(x),ToFixedPoint(y));
- this.Canvas.lineTo(ToFixedPoint(x),ToFixedPoint(drawType==3?Math.min(yClose,yOpen):yClose));
- }
- this.Canvas.stroke();
- y=yClose;
- }
- else
- {
- y=yClose;
- }
- this.Canvas.fillStyle=barColor;
- if (isHScreen)
- {
- if (Math.abs(yOpen-y)<1)
- {
- this.Canvas.fillRect(ToFixedRect(y),ToFixedRect(left),1,ToFixedRect(dataWidth)); //高度小于1,统一使用高度1
- }
- else
- {
- if (drawType==3) //空心柱
- {
- this.Canvas.beginPath();
- this.Canvas.rect(ToFixedPoint(y),ToFixedPoint(left),ToFixedRect(yOpen-y),ToFixedRect(dataWidth));
- this.Canvas.stroke();
- }
- else
- {
- this.Canvas.fillRect(ToFixedRect(y),ToFixedRect(left),ToFixedRect(yOpen-y),ToFixedRect(dataWidth));
- }
- }
- }
- else
- {
- if (Math.abs(yOpen-y)<1)
- {
- this.Canvas.fillRect(ToFixedRect(left),ToFixedRect(y),ToFixedRect(dataWidth),1); //高度小于1,统一使用高度1
- }
- else
- {
- if (drawType==3) //空心柱
- {
- this.Canvas.beginPath();
- this.Canvas.rect(ToFixedPoint(left),ToFixedPoint(y),ToFixedRect(dataWidth),ToFixedRect(yOpen-y));
- this.Canvas.stroke();
- }
- else
- {
- this.Canvas.fillRect(ToFixedRect(left),ToFixedRect(Math.min(y,yOpen)),ToFixedRect(dataWidth),ToFixedRect(Math.abs(yOpen-y)));
- }
- }
- }
- if (data.Open>data.Low) //下影线
- {
- this.Canvas.beginPath();
- if (isHScreen)
- {
- this.Canvas.moveTo(ToFixedPoint(drawType==3?Math.min(yClose,yOpen):y),ToFixedPoint(x));
- this.Canvas.lineTo(ToFixedPoint(yLow),ToFixedPoint(x));
- }
- else
- {
- this.Canvas.moveTo(ToFixedPoint(x),ToFixedPoint(drawType==3?Math.max(yClose,yOpen):y));
- this.Canvas.lineTo(ToFixedPoint(x),ToFixedPoint(yLow));
- }
- this.Canvas.stroke();
- }
- }
- else
- {
- this.Canvas.beginPath();
- if (isHScreen)
- {
- this.Canvas.moveTo(yHigh,ToFixedPoint(x));
- this.Canvas.lineTo(yLow,ToFixedPoint(x));
- }
- else
- {
- this.Canvas.moveTo(ToFixedPoint(x),yHigh);
- this.Canvas.lineTo(ToFixedPoint(x),yLow);
- }
- this.Canvas.strokeStyle=barColor;
- this.Canvas.stroke();
- }
- }
- //绘制自定义K线
- this.DrawColorKBar=function(data, colorData, dataWidth, x, y, left, right, yLow, yHigh, yOpen, yClose, isHScreen)
- {
- if (Math.abs(yClose-yOpen)<1)
- this.DrawColorKBar_Line(data, colorData, dataWidth, x, y, left, right, yLow, yHigh, yOpen, yClose, isHScreen);
- else if (colorData.Border || colorData.Type===0)
- this.DrawColorKBar_Border(data, colorData, dataWidth, x, y, left, right, yLow, yHigh, yOpen, yClose, isHScreen);
- else
- this.DrawColorKBar_NoBorder(data, colorData, dataWidth, x, y, left, right, yLow, yHigh, yOpen, yClose, isHScreen);
- }
- //带边框柱子
- this.DrawColorKBar_Border=function(data, colorData, dataWidth, x, y, left, right, yLow, yHigh, yOpen, yClose, isHScreen)
- {
- if (dataWidth>=this.MinColorBarWidth)
- {
- if ((dataWidth%2)!=0) dataWidth-=1;
- var topPrice=Math.max(data.Close,data.Open);
- var bottomPrice=Math.min(data.Close,data.Open);
- if (isHScreen)
- {
- var yBarTop=Math.max(yClose,yOpen);
- var yBarBottom=Math.min(yClose,yOpen);
- }
- else
- {
- var yBarTop=Math.min(yClose,yOpen);
- var yBarBottom=Math.max(yClose,yOpen);
- }
- var yBarHeight=Math.abs(yClose-yOpen);
- //上影线
- if (data.High>topPrice && colorData.Line)
- {
- this.Canvas.strokeStyle=colorData.Line.Color;
- this.Canvas.beginPath();
- if (isHScreen)
- {
- this.Canvas.moveTo(ToFixedPoint(yHigh),ToFixedPoint(x));
- this.Canvas.lineTo(ToFixedPoint(yBarTop),ToFixedPoint(x));
- }
- else
- {
- var xFixed=left+dataWidth/2;
- this.Canvas.moveTo(ToFixedPoint(xFixed),ToFixedPoint(yHigh));
- this.Canvas.lineTo(ToFixedPoint(xFixed),ToFixedPoint(yBarTop));
- }
- this.Canvas.stroke();
- }
- //下影线
- if (bottomPrice>data.Low && colorData.Line)
- {
- this.Canvas.strokeStyle=colorData.Line.Color;
- this.Canvas.beginPath();
- if (isHScreen)
- {
- this.Canvas.moveTo(ToFixedPoint(yBarBottom),ToFixedPoint(x));
- this.Canvas.lineTo(ToFixedPoint(yLow),ToFixedPoint(x));
- }
- else
- {
- var xFixed=left+dataWidth/2;
- this.Canvas.moveTo(ToFixedPoint(xFixed),ToFixedPoint(yBarBottom));
- this.Canvas.lineTo(ToFixedPoint(xFixed),ToFixedPoint(yLow));
- }
- this.Canvas.stroke();
- }
- //中心柱子
- this.Canvas.beginPath();
- if (isHScreen)
- {
- this.Canvas.rect(ToFixedPoint(yBarBottom),ToFixedPoint(left),ToFixedRect(yBarHeight),ToFixedRect(dataWidth));
- }
- else
- {
- this.Canvas.rect(ToFixedPoint(left),ToFixedPoint(yBarTop),ToFixedRect(dataWidth),ToFixedRect(yBarHeight));
- }
- this.Canvas.closePath();
- if (colorData.Type==0) //空心柱子
- {
- if (colorData.BarColor) //边框
- {
- this.Canvas.strokeStyle=colorData.BarColor;
- this.Canvas.stroke();
- }
- if (colorData.Border)
- {
- this.Canvas.strokeStyle=colorData.Border.Color;
- this.Canvas.stroke();
- }
- }
- else if (colorData.Type==1) //实心
- {
- if (colorData.BarColor) //内部填充
- {
- this.Canvas.fillStyle=colorData.BarColor;
- this.Canvas.fill();
- }
- if (colorData.Border) //边框
- {
- this.Canvas.strokeStyle=colorData.Border.Color;
- this.Canvas.stroke();
- }
- }
-
- }
- else
- {
- this.DrawColorKBar_MinBar(data, colorData, dataWidth, x, y, left, right, yLow, yHigh, yOpen, yClose, isHScreen);
- }
- }
- //不带边框柱子
- this.DrawColorKBar_NoBorder=function(data, colorData, dataWidth, x, y, left, right, yLow, yHigh, yOpen, yClose, isHScreen)
- {
- if (dataWidth>=this.MinColorBarWidth)
- {
- var topPrice=Math.max(data.Close,data.Open);
- var bottomPrice=Math.min(data.Close,data.Open);
- if (isHScreen)
- {
- var yBarTop=Math.max(yClose,yOpen);
- var yBarBottom=Math.min(yClose,yOpen);
- }
- else
- {
- var yBarTop=Math.min(yClose,yOpen);
- var yBarBottom=Math.max(yClose,yOpen);
- }
- var yBarHeight=Math.abs(yClose-yOpen);
- //上影线
- if (data.High>topPrice && colorData.Line)
- {
- this.Canvas.strokeStyle=colorData.Line.Color;
- this.Canvas.beginPath();
- if (isHScreen)
- {
- this.Canvas.moveTo(ToFixedPoint(yHigh),ToFixedPoint(x));
- this.Canvas.lineTo(ToFixedPoint(yBarTop),ToFixedPoint(x));
- }
- else
- {
- var xFixed=left+dataWidth/2;
- this.Canvas.moveTo(ToFixedPoint(xFixed),ToFixedPoint(yHigh));
- this.Canvas.lineTo(ToFixedPoint(xFixed),ToFixedPoint(yBarTop));
- }
- this.Canvas.stroke();
- }
- //下影线
- if (bottomPrice>data.Low && colorData.Line)
- {
- this.Canvas.strokeStyle=colorData.Line.Color;
- this.Canvas.beginPath();
- if (isHScreen)
- {
- this.Canvas.moveTo(ToFixedPoint(yBarBottom),ToFixedPoint(x));
- this.Canvas.lineTo(ToFixedPoint(yLow),ToFixedPoint(x));
- }
- else
- {
- var xFixed=left+dataWidth/2;
- this.Canvas.moveTo(ToFixedPoint(xFixed),ToFixedPoint(yBarBottom));
- this.Canvas.lineTo(ToFixedPoint(xFixed),ToFixedPoint(yLow));
- }
- this.Canvas.stroke();
- }
- //中心柱子
- this.Canvas.beginPath();
- if (isHScreen)
- {
- this.Canvas.rect(ToFixedPoint(yBarBottom),ToFixedPoint(left),ToFixedRect(yBarHeight),ToFixedRect(dataWidth));
- }
- else
- {
- this.Canvas.rect(ToFixedRect(left),ToFixedRect(yBarTop),ToFixedRect(dataWidth),ToFixedRect(yBarHeight));
- }
- this.Canvas.closePath();
- if (colorData.Type==1) //实心
- {
- if (colorData.BarColor) //内部填充
- {
- this.Canvas.fillStyle=colorData.BarColor;
- this.Canvas.fill();
- }
- }
- }
- else
- {
- this.DrawColorKBar_MinBar(data, colorData, dataWidth, x, y, left, right, yLow, yHigh, yOpen, yClose, isHScreen);
- }
- }
- this.DrawColorKBar_MinBar=function(data, colorData, dataWidth, x, y, left, right, yLow, yHigh, yOpen, yClose, isHScreen)
- {
- if (colorData.Line)
- {
- this.Canvas.strokeStyle=colorData.Line.Color;
- this.Canvas.beginPath();
- if (isHScreen)
- {
- this.Canvas.moveTo(ToFixedPoint(yHigh),ToFixedPoint(x));
- this.Canvas.lineTo(ToFixedPoint(yLow),ToFixedPoint(x));
- }
- else
- {
- this.Canvas.moveTo(ToFixedPoint(x),ToFixedPoint(yHigh));
- this.Canvas.lineTo(ToFixedPoint(x),ToFixedPoint(yLow));
- }
- this.Canvas.stroke();
- }
- /*
- var barColor;
- if (colorData.Type==0) //空心柱子
- {
- if (colorData.Border) barColor=colorData.Border.Color;
- else if (colorData.BarColor) barColor=colorData.BarColor;
- }
- else if (colorData.Type==1) //实心
- {
- if (colorData.Border) barColor=colorData.Border.Color;
- else if (colorData.BarColor) barColor=colorData.BarColor;
- }
- if (barColor)
- {
- this.Canvas.strokeStyle=barColor;
- this.Canvas.beginPath();
- if (isHScreen)
- {
- this.Canvas.moveTo(ToFixedPoint(yOpen),ToFixedPoint(x));
- this.Canvas.lineTo(ToFixedPoint(yClose),ToFixedPoint(x));
- }
- else
- {
- this.Canvas.moveTo(ToFixedPoint(x),ToFixedPoint(yOpen));
- this.Canvas.lineTo(ToFixedPoint(x),ToFixedPoint(yClose));
- }
- this.Canvas.stroke();
- }
- */
- }
- //十字线
- this.DrawColorKBar_Line=function(data, colorData, dataWidth, x, y, left, right, yLow, yHigh, yOpen, yClose, isHScreen)
- {
- if (dataWidth>=this.MinColorBarWidth)
- {
-
- if (colorData.Line)
- {
- this.Canvas.strokeStyle=colorData.Line.Color;
- this.Canvas.beginPath();
- if (isHScreen)
- {
- this.Canvas.moveTo(ToFixedPoint(yHigh),ToFixedPoint(x));
- this.Canvas.lineTo(ToFixedPoint(yLow),ToFixedPoint(x));
- }
- else
- {
- this.Canvas.moveTo(ToFixedPoint(x),ToFixedPoint(yHigh));
- this.Canvas.lineTo(ToFixedPoint(x),ToFixedPoint(yLow));
- }
-
- this.Canvas.stroke();
- }
- var barColor;
- if (colorData.Type==0) //空心柱子
- {
- if (colorData.Border) barColor=colorData.Border.Color;
- else if (colorData.BarColor) barColor=colorData.BarColor;
- }
- else if (colorData.Type==1) //实心
- {
- if (colorData.Border) barColor=colorData.Border.Color;
- else if (colorData.BarColor) barColor=colorData.BarColor;
- }
- if (barColor)
- {
- this.Canvas.strokeStyle=barColor;
- this.Canvas.beginPath();
- if (isHScreen)
- {
- this.Canvas.moveTo(ToFixedPoint(yOpen),ToFixedPoint(left));
- this.Canvas.lineTo(ToFixedPoint(yOpen),ToFixedPoint(right));
- }
- else
- {
- this.Canvas.moveTo(ToFixedPoint(left),ToFixedPoint(yOpen));
- this.Canvas.lineTo(ToFixedPoint(right),ToFixedPoint(yOpen));
- }
- this.Canvas.stroke();
- }
- }
- else
- {
- if (colorData.Line)
- {
- var xFixed=left+dataWidth/2;
- this.Canvas.strokeStyle=colorData.Line.Color;
- this.Canvas.beginPath();
- if (isHScreen)
- {
- this.Canvas.moveTo(ToFixedPoint(yHigh),ToFixedPoint(x));
- this.Canvas.lineTo(ToFixedPoint(yLow),ToFixedPoint(x));
- }
- else
- {
- this.Canvas.moveTo(ToFixedPoint(x),ToFixedPoint(yHigh));
- this.Canvas.lineTo(ToFixedPoint(x),ToFixedPoint(yLow));
- }
- this.Canvas.stroke();
- }
- }
- }
- this.ClearCustomKLine=function()
- {
- this.CustomKLine=null;
- }
- this.GetCustomKLine=function(kItem)
- {
- if (!this.CustomKLine) return null;
- if (!kItem) return null;
- var key=kItem.Date*1000000;
- if (IFrameSplitOperator.IsNumber(kItem.Time)) key+=kItem.Time;
- if (!this.CustomKLine.has(key)) return null;
- var value=this.CustomKLine.get(key);
- return value;
- }
- this.DrawTrade = function () //交易系统
- {
- if (!this.TradeData) return;
- var isHScreen = (this.ChartFrame.IsHScreen === true);
- var dataWidth = this.ChartFrame.DataWidth;
- var distanceWidth = this.ChartFrame.DistanceWidth;
- var xOffset = this.ChartBorder.GetLeft() + distanceWidth / 2.0 + 2.0;
- var chartright = this.ChartBorder.GetRight();
- var xPointCount = this.ChartFrame.XPointCount;
- if (isHScreen) {
- xOffset = this.ChartBorder.GetTop() + distanceWidth / 2.0 + 2.0;
- chartright = this.ChartBorder.GetBottom();
- }
- var sellData = this.TradeData.Sell;
- var buyData = this.TradeData.Buy;
- var arrowWidth = dataWidth;
- if (arrowWidth > 10) arrowWidth = 10;
- for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j, xOffset += (dataWidth + distanceWidth)) {
- var data = this.Data.Data[i];
- if (data.Open == null || data.High == null || data.Low == null || data.Close == null) continue;
- var buy = false, sell = false;
- if (sellData && i < sellData.length) sell = sellData[i] > 0;
- if (buyData && i < buyData.length) buy = buyData[i] > 0;
- if (!sell && !buy) continue;
- var left = xOffset;
- var right = xOffset + dataWidth;
- if (right > chartright) break;
- var x = left + (right - left) / 2;
- var yLow = this.ChartFrame.GetYFromData(data.Low);
- var yHigh = this.ChartFrame.GetYFromData(data.High);
- var yOpen = this.ChartFrame.GetYFromData(data.Open);
- var yClose = this.ChartFrame.GetYFromData(data.Close);
- var y = yHigh;
- if (buy) {
- this.Canvas.fillStyle = this.UpColor;
- this.Canvas.strokeStyle = this.UnchagneColor;
- this.Canvas.beginPath();
- if (isHScreen) {
- this.Canvas.moveTo(yLow - 1, x);
- this.Canvas.lineTo(yLow - arrowWidth - 1, x - arrowWidth / 2);
- this.Canvas.lineTo(yLow - arrowWidth - 1, x + arrowWidth / 2);
- }
- else {
- this.Canvas.moveTo(x, yLow + 1);
- this.Canvas.lineTo(x - arrowWidth / 2, yLow + arrowWidth + 1);
- this.Canvas.lineTo(x + arrowWidth / 2, yLow + arrowWidth + 1);
- }
- this.Canvas.closePath();
- this.Canvas.fill();
- this.Canvas.stroke();
- }
- if (sell) {
- this.Canvas.fillStyle = this.DownColor;
- this.Canvas.strokeStyle = this.UnchagneColor;
- this.Canvas.beginPath();
- if (isHScreen) {
- this.Canvas.moveTo(yHigh + 1, x);
- this.Canvas.lineTo(yHigh + arrowWidth + 1, x - arrowWidth / 2);
- this.Canvas.lineTo(yHigh + arrowWidth + 1, x + arrowWidth / 2);
- }
- else {
- this.Canvas.moveTo(x, yHigh - 1);
- this.Canvas.lineTo(x - arrowWidth / 2, yHigh - arrowWidth - 1);
- this.Canvas.lineTo(x + arrowWidth / 2, yHigh - arrowWidth - 1);
- }
- this.Canvas.closePath();
- this.Canvas.fill();
- this.Canvas.stroke();
- }
- }
- }
- this.Draw = function ()
- {
- this.PtMax = { X: null, Y: null, Value: null, Align: 'left' }; //清空最大
- this.PtMin = { X: null, Y: null, Value: null, Align: 'left' }; //清空最小
- this.ChartFrame.ChartKLine = { Max: null, Min: null }; //保存K线上 显示最大最小值坐标
- this.DrawKRange={ Start:null, End:null };
- this.AryPriceGapCache=[];
- if (this.IsShow == false) return;
- if (this.DrawType == 1)
- {
- this.DrawCloseLine();
- if (this.PriceGap.Enable) this.DrawPriceGap();
- return;
- }
- else if (this.DrawType == 2)
- {
- this.DrawAKLine();
- }
- else if (this.DrawType == 4)
- {
- this.DrawCloseArea();
- }
- else if (this.DrawType==9)
- {
- this.DrawKBar();
- }
- else
- {
- this.DrawKBar();
- }
- this.DrawTrade();
- if (this.PriceGap.Enable) this.DrawPriceGap();
- if (this.IsShowMaxMinPrice) //标注最大值最小值
- {
- if (this.ChartFrame.IsHScreen === true) this.HScreenDrawMaxMinPrice(this.PtMax, this.PtMin);
- else this.DrawMaxMinPrice(this.PtMax, this.PtMin);
- }
- }
- this.OnFormatHighLowTitle=function(ptMax, ptMin)
- {
- if (!ptMax || !ptMin) return null;
- if (!IFrameSplitOperator.IsNumber(ptMax.Value) || !IFrameSplitOperator.IsNumber(ptMin.Value)) return null;
- var defaultfloatPrecision=JSCommonCoordinateData.GetfloatPrecision(this.Symbol); //小数位数
- var title=
- {
- High:ptMax.Value.toFixed(defaultfloatPrecision),
- Low:ptMin.Value.toFixed(defaultfloatPrecision)
- };
-
- if (!this.GetEventCallback) return title;
- var event=this.GetEventCallback(JSCHART_EVENT_ID.ON_FORMAT_KLINE_HIGH_LOW_TITLE);
- if (!event || !event.Callback) return title;
- var data={ Max:ptMax, Min:ptMin, Symbol:this.Symbol, Title:{ High:title.High, Low:title.Low }, Decimal:defaultfloatPrecision, PreventDefault:false };
- event.Callback(event, data, this);
- if (data.PreventDefault) return data.Title; //使用外部回调的数值
- return title;
- }
- this.DrawMaxMinPrice = function (ptMax, ptMin)
- {
- if (ptMax.X == null || ptMax.Y == null || ptMax.Value == null) return;
- if (ptMin.X == null || ptMin.Y == null || ptMin.Value == null) return;
- var title=this.OnFormatHighLowTitle(ptMax,ptMin);
- if (!title) return;
- var leftArrow=g_JSChartResource.KLine.MaxMin.LeftArrow;
- var rightArrow=g_JSChartResource.KLine.MaxMin.RightArrow;
- var highYOffset=g_JSChartResource.KLine.MaxMin.HighYOffset;
- var lowYOffset=g_JSChartResource.KLine.MaxMin.LowYOffset;
- var defaultfloatPrecision = JSCommonCoordinateData.GetfloatPrecision(this.Symbol);
- this.Canvas.font = this.TextFont;
-
- this.Canvas.textAlign = ptMax.Align;
- this.Canvas.textBaseline = 'bottom';
- var left = ptMax.X;
- if (IFrameSplitOperator.IsNumber(highYOffset)) ptMax.Y+=highYOffset;
- //var text = ptMax.Value.toFixed(defaultfloatPrecision);
- var text=title.High;
- var textColor=this.TextColor;
- if (title.HighColor) textColor=title.HighColor;
- this.Canvas.fillStyle = textColor;
- if (ptMax.Align == 'left') text = leftArrow + text;
- else text = text + rightArrow;
- this.Canvas.fillText(text, left, ptMax.Y);
- this.ChartFrame.ChartKLine.Max = { X: left, Y: ptMax.Y, Text: { BaseLine: 'bottom' } };
- this.Canvas.textAlign = ptMin.Align;
- this.Canvas.textBaseline = 'top';
- var left = ptMin.X;
- if (IFrameSplitOperator.IsNumber(lowYOffset)) ptMin.Y+=lowYOffset;
- //text = ptMin.Value.toFixed(defaultfloatPrecision);
- var text=title.Low;
- var textColor=this.TextColor;
- if (title.LowColor) textColor=title.LowColor;
- this.Canvas.fillStyle = textColor;
- if (ptMin.Align == 'left') text = leftArrow + text;
- else text = text + rightArrow;
- this.Canvas.fillText(text, left, ptMin.Y);
- this.ChartFrame.ChartKLine.Min = { X: left, Y: ptMin.Y, Text: { BaseLine: 'top' } };
- }
- this.HScreenDrawMaxMinPrice = function (ptMax, ptMin) //横屏模式下显示最大最小值
- {
- if (ptMax.X == null || ptMax.Y == null || ptMax.Value == null) return;
- if (ptMin.X == null || ptMin.Y == null || ptMin.Value == null) return;
- var title=this.OnFormatHighLowTitle(ptMax,ptMin);
- if (!title) return;
- var leftArrow=g_JSChartResource.KLine.MaxMin.LeftArrow;
- var rightArrow=g_JSChartResource.KLine.MaxMin.RightArrow;
- var highYOffset=g_JSChartResource.KLine.MaxMin.HighYOffset;
- var lowYOffset=g_JSChartResource.KLine.MaxMin.LowYOffset;
- var defaultfloatPrecision = JSCommonCoordinateData.GetfloatPrecision(this.Symbol);
- var xText = ptMax.Y;
- var yText = ptMax.X;
- if (IFrameSplitOperator.IsNumber(highYOffset)) xText+=highYOffset;
- this.Canvas.save();
- this.Canvas.translate(xText, yText);
- this.Canvas.rotate(90 * Math.PI / 180);
- this.Canvas.font = this.TextFont;
- if (title.HighColor) this.Canvas.fillStyle=title.HighColor;
- else this.Canvas.fillStyle=this.TextColor;
- this.Canvas.textAlign = ptMax.Align;
- this.Canvas.textBaseline = 'bottom';
- var text=title.High;
- //var text = ptMax.Value.toFixed(defaultfloatPrecision);
- if (ptMax.Align == 'left') text = leftArrow + text;
- else text = text + rightArrow;
- this.Canvas.fillText(text, 0, 0);
- this.Canvas.restore();
- var xText = ptMin.Y;
- var yText = ptMin.X;
- if (IFrameSplitOperator.IsNumber(lowYOffset)) xText+=lowYOffset;
- this.Canvas.save();
- this.Canvas.translate(xText, yText);
- this.Canvas.rotate(90 * Math.PI / 180);
- this.Canvas.font = this.TextFont;
- if (title.LowColor) this.Canvas.fillStyle=title.LowColor;
- else this.Canvas.fillStyle=this.TextColor;
- this.Canvas.textAlign = ptMin.Align;
- this.Canvas.textBaseline = 'top';
- var text=title.Low;
- //var text = ptMin.Value.toFixed(defaultfloatPrecision);
- if (ptMin.Align == 'left') text = leftArrow + text;
- else text = text + rightArrow;
- this.Canvas.fillText(text, 0, 0);
- this.Canvas.restore();
- }
- //画某一天的信息地雷 画在底部
- this.DrawInfoDiv = function (item) {
- if (!this.InfoData || this.InfoData.size <= 0) return;
- var dataWidth = this.ChartFrame.DataWidth;
- var distanceWidth = this.ChartFrame.DistanceWidth;
- var infoData = this.InfoData.get(item.DayData.Date.toString());
- if (!infoData || infoData.Data.length <= 0) return;
- var bHScreen = (this.ChartFrame.IsHScreen === true);
- if (this.InfoDrawType === 1) {
- this.Canvas.font = this.GetDynamicFont(dataWidth);
- this.Canvas.fillStyle = this.InfoPointColor2;
- this.Canvas.textAlign = 'center';
- this.Canvas.textBaseline = 'top';
- if (bHScreen) {
- var xText = item.YMin;
- var yText = item.X;
- this.Canvas.save();
- this.Canvas.translate(xText, yText);
- this.Canvas.rotate(90 * Math.PI / 180);
- this.Canvas.fillText('▲', 0, 0);
- this.Canvas.restore();
- }
- else {
- var left = ToFixedPoint(item.X);
- this.Canvas.fillText('▲', left, item.YMin);
- }
- }
- else {
- var dataWidth = this.ChartFrame.DataWidth;
- var radius = dataWidth / 2;
- if (radius > 3) radius = 3;
- var x = item.X;
- var y = this.ChartFrame.ChartBorder.GetBottom() - 2 - radius;
- if (bHScreen) y = this.ChartFrame.ChartBorder.GetLeft() + 2 + radius;
- this.Canvas.fillStyle = this.InfoPointColor;
- this.Canvas.beginPath();
- if (bHScreen) this.Canvas.arc(y, x, radius, 0, Math.PI * 2, true);
- else this.Canvas.arc(ToFixedPoint(x), y, radius, 0, Math.PI * 2, true);
- this.Canvas.closePath();
- this.Canvas.fill();
- }
- }
- this.GetTooltipData = function (x, y, tooltip) {
- return false;
- }
- this.GetMaxMin = function () //计算当天显示数据的最大最小值
- {
- var xPointCount = this.ChartFrame.XPointCount;
- var range = {};
- range.Max = null;
- range.Min = null;
- if (this.IsShow == false) return range;
- if (this.DrawType==1 || this.DrawType==4 ) // 1=收盘价线 4=收盘价面积图
- {
- for(var i=this.Data.DataOffset,j=0;i<this.Data.Data.length && j<xPointCount;++i,++j)
- {
- var data=this.Data.Data[i];
- if (!IFrameSplitOperator.IsNumber(data.Close)) continue;
- if (range.Max==null) range.Max=data.Close;
- if (range.Min==null) range.Min=data.Close;
- if (range.Max<data.Close) range.Max=data.Close;
- if (range.Min>data.Close) range.Min=data.Close;
- }
- }
- else
- {
- for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j)
- {
- var data = this.Data.Data[i];
- if (data.Open == null || data.High == null || data.Low == null || data.Close == null) continue;
-
- if (range.Max == null) range.Max = data.High;
- if (range.Min == null) range.Min = data.Low;
-
- if (range.Max < data.High) range.Max = data.High;
- if (range.Min > data.Low) range.Min = data.Low;
- }
-
- }
-
- return range;
- }
- this.DrawLastPointEvent=function(ptLast)
- {
- if (!this.GetEventCallback) return;
-
- //通知外部绘制最后一个点
- var event=this.GetEventCallback(JSCHART_EVENT_ID.ON_DRAW_KLINE_LAST_POINT);
- if (event)
- {
- var kWidth={ Data: this.ChartFrame.DataWidth, Distance:this.ChartFrame.DistanceWidth };
- if (ptLast) var data={ LastPoint:{ X:ptLast.X, Y:ptLast.Y, XLeft:ptLast.XLeft, XRight:ptLast.XRight }, KItem:ptLast.KItem, DrawType:this.DrawType, KWidth:kWidth, ChartRight:ptLast.ChartRight };
- else var data={ LastPoint:null, KItem:null, KWidth:kWidth };
- event.Callback(event,data,this);
- }
- }
- //////////////////////////////////////////////////////////////
- // 标识缺口
- /////////////////////////////////////////////////////////////
- this.DrawPriceGap=function()
- {
- if (!IFrameSplitOperator.IsNonEmptyArray(this.AryPriceGapCache)) return;
- if (this.PriceGap.Count<=0) return;
- var index=this.AryPriceGapCache.length-this.PriceGap.Count;
- if (index<0) index=0;
- var isHScreen=(this.ChartFrame.IsHScreen===true);
- var border=null;
-
- if (isHScreen) border=this.ChartBorder.GetHScreenBorder();
- else border=this.ChartBorder.GetBorder();
- this.Canvas.font=this.PriceGapStyple.Text.Font;
- this.Canvas.textAlign = 'left';
- this.Canvas.textBaseline = 'bottom';
- var textHeight=this.Canvas.measureText("擎").width;
- var decNum=JSCommonCoordinateData.GetfloatPrecision(this.Symbol);
- for(var i=index;i<this.AryPriceGapCache.length;++i)
- {
- var item=this.AryPriceGapCache[i];
- var start=item.Data[0];
- var end=item.Data[1];
- var rect=null, rtText=null, text=null;
- if (item.Type==1) //上缺口
- {
- if (isHScreen)
- {
- rect={ Left:start.Coordinate.High, Right:end.Coordinate.Low, Top:start.Coordinate.X, Bottom: border.Bottom };
- rect.Width=rect.Right-rect.Left;
- rect.Height=rect.Bottom-rect.Top;
- rtText={ Left:start.Coordinate.High-textHeight-2, Top:start.Coordinate.Right+2, Height:textHeight };
- rtText.Bottom=rtText.Top+rtText.Height;
- }
- else
- {
- rect={ Left:start.Coordinate.X, Right:border.Right, Top:end.Coordinate.Low, Bottom:start.Coordinate.High };
- rect.Width=rect.Right-rect.Left;
- rect.Height=rect.Bottom-rect.Top;
-
- rtText={ Left:start.Coordinate.Right+2, Top:rect.Bottom+2, Right:rect.Right, Height:textHeight };
- rtText.Bottom=rtText.Top+rtText.Height;
- }
- text=`${start.Data.High.toFixed(decNum)}-${end.Data.Low.toFixed(decNum)}`;
-
- }
- else if (item.Type==2) //下缺口
- {
- if (isHScreen)
- {
- rect={ Left:start.Coordinate.Low, Right:end.Coordinate.High, Top:start.Coordinate.X, Bottom: border.Bottom };
- rect.Width=rect.Right-rect.Left;
- rect.Height=rect.Bottom-rect.Top;
- rtText={ Left:start.Coordinate.Low+2, Top:start.Coordinate.Right+2, Height:textHeight };
- rtText.Bottom=rtText.Top+rtText.Height;
- }
- else
- {
- rect={ Left:start.Coordinate.X, Right:border.Right, Top:start.Coordinate.Low, Bottom:end.Coordinate.High };
- rect.Width=rect.Right-rect.Left;
- rect.Height=rect.Bottom-rect.Top;
-
- rtText={ Left:start.Coordinate.Right+2, Bottom:rect.Top, Right:rect.Right, Height:textHeight };
- rtText.Top=rtText.Bottom-rtText.Height;
- }
- text=`${start.Data.Low.toFixed(decNum)}-${end.Data.High.toFixed(decNum)}`;
- }
- else
- {
- continue;
- }
- if (!rect) return;
- this.Canvas.fillStyle=this.PriceGapStyple.Line.Color;
- this.Canvas.fillRect(rect.Left, rect.Top,rect.Width, rect.Height);
-
- if (rtText)
- {
- var textWidth=this.Canvas.measureText(text).width;
- rtText.Width=textWidth;
- rtText.Right=rtText.Left+rtText.Width;
- this.Canvas.fillStyle=this.PriceGapStyple.Text.Color;
- if (isHScreen)
- {
- this.Canvas.save();
- this.Canvas.translate(rtText.Left, rtText.Top);
- this.Canvas.rotate(90 * Math.PI / 180);
- this.Canvas.fillText(text,0,0);
- this.Canvas.restore();
- }
- else
- {
- if (rtText.Right>rect.Right)
- {
- rtText.Right=rect.Right;
- rtText.Left=rtText.Right-rtText.Width;
- }
- this.Canvas.fillStyle=this.PriceGapStyple.Text.Color;
- this.Canvas.fillText(text,rtText.Left,rtText.Bottom);
- }
-
- //this.Canvas.fillStyle="rgb(250,250,250)"
- //this.Canvas.fillRect(rtText.Left, rtText.Top, rtText.Width, rtText.Height);
-
-
- }
- }
-
- }
- //是否有缺口
- this.IsPriceGap=function(item, preItem)
- {
- if (!preItem || !item) return 0;
- if (preItem.Data.Low>item.Data.High) return 2; //下缺口
- if (preItem.Data.High<item.Data.Low) return 1; //上缺口
- return -1;
- }
- //检测缺口是不回补了
- this.CheckPriceGap=function(kItemInfo)
- {
- var kItem=kItemInfo.Data;
- for(var i=0;i<this.AryPriceGapCache.length;++i)
- {
- var item=this.AryPriceGapCache[i];
- var start=item.Data[0];
- var end=item.Data[1];
- if (item.Type==1) //上缺口
- {
- if (kItem.Low<=start.Data.High)
- {
- this.AryPriceGapCache.splice(i,1);
- --i;
- continue;
- }
- if (kItem.Low<end.Data.Low) item.Data[1]=kItemInfo;
- }
- else if (item.Type==2) //下缺口
- {
- if (kItem.High>=start.Data.Low)
- {
- this.AryPriceGapCache.splice(i,1);
- --i;
- continue;
- }
- if (kItem.High>end.Data.High) item.Data[1]=kItemInfo;
- }
- }
- }
- }
- function ChartColorKline()
- {
- this.newMethod=IChartPainting; //派生
- this.newMethod();
- delete this.newMethod;
- this.ClassName='ChartColorKline'; //类名
- this.Symbol; //股票代码
- this.Color='rgb(0,255,44)';
- this.IsEmptyBar=false;
- this.DrawType=0; //0=实心K线柱子 3=空心K线柱子
- this.KLineColor; //Map key=K线索引 value=设置
- this.DrawName;
- this.Draw=function()
- {
- if (!this.IsShow) return;
- if (this.DrawName=="DRAWCOLORKLINE")
- {
- this.DrawColorBar();
- }
- else
- {
- if (!this.KLineColor) return;
- this.DrawBar();
- }
- }
- this.DrawUpBarItem=function(data, xOffset, dataWidth, option)
- {
- var isHScreen=(this.ChartFrame.IsHScreen===true);
- var left=xOffset;
- var right=xOffset+dataWidth;
- var x=left+(right-left)/2;
- var yLow=this.ChartFrame.GetYFromData(data.Low);
- var yHigh=this.ChartFrame.GetYFromData(data.High);
- var yOpen=this.ChartFrame.GetYFromData(data.Open);
- var yClose=this.ChartFrame.GetYFromData(data.Close);
- var y=yHigh;
- if (dataWidth>=4)
- {
- if (data.High>data.Close) //上影线
- {
- this.Canvas.beginPath();
- if (isHScreen)
- {
- this.Canvas.moveTo(ToFixedPoint(y),ToFixedPoint(x));
- this.Canvas.lineTo(ToFixedPoint(this.DrawType==3?Math.max(yClose,yOpen):yClose),ToFixedPoint(x));
- }
- else
- {
- this.Canvas.moveTo(ToFixedPoint(x),ToFixedPoint(y));
- this.Canvas.lineTo(ToFixedPoint(x),ToFixedPoint(this.DrawType==3?Math.min(yClose,yOpen):yClose));
- }
- this.Canvas.stroke();
- y=yClose;
- }
- else
- {
- y=yClose;
- }
- if (isHScreen)
- {
- if (Math.abs(yOpen-y)<1)
- {
- this.Canvas.fillRect(ToFixedRect(y),ToFixedRect(left),1,ToFixedRect(dataWidth)); //高度小于1,统一使用高度1
- }
- else
- {
- if (this.DrawType==3) //空心柱
- {
- this.Canvas.beginPath();
- this.Canvas.rect(ToFixedPoint(y),ToFixedPoint(left),ToFixedRect(yOpen-y),ToFixedRect(dataWidth));
- this.Canvas.stroke();
- }
- else
- {
- this.Canvas.fillRect(ToFixedRect(y),ToFixedRect(left),ToFixedRect(yOpen-y),ToFixedRect(dataWidth));
- }
- }
- }
- else
- {
- if (Math.abs(yOpen-y)<1)
- {
- this.Canvas.fillRect(ToFixedRect(left),ToFixedRect(y),ToFixedRect(dataWidth),1); //高度小于1,统一使用高度1
- }
- else
- {
- if (this.DrawType==3) //空心柱
- {
- this.Canvas.beginPath();
- this.Canvas.rect(ToFixedPoint(left),ToFixedPoint(y),ToFixedRect(dataWidth),ToFixedRect(yOpen-y));
- this.Canvas.stroke();
- }
- else
- {
- this.Canvas.fillRect(ToFixedRect(left),ToFixedRect(Math.min(y,yOpen)),ToFixedRect(dataWidth),ToFixedRect(Math.abs(yOpen-y)));
- }
- }
- }
- if (data.Open>data.Low) //下影线
- {
- this.Canvas.beginPath();
- if (isHScreen)
- {
- this.Canvas.moveTo(ToFixedPoint(this.DrawType==3?Math.min(yClose,yOpen):y),ToFixedPoint(x));
- this.Canvas.lineTo(ToFixedPoint(yLow),ToFixedPoint(x));
- }
- else
- {
- this.Canvas.moveTo(ToFixedPoint(x),ToFixedPoint(this.DrawType==3?Math.max(yClose,yOpen):y));
- this.Canvas.lineTo(ToFixedPoint(x),ToFixedPoint(yLow));
- }
- this.Canvas.stroke();
- }
- }
- else
- {
- this.Canvas.beginPath();
- if (isHScreen)
- {
- this.Canvas.moveTo(yHigh,ToFixedPoint(x));
- this.Canvas.lineTo(yLow,ToFixedPoint(x));
- }
- else
- {
- this.Canvas.moveTo(ToFixedPoint(x),yHigh);
- this.Canvas.lineTo(ToFixedPoint(x),yLow);
- }
- this.Canvas.stroke();
- }
- }
- this.DrawDownBarItem=function(data, xOffset, dataWidth, option)
- {
- var isHScreen=(this.ChartFrame.IsHScreen===true);
- var left=xOffset;
- var right=xOffset+dataWidth;
- var x=left+(right-left)/2;
- var yLow=this.ChartFrame.GetYFromData(data.Low);
- var yHigh=this.ChartFrame.GetYFromData(data.High);
- var yOpen=this.ChartFrame.GetYFromData(data.Open);
- var yClose=this.ChartFrame.GetYFromData(data.Close);
- var y=yHigh;
- if (dataWidth>=4)
- {
- if (data.High>data.Close) //上影线
- {
- this.Canvas.beginPath();
- if (isHScreen)
- {
- this.Canvas.moveTo(ToFixedPoint(y),ToFixedPoint(x));
- this.Canvas.lineTo(ToFixedPoint(yOpen),ToFixedPoint(x));
- }
- else
- {
- this.Canvas.moveTo(ToFixedPoint(x),ToFixedPoint(y));
- this.Canvas.lineTo(ToFixedPoint(x),ToFixedPoint(yOpen));
- }
- this.Canvas.stroke();
- y=yOpen;
- }
- else
- {
- y=yOpen
- }
- if (isHScreen)
- {
- if (Math.abs(yClose-y)<1) this.Canvas.fillRect(ToFixedRect(y),ToFixedRect(left),1,ToFixedRect(dataWidth)); //高度小于1,统一使用高度1
- else this.Canvas.fillRect(ToFixedRect(y),ToFixedRect(left),ToFixedRect(yClose-y),ToFixedRect(dataWidth));
- }
- else
- {
- if (Math.abs(yClose-y)<1) this.Canvas.fillRect(ToFixedRect(left),ToFixedRect(y),ToFixedRect(dataWidth),1); //高度小于1,统一使用高度1
- else this.Canvas.fillRect(ToFixedRect(left),ToFixedRect(Math.min(y,yClose)),ToFixedRect(dataWidth),ToFixedRect(Math.abs(yClose-y)));
- }
- if (data.Open>data.Low) //下影线
- {
- this.Canvas.beginPath();
- if (isHScreen)
- {
- this.Canvas.moveTo(ToFixedPoint(y),ToFixedPoint(x));
- this.Canvas.lineTo(ToFixedPoint(yLow),ToFixedPoint(x));
- }
- else
- {
- this.Canvas.moveTo(ToFixedPoint(x),ToFixedPoint(y));
- this.Canvas.lineTo(ToFixedPoint(x),ToFixedPoint(yLow));
- }
- this.Canvas.stroke();
- }
- }
- else
- {
- this.Canvas.beginPath();
- if (isHScreen)
- {
- this.Canvas.moveTo(yHigh,ToFixedPoint(x));
- this.Canvas.lineTo(yLow,ToFixedPoint(x));
- }
- else
- {
- this.Canvas.moveTo(ToFixedPoint(x),yHigh);
- this.Canvas.lineTo(ToFixedPoint(x),yLow);
- }
- this.Canvas.stroke();
- }
- }
- this.DrawUnChangeBarItem=function(data, xOffset, dataWidth, option)
- {
- var isHScreen=(this.ChartFrame.IsHScreen===true);
- var left=xOffset;
- var right=xOffset+dataWidth;
- var x=left+(right-left)/2;
- var yLow=this.ChartFrame.GetYFromData(data.Low);
- var yHigh=this.ChartFrame.GetYFromData(data.High);
- var yOpen=this.ChartFrame.GetYFromData(data.Open);
- var yClose=this.ChartFrame.GetYFromData(data.Close);
- var y=yHigh;
- if (dataWidth>=4)
- {
- this.Canvas.beginPath();
- if (data.High>data.Close) //上影线
- {
- if (isHScreen)
- {
- this.Canvas.moveTo(y,ToFixedPoint(x));
- this.Canvas.lineTo(yOpen,ToFixedPoint(x));
- }
- else
- {
- this.Canvas.moveTo(ToFixedPoint(x),y);
- this.Canvas.lineTo(ToFixedPoint(x),yOpen);
- }
- y=yOpen;
- }
- else
- {
- y=yOpen;
- }
- if (isHScreen)
- {
- this.Canvas.moveTo(ToFixedPoint(y),ToFixedPoint(left));
- this.Canvas.lineTo(ToFixedPoint(y),ToFixedPoint(right));
- }
- else
- {
- this.Canvas.moveTo(ToFixedPoint(left),ToFixedPoint(y));
- this.Canvas.lineTo(ToFixedPoint(right),ToFixedPoint(y));
- }
- if (data.Open>data.Low) //下影线
- {
- if (isHScreen)
- {
- this.Canvas.moveTo(ToFixedPoint(y),ToFixedPoint(x));
- this.Canvas.lineTo(ToFixedPoint(yLow),ToFixedPoint(x));
- }
- else
- {
- this.Canvas.moveTo(ToFixedPoint(x),ToFixedPoint(y));
- this.Canvas.lineTo(ToFixedPoint(x),ToFixedPoint(yLow));
- }
- }
- this.Canvas.stroke();
- }
- else
- {
- this.Canvas.beginPath();
- if (isHScreen)
- {
- this.Canvas.moveTo(yHigh,ToFixedPoint(x));
- this.Canvas.lineTo(yLow,ToFixedPoint(x));
- }
- else
- {
- this.Canvas.moveTo(ToFixedPoint(x),yHigh);
- this.Canvas.lineTo(ToFixedPoint(x),yLow);
- }
- this.Canvas.stroke();
- }
- }
- this.DrawBar=function()
- {
- var dataWidth=this.ChartFrame.DataWidth;
- var distanceWidth=this.ChartFrame.DistanceWidth;
- var xOffset=this.ChartBorder.GetLeft()+distanceWidth/2.0+2.0;
- var chartright=this.ChartBorder.GetRight();
- var xPointCount=this.ChartFrame.XPointCount;
- if (this.IsHScreen)
- {
- xOffset=this.ChartBorder.GetTop()+distanceWidth/2.0+2.0;
- chartright=this.ChartBorder.GetBottom();
- }
- for(var i=this.Data.DataOffset,j=0;i<this.Data.Data.length && j<xPointCount;++i,++j,xOffset+=(dataWidth+distanceWidth))
- {
- var data=this.Data.Data[i];
- if (data.Open==null || data.High==null || data.Low==null || data.Close==null) continue;
- if (!this.KLineColor.has(i)) continue;
- var itemOption=this.KLineColor.get(i);
- var left=xOffset;
- var right=xOffset+dataWidth;
- if (right>chartright) break;
- if (itemOption.Color)
- {
- this.Canvas.strokeStyle=itemOption.Color;
- this.Canvas.fillStyle=itemOption.Color;
- }
- else
- {
- this.Canvas.strokeStyle=this.Color;
- this.Canvas.fillStyle=this.Color;
- }
- if (data.Open<data.Close) //阳线
- {
- this.DrawUpBarItem(data,xOffset,dataWidth,itemOption);
- }
- else if (data.Open>data.Close) //阴线
- {
- this.DrawDownBarItem(data,xOffset,dataWidth,itemOption);
- }
- else //平线
- {
- this.DrawUnChangeBarItem(data,xOffset,dataWidth,itemOption);
- }
- }
- }
- this.DrawColorBar=function()
- {
- var isHScreen=(this.ChartFrame.IsHScreen===true);
- var dataWidth=this.ChartFrame.DataWidth;
- var distanceWidth=this.ChartFrame.DistanceWidth;
- var border=this.ChartBorder.GetBorder();
- var xOffset=border.LeftEx+distanceWidth/2.0+g_JSChartResource.FrameLeftMargin;
- var chartright=border.RightEx;
- var xPointCount=this.ChartFrame.XPointCount;
- if (isHScreen)
- {
- var border=this.ChartBorder.GetHScreenBorder();
- xOffset=border.TopEx+distanceWidth/2.0+g_JSChartResource.FrameLeftMargin;
- chartright=border.BottomEx;
- }
- for(var i=this.Data.DataOffset,j=0;i<this.Data.Data.length && j<xPointCount;++i,++j,xOffset+=(dataWidth+distanceWidth))
- {
- var data=this.Data.Data[i];
- if (!data) continue;
- if (!IFrameSplitOperator.IsNumber(data.Open) || !IFrameSplitOperator.IsNumber(data.High) ||
- !IFrameSplitOperator.IsNumber(data.Low) || !IFrameSplitOperator.IsNumber(data.Close)) continue;
- var left=xOffset;
- var right=xOffset+dataWidth;
- if (right>chartright) break;
- var x=left+(right-left)/2;
- var yLow=this.GetYFromData(data.Low, false);
- var yHigh=this.GetYFromData(data.High, false);
- var yOpen=this.GetYFromData(data.Open, false);
- var yClose=this.GetYFromData(data.Close, false);
- var y=yHigh;
- if (data.Open==data.Close)
- this.DrawKBar_Unchagne(data, dataWidth, this.Color, this.IsEmptyBar, x, y, left, right, yLow, yHigh, yOpen, yClose, isHScreen);
- else
- this.DrawKBar_Custom(data, dataWidth, this.Color, this.IsEmptyBar, x, y, left, right, yLow, yHigh, yOpen, yClose, isHScreen);
- }
- }
- this.DrawKBar_Unchagne=function(data, dataWidth, unchagneColor, drawType, x, y, left, right, yLow, yHigh, yOpen, yClose, isHScreen)
- {
- if (dataWidth>=4)
- {
- if ((dataWidth%2)!=0) dataWidth-=1;
- this.Canvas.strokeStyle=unchagneColor;
- this.Canvas.beginPath();
- if (data.High>data.Close) //上影线
- {
- if (isHScreen)
- {
- this.Canvas.moveTo(y,ToFixedPoint(x));
- this.Canvas.lineTo(yOpen,ToFixedPoint(x));
- }
- else
- {
- var xFixed=ToFixedPoint(left+dataWidth/2);
- this.Canvas.moveTo(xFixed,y);
- this.Canvas.lineTo(xFixed,yOpen);
- }
- y=yOpen;
- }
- else
- {
- y=yOpen;
- }
- if (isHScreen)
- {
- this.Canvas.moveTo(ToFixedPoint(y),ToFixedPoint(left));
- this.Canvas.lineTo(ToFixedPoint(y),ToFixedPoint(right));
- }
- else
- {
- this.Canvas.moveTo(ToFixedPoint(left),ToFixedPoint(y));
- this.Canvas.lineTo(ToFixedPoint(left+dataWidth),ToFixedPoint(y));
- }
- if (data.Open>data.Low) //下影线
- {
- if (isHScreen)
- {
- this.Canvas.moveTo(ToFixedPoint(y),ToFixedPoint(x));
- this.Canvas.lineTo(ToFixedPoint(yLow),ToFixedPoint(x));
- }
- else
- {
- var xFixed=ToFixedPoint(left+dataWidth/2);
- this.Canvas.moveTo(xFixed,ToFixedPoint(y));
- this.Canvas.lineTo(xFixed,ToFixedPoint(yLow));
- }
- }
- this.Canvas.stroke();
- }
- else
- {
- this.Canvas.beginPath();
- if (isHScreen)
- {
- this.Canvas.moveTo(yHigh,ToFixedPoint(x));
- this.Canvas.lineTo(yLow,ToFixedPoint(x));
- }
- else
- {
- if (data.High==data.Low)
- {
- this.Canvas.moveTo(ToFixedPoint(x),yHigh);
- this.Canvas.lineTo(ToFixedPoint(x),yLow+1);
- }
- else
- {
- this.Canvas.moveTo(ToFixedPoint(x),yHigh);
- this.Canvas.lineTo(ToFixedPoint(x),yLow);
- }
-
- }
- this.Canvas.strokeStyle=unchagneColor;
- this.Canvas.stroke();
- }
- }
- this.DrawKBar_Custom=function(data, dataWidth, barColor, isEmptyBar, x, y, left, right, yLow, yHigh, yOpen, yClose, isHScreen)
- {
- if (isEmptyBar)
- {
- if ((dataWidth%2)!=0) dataWidth-=1;
- }
- if (dataWidth>=4)
- {
- this.Canvas.strokeStyle=barColor;
- if (data.High>data.Close) //上影线
- {
- this.Canvas.beginPath();
- if (isHScreen)
- {
- this.Canvas.moveTo(ToFixedPoint(y),ToFixedPoint(x));
- this.Canvas.lineTo(ToFixedPoint(isEmptyBar?Math.max(yClose,yOpen):yClose),ToFixedPoint(x));
- }
- else
- {
- if (isEmptyBar)
- {
- var xFixed=left+dataWidth/2;
- this.Canvas.moveTo(ToFixedPoint(xFixed),ToFixedPoint(y));
- this.Canvas.lineTo(ToFixedPoint(xFixed),ToFixedPoint(Math.min(yClose,yOpen)));
- }
- else
- {
- this.Canvas.moveTo(ToFixedPoint(x),ToFixedPoint(y));
- this.Canvas.lineTo(ToFixedPoint(x),ToFixedPoint(yClose));
- }
-
- }
- this.Canvas.stroke();
- y=yClose;
- }
- else
- {
- y=yClose;
- }
-
- this.Canvas.fillStyle=barColor;
- if (isHScreen)
- {
- if (Math.abs(yOpen-y)<1)
- {
- this.Canvas.fillRect(ToFixedRect(y),ToFixedRect(left),1,ToFixedRect(dataWidth)); //高度小于1,统一使用高度1
- }
- else
- {
- if (isEmptyBar) //空心柱
- {
- this.Canvas.beginPath();
- this.Canvas.rect(ToFixedPoint(y),ToFixedPoint(left),ToFixedRect(yOpen-y),ToFixedRect(dataWidth));
- this.Canvas.stroke();
- }
- else
- {
- this.Canvas.fillRect(ToFixedRect(y),ToFixedRect(left),ToFixedRect(yOpen-y),ToFixedRect(dataWidth));
- }
- }
- }
- else
- {
- if (Math.abs(yOpen-y)<1)
- {
- this.Canvas.fillRect(ToFixedRect(left),ToFixedRect(y),ToFixedRect(dataWidth),1); //高度小于1,统一使用高度1
- }
- else
- {
- if (isEmptyBar) //空心柱
- {
- this.Canvas.beginPath();
- this.Canvas.rect(ToFixedPoint(left),ToFixedPoint(y),ToFixedRect(dataWidth),ToFixedRect(yOpen-y));
- this.Canvas.stroke();
- }
- else
- {
- this.Canvas.fillRect(ToFixedRect(left),ToFixedRect(Math.min(y,yOpen)),ToFixedRect(dataWidth),ToFixedRect(Math.abs(yOpen-y)));
- }
- }
- }
-
- if (data.Open>data.Low) //下影线
- {
- this.Canvas.beginPath();
- if (isHScreen)
- {
- this.Canvas.moveTo(ToFixedPoint(isEmptyBar?Math.min(yClose,yOpen):y),ToFixedPoint(x));
- this.Canvas.lineTo(ToFixedPoint(yLow),ToFixedPoint(x));
- }
- else
- {
- if (isEmptyBar)
- {
- var xFixed=left+dataWidth/2;
- this.Canvas.moveTo(ToFixedPoint(xFixed),ToFixedPoint(Math.max(yClose,yOpen)));
- this.Canvas.lineTo(ToFixedPoint(xFixed),ToFixedPoint(yLow));
- }
- else
- {
- this.Canvas.moveTo(ToFixedPoint(x),ToFixedPoint(y));
- this.Canvas.lineTo(ToFixedPoint(x),ToFixedPoint(yLow));
- }
-
- }
- this.Canvas.stroke();
- }
- }
- else
- {
- this.Canvas.beginPath();
- if (isHScreen)
- {
- this.Canvas.moveTo(yHigh,ToFixedPoint(x));
- this.Canvas.lineTo(yLow,ToFixedPoint(x));
- }
- else
- {
- this.Canvas.moveTo(ToFixedPoint(x),yHigh);
- this.Canvas.lineTo(ToFixedPoint(x),yLow);
- }
- this.Canvas.strokeStyle=barColor;
- this.Canvas.stroke();
- }
- }
- this.GetMaxMin=function()
- {
- var range={Max:null,Min:null };
- if (this.DrawName=="DRAWCOLORKLINE")
- {
- var xPointCount=this.ChartFrame.XPointCount;
-
- for(var i=this.Data.DataOffset,j=0;i<this.Data.Data.length && j<xPointCount;++i,++j)
- {
- var data=this.Data.Data[i];
- if (!data) continue;
- if (data.Open==null || data.High==null || data.Low==null || data.Close==null) continue;
-
- if (range.Max==null) range.Max=data.High;
- if (range.Min==null) range.Min=data.Low;
- if (range.Max<data.High) range.Max=data.High;
- if (range.Min>data.Low) range.Min=data.Low;
- }
- }
- return range;
- }
- }
- function ChartDrawIcon()
- {
- this.newMethod = IChartPainting; //派生
- this.newMethod();
- delete this.newMethod;
- this.ClassName="ChartDrawIcon";
- this.IsHScreen=false; //是否横屏
- this.DrawCallback; //function(op, obj) op:1=开始 2=绘制 4=销毁
- this.IsDestroy=false; //是否已销毁
- this.TextAlign = 'left';
- this.TextBaseline="middle";
- this.IconID;
- this.Color;
- this.FixedIconSize;
- this.DrawItem=[];
- this.Identify;
- this.Draw=function()
- {
- this.DrawItem=[];
- if (this.DrawCallback) this.DrawCallback(1, {Self:this} );
- this.DrawAllText();
-
- if (this.DrawCallback) this.DrawCallback(2, { Self:this, Draw:this.DrawItem } );
- }
- this.DrawAllText=function()
- {
- var isHScreen = (this.ChartFrame.IsHScreen === true)
- var dataWidth = this.ChartFrame.DataWidth;
- var distanceWidth = this.ChartFrame.DistanceWidth;
- var chartright = this.ChartBorder.GetRight();
- var top = this.ChartBorder.GetTopEx();
- var bottom = this.ChartBorder.GetBottomEx();
- if (isHScreen)
- {
- chartright = this.ChartBorder.GetBottom();
- top = this.ChartBorder.GetRightEx();
- bottom = this.ChartBorder.GetLeftEx();
- }
- var xPointCount = this.ChartFrame.XPointCount;
- var isArrayText = Array.isArray(this.Text);
-
- for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j)
- {
- var value = this.Data.Data[i];
- if (value == null) continue;
- var x = this.ChartFrame.GetXFromIndex(j);
- var y = this.ChartFrame.GetYFromData(value);
- if (x > chartright) break;
- var drawTextInfo=
- {
- Text:
- {
- Color:this.Color,
- Align:this.TextAlign,
- Baseline:this.TextBaseline,
- },
- X:x, Y:y,
- IconID:this.IconID
- };
- this.DrawItem.push(drawTextInfo);
- }
- }
- this.OnDestroy=function()
- {
- this.IsDestroy=true;
- if (this.DrawCallback) this.DrawCallback(4, { Self:this } );
- }
- }
- /*
- 文字输出 支持横屏
- 数组不为null的数据中输出 this.Text文本
- */
- function ChartSingleText()
- {
- this.newMethod = IChartPainting; //派生
- this.newMethod();
- delete this.newMethod;
- this.Color = "rgb(255,193,37)"; //线段颜色
- this.TextFont = "14px 微软雅黑"; //字体
- this.Text;
- this.TextAlign = 'left';
- this.Direction = 0; //0=middle 1=bottom 2=top
- this.FixedFontSize=-1; //固定字体大小
- this.YOffset = 0;
- this.Position; //指定输出位置
- this.TextBG; //{ Color:"rgb(0,0,92)", Border:"rgb(205,0,92)", Margin:[0,1,1,1], } // { Color:背景色, Border:边框颜色, Margin=[上,下,左, 右] }
- this.ShowOffset={ X:0, Y:0 }; //显示偏移
- this.TextSize=
- {
- Max: g_JSChartResource.DRAWICON.Text.MaxSize, Min:g_JSChartResource.DRAWICON.Text.MinSize, //字体的最大最小值
- Zoom:{ Type:g_JSChartResource.DRAWICON.Text.Zoom.Type , Value:g_JSChartResource.DRAWICON.Text.Zoom.Value }, //放大倍数
- FontName:g_JSChartResource.DRAWICON.Text.FontName
- }
- this.ReloadResource=function(resource)
- {
- if (this.Name=="DRAWTEXT")
- {
- this.TextSize=
- {
- Max: g_JSChartResource.DRAWTEXT.MaxSize, Min:g_JSChartResource.DRAWTEXT.MinSize, //字体的最大最小值
- Zoom:{ Type:g_JSChartResource.DRAWTEXT.Zoom.Type , Value:g_JSChartResource.DRAWTEXT.Zoom.Value }, //放大倍数
- FontName:g_JSChartResource.DRAWTEXT.FontName
- }
- }
- else if (this.Name=="DRAWNUMBER")
- {
- this.TextSize=
- {
- Max: g_JSChartResource.DRAWNUMBER.MaxSize, Min:g_JSChartResource.DRAWNUMBER.MinSize, //字体的最大最小值
- Zoom:{ Type:g_JSChartResource.DRAWNUMBER.Zoom.Type , Value:g_JSChartResource.DRAWNUMBER.Zoom.Value }, //放大倍数
- FontName:g_JSChartResource.DRAWNUMBER.FontName
- }
- }
- }
- this.Draw = function ()
- {
- if (!this.IsShow || this.ChartFrame.IsMinSize) return;
- if (this.NotSupportMessage)
- {
- this.DrawNotSupportmessage();
- return;
- }
- if (this.Name=="DRAWTEXTREL" || this.Name=="DRAWTEXTABS")
- {
- this.DrawRectText();
- return;
- }
- if (this.Position)
- {
- this.DrawPosition();
- return;
- }
- if (!this.Data || !this.Data.Data) return;
- var isHScreen = (this.ChartFrame.IsHScreen === true)
- var dataWidth = this.ChartFrame.DataWidth;
- var distanceWidth = this.ChartFrame.DistanceWidth;
- var chartright = this.ChartBorder.GetRight();
- var top = this.ChartBorder.GetTopEx();
- var bottom = this.ChartBorder.GetBottomEx();
- if (isHScreen)
- {
- chartright = this.ChartBorder.GetBottom();
- top = this.ChartBorder.GetRightEx();
- bottom = this.ChartBorder.GetLeftEx();
- }
- var xPointCount = this.ChartFrame.XPointCount;
- var isArrayText = Array.isArray(this.Text);
- var text;
- var drawTextInfo={ Text:{ }, Font:{ } };
- //上下位置
- if (this.Direction == 1)
- {
- this.Canvas.textBaseline = 'bottom';
- drawTextInfo.Text={ Baseline: 'bottom'};
- }
- else if (this.Direction == 2)
- {
- this.Canvas.textBaseline = 'top';
- drawTextInfo.Text={ Baseline: 'top'};
- }
- else
- {
- this.Canvas.textBaseline = 'middle';
- drawTextInfo.Text={ Baseline: 'middle'};
- }
- //字体大小
- if (this.FixedFontSize>0)
- this.TextFont=`${this.FixedFontSize}px ${this.TextSize.FontName}`;
- else
- this.TextFont = this.GetDynamicFontEx(dataWidth,distanceWidth,this.TextSize.Max,this.TextSize.Min,this.TextSize.Zoom,this.TextSize.FontName);
- drawTextInfo.Font={ Height:this.GetFontHeight(this.TextFont) };
- for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j)
- {
- var value = this.Data.Data[i];
- if (value == null) continue;
- var x = this.ChartFrame.GetXFromIndex(j);
- var y = this.ChartFrame.GetYFromData(value);
- if (x > chartright) break;
- y+=this.ShowOffset.Y;
- x+=this.ShowOffset.X;
- this.Canvas.textAlign = this.TextAlign;
- this.Canvas.fillStyle = this.Color;
- this.Canvas.font = this.TextFont;
- drawTextInfo.Text.Color=this.Color;
- drawTextInfo.Text.Align=this.TextAlign;
- drawTextInfo.X=x;
- drawTextInfo.Y=y;
- if (this.YOffset > 0 && this.Direction > 0)
- {
- var yPrice = y;
-
- this.Canvas.save();
- this.Canvas.setLineDash([5, 10]);
- this.Canvas.strokeStyle = this.Color;
- this.Canvas.beginPath();
- if (isHScreen)
- {
- if (this.Direction == 1)
- {
- y = top - this.YOffset;
- yPrice += 5;
- }
- else
- {
- y = bottom + this.YOffset;
- yPrice -= 5;
- }
- this.Canvas.moveTo(ToFixedPoint(yPrice), ToFixedPoint(x));
- this.Canvas.lineTo(ToFixedPoint(y), ToFixedPoint(x));
- }
- else
- {
- if (this.Direction == 1)
- {
- y = top + this.YOffset;
- yPrice += 5;
- }
- else
- {
- y = bottom - this.YOffset;
- yPrice -= 5;
- }
- this.Canvas.moveTo(ToFixedPoint(x), ToFixedPoint(yPrice));
- this.Canvas.lineTo(ToFixedPoint(x), ToFixedPoint(y));
- }
-
- this.Canvas.stroke();
- this.Canvas.restore();
- }
- if (isArrayText)
- {
- text = this.Text[i];
- if (!text) continue;
- if (isHScreen)
- {
- if (this.Name=='DRAWNUMBER')
- {
- if (this.Direction==1) y+=g_JSChartResource.DRAWABOVE.YOffset;
- else if (this.Direction==2) y-=4;
- }
- }
- else
- {
- if (this.Name=='DRAWNUMBER')
- {
- if (this.Direction==1) y-=g_JSChartResource.DRAWABOVE.YOffset;
- else if (this.Direction==2) y+=4;
- }
- }
- if (this.Name=="DRAWTEXT")
- this.DrawTextV2(text,drawTextInfo,isHScreen);
- else
- this.DrawText(text, x, y, isHScreen);
- }
- else
- {
- if (this.Name=="DRAWTEXT")
- {
- this.DrawTextV2(this.Text,drawTextInfo,isHScreen);
- }
- else
- {
- this.DrawText(this.Text, x, y, isHScreen);
- }
- }
- }
- }
- this.DrawPosition=function() //绘制在指定位置上
- {
- if (!this.Text) return;
- var isHScreen=(this.ChartFrame.IsHScreen===true)
- if (isHScreen)
- {
- var y=this.ChartBorder.GetRightEx()-this.ChartBorder.GetWidthEx()*this.Position.Y;
- var x=this.ChartBorder.GetTop()+this.ChartBorder.GetHeight()*this.Position.X;
- }
- else
- {
- var x=this.ChartBorder.GetLeft()+this.ChartBorder.GetWidth()*this.Position.X;
- var y=this.ChartBorder.GetTopEx()+this.ChartBorder.GetHeight()*this.Position.Y;
- }
- this.Canvas.fillStyle=this.Color;
- //TYPE:0为左对齐,1为右对齐.
- if (this.Position.Type==0) this.Canvas.textAlign='left';
- else if (this.Position.Type==1) this.Canvas.textAlign='right';
- else this.Canvas.textAlign='center';
- if (this.Direction==1) this.Canvas.textBaseline='bottom';
- else if (this.Direction==2) this.Canvas.textBaseline='top';
- else this.Canvas.textBaseline='middle';
- this.DrawText(this.Text,x,y,isHScreen);
- }
- this.DrawText = function (text, x, y, isHScreen)
- {
- if (isHScreen)
- {
- this.Canvas.save();
- this.Canvas.translate(y, x);
- this.Canvas.rotate(90 * Math.PI / 180);
- this.Canvas.fillText(text, 0, 0);
- this.Canvas.restore();
- }
- else
- {
- this.Canvas.fillText(text, x, y);
- }
- }
- this.DrawTextV2=function(text, drawInfo, isHScreen)
- {
- var textWidth=this.Canvas.measureText(text).width;
- if (isHScreen)
- {
- var x=drawInfo.Y;
- var y=drawInfo.X;
- if (drawInfo.Text.Align=="right") y=y-textWidth;
- else if (drawInfo.Text.Align=="center") y=y-textWidth/2;
- if (drawInfo.Text.Baseline=="top") x-=drawInfo.Font.Height;
- else if (drawInfo.Text.Baseline=="middle") x-=drawInfo.Font.Height/2;
- if (this.TextBG && (this.TextBG.Color || this.TextBG.Border))
- {
- var margin=this.TextBG.Margin; //0=上 1=下 2=左 3=右
- var xRect=x-margin[0];
- var yRect=y-margin[2];
- var bgWidth=textWidth+margin[2]+margin[3];
- var bgHeight=drawInfo.Font.Height+margin[0]+margin[1];
- if (this.TextBG.Color)
- {
- this.Canvas.fillStyle=this.TextBG.Color;
- this.Canvas.fillRect(xRect,yRect,bgHeight,bgWidth);
- }
- if (this.TextBG.Border)
- {
- this.Canvas.strokeStyle=this.TextBG.Border;
- this.Canvas.strokeRect(ToFixedPoint(xRect),ToFixedPoint(yRect),ToFixedRect(bgHeight),ToFixedRect(bgWidth));
- }
- }
- this.Canvas.textBaseline="bottom";
- this.Canvas.textAlign="left";
- this.Canvas.fillStyle=drawInfo.Text.Color;
- this.Canvas.save();
- this.Canvas.translate(x, y);
- this.Canvas.rotate(90 * Math.PI / 180);
- this.Canvas.fillText(text,0,0);
- this.Canvas.restore();
- }
- else
- {
- var x=drawInfo.X;
- var y=drawInfo.Y;
- if (drawInfo.Text.Align=="right") x=x-textWidth;
- else if (drawInfo.Text.Align=="center") x=x-textWidth/2;
- if (drawInfo.Text.Baseline=="top") y+=drawInfo.Font.Height;
- else if (drawInfo.Text.Baseline=="middle") y+=drawInfo.Font.Height/2;
- if (this.TextBG && (this.TextBG.Color || this.TextBG.Border))
- {
- var margin=this.TextBG.Margin; //0=上 1=下 2=左 3=右
- var xRect=x-margin[2];
- var yRect=y-drawInfo.Font.Height-margin[1];
- var bgWidth=textWidth+margin[2]+margin[3];
- var bgHeight=drawInfo.Font.Height+margin[0]+margin[1];
- if (this.TextBG.Color)
- {
- this.Canvas.fillStyle=this.TextBG.Color;
- this.Canvas.fillRect(xRect,yRect,bgWidth,bgHeight);
- }
- if (this.TextBG.Border)
- {
- this.Canvas.strokeStyle=this.TextBG.Border;
- this.Canvas.strokeRect(ToFixedPoint(xRect),ToFixedPoint(yRect),ToFixedRect(bgWidth),ToFixedRect(bgHeight));
- }
- }
- this.Canvas.textBaseline="bottom";
- this.Canvas.textAlign="left";
- this.Canvas.fillStyle=drawInfo.Text.Color;
- this.Canvas.fillText(text,x,y);
- }
- }
- this.DrawRectText=function()
- {
- if (!this.DrawData) return;
- var isHScreen=(this.ChartFrame.IsHScreen===true)
- var border=this.ChartFrame.GetBorder();
- if (this.Name=="DRAWTEXTREL")
- {
- if (isHScreen)
- {
- var height=border.RightTitle-border.LeftEx;
- var width=border.BottomEx-border.TopEx;
- var x=this.DrawData.Point.X/1000*width+border.TopEx;
- var y=border.RightTitle-this.DrawData.Point.Y/1000*width;
- }
- else
- {
- var width=border.RightEx-border.LeftEx;
- var height=border.BottomEx-border.TopTitle;
- var x=this.DrawData.Point.X/1000*width+border.LeftEx;
- var y=this.DrawData.Point.Y/1000*height+border.TopTitle;
- }
-
- }
- else if (this.Name=="DRAWTEXTABS")
- {
- if (isHScreen)
- {
- var x=this.DrawData.Point.X+border.TopEx;
- var y=border.RightTitle-this.DrawData.Point.Y;
- }
- else
- {
- var x=this.DrawData.Point.X+border.LeftEx;
- var y=this.DrawData.Point.Y+border.TopTitle;
- }
- }
- else
- {
- return;
- }
- if (this.Direction==1) this.Canvas.textBaseline='bottom';
- else if (this.Direction==2) this.Canvas.textBaseline='top';
- else this.Canvas.textBaseline='middle';
- this.Canvas.textAlign=this.TextAlign;
- this.Canvas.font=this.TextFont;
- this.Canvas.fillStyle=this.Color;
- this.DrawText(this.DrawData.Text,x,y,isHScreen);
- }
- this.SuperGetMaxMin=this.GetMaxMin;
- this.GetMaxMin=function()
- {
- if (this.Name=="DRAWTEXTREL" || this.Name=="DRAWTEXTABS")
- {
- return { Min:null,Max:null };
- }
- else
- {
- return this.SuperGetMaxMin();
- }
- }
- }
- function ChartDrawText()
- {
- this.newMethod=IChartPainting; //派生
- this.newMethod();
- delete this.newMethod;
- this.ClassName='ChartDrawText'; //类名
- this.Color = "rgb(255,193,37)"; //线段颜色
- this.TextFont = "14px 微软雅黑"; //字体
- this.Text;
- this.TextAlign = 'left';
- this.TextBaseline="middle";
- this.FixedFontSize=-1; //固定字体大小
- this.YOffset = 0;
- this.FixedPosition=-1; //固定位置输出 1顶部, 2底部
- this.TextBG; //{ Color:"rgb(0,0,92)", Border:"rgb(205,0,92)", Margin:[0,1,1,1], } // { Color:背景色, Border:边框颜色, Margin=[上,下,左, 右] }
- this.VerticalLine; //垂直线
- this.ShowOffset={ X:0, Y:0 }; //显示偏移
- this.TextSize=
- {
- Max: g_JSChartResource.DRAWICON.Text.MaxSize, Min:g_JSChartResource.DRAWICON.Text.MinSize, //字体的最大最小值
- Zoom:{ Type:g_JSChartResource.DRAWICON.Text.Zoom.Type , Value:g_JSChartResource.DRAWICON.Text.Zoom.Value }, //放大倍数
- FontName:g_JSChartResource.DRAWICON.Text.FontName
- }
- this.ReloadResource=function(resource)
- {
- this.TextSize=
- {
- Max: g_JSChartResource.DRAWTEXT.MaxSize, Min:g_JSChartResource.DRAWTEXT.MinSize, //字体的最大最小值
- Zoom:{ Type:g_JSChartResource.DRAWTEXT.Zoom.Type , Value:g_JSChartResource.DRAWTEXT.Zoom.Value }, //放大倍数
- FontName:g_JSChartResource.DRAWTEXT.FontName
- }
- }
- this.Draw = function ()
- {
- if (!this.IsShow || this.ChartFrame.IsMinSize) return;
- if (this.NotSupportMessage)
- {
- this.DrawNotSupportmessage();
- return;
- }
- if (!this.Data || !this.Data.Data) return;
- var isHScreen = (this.ChartFrame.IsHScreen === true)
- var dataWidth = this.ChartFrame.DataWidth;
- var distanceWidth = this.ChartFrame.DistanceWidth;
- var chartright = this.ChartBorder.GetRight();
- var top = this.ChartBorder.GetTopEx();
- var bottom = this.ChartBorder.GetBottomEx();
- if (isHScreen)
- {
- chartright = this.ChartBorder.GetBottom();
- top = this.ChartBorder.GetRightEx();
- bottom = this.ChartBorder.GetLeftEx();
- }
- var xPointCount = this.ChartFrame.XPointCount;
- var isArrayText = Array.isArray(this.Text);
- var text;
- var drawTextInfo={ Text:{ Color:this.Color, Align:this.TextAlign, Baseline:this.TextBaseline }, Font:{ } };
- //字体大小
- if (this.FixedFontSize>0)
- this.TextFont=`${this.FixedFontSize}px ${this.TextSize.FontName}`;
- else
- this.TextFont = this.GetDynamicFontEx(dataWidth,distanceWidth,this.TextSize.Max,this.TextSize.Min,this.TextSize.Zoom,this.TextSize.FontName);
- drawTextInfo.Font={ Height:this.GetFontHeight(this.TextFont) };
- for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j)
- {
- var value = this.Data.Data[i];
- if (value == null) continue;
- var x = this.ChartFrame.GetXFromIndex(j);
- var y;
- if (this.FixedPosition===1) y=top;
- else if (this.FixedPosition===2) y=bottom;
- else y=this.ChartFrame.GetYFromData(value);
- if (x > chartright) break;
- y+=this.ShowOffset.Y;
- x+=this.ShowOffset.X;
-
- drawTextInfo.X=x;
- drawTextInfo.Y=y;
- if (isArrayText)
- {
- text = this.Text[i];
- if (!text) continue;
- this.DrawText(text,drawTextInfo,isHScreen);
- }
- else
- {
- this.DrawText(this.Text,drawTextInfo,isHScreen);
- }
- this.DrawVerticalLine(i, drawTextInfo, isHScreen);
- }
- }
- this.DrawText=function(text, drawInfo, isHScreen)
- {
- var textWidth=this.Canvas.measureText(text).width;
- if (isHScreen)
- {
- var x=drawInfo.Y;
- var y=drawInfo.X;
- if (drawInfo.Text.Align=="right") y=y-textWidth;
- else if (drawInfo.Text.Align=="center") y=y-textWidth/2;
- if (drawInfo.Text.Baseline=="top") x-=drawInfo.Font.Height;
- else if (drawInfo.Text.Baseline=="middle") x-=drawInfo.Font.Height/2;
- if (this.TextBG && (this.TextBG.Color || this.TextBG.Border))
- {
- var margin=this.TextBG.Margin; //0=上 1=下 2=左 3=右
- var xRect=x-margin[0];
- var yRect=y-margin[2];
- var bgWidth=textWidth+margin[2]+margin[3];
- var bgHeight=drawInfo.Font.Height+margin[0]+margin[1];
- if (this.TextBG.Color)
- {
- this.Canvas.fillStyle=this.TextBG.Color;
- this.Canvas.fillRect(xRect,yRect,bgHeight,bgWidth);
- }
- if (this.TextBG.Border)
- {
- this.Canvas.strokeStyle=this.TextBG.Border;
- this.Canvas.strokeRect(ToFixedPoint(xRect),ToFixedPoint(yRect),ToFixedRect(bgHeight),ToFixedRect(bgWidth));
- }
- drawInfo.Rect={Bottom:xRect, Top:xRect+bgHeight };
- }
- else
- {
- var xRect=x;
- var bgHeight=drawInfo.Font.Height;
- drawInfo.Rect={Bottom:xRect, Top:xRect+bgHeight };
- }
- this.Canvas.textBaseline="bottom";
- this.Canvas.textAlign="left";
- this.Canvas.fillStyle=drawInfo.Text.Color;
- this.Canvas.save();
- this.Canvas.translate(x, y);
- this.Canvas.rotate(90 * Math.PI / 180);
- this.Canvas.fillText(text,0,0);
- this.Canvas.restore();
- }
- else
- {
- var x=drawInfo.X;
- var y=drawInfo.Y;
- if (drawInfo.Text.Align=="right") x=x-textWidth;
- else if (drawInfo.Text.Align=="center") x=x-textWidth/2;
- if (drawInfo.Text.Baseline=="top") y+=drawInfo.Font.Height;
- else if (drawInfo.Text.Baseline=="middle") y+=drawInfo.Font.Height/2;
- if (this.TextBG && (this.TextBG.Color || this.TextBG.Border))
- {
- var margin=this.TextBG.Margin; //0=上 1=下 2=左 3=右
- var xRect=x-margin[2];
- var yRect=y-drawInfo.Font.Height-margin[1];
- var bgWidth=textWidth+margin[2]+margin[3];
- var bgHeight=drawInfo.Font.Height+margin[0]+margin[1];
- if (this.TextBG.Color)
- {
-
- this.Canvas.fillStyle=this.TextBG.Color;
- this.Canvas.fillRect(xRect,yRect,bgWidth,bgHeight);
- }
- if (this.TextBG.Border)
- {
- this.Canvas.strokeStyle=this.TextBG.Border;
- this.Canvas.strokeRect(ToFixedPoint(xRect),ToFixedPoint(yRect),ToFixedRect(bgWidth),ToFixedRect(bgHeight));
- }
- drawInfo.Rect={Top:yRect, Bottom:yRect+bgHeight };
- }
- else
- {
- var yRect=y-drawInfo.Font.Height;
- var bgHeight=drawInfo.Font.Height;
- drawInfo.Rect={Top:yRect, Bottom:yRect+bgHeight };
- }
- this.Canvas.textBaseline="bottom";
- this.Canvas.textAlign="left";
- this.Canvas.fillStyle=drawInfo.Text.Color;
- this.Canvas.fillText(text,x,y);
- }
- }
- //画连线
- this.DrawVerticalLine=function(index, drawTextInfo, isHScreen)
- {
- if (!this.VerticalLine) return;
- var item=this.VerticalLine.Data[index];
- if (!item) return;
- if (!IFrameSplitOperator.IsNumber(item.High)) return;
- if (!IFrameSplitOperator.IsNumber(item.Low)) return;
- var yHigh=this.ChartFrame.GetYFromData(item.High);
- var yLow=this.ChartFrame.GetYFromData(item.Low);
- var yLine, yLine2;
- if (isHScreen)
- {
- if (drawTextInfo.Rect.Bottom>yHigh)
- {
- yLine=drawTextInfo.Rect.Bottom-1;
- yLine2=yHigh+1;
- }
- else if (drawTextInfo.Rect.Top<yLow)
- {
- yLine=drawTextInfo.Rect.Top-1;
- yLine2=yLow-1;
- }
- else
- {
- return;
- }
- }
- else
- {
- if (drawTextInfo.Rect.Bottom<yHigh)
- {
- yLine=drawTextInfo.Rect.Bottom+1;
- yLine2=yHigh-1;
- }
- else if (drawTextInfo.Rect.Top>yLow)
- {
- yLine=drawTextInfo.Rect.Top-1;
- yLine2=yLow+1;
- }
- else
- {
- return;
- }
- }
- this.Canvas.save();
- var pixelTatio =1;
- var xLine=drawTextInfo.X;
- if (this.VerticalLine.LineType==1)
- {
- if (this.VerticalLine.LineDotted)
- this.Canvas.setLineDash(this.VerticalLine.LineDotted);
- else
- this.Canvas.setLineDash([3,3]);
- }
- if (IFrameSplitOperator.IsPlusNumber(this.VerticalLine.LineWidth))
- {
- this.Canvas.lineWidth=this.VerticalLine.LineWidth*pixelTatio;
- }
-
- this.Canvas.strokeStyle=this.VerticalLine.Color;
- this.Canvas.beginPath();
- if (isHScreen)
- {
- this.Canvas.moveTo(ToFixedPoint(yLine),ToFixedPoint(xLine));
- this.Canvas.lineTo(ToFixedPoint(yLine2),ToFixedPoint(xLine));
- }
- else
- {
- this.Canvas.moveTo(ToFixedPoint(xLine),ToFixedPoint(yLine));
- this.Canvas.lineTo(ToFixedPoint(xLine),ToFixedPoint(yLine2));
- }
- this.Canvas.stroke();
- this.Canvas.restore();
- }
- }
- function ChartDrawNumber()
- {
- this.newMethod=ChartDrawText; //派生
- this.newMethod();
- delete this.newMethod;
- this.ClassName='ChartDrawNumber'; //类名
- this.ReloadResource=function(resource)
- {
- this.TextSize=
- {
- Max: g_JSChartResource.DRAWNUMBER.MaxSize, Min:g_JSChartResource.DRAWNUMBER.MinSize, //字体的最大最小值
- Zoom:{ Type:g_JSChartResource.DRAWNUMBER.Zoom.Type , Value:g_JSChartResource.DRAWNUMBER.Zoom.Value }, //放大倍数
- FontName:g_JSChartResource.DRAWNUMBER.FontName
- }
- }
- }
- function ChartDrawText_Fix()
- {
- this.newMethod=IChartPainting; //派生
- this.newMethod();
- delete this.newMethod;
- this.ClassName='ChartDrawText_Fix'; //类名
- this.Color="rgb(255,193,37)"; //字颜色
- this.TextFont=g_JSChartResource.DRAWTEXT_FIX.Font;
- this.PtPercentage=null; //{ X:, Y: } 百分比坐标
- this.TextBaseline="top";
- this.TextAlign='center';
- this.ShowOffset={ X:0, Y:0 }; //显示偏移
- this.MapCache;
- this.HQChart;
- this.AryText;
-
- this.BuildCacheData=function(kData, data)
- {
- var mapData=new Map();
- this.MapCache=mapData;
- if (!kData || !IFrameSplitOperator.IsNonEmptyArray(kData.Data)) return;
- if (!data || !IFrameSplitOperator.IsNonEmptyArray(data.Value) || !IFrameSplitOperator.IsNonEmptyArray(data.Text)) return;
- for(var i=0;i<kData.Data.length;++i)
- {
- var value=data.Value[i];
- if (value!==1) continue;
- var text=data.Text[i];
- if (!text) continue;
- var kItem=kData.Data[i];
- var item={ Value:value, Text:text, Date:kItem.Date, Time:kItem.Time };
- var key=this.BuildKey(item);
- /* //测试
- item.Text=
- [
- { Name:`日期`, Text:`${item.Date}`, Margin:{ Bottom:10 }},
- { Name:`日期2`, Text:`${item.Date}-2`},
- ]
- */
- mapData.set(key,item);
- }
- }
- this.ReloadResource=function(resource)
- {
- this.TextFont=g_JSChartResource.DRAWTEXT_FIX.Font;
- }
- this.Draw=function()
- {
- this.AryText=null;
- if (!this.IsShow || this.ChartFrame.IsMinSize) return;
- if (this.IsHideScriptIndex()) return;
- if (!this.MapCache || this.MapCache.size<=0) return;
- if (!this.PtPercentage || !IFrameSplitOperator.IsNumber(this.PtPercentage.X) || !IFrameSplitOperator.IsNumber(this.PtPercentage.Y)) return;
- if (!this.IsDrawText()) return;
-
- var bHScreen=(this.ChartFrame.IsHScreen===true)
- this.Canvas.save();
- this.ClipClient(bHScreen);
- this.DrawText();
- this.Canvas.restore();
- this.AryText=null;
- }
- //当前屏是否要绘制文字
- this.IsDrawText=function()
- {
- if (!this.HQChart) return false;
- var kData=this.HQChart.GetKData();
- if (!kData || !IFrameSplitOperator.IsNonEmptyArray(kData.Data)) return false;
- var bHScreen=(this.ChartFrame.IsHScreen===true)
- var dataWidth=this.ChartFrame.DataWidth;
- var distanceWidth=this.ChartFrame.DistanceWidth;
- var xPointCount=this.ChartFrame.XPointCount;
- var xOffset=this.ChartBorder.GetLeft()+distanceWidth/2.0+g_JSChartResource.FrameLeftMargin;
- var chartright=this.ChartBorder.GetRight();
- var top=this.ChartBorder.GetTopEx();
- var bottom=this.ChartBorder.GetBottomEx();
- if (bHScreen)
- {
- chartright=this.ChartBorder.GetBottom();
- top=this.ChartBorder.GetRightEx();
- bottom=this.ChartBorder.GetLeftEx();
- xOffset=this.ChartBorder.GetTop()+distanceWidth/2.0+g_JSChartResource.FrameLeftMargin;
- }
- for(var i=kData.DataOffset,j=0;i<kData.Data.length && j<xPointCount;++i,++j,xOffset+=(dataWidth+distanceWidth))
- {
- var kItem=kData.Data[i];
- if (kItem==null) continue;
- var key=this.BuildKey(kItem);
- if (!this.MapCache.has(key)) continue;
- var item=this.MapCache.get(key);
- if (Array.isArray(item.Text)) this.AryText=item.Text;
- else this.AryText=[{ Name:item.Text }];
- return true;
- }
- return false;
- }
- this.DrawText=function()
- {
- var bHScreen=(this.ChartFrame.IsHScreen===true);
- if (bHScreen)
- {
- var x=this.ChartBorder.GetRightEx()-this.ChartBorder.GetWidthEx()*this.PtPercentage.Y;
- var y=this.ChartBorder.GetTop()+this.ChartBorder.GetHeight()*this.PtPercentage.X;
- }
- else
- {
- var x=this.ChartBorder.GetLeft()+this.ChartBorder.GetWidth()*this.PtPercentage.X;
- var y=this.ChartBorder.GetTopEx()+this.ChartBorder.GetHeightEx()*this.PtPercentage.Y;
- }
- var drawInfo=this.CalculateComplexTextSize(this.AryText, { Font:this.TextFont, Color:this.Color });
- if (!drawInfo) return;
- drawInfo.IsHScreen=bHScreen;
- if (bHScreen)
- {
- if (this.TextBaseline=="middle") x=x-drawInfo.Height/2; //上下居中
- else if (this.TextBaseline=="bottom") x=x-drawInfo.Height; //底部
- if (this.TextAlign=="center") y=y-drawInfo.Width/2; //左右居中
- else if (this.TextAlign=='right') y=y-drawInfo.Width; //右对齐
- this.DrawComplexText(x,y, drawInfo);
- }
- else
- {
- if (this.TextBaseline=="middle") y=y-drawInfo.Height/2; //上下居中
- else if (this.TextBaseline=="bottom") y=y-drawInfo.Height; //底部
- if (this.TextAlign=="center") x=x-drawInfo.Width/2; //左右居中
- else if (this.TextAlign=='right') x=x-drawInfo.Width; //右对齐
- this.DrawComplexText(x,y, drawInfo);
- }
- }
- this.DrawComplexText=function(x, y, drawInfo)
- {
- var left=x;
- var lineTop=y;
- if (drawInfo.IsHScreen)
- {
- left=0;
- lineTop=0;
- this.Canvas.save();
- this.Canvas.translate(x, y);
- this.Canvas.rotate(90 * Math.PI / 180);
- }
- this.Canvas.textBaseline="bottom";
- this.Canvas.textAlign="left";
- for(var i=0;i<drawInfo.AryData.length;++i)
- {
- var item=drawInfo.AryData[i];
- var margin=item.Margin;
- var xText=left+margin.Left;
- var yText=lineTop+item.Height-margin.Bottom;
- if (item.Name)
- {
- this.Canvas.font=item.Font;
- this.Canvas.fillStyle=item.NameColor;
- this.Canvas.fillText(item.Name,xText,yText);
- xText+=item.NameWidth+item.Space;
- }
- if (item.Text)
- {
- this.Canvas.font=item.Font;
- this.Canvas.fillStyle=item.TextColor;
- this.Canvas.fillText(item.Text,xText,yText);
- xText+=item.TextWidth;
- }
- lineTop+=item.Height;
- }
- if (drawInfo.IsHScreen) this.Canvas.restore();
- }
- //计算复杂文本长度高度 defaultOption:{ Font:, }
- this.CalculateComplexTextSize=function(aryText, defaultOption)
- {
- if (!defaultOption) return null;
- if (!aryText || !IFrameSplitOperator.IsNonEmptyArray(aryText)) return null;
- this.Canvas.font=defaultOption.Font;
- var lineHeight=this.Canvas.measureText("擎").width;
- var maxNameWidth=0, maxTextWidth=0;
- var result={ AryData:[], Width:0, Height:0 }
- for(var i=0;i<aryText.length;++i)
- {
- var item=aryText[i];
- var newItem={ NameWidth:0, TextWidth:0, Margin:{ Left:0, Top:0, Right:0, Bottom:0 }, Font:defaultOption.Font, Space:0, YOffset:0, Width:0, Height:0 };
- if (item.Name)
- {
- newItem.NameWidth=this.Canvas.measureText(item.Name).width;
- newItem.Name=item.Name;
- if (maxNameWidth<item.NameWidth) maxNameWidth=newItem.NameWidth;
- if (IFrameSplitOperator.IsNumber(item.Space)) newItem.Space=item.Space;
- if (item.NameColor) newItem.NameColor=item.NameColor;
- else newItem.NameColor=defaultOption.Color;
- }
- if (item.Text)
- {
- newItem.TextWidth=this.Canvas.measureText(item.Text).width;
- newItem.Text=item.Text;
- if (maxTextWidth<item.TextWidth) maxTextWidth=newItem.TextWidth;
- if (item.TextColor) newItem.TextColor=item.TextColor;
- else newItem.TextColor=defaultOption.Color;
- }
- JSChartResource.CopyMarginConfig(newItem.Margin, item.Margin);
- if (IFrameSplitOperator.IsNumber(item.YOffset)) newItem.YOffset=item.YOffset;
- newItem.Width=newItem.NameWidth+newItem.TextWidth;
- newItem.Width+=newItem.Margin.Left+newItem.Margin.Right+newItem.Space;
- newItem.Height=(lineHeight+newItem.Margin.Top+newItem.Margin.Bottom);
- result.AryData.push(newItem);
- result.Height+=newItem.Height;
- if (result.Width<newItem.Width) result.Width=newItem.Width;
- }
- return result;
- }
- }
- function ChartDrawNumber_Fix()
- {
- this.newMethod=ChartDrawText_Fix; //派生
- this.newMethod();
- delete this.newMethod;
- this.ClassName='ChartDrawNumber_Fix'; //类名
- this.TextFont=g_JSChartResource.DRAWNUMBER_FIX.Font;
- this.BuildCacheData=function(kData, data)
- {
- var mapData=new Map();
- this.MapCache=mapData;
- if (!kData || !IFrameSplitOperator.IsNonEmptyArray(kData.Data)) return;
- if (!data || !IFrameSplitOperator.IsNonEmptyArray(data.Value) || !IFrameSplitOperator.IsNonEmptyArray(data.Text)) return;
- for(var i=0;i<kData.Data.length;++i)
- {
- var value=data.Value[i];
- var text=data.Text[i];
- if (!text) continue;
- var kItem=kData.Data[i];
- var item={ Value:value, Text:text, Date:kItem.Date, Time:kItem.Time };
- var key=this.BuildKey(item);
- mapData.set(key,item);
- }
- }
- this.ReloadResource=function(resource)
- {
- this.TextFont=g_JSChartResource.DRAWNUMBER_FIX.Font;
- }
- }
- //线段
- function ChartLine()
- {
- this.newMethod = IChartPainting; //派生
- this.newMethod();
- delete this.newMethod;
- this.ClassName ='ChartLine';
- this.Color = "rgb(255,193,37)"; //线段颜色
- this.LineWidth; //线段宽度
- this.DrawType = 0; //画图方式 0=无效数平滑 1=无效数不画断开
- this.IsDotLine = false; //虚线
- this.LineDash=g_JSChartResource.DOTLINE.LineDash;
- this.Draw = function ()
- {
- if (!this.IsShow || this.ChartFrame.IsMinSize || !this.IsVisible) return;
- if (this.IsHideScriptIndex()) return;
- if (this.NotSupportMessage)
- {
- this.DrawNotSupportmessage();
- return;
- }
- if (!this.Data || !this.Data.Data) return;
- switch (this.DrawType)
- {
- case 0:
- return this.DrawLine();
- case 1:
- return this.DrawStraightLine();
- }
- }
- this.DrawLine = function ()
- {
- var bHScreen = (this.ChartFrame.IsHScreen === true);
- var dataWidth = this.ChartFrame.DataWidth;
- var distanceWidth = this.ChartFrame.DistanceWidth;
- var chartright = this.ChartBorder.GetRight();
- if (bHScreen) chartright = this.ChartBorder.GetBottom();
- var xPointCount = this.ChartFrame.XPointCount;
- this.Canvas.save();
- if (this.LineWidth > 0) this.Canvas.lineWidth = this.LineWidth;
- var bFirstPoint = true;
- var drawCount = 0;
- for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j)
- {
- var value = this.Data.Data[i];
- if (value == null) continue;
- var x = this.ChartFrame.GetXFromIndex(j);
- var y = this.GetYFromData(value);
- if (x > chartright) break;
- if (bFirstPoint)
- {
- this.Canvas.strokeStyle = this.Color;
- this.Canvas.beginPath();
- if (bHScreen) this.Canvas.moveTo(y, x); //横屏坐标轴对调
- else this.Canvas.moveTo(x, y);
- bFirstPoint = false;
- }
- else
- {
- if (bHScreen) this.Canvas.lineTo(y, x);
- else this.Canvas.lineTo(x, y);
- }
- ++drawCount;
- }
- if (drawCount > 0) this.Canvas.stroke();
- this.Canvas.restore();
- }
- //无效数不画
- this.DrawStraightLine = function ()
- {
- var bHScreen = (this.ChartFrame.IsHScreen === true);
- var isMinute=this.IsMinuteFrame();
- var dataWidth = this.ChartFrame.DataWidth;
- var distanceWidth = this.ChartFrame.DistanceWidth;
- var xOffset=this.ChartBorder.GetLeft()+distanceWidth/2.0+g_JSChartResource.FrameLeftMargin;
- var chartright = this.ChartBorder.GetRight();
- if (bHScreen) chartright = this.ChartBorder.GetBottom();
- if (bHScreen) xOffset=this.ChartBorder.GetTop()+distanceWidth/2.0+g_JSChartResource.FrameLeftMargin;
- var xPointCount = this.ChartFrame.XPointCount;
- var lockRect=this.GetLockRect();
- if (lockRect)
- {
- if (bHScreen) chartright=lockRect.Top;
- else chartright=lockRect.Left;
- }
- this.Canvas.save();
- if (this.LineWidth > 0) this.Canvas.lineWidth = this.LineWidth;
- this.Canvas.strokeStyle = this.Color;
- if (this.IsDotLine) this.Canvas.setLineDash(this.LineDash); //画虚线
- var bFirstPoint = true;
- var drawCount = 0;
- for(var i=this.Data.DataOffset,j=0;i<this.Data.Data.length && j<xPointCount;++i,++j,xOffset+=(dataWidth+distanceWidth))
- //for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j)
- {
- var value = this.Data.Data[i];
- if (value == null)
- {
- if (drawCount > 0) this.Canvas.stroke();
- bFirstPoint = true;
- drawCount = 0;
- continue;
- }
- if (isMinute)
- {
- var x = this.ChartFrame.GetXFromIndex(j);
- }
- else
- {
- var left=xOffset;
- var right=xOffset+dataWidth;
- if (right>chartright) break;
- var x=left+(right-left)/2;
- }
-
-
- var y = this.GetYFromData(value);
- if (x > chartright) break;
- if (bFirstPoint)
- {
- this.Canvas.beginPath();
- if (bHScreen) this.Canvas.moveTo(y, x); //横屏坐标轴对调
- else this.Canvas.moveTo(x, y);
- bFirstPoint = false;
- }
- else
- {
- if (bHScreen) this.Canvas.lineTo(y, x);
- else this.Canvas.lineTo(x, y);
- }
- ++drawCount;
- }
- if (drawCount > 0) this.Canvas.stroke();
- this.Canvas.restore();
- }
- this.GetYFromData = function (value)
- {
- return this.ChartFrame.GetYFromData(value);
- }
- }
- //独立线段
- //独立线段
- function ChartSingleLine()
- {
- this.newMethod=ChartLine; //派生
- this.newMethod();
- delete this.newMethod;
- this.ClassName='ChartSingleLine'; //类名
- this.MaxMin=null; //当前的显示范围
- this.Draw=function()
- {
- this.MaxMin=null;
- if (!this.IsShow || this.ChartFrame.IsMinSize || !this.IsVisible) return;
- if (this.IsHideScriptIndex()) return;
- if (!this.Data || !this.Data.Data) return;
- this.MaxMin=this.GetCurrentMaxMin();
- if (!this.MaxMin) return;
- if (!IFrameSplitOperator.IsNumber(this.MaxMin.Max) || !IFrameSplitOperator.IsNumber(this.MaxMin.Min)) return;
- switch(this.DrawType)
- {
-
- default:
- return this.DrawStraightLine();
- }
- }
- //获取当前页的最大最小值
- this.GetCurrentMaxMin=function()
- {
- var xPointCount=this.ChartFrame.XPointCount;
- var range={ Max:null, Min:null };
- for(var i=this.Data.DataOffset,j=0;i<this.Data.Data.length && j<xPointCount;++i,++j)
- {
- var value=this.Data.Data[i];
- if (!IFrameSplitOperator.IsNumber(value)) continue;
- if (range.Max==null) range.Max=value;
- if (range.Min==null) range.Min=value;
- if (range.Max<value) range.Max=value;
- if (range.Min>value) range.Min=value;
- }
- return range;
- }
- this.GetMaxMin=function()
- {
- return { Max:null, Min:null };
- }
- this.GetYFromData=function(value)
- {
- var bHScreen = (this.ChartFrame.IsHScreen === true);
- if (bHScreen)
- {
- if (value <= this.MaxMin.Min) return this.ChartBorder.GetLeftEx();
- if (value >= this.MaxMin.Max) return this.ChartBorder.GetRightEx();
- var width = this.ChartBorder.GetWidthEx() * (value - this.MaxMin.Min) / (this.MaxMin.Max - this.MaxMin.Min);
- return this.ChartBorder.GetLeftEx() + width;
- }
- else
- {
- if(value<=this.MaxMin.Min) return this.ChartBorder.GetBottomEx();
- if(value>=this.MaxMin.Max) return this.ChartBorder.GetTopEx();
-
- var height=this.ChartBorder.GetHeightEx()*(value-this.MaxMin.Min)/(this.MaxMin.Max-this.MaxMin.Min);
- return this.ChartBorder.GetBottomEx()-height;
- }
- }
- }
- //彩色线段
- function ChartPartLine()
- {
- this.newMethod=IChartPainting; //派生
- this.newMethod();
- delete this.newMethod;
- this.ClassName='ChartPartLine'; //类名
- this.LineWidth; //线段宽度
- this.IsDotLine=false; //虚线
- this.LineDash=[3,5]; //虚线设置
- this.Draw=function()
- {
- if (!this.IsShow || this.ChartFrame.IsMinSize || !this.IsVisible) return;
- if (this.IsHideScriptIndex()) return;
- if (!this.Data || !this.Data.Data) return;
- this.DrawLine();
- }
- this.DrawLine=function()
- {
- var bHScreen=(this.ChartFrame.IsHScreen===true);
- var dataWidth=this.ChartFrame.DataWidth;
- var distanceWidth=this.ChartFrame.DistanceWidth;
- if (bHScreen)
- {
- var border=this.ChartBorder.GetHScreenBorder();
- var chartright=border.BottomEx;
- var xOffset=border.TopEx+distanceWidth/2.0+g_JSChartResource.FrameLeftMargin;
- }
- else
- {
- var border=this.ChartBorder.GetBorder();
- var xOffset=border.LeftEx+distanceWidth/2.0+g_JSChartResource.FrameLeftMargin;
- var chartright=border.RightEx;
- }
- var xPointCount=this.ChartFrame.XPointCount;
- var isMinute=this.IsMinuteFrame();
- this.Canvas.save();
- if (this.LineWidth>0) this.Canvas.lineWidth=this.LineWidth;
- if (this.IsDotLine) this.Canvas.setLineDash(this.LineDash); //画虚线
-
- var drawCount=0;
- var lastColor;
- var lastPoint={X:null,Y:null};
- var isPerNull=false;
- for(var i=this.Data.DataOffset,j=0;i<this.Data.Data.length && j<xPointCount;++i,++j,xOffset+=(dataWidth+distanceWidth))
- {
- var item=this.Data.Data[i];
- if (item==null || item.Value==null)
- {
- lastPoint.X=null;
- lastPoint.Y=null;
- isPerNull=true;
- continue;
- }
- if (isMinute)
- {
- var x=this.ChartFrame.GetXFromIndex(j);
- }
- else
- {
- var left=xOffset;
- var right=xOffset+dataWidth;
- if (right>chartright) break;
- var x=left+(right-left)/2;
- }
- var value=item.Value;
- var color=item.RGB;
- var y=this.ChartFrame.GetYFromData(value);
- if (x>chartright) break;
- if (color!=lastColor || isPerNull==true)
- {
- if (lastColor && drawCount>0) this.Canvas.stroke();
- drawCount=0;
- lastColor=color;
- this.Canvas.strokeStyle=color;
- this.Canvas.beginPath();
- if (lastPoint.X!=null && lastPoint.Y!=null) //接着上一个点连线
- {
- if (bHScreen) this.Canvas.moveTo(lastPoint.Y,lastPoint.X); //横屏坐标轴对调
- else this.Canvas.moveTo(lastPoint.X,lastPoint.Y);
- if (bHScreen) this.Canvas.lineTo(y,x);
- else this.Canvas.lineTo(x,y);
- ++drawCount;
- }
- else
- {
- if (bHScreen) this.Canvas.moveTo(y,x); //横屏坐标轴对调
- else this.Canvas.moveTo(x,y);
- }
- }
- else
- {
- if (bHScreen) this.Canvas.lineTo(y,x);
- else this.Canvas.lineTo(x,y);
- ++drawCount;
- }
- lastPoint.X=x;
- lastPoint.Y=y;
- isPerNull=false;
- }
- if (drawCount>0) this.Canvas.stroke();
- this.Canvas.restore();
- }
- this.GetMaxMin=function()
- {
- var xPointCount=this.ChartFrame.XPointCount;
- var range={};
- range.Min=null;
- range.Max=null;
- for(var i=this.Data.DataOffset,j=0;i<this.Data.Data.length && j<xPointCount;++i,++j)
- {
- var item = this.Data.Data[i];
- if (!item || !item.Value) continue;
- if (range.Max == null || range.Max<item.Value) range.Max = item.Value;
- if (range.Min == null || range.Min>item.Value) range.Min = item.Value;
- }
- return range;
- }
- }
- //面积图 支持横屏
- function ChartArea()
- {
- this.newMethod=IChartPainting; //派生
- this.newMethod();
- delete this.newMethod;
- this.ClassName='ChartArea'; //类名
- this.Color="rgb(255,193,37)"; //线段颜色
- this.AreaColor; //面积颜色
- this.LineWidth; //线段宽度
- this.LineDash; //虚线
- this.AreaDirection=0 //0=向下 1=向上
- this.DrawSelectedStatus=this.DrawLinePoint;
- this.PtInChart=this.PtInLine;
- this.ExportData=this.ExportArrayData;
- this.GetItemData=this.GetArrayItemData;
- this.Draw=function()
- {
- if (!this.IsShow || this.ChartFrame.IsMinSize) return;
- if (this.NotSupportMessage)
- {
- this.DrawNotSupportmessage();
- return;
- }
- if (!this.Data || !this.Data.Data) return;
- this.DrawArea();
- }
- //无效数不画
- this.DrawArea=function()
- {
- var bHScreen=(this.ChartFrame.IsHScreen===true);
- var isMinute=this.IsMinuteFrame();
- var dataWidth=this.ChartFrame.DataWidth;
- var distanceWidth=this.ChartFrame.DistanceWidth;
- var xPointCount=this.ChartFrame.XPointCount;
- if (bHScreen)
- {
- var border=this.ChartBorder.GetHScreenBorder();
- var chartright=border.BottomEx;
- var xOffset=border.TopEx+distanceWidth/2.0+g_JSChartResource.FrameLeftMargin;
- }
- else
- {
- var border=this.ChartBorder.GetBorder();
- var xOffset=border.LeftEx+distanceWidth/2.0+g_JSChartResource.FrameLeftMargin;
- var chartright=border.RightEx;
- }
- var lockRect=this.GetLockRect();
- if (lockRect)
- {
- if (bHScreen) chartright=lockRect.Top;
- else chartright=lockRect.Left;
- }
- this.Canvas.save();
- if (this.LineWidth>0) this.Canvas.lineWidth=this.LineWidth;
- this.Canvas.strokeStyle=this.Color;
- if (this.AreaColor) this.Canvas.fillStyle=this.AreaColor;
- else this.Canvas.fillStyle=ColorToRGBA(this.Color,0.6);
- if (IFrameSplitOperator.IsNonEmptyArray(this.LineDash)) this.Canvas.setLineDash(this.LineDas); //画虚线
- var bFirstPoint=true;
- var ptFirst=null, ptEnd=null //起始结束点
- var drawCount=0;
- for(var i=this.Data.DataOffset,j=0;i<this.Data.Data.length && j<xPointCount;++i,++j,xOffset+=(dataWidth+distanceWidth))
- {
- var value=this.Data.Data[i];
- if (!IFrameSplitOperator.IsNumber(value))
- {
- if (drawCount>0) this.Canvas.stroke();
- if (ptFirst && ptEnd)
- {
- if (bHScreen)
- {
- if (this.AreaDirection==1)
- {
- this.Canvas.lineTo(border.RightEx,ptEnd.X);
- this.Canvas.lineTo(border.RightEx,ptFirst.X);
- }
- else
- {
- this.Canvas.lineTo(border.LeftEx,ptEnd.X);
- this.Canvas.lineTo(border.LeftEx,ptFirst.X);
- }
- this.Canvas.closePath();
- this.Canvas.fill();
- }
- else
- {
- if (this.AreaDirection==1)
- {
- this.Canvas.lineTo(ptEnd.X, border.TopEx);
- this.Canvas.lineTo(ptFirst.X, border.TopEx);
- }
- else
- {
- this.Canvas.lineTo(ptEnd.X, border.BottomEx);
- this.Canvas.lineTo(ptFirst.X, border.BottomEx);
- }
- this.Canvas.closePath();
- this.Canvas.fill();
- }
- }
- bFirstPoint=true;
- drawCount=0;
- ptFirst=null;
- ptEnd=null;
- continue;
- }
- if (isMinute)
- {
- var x=this.ChartFrame.GetXFromIndex(j);
- }
- else
- {
- var left=xOffset;
- var right=xOffset+dataWidth;
- if (right>chartright) break;
- var x=left+(right-left)/2;
- }
-
- var y=this.GetYFromData(value,false);
- if (x>chartright) break;
- if (bFirstPoint)
- {
- this.Canvas.beginPath();
- if (bHScreen) this.Canvas.moveTo(y,x); //横屏坐标轴对调
- else this.Canvas.moveTo(x,y);
- bFirstPoint=false;
- ptFirst={ X:x, Y:y };
- }
- else
- {
- if (bHScreen) this.Canvas.lineTo(y,x);
- else this.Canvas.lineTo(x,y);
- ptEnd={ X:x, Y:y };
- }
- ++drawCount;
- }
- if (drawCount>0)
- {
- if (drawCount==1 && ptFirst) //如果只有1个点, 画一个像素的横线
- {
- if (bHScreen) this.Canvas.lineTo(ptFirst.Y,ptFirst.X+1*GetDevicePixelRatio());
- else this.Canvas.lineTo(ptFirst.X+1*GetDevicePixelRatio(),ptFirst.Y);
- }
-
- this.Canvas.stroke();
- if (ptFirst && ptEnd)
- {
- if (bHScreen)
- {
- if (this.AreaDirection==1)
- {
- this.Canvas.lineTo(border.RightEx,ptEnd.X);
- this.Canvas.lineTo(border.RightEx,ptFirst.X);
- }
- else
- {
- this.Canvas.lineTo(border.LeftEx,ptEnd.X);
- this.Canvas.lineTo(border.LeftEx,ptFirst.X);
- }
- this.Canvas.closePath();
- this.Canvas.fill();
- }
- else
- {
- if (this.AreaDirection==1)
- {
- this.Canvas.lineTo(ptEnd.X, border.TopEx);
- this.Canvas.lineTo(ptFirst.X, border.TopEx);
- }
- else
- {
- this.Canvas.lineTo(ptEnd.X, border.BottomEx);
- this.Canvas.lineTo(ptFirst.X, border.BottomEx);
- }
- this.Canvas.closePath();
- this.Canvas.fill();
- }
- }
- }
- this.Canvas.restore();
- }
- }
- //子线段
- function ChartSubLine()
- {
- this.newMethod = ChartLine; //派生
- this.newMethod();
- delete this.newMethod;
- this.ClassName = 'ChartSubLine'; //类名
- this.Color = "rgb(255,193,37)"; //线段颜色
- this.LineWidth; //线段宽度
- this.DrawType = 0; //画图方式 0=无效数平滑 1=无效数不画断开
- this.IsDotLine = false; //虚线
- this.SubFrame = { Max: null, Min: null };
- this.Draw = function ()
- {
- if (!this.IsShow) return;
- if (!this.Data || !this.Data.Data) return;
- this.CalculateDataMaxMin();
- switch (this.DrawType)
- {
- case 0:
- return this.DrawLine();
- case 1:
- return this.DrawStraightLine();
- }
- }
- this.GetYFromData = function (value)
- {
- var bHScreen = (this.ChartFrame.IsHScreen === true);
- if (bHScreen)
- {
- if (value <= this.SubFrame.Min) return this.ChartBorder.GetLeftEx();
- if (value >= this.SubFrame.Max) return this.ChartBorder.GetRightEx();
- var width = this.ChartBorder.GetWidthEx() * (value - this.SubFrame.Min) / (this.SubFrame.Max - this.SubFrame.Min);
- return this.ChartBorder.GetLeftEx() + width;
- }
- else
- {
- if (value <= this.SubFrame.Min) return this.ChartBorder.GetBottomEx();
- if (value >= this.SubFrame.Max) return this.ChartBorder.GetTopEx();
- var height = this.ChartBorder.GetHeightEx() * (value - this.SubFrame.Min) / (this.SubFrame.Max - this.SubFrame.Min);
- return this.ChartBorder.GetBottomEx() - height;
- }
- }
- this.CalculateDataMaxMin = function ()
- {
- this.SubFrame = { Max: null, Min: null };
- var bHScreen = (this.ChartFrame.IsHScreen === true);
- var chartright = this.ChartBorder.GetRight();
- if (bHScreen) chartright = this.ChartBorder.GetBottom();
- var xPointCount = this.ChartFrame.XPointCount;
- for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j)
- {
- var value = this.Data.Data[i];
- if (value == null) continue;
- var x = this.ChartFrame.GetXFromIndex(j);
- if (x > chartright) break;
- if (this.SubFrame.Min == null || this.SubFrame.Min > value) this.SubFrame.Min = value;
- if (this.SubFrame.Max == null || this.SubFrame.Max < value) this.SubFrame.Max = value;
- }
- }
- this.GetMaxMin = function () //数据不参与坐标轴最大最小值计算
- {
- var range = { Min: null, Max: null };
- return range;
- }
- }
- //POINTDOT 圆点 支持横屏
- function ChartPointDot()
- {
- this.newMethod = IChartPainting; //派生
- this.newMethod();
- delete this.newMethod;
- this.Color = "rgb(255,193,37)"; //线段颜色
- this.Radius = 1; //点半径
- this.ClassName = 'ChartPointDot';
- this.EnableUpDownColor=false; //是否是红绿点
- this.UpColor=g_JSChartResource.ChartPointDot.UpColor;
- this.DownColor=g_JSChartResource.ChartPointDot.DownColor;
- this.HistoryData;
- this.Draw = function ()
- {
- if (!this.IsShow || this.ChartFrame.IsMinSize) return;
- if (this.NotSupportMessage)
- {
- this.DrawNotSupportmessage();
- return;
- }
- if (!this.Data || !this.Data.Data) return;
- var bHScreen = (this.ChartFrame.IsHScreen === true);
- var dataWidth = this.ChartFrame.DataWidth;
- var distanceWidth = this.ChartFrame.DistanceWidth;
- var chartright = this.ChartBorder.GetRight();
- if (bHScreen === true) chartright = this.ChartBorder.GetBottom();
- var xPointCount = this.ChartFrame.XPointCount;
- this.Canvas.save();
- this.Canvas.fillStyle = this.Color;
- var colorDot;
- for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j)
- {
- var value = this.Data.Data[i];
- if (value == null) continue;
- var x = this.ChartFrame.GetXFromIndex(j);
- var y = this.ChartFrame.GetYFromData(value);
- if (x > chartright) break;
- if (this.EnableUpDownColor)
- {
- var kItem=this.HistoryData.Data[i];
- if (kItem.Close>value) colorDot=this.UpColor
- else colorDot=this.DownColor;
- this.Canvas.fillStyle=colorDot;
- }
- this.Canvas.beginPath();
- if (bHScreen) this.Canvas.arc(y, x, this.Radius, 0, Math.PI * 2, true);
- else this.Canvas.arc(x, y, this.Radius, 0, Math.PI * 2, true);
- this.Canvas.closePath();
- this.Canvas.fill();
- }
- this.Canvas.restore();
- }
- }
- //通达信语法 STICK 支持横屏
- function ChartStick()
- {
- this.newMethod = IChartPainting; //派生
- this.newMethod();
- delete this.newMethod;
- this.Color = "rgb(255,193,37)"; //线段颜色
- this.LineWidth; //线段宽度
- this.ClassName = 'ChartStick';
- this.DrawLine = function ()
- {
- if (this.ChartFrame.IsMinSize) return;
- if (this.IsHideScriptIndex()) return;
- if (!this.Data || !this.Data.Data) return;
- var isHScreen = (this.ChartFrame.IsHScreen === true);
- var dataWidth = this.ChartFrame.DataWidth;
- var distanceWidth = this.ChartFrame.DistanceWidth;
- var chartright = this.ChartBorder.GetRight();
- if (isHScreen === true) chartright = this.ChartBorder.GetBottom();
- var xPointCount = this.ChartFrame.XPointCount;
- this.Canvas.save();
- if (this.LineWidth > 0) this.Canvas.lineWidth = this.LineWidth;
- var bFirstPoint = true;
- var drawCount = 0;
- for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j)
- {
- var value = this.Data.Data[i];
- if (value == null) continue;
- var x = this.ChartFrame.GetXFromIndex(j);
- var y = this.ChartFrame.GetYFromData(value);
- if (x > chartright) break;
- if (bFirstPoint)
- {
- this.Canvas.strokeStyle = this.Color;
- this.Canvas.beginPath();
- if (isHScreen) this.Canvas.moveTo(y, x);
- else this.Canvas.moveTo(x, y);
- bFirstPoint = false;
- }
- else
- {
- if (isHScreen) this.Canvas.lineTo(y, x);
- else this.Canvas.lineTo(x, y);
- }
- ++drawCount;
- }
- if (drawCount > 0) this.Canvas.stroke();
- this.Canvas.restore();
- }
- this.DrawStick = function ()
- {
- if (!this.Data || !this.Data.Data) return;
- var bHScreen = (this.ChartFrame.IsHScreen === true);
- var chartright = this.ChartBorder.GetRight();
- if (bHScreen) chartright = this.ChartBorder.GetBottom();
- var xPointCount = this.ChartFrame.XPointCount;
- var yBottom = this.ChartBorder.GetBottom();
- var xLeft = this.ChartBorder.GetLeft();
- this.Canvas.save();
- this.Canvas.strokeStyle = this.Color;
- if (this.LineWidth) this.Canvas.lineWidth = this.LineWidth;
- for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j)
- {
- var value = this.Data.Data[i];
- if (value == null) continue;
- var x = this.ChartFrame.GetXFromIndex(j);
- var y = this.ChartFrame.GetYFromData(value);
- if (x > chartright) break;
- this.Canvas.beginPath();
- if (bHScreen)
- {
- this.Canvas.moveTo(xLeft, x);
- this.Canvas.lineTo(y, x);
- this.Canvas.stroke();
- }
- else
- {
- var xFix = parseInt(x.toString()) + 0.5;
- this.Canvas.moveTo(xFix, y);
- this.Canvas.lineTo(xFix, yBottom);
- }
- this.Canvas.stroke();
- }
- this.Canvas.restore();
- }
- this.Draw = function ()
- {
- if (!this.IsShow) return;
- if (this.NotSupportMessage)
- {
- this.DrawNotSupportmessage();
- return;
- }
- this.DrawStick();
- }
- }
- //通达信语法 LINESTICK 支持横屏
- function ChartLineStick()
- {
- this.newMethod = ChartStick; //派生
- this.newMethod();
- delete this.newMethod;
- this.ClassName = 'ChartLineStick';
- this.Draw = function ()
- {
- if (!this.IsShow || this.ChartFrame.IsMinSize) return;
- if (this.IsHideScriptIndex()) return;
- if (this.NotSupportMessage)
- {
- this.DrawNotSupportmessage();
- return;
- }
- this.DrawStick();
- this.DrawLine();
- }
- }
- //柱子 支持横屏
- function ChartStickLine()
- {
- this.newMethod = IChartPainting; //派生
- this.newMethod();
- delete this.newMethod;
- this.ClassName ='ChartStickLine';
- this.Color = "rgb(255,193,37)"; //线段颜色
- this.BarType = 0; //柱子类型 0=实心 1=空心 -1=画虚线空心柱
- this.LineDotted=[3,3]; //虚线设置
- this.Width=0; //柱子宽度 0=1 3,50=k线宽度 101=K线宽度+间距宽度
- this.MinBarWidth=g_JSChartResource.MinKLineBarWidth; //最小的柱子宽度
- this.IsHScreen=false;
- this.BarCache={ Type:0 }; //Type:1=线段 2=柱子
- this.SetEmptyBar=function() //设置空心柱子
- {
- if (this.BarType!=1 && this.BarType!=-1) return false;
- this.Canvas.lineWidth=1;
- this.Canvas.strokeStyle=this.Color;
- var emptyBGColor=g_JSChartResource.EmptyBarBGColor;
- if (emptyBGColor) this.BarCache.EmptyBGColor=emptyBGColor;
- if (this.BarType==-1) this.BarCache.LineDotted=this.LineDotted; //虚线
- return true;
- }
- this.IsEmptyBar=function()
- {
- return (this.BarType==1 || this.BarType==-1);
- }
- this.Draw = function ()
- {
- if (this.ChartFrame.IsMinSize) return;
- if (this.NotSupportMessage)
- {
- this.DrawNotSupportmessage();
- return;
- }
- if (!this.Data || !this.Data.Data) return;
- this.BarCache={ Color:this.Color, EmptyBGColor:null, Width:1, Type:0, LineDotted:null };
- this.IsHScreen = (this.ChartFrame.IsHScreen === true);
- var dataWidth = this.ChartFrame.DataWidth;
- var distanceWidth = this.ChartFrame.DistanceWidth;
- var chartright = this.ChartBorder.GetRight();
- var xPointCount = this.ChartFrame.XPointCount;
- var xOffset = this.ChartBorder.GetLeft() + distanceWidth / 2.0 + g_JSChartResource.FrameLeftMargin;
- var isMinute=this.IsMinuteFrame();
- if (this.IsHScreen)
- {
- chartright = this.ChartBorder.GetBottom();
- xOffset = this.ChartBorder.GetTop() + distanceWidth / 2.0 + g_JSChartResource.FrameLeftMargin;
- }
- if (isMinute)
- {
- if (this.Width>1) this.BarCache.Width=2;
- this.BarCache.Type=1;
- }
- else if(this.Width==0)
- {
- this.BarCache.Type=1;
- this.SetEmptyBar();
- }
- else if (this.Width==50 || this.Width==3) //3和50 K线宽度
- {
- this.BarCache.Type=1;
- if (dataWidth >= this.MinBarWidth)
- {
- this.BarCache.Type=2;
- this.BarCache.Width=dataWidth;
- this.SetEmptyBar();
- }
- }
- else if (this.Width==101) //柱子+间距
- {
- var lineWidth=dataWidth+distanceWidth+1;
- this.BarCache.Type=1;
- if (lineWidth >= this.MinBarWidth)
- {
- this.BarCache.Type=2;
- this.BarCache.Width=lineWidth;
- }
- }
- else if (this.Width <=3)
- {
- var minWidth=2;
- var barWidth=dataWidth*(this.Width/3);
- if (barWidth<minWidth) barWidth=minWidth;
- this.BarCache.Type=1;
- if (barWidth >= this.MinBarWidth)
- {
- this.BarCache.Type=2;
- this.BarCache.Width=barWidth;
- this.SetEmptyBar();
- }
- }
- else
- {
- var barWidth=this.Width;
- this.BarCache.Type=2;
- this.BarCache.Width=barWidth;
- this.SetEmptyBar();
- }
- this.Canvas.save();
- this.Canvas.strokeStyle=this.BarCache.Color;
- if (this.BarCache.EmptyBGColor) this.Canvas.fillStyle=this.BarCache.EmptyBGColor; //空心柱子
- else this.Canvas.fillStyle=this.BarCache.Color;
- if (IFrameSplitOperator.IsNonEmptyArray(this.BarCache.LineDotted)) this.Canvas.setLineDash(this.BarCache.LineDotted); //虚线
- if (this.BarCache.Type==1) this.Canvas.lineWidth=this.BarCache.Width;
- for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j, xOffset += (dataWidth + distanceWidth))
- {
- var value = this.Data.Data[i];
- if (!value) continue;
- if (!IFrameSplitOperator.IsNumber(value.Value)) continue;
-
- var price = value.Value;
- var price2 =0;
- if (IFrameSplitOperator.IsNumber(value.Value2)) price2=value.Value2;
- if (isMinute)
- {
- var x=this.ChartFrame.GetXFromIndex(j);
- }
- else
- {
- var left=xOffset;
- var right=xOffset+dataWidth;
- var x=left+(right-left)/2;
- }
- var y = this.ChartFrame.GetYFromData(price);
- var y2 = this.ChartFrame.GetYFromData(price2);
- if (x > chartright) break;
- var xCenter=x;
- var yTop=Math.min(y,y2);
- var barHeight=Math.abs(y-y2); //柱子高度
- this.DrawBar(xCenter, yTop, barHeight);
- }
- this.Canvas.restore();
- }
- this.DrawBar=function(xCenter, ytop, barHeight)
- {
- if (barHeight<1) barHeight=1;
- if (this.BarCache.Type==1) //线段
- {
- if (this.IsHScreen)
- {
- this.Canvas.beginPath();
- this.Canvas.moveTo(ytop,ToFixedPoint(xCenter));
- this.Canvas.lineTo(ytop+barHeight,ToFixedPoint(xCenter));
- this.Canvas.stroke();
- }
- else
- {
- this.Canvas.beginPath();
- this.Canvas.moveTo(ToFixedPoint(xCenter),ytop);
- this.Canvas.lineTo(ToFixedPoint(xCenter),ytop+barHeight);
- this.Canvas.stroke();
- }
- }
- else if (this.BarCache.Type==2) //柱子
- {
- if (this.IsHScreen)
- {
- var xLeft=xCenter-this.BarCache.Width/2;
- if (this.IsEmptyBar()) //空心
- {
- if (this.BarCache.EmptyBGColor) //背景色填充
- this.Canvas.fillRect(ToFixedRect(ytop),ToFixedRect(xLeft),ToFixedRect(barHeight),ToFixedRect(this.BarCache.Width));
- this.Canvas.beginPath();
- this.Canvas.rect(ToFixedPoint(ytop),ToFixedPoint(xLeft),ToFixedRect(barHeight),ToFixedRect(this.BarCache.Width));
- this.Canvas.stroke();
- }
- else
- {
- this.Canvas.fillRect(ToFixedRect(ytop),ToFixedRect(xLeft),ToFixedRect(barHeight),ToFixedRect(this.BarCache.Width));
- }
- }
- else
- {
- var xLeft=xCenter-this.BarCache.Width/2;
- if (this.IsEmptyBar()) //空心
- {
- if (this.BarCache.EmptyBGColor) //背景色填充
- this.Canvas.fillRect(ToFixedRect(xLeft),ToFixedRect(ytop),ToFixedRect(this.BarCache.Width),ToFixedRect(barHeight));
- this.Canvas.beginPath();
- this.Canvas.rect(ToFixedPoint(xLeft),ToFixedPoint(ytop),ToFixedRect(this.BarCache.Width),ToFixedRect(barHeight));
- this.Canvas.stroke();
- }
- else
- {
- this.Canvas.fillRect(ToFixedRect(xLeft),ToFixedRect(ytop),ToFixedRect(this.BarCache.Width),ToFixedRect(barHeight));
- }
- }
- }
- }
- this.GetMaxMin = function ()
- {
- var xPointCount = this.ChartFrame.XPointCount;
- var range = {};
- range.Min = null;
- range.Max = null;
- if (!this.Data || !this.Data.Data) return range;
- for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j)
- {
- var data = this.Data.Data[i];
- if (data == null) continue;
- var value2 = data.Value2;
- if (value2 == null) value2 = 0;
- if (data == null || isNaN(data.Value) || isNaN(value2)) continue;
- var valueMax = Math.max(data.Value, value2);
- var valueMin = Math.min(data.Value, value2);
- if (range.Max == null) range.Max = valueMax;
- if (range.Min == null) range.Min = valueMin;
- if (range.Max < valueMax) range.Max = valueMax;
- if (range.Min > valueMin) range.Min = valueMin;
- }
- return range;
- }
- }
- //画矩形
- function ChartRectangle()
- {
- this.newMethod = IChartPainting; //派生
- this.newMethod();
- delete this.newMethod;
- this.ClassName ='ChartRectangle';
- this.Color = [];
- this.Rect;
- this.BorderColor = g_JSChartResource.FrameBorderPen;
- this.Draw = function ()
- {
- if (!this.IsShow || this.ChartFrame.IsMinSize) return;
- if (!this.Color || !this.Rect) return;
- if (this.Color.length <= 0) return;
- this.Canvas.strokeStyle = this.BorderColor;
- var bFill = false;
- if (this.Color.length == 2)
- {
- /* TODO 渐变下次做吧
- if (this.ColorAngle==0)
- {
- var ptStart={ X:this.ChartBorder.GetLeft(), Y:this.ChartBorder.GetTopEx() };
- var ptEnd={ X:this.ChartBorder.GetLeft(), Y:this.ChartBorder.GetBottomEx() };
- }
- else
- {
- var ptStart={ X:this.ChartBorder.GetLeft(), Y:this.ChartBorder.GetTopEx() };
- var ptEnd={ X:this.ChartBorder.GetRight(), Y:this.ChartBorder.GetTopEx() };
- }
- let gradient = this.Canvas.createLinearGradient(ptStart.X,ptStart.Y, ptEnd.X,ptEnd.Y);
- gradient.addColorStop(0, this.Color[0]);
- gradient.addColorStop(1, this.Color[1]);
- this.Canvas.fillStyle=gradient;
- */
- this.Canvas.fillStyle = this.Color[0];
- bFill = true;
- }
- else if (this.Color.length == 1)
- {
- if (this.Color[0])
- {
- this.Canvas.fillStyle = this.Color[0];
- bFill = true;
- }
- }
- else
- {
- return;
- }
- var chartWidth = this.ChartBorder.GetWidth();
- var chartHeight = this.ChartBorder.GetHeightEx();
- var left = this.Rect.Left / 1000 * chartWidth;
- var top = this.Rect.Top / 1000 * chartHeight;
- var right = this.Rect.Right / 1000 * chartWidth;
- var bottom = this.Rect.Bottom / 1000 * chartHeight;
- left = this.ChartBorder.GetLeft() + left
- top = this.ChartBorder.GetTopEx() + top;
- right = this.ChartBorder.GetLeft() + right;
- bottom = this.ChartBorder.GetTopEx() + bottom;
- var width = Math.abs(left - right);
- var height = Math.abs(top - bottom);
- if (bFill) this.Canvas.fillRect(left, top, width, height);
- this.Canvas.beginPath();
- this.Canvas.rect(ToFixedPoint(left), ToFixedPoint(top), ToFixedRect(width), ToFixedRect(height));
- this.Canvas.stroke();
- }
- }
- //K线叠加
- function ChartOverlayKLine()
- {
- this.newMethod = IChartPainting; //派生
- this.newMethod();
- delete this.newMethod;
- this.Color = "rgb(65,105,225)";
- this.MainData; //主图K线数据
- this.SourceData; //叠加的原始数据
- this.Name = "ChartOverlayKLine";
- this.Title;
- this.DrawType = 0;
- this.ClassName ='ChartOverlayKLine';
- this.CustomDrawType = null; //图形类型
- this.Status=OVERLAY_STATUS_ID.STATUS_NONE_ID;
- this.ShowRange={ }; //K线显示范围 { Start:, End:, DataCount:, ShowCount: }
- this.DrawKRange={ Start:null, End:null }; //当前屏K线的索引{ Start: , End:}
- this.YInfoType=4;
-
- this.SetOption = function (option)
- {
- if (!option) return;
- if (IFrameSplitOperator.IsNumber(option.DrawType)) this.CustomDrawType = option.DrawType;
- if (IFrameSplitOperator.IsNumber(option.YInfoType)) this.YInfoType=option.YInfoType;
- }
- this.DrawKBar = function (firstOpen) //firstOpen 当前屏第1个显示数据
- {
- var isHScreen = (this.ChartFrame.IsHScreen === true);
- var dataWidth = this.ChartFrame.DataWidth;
- var distanceWidth = this.ChartFrame.DistanceWidth;
- var xOffset = this.ChartBorder.GetLeft() + distanceWidth / 2.0 + 2.0;
- if (isHScreen) xOffset = this.ChartBorder.GetTop() + distanceWidth / 2.0 + 2.0;
- var chartright = this.ChartBorder.GetRight();
- if (isHScreen) chartright = this.ChartBorder.GetBottom();
- var xPointCount = this.ChartFrame.XPointCount;
- var isFristDraw = true;
- var firstOverlayOpen = null;
- this.ShowRange.Start=this.Data.DataOffset;
- this.ShowRange.End=this.ShowRange.Start;
- this.ShowRange.DataCount=0;
- this.ShowRange.ShowCount=xPointCount;
- this.ShowRange.FirstOpen=firstOpen;
- this.DrawKRange.Start=this.Data.DataOffset;
- for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j, xOffset += (dataWidth + distanceWidth),++this.ShowRange.DataCount)
- {
- var data = this.Data.Data[i];
- if (!data || data.Open == null || data.High == null || data.Low == null || data.Close == null) continue;
- if (firstOverlayOpen == null)
- {
- firstOverlayOpen = data.Open;
- this.ShowRange.FirstOverlayOpen=data.Open;
- }
- if (isFristDraw)
- {
- this.Canvas.strokeStyle = this.Color;
- this.Canvas.fillStyle = this.Color;
- this.Canvas.beginPath();
- isFristDraw = false;
- }
- var left = xOffset;
- var right = xOffset + dataWidth;
- if (right > chartright) break;
- var x = left + (right - left) / 2;
- var yLow = this.ChartFrame.GetYFromData(data.Low / firstOverlayOpen * firstOpen);
- var yHigh = this.ChartFrame.GetYFromData(data.High / firstOverlayOpen * firstOpen);
- var yOpen = this.ChartFrame.GetYFromData(data.Open / firstOverlayOpen * firstOpen);
- var yClose = this.ChartFrame.GetYFromData(data.Close / firstOverlayOpen * firstOpen);
- var y = yHigh;
- this.DrawKRange.End=i;
- if (data.Open < data.Close) //阳线
- {
- if (dataWidth >= 4)
- {
- if (data.High > data.Close) //上影线
- {
- if (isHScreen)
- {
- this.Canvas.moveTo(ToFixedPoint(y), ToFixedPoint(x));
- this.Canvas.lineTo(ToFixedPoint(this.DrawType == 3 ? Math.max(yClose, yOpen) : yClose), ToFixedPoint(x));
- }
- else
- {
- this.Canvas.moveTo(ToFixedPoint(x), ToFixedPoint(y));
- this.Canvas.lineTo(ToFixedPoint(x), ToFixedPoint(this.DrawType == 3 ? Math.min(yClose, yOpen) : yClose));
- }
- y = yClose;
- }
- else
- {
- y = yClose;
- }
- if (isHScreen) {
- if (Math.abs(yOpen - y) < 1)
- {
- this.Canvas.fillRect(ToFixedRect(y), ToFixedRect(left), 1, ToFixedRect(dataWidth)); //高度小于1,统一使用高度1
- }
- else
- {
- if (this.DrawType == 3) this.Canvas.rect(ToFixedPoint(y), ToFixedPoint(left), ToFixedRect(yOpen - y), ToFixedRect(dataWidth)); //空心柱
- else this.Canvas.fillRect(ToFixedRect(y), ToFixedRect(left), ToFixedRect(yOpen - y), ToFixedRect(dataWidth));
- }
- }
- else
- {
- if (Math.abs(yOpen - y) < 1)
- {
- this.Canvas.fillRect(ToFixedRect(left), ToFixedRect(y), ToFixedRect(dataWidth), 1); //高度小于1,统一使用高度1
- }
- else
- {
- if (this.DrawType == 3) this.Canvas.rect(ToFixedPoint(left), ToFixedPoint(y), ToFixedRect(dataWidth), ToFixedRect(yOpen - y)); //空心柱
- else this.Canvas.fillRect(ToFixedRect(left), ToFixedRect(y), ToFixedRect(dataWidth), ToFixedRect(yOpen - y));
- }
- }
- if (data.Open > data.Low)
- {
- if (isHScreen)
- {
- this.Canvas.moveTo(ToFixedPoint(this.DrawType == 3 ? Math.min(yClose, yOpen) : y), ToFixedPoint(x));
- this.Canvas.lineTo(ToFixedPoint(yLow), ToFixedPoint(x));
- }
- else
- {
- this.Canvas.moveTo(ToFixedPoint(x), ToFixedPoint(this.DrawType == 3 ? Math.max(yClose, yOpen) : y));
- this.Canvas.lineTo(ToFixedPoint(x), ToFixedPoint(yLow));
- }
- }
- }
- else
- {
- if (isHScreen)
- {
- this.Canvas.moveTo(yHigh, ToFixedPoint(x));
- this.Canvas.lineTo(yLow, ToFixedPoint(x));
- }
- else
- {
- this.Canvas.moveTo(ToFixedPoint(x), yHigh);
- this.Canvas.lineTo(ToFixedPoint(x), yLow);
- }
- }
- }
- else if (data.Open > data.Close) //阴线
- {
- if (dataWidth >= 4)
- {
- if (data.High > data.Close) //上影线
- {
- if (isHScreen)
- {
- this.Canvas.moveTo(ToFixedPoint(y), ToFixedPoint(x));
- this.Canvas.lineTo(ToFixedPoint(yOpen), ToFixedPoint(x));
- }
- else
- {
- this.Canvas.moveTo(ToFixedPoint(x), ToFixedPoint(y));
- this.Canvas.lineTo(ToFixedPoint(x), ToFixedPoint(yOpen));
- }
- y = yOpen;
- }
- else
- {
- y = yOpen
- }
- if (isHScreen)
- {
- if (Math.abs(yClose - y) < 1) this.Canvas.fillRect(ToFixedRect(y), ToFixedRect(left), 1, ToFixedRect(dataWidth)); //高度小于1,统一使用高度1
- else this.Canvas.fillRect(ToFixedRect(y), ToFixedRect(left), ToFixedRect(yClose - y), ToFixedRect(dataWidth));
- }
- else
- {
- if (Math.abs(yClose - y) < 1) this.Canvas.fillRect(ToFixedRect(left), ToFixedRect(y), ToFixedRect(dataWidth), 1); //高度小于1,统一使用高度1
- else this.Canvas.fillRect(ToFixedRect(left), ToFixedRect(y), ToFixedRect(dataWidth), ToFixedRect(yClose - y));
- }
- if (data.Open > data.Low) //下影线
- {
- if (isHScreen)
- {
- this.Canvas.moveTo(ToFixedPoint(y), ToFixedPoint(x));
- this.Canvas.lineTo(ToFixedPoint(yLow), ToFixedPoint(x));
- }
- else
- {
- this.Canvas.moveTo(ToFixedPoint(x), ToFixedPoint(y));
- this.Canvas.lineTo(ToFixedPoint(x), ToFixedPoint(yLow));
- }
- }
- }
- else
- {
- if (isHScreen)
- {
- this.Canvas.moveTo(yHigh, ToFixedPoint(x));
- this.Canvas.lineTo(yLow, ToFixedPoint(x));
- }
- else
- {
- this.Canvas.moveTo(ToFixedPoint(x), yHigh);
- this.Canvas.lineTo(ToFixedPoint(x), yLow);
- }
- }
- }
- else // 平线
- {
- if (dataWidth >= 4)
- {
- if (data.High > data.Close) //上影线
- {
- if (isHScreen)
- {
- this.Canvas.moveTo(y, ToFixedPoint(x));
- this.Canvas.lineTo(yOpen, ToFixedPoint(x));
- }
- else
- {
- this.Canvas.moveTo(ToFixedPoint(x), y);
- this.Canvas.lineTo(ToFixedPoint(x), yOpen);
- }
- y = yOpen;
- }
- else
- {
- y = yOpen;
- }
- if (isHScreen)
- {
- this.Canvas.moveTo(ToFixedPoint(y), ToFixedPoint(left));
- this.Canvas.lineTo(ToFixedPoint(y), ToFixedPoint(right));
- }
- else
- {
- this.Canvas.moveTo(ToFixedPoint(left), ToFixedPoint(y));
- this.Canvas.lineTo(ToFixedPoint(right), ToFixedPoint(y));
- }
- if (data.Open > data.Low) //下影线
- {
- if (isHScreen)
- {
- this.Canvas.moveTo(ToFixedPoint(y), ToFixedPoint(x));
- this.Canvas.lineTo(ToFixedPoint(yLow), ToFixedPoint(x));
- }
- else
- {
- this.Canvas.moveTo(ToFixedPoint(x), ToFixedPoint(y));
- this.Canvas.lineTo(ToFixedPoint(x), ToFixedPoint(yLow));
- }
- }
- }
- else
- {
- if (isHScreen)
- {
- this.Canvas.moveTo(yHigh, ToFixedPoint(x));
- this.Canvas.lineTo(yLow, ToFixedPoint(x));
- }
- else
- {
- this.Canvas.moveTo(ToFixedPoint(x), yHigh);
- this.Canvas.lineTo(ToFixedPoint(x), yLow);
- }
- }
- }
- }
- if (isFristDraw == false) this.Canvas.stroke();
- }
- this.DrawAKLine = function (firstOpen) //美国线
- {
- var isHScreen = (this.ChartFrame.IsHScreen === true);
- var dataWidth = this.ChartFrame.DataWidth;
- var distanceWidth = this.ChartFrame.DistanceWidth;
- var xOffset = this.ChartBorder.GetLeft() + distanceWidth / 2.0 + 2.0;
- if (isHScreen) xOffset = this.ChartBorder.GetTop() + distanceWidth / 2.0 + 2.0;
- var chartright = this.ChartBorder.GetRight();
- if (isHScreen) chartright = this.ChartBorder.GetBottom();
- var xPointCount = this.ChartFrame.XPointCount;
- var firstOverlayOpen = null;
- this.Canvas.strokeStyle = this.Color;
- this.ShowRange.Start=this.Data.DataOffset;
- this.ShowRange.End=this.ShowRange.Start;
- this.ShowRange.DataCount=0;
- this.ShowRange.ShowCount=xPointCount;
- this.ShowRange.FirstOpen=firstOpen;
- this.DrawKRange.Start=this.Data.DataOffset;
- for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j, xOffset += (dataWidth + distanceWidth),++this.ShowRange.DataCount)
- {
- var data = this.Data.Data[i];
- if (data.Open == null || data.High == null || data.Low == null || data.Close == null) continue;
- if (firstOverlayOpen == null)
- {
- firstOverlayOpen = data.Open;
- this.ShowRange.FirstOverlayOpen=data.Open;
- }
- var left = xOffset;
- var right = xOffset + dataWidth;
- if (right > chartright) break;
- var x = left + (right - left) / 2;
- var yLow = this.ChartFrame.GetYFromData(data.Low / firstOverlayOpen * firstOpen);
- var yHigh = this.ChartFrame.GetYFromData(data.High / firstOverlayOpen * firstOpen);
- var yOpen = this.ChartFrame.GetYFromData(data.Open / firstOverlayOpen * firstOpen);
- var yClose = this.ChartFrame.GetYFromData(data.Close / firstOverlayOpen * firstOpen);
- this.DrawKRange.End=i;
- this.Canvas.beginPath(); //最高-最低
- if (isHScreen)
- {
- this.Canvas.moveTo(yHigh, ToFixedPoint(x));
- this.Canvas.lineTo(yLow, ToFixedPoint(x));
- }
- else
- {
- this.Canvas.moveTo(ToFixedPoint(x), yHigh);
- this.Canvas.lineTo(ToFixedPoint(x), yLow);
- }
- this.Canvas.stroke();
- if (dataWidth >= 4)
- {
- this.Canvas.beginPath(); //开盘
- if (isHScreen)
- {
- this.Canvas.moveTo(ToFixedPoint(yOpen), left);
- this.Canvas.lineTo(ToFixedPoint(yOpen), x);
- }
- else
- {
- this.Canvas.moveTo(left, ToFixedPoint(yOpen));
- this.Canvas.lineTo(x, ToFixedPoint(yOpen));
- }
- this.Canvas.stroke();
- this.Canvas.beginPath(); //收盘
- if (isHScreen)
- {
- this.Canvas.moveTo(ToFixedPoint(yClose), right);
- this.Canvas.lineTo(ToFixedPoint(yClose), x);
- }
- else
- {
- this.Canvas.moveTo(right, ToFixedPoint(yClose));
- this.Canvas.lineTo(x, ToFixedPoint(yClose));
- }
- this.Canvas.stroke();
- }
- }
- }
- this.DrawCloseLine = function (firstOpen) //收盘价线
- {
- var isHScreen = (this.ChartFrame.IsHScreen === true);
- var dataWidth = this.ChartFrame.DataWidth;
- var distanceWidth = this.ChartFrame.DistanceWidth;
- var xOffset = this.ChartBorder.GetLeft() + distanceWidth / 2.0 + 2.0;
- if (isHScreen) xOffset = this.ChartBorder.GetTop() + distanceWidth / 2.0 + 2.0;
- var chartright = this.ChartBorder.GetRight();
- if (isHScreen) chartright = this.ChartBorder.GetBottom();
- var xPointCount = this.ChartFrame.XPointCount;
- var firstOverlayOpen = null;
- var bFirstPoint = true;
- this.ShowRange.Start=this.Data.DataOffset;
- this.ShowRange.End=this.ShowRange.Start;
- this.ShowRange.DataCount=0;
- this.ShowRange.ShowCount=xPointCount;
- this.ShowRange.FirstOpen=firstOpen;
- this.DrawKRange.Start=this.Data.DataOffset;
- this.Canvas.strokeStyle = this.Color;
- this.Canvas.beginPath();
- for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j, xOffset += (dataWidth + distanceWidth),++this.ShowRange.DataCount)
- {
- var data = this.Data.Data[i];
- if (data.Open == null || data.High == null || data.Low == null || data.Close == null) continue;
- if (firstOverlayOpen == null)
- {
- firstOverlayOpen = data.Open;
- this.ShowRange.FirstOverlayOpen=data.Open;
- }
- var left = xOffset;
- var right = xOffset + dataWidth;
- if (right > chartright) break;
- var x = left + (right - left) / 2;
- var yClose = this.ChartFrame.GetYFromData(data.Close / firstOverlayOpen * firstOpen);
- this.DrawKRange.End=i;
- if (bFirstPoint)
- {
- if (isHScreen) this.Canvas.moveTo(yClose, x);
- else this.Canvas.moveTo(x, yClose);
- bFirstPoint = false;
- }
- else
- {
- if (isHScreen) this.Canvas.lineTo(yClose, x);
- else this.Canvas.lineTo(x, yClose);
- }
- }
- if (bFirstPoint == false) this.Canvas.stroke();
- }
- this.GetFirstOpen=function()
- {
- var xPointCount = this.ChartFrame.XPointCount;
- var firstOpen = null; //主线数据第1个开盘价
- for (var i = this.Data.DataOffset, j = 0; i < this.MainData.Data.length && j < xPointCount; ++i, ++j)
- {
- var data = this.MainData.Data[i];
- if (data.Open == null || data.High == null || data.Low == null || data.Close == null) continue;
- firstOpen = data.Open;
- break;
- }
- return firstOpen;
- }
- this.Draw = function ()
- {
- this.TooltipRect = [];
- this.DrawKRange={ Start:null, End:null };
- if (!this.MainData || !this.Data) return;
- var firstOpen = this.GetFirstOpen(); //主线数据第1个开盘价
- if (firstOpen == null) return;
- var drawTypeBackup = this.DrawType; //备份下线段类型
- if (this.CustomDrawType != null) this.DrawType = this.CustomDrawType;
- if (this.DrawType == 1) this.DrawCloseLine(firstOpen);
- else if (this.DrawType == 2) this.DrawAKLine(firstOpen);
- else this.DrawKBar(firstOpen);
- this.DrawType = drawTypeBackup; //还原线段类型
- }
- this.GetMaxMin = function ()
- {
- var xPointCount = this.ChartFrame.XPointCount;
- var range = {};
- range.Max = null;
- range.Min = null;
- if (!this.MainData || !this.Data) return range;
- var firstOpen = this.GetFirstOpen(); //主线数据第1个收盘价
- if (firstOpen == null) return range;
- var firstOverlayOpen = null;
- var high, low;
- for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j)
- {
- var data = this.Data.Data[i];
- if (!data || data.Open == null || data.High == null || data.Low == null || data.Close == null) continue;
- if (firstOverlayOpen == null) firstOverlayOpen = data.Open;
- high = data.High / firstOverlayOpen * firstOpen;
- low = data.Low / firstOverlayOpen * firstOpen;
- if (range.Max == null) range.Max = high;
- if (range.Min == null) range.Min = low;
- if (range.Max < high) range.Max = high;
- if (range.Min > low) range.Min = low;
- }
- return range;
- }
- }
- // 多文本集合2.0 支持横屏
- function ChartMultiText()
- {
- this.newMethod = IChartPainting; //派生
- this.newMethod();
- delete this.newMethod;
- this.ClassName ='ChartMultiText';
- this.Texts = []; //[ {Date, Time:, Value:, Text:, Color:, Font: , Baseline:, Line:{ Color:, Dash:[虚线点], KData:"H/L", Offset:[5,10], Width:线粗细 } } ]
- this.Font = g_JSChartResource.DefaultTextFont;
- this.Color = g_JSChartResource.DefaultTextColor;
- this.IsHScreen = false; //是否横屏
- this.MapCache=null; //key=date/date-time value={ Data:[] }
- this.GetKValue=ChartData.GetKValue;
- this.BuildCacheData=function()
- {
- var mapData=new Map();
- this.MapCache=mapData;
- if (!IFrameSplitOperator.IsNonEmptyArray(this.Texts)) return;
- for(var i=0;i<this.Texts.length;++i)
- {
- var item=this.Texts[i];
- var key=this.BuildKey(item);
- if (mapData.has(key))
- {
- var mapItem=mapData.get(key);
- mapItem.Data.push(item);
- }
- else
- {
- mapData.set(key,{ Data:[item] });
- }
- }
- }
- this.Draw = function ()
- {
- if (!this.IsShow || this.ChartFrame.IsMinSize) return;
- if (!this.Data || !IFrameSplitOperator.IsNonEmptyArray(this.Data.Data)) return; //k线数据
- if (!IFrameSplitOperator.IsNonEmptyArray(this.Texts)) return;
- if (!this.MapCache || this.MapCache.size<=0) return;
- this.IsHScreen = (this.ChartFrame.IsHScreen === true);
- this.Canvas.save();
- this.ClipClient(this.IsHScreen);
- this.DrawAllText();
- this.Canvas.restore();
- }
- this.DrawAllText=function()
- {
- var bHScreen=(this.ChartFrame.IsHScreen===true);
- var isMinute=this.IsMinuteFrame();
- var dataWidth=this.ChartFrame.DataWidth;
- var distanceWidth=this.ChartFrame.DistanceWidth;
- var xPointCount=this.ChartFrame.XPointCount;
- if (bHScreen)
- {
- var border=this.ChartBorder.GetHScreenBorder();
- var chartright=border.BottomEx;
- var chartleft=border.TopEx;
- var xOffset=border.TopEx+distanceWidth/2.0+g_JSChartResource.FrameLeftMargin;
- var left=this.ChartBorder.GetTop();
- var right=this.ChartBorder.GetBottom();
- var top=border.RightEx;
- var bottom=border.LeftEx;
- }
- else
- {
- var border=this.ChartBorder.GetBorder();
- var xOffset=border.LeftEx+distanceWidth/2.0+g_JSChartResource.FrameLeftMargin;
- var chartright=border.RightEx;
- var chartleft=border.LeftEx;
- var left=this.ChartBorder.GetLeft();
- var right=this.ChartBorder.GetRight();
- var top=border.TopEx;
- var bottom=border.BottomEx;
- }
- for(var i=this.Data.DataOffset,j=0;i<this.Data.Data.length && j<xPointCount;++i,++j,xOffset+=(dataWidth+distanceWidth))
- {
- var kItem=this.Data.Data[i];
- if (!kItem) continue;
- var key=this.BuildKey(kItem);
- if (!this.MapCache.has(key)) continue;
- var mapItem=this.MapCache.get(key);
- if (!IFrameSplitOperator.IsNonEmptyArray(mapItem.Data)) continue;
- if (isMinute)
- {
- var x=this.ChartFrame.GetXFromIndex(j);
- }
- else
- {
- var left=xOffset;
- var right=xOffset+dataWidth;
- if (right>chartright) break;
- var x=left+(right-left)/2;
- }
- for(var k=0;k<mapItem.Data.length;++k)
- {
- var item=mapItem.Data[k];
- var y=top;
- if (item.Value=="TOP") y=top;
- else if (item.Value=="BOTTOM") y=bottom;
- else
- {
- var price=item.Value;
- if (IFrameSplitOperator.IsString(item.Value)) price=this.GetKValue(kItem,item.Value);
-
- y=this.ChartFrame.GetYFromData(price, false);
- }
-
- if (item.Color) this.Canvas.fillStyle = item.Color;
- else this.Canvas.fillStyle = this.Color;
- if (item.Font) this.Canvas.font = item.Font;
- else this.Canvas.font=this.Font;
- var textWidth=this.Canvas.measureText(item.Text).width;
- this.Canvas.textAlign='center';
- if (x+textWidth/2>=chartright)
- {
- this.Canvas.textAlign='right';
- x=chartright;
- }
- else if (x-textWidth/2<chartleft)
- {
- this.Canvas.textAlign = 'left';
- x=chartleft;
- }
-
- if (item.Baseline==1) this.Canvas.textBaseline='top';
- else if (item.Baseline==2) this.Canvas.textBaseline='bottom';
- else this.Canvas.textBaseline = 'middle';
- if (this.IsHScreen)
- {
- this.Canvas.save();
- this.Canvas.translate(y, x);
- this.Canvas.rotate(90 * Math.PI / 180);
- this.Canvas.fillText(item.Text,0,0);
- this.Canvas.restore();
- }
- else
- {
- if (IFrameSplitOperator.IsNumber(item.YMove)) y+=item.YMove;
- this.Canvas.fillText(item.Text, x, y);
- }
- if (item.Line)
- {
- var price=item.Line.KData=="H"? kItem.High:kItem.Low;
- var yPrice=this.ChartFrame.GetYFromData(price, false);
- var yText=y;
- if (Array.isArray(item.Line.Offset) && item.Line.Offset.length==2)
- {
- if (yText>yPrice) //文字在下方
- {
- yText-=item.Line.Offset[1];
- yPrice+=item.Line.Offset[0]
- }
- else if (yText<yPrice)
- {
- yText+=item.Line.Offset[1];
- yPrice-=item.Line.Offset[0]
- }
- }
- this.Canvas.save();
- if (item.Line.Dash) this.Canvas.setLineDash(item.Line.Dash); //虚线
- if (item.Line.Width>0) this.Canvas.lineWidth=item.Line.Width; //线宽
- this.Canvas.strokeStyle = item.Line.Color;
- this.Canvas.beginPath();
- if (this.IsHScreen)
- {
- this.Canvas.moveTo(yText, ToFixedPoint(x));
- this.Canvas.lineTo(yPrice,ToFixedPoint(x));
- }
- else
- {
- this.Canvas.moveTo(ToFixedPoint(x),yText);
- this.Canvas.lineTo(ToFixedPoint(x),yPrice);
- }
-
- this.Canvas.stroke();
- this.Canvas.restore();
- }
- }
- }
- }
- this.GetMaxMin = function ()
- {
- var range = { Min: null, Max: null };
- if (!this.Texts) return range;
- var xPointCount = this.ChartFrame.XPointCount;
- var start = this.Data.DataOffset;
- var end = start + xPointCount;
- for (var i in this.Texts)
- {
- var item = this.Texts[i];
- if (item.Index >= start && item.Index < end)
- {
- if (range.Max == null) range.Max = item.Value;
- else if (range.Max < item.Value) range.Max = item.Value;
- if (range.Min == null) range.Min = item.Value;
- else if (range.Min > item.Value) range.Min = item.Value;
- }
- }
- return range;
- }
- }
- // 多dom节点
- function ChartMultiHtmlDom()
- {
- this.newMethod=IChartPainting; //派生
- this.newMethod();
- delete this.newMethod;
- this.ClassName="ChartMultiHtmlDom";
- this.Texts=[]; //[ {Index:, Value:, Text: ] Text=dom内容
- this.IsHScreen=false; //是否横屏
- this.DrawCallback; //function(op, obj) op:1=开始 2=结束 3=绘制单个数据 4=销毁
- this.DrawItem=[];
- this.IsDestroy=false; //是否已销毁
- this.Draw=function()
- {
- this.DrawItem=[];
- if (this.DrawCallback) this.DrawCallback(1, {Self:this} );
- this.DrawDom();
-
- if (this.DrawCallback) this.DrawCallback(2, { Self:this, Draw:this.DrawItem } );
- }
- this.OnDestroy=function()
- {
- this.IsDestroy=true;
- if (this.DrawCallback) this.DrawCallback(4, { Self:this } );
- }
- this.DrawDom=function()
- {
- if (!this.IsShow || this.ChartFrame.IsMinSize) return;
- if (!this.Data || this.Data.length<=0) return;
- this.IsHScreen=(this.ChartFrame.IsHScreen===true);
- var xPointCount=this.ChartFrame.XPointCount;
- var offset=this.Data.DataOffset;
-
- for(var i in this.Texts)
- {
- var item=this.Texts[i];
- if (!item.Text) continue;
- if (!IFrameSplitOperator.IsNumber(item.Index)) continue;
- var index=item.Index-offset;
- var kItem=this.Data.Data[item.Index]; //K线数据
- var obj={ KData:kItem, Item:item, IsShow:false, Self:this };
- if (index>=0 && index<xPointCount)
- {
- var x=this.ChartFrame.GetXFromIndex(index);
- var y=this.ChartFrame.GetYFromData(item.Value);
- obj.X=x;
- obj.Y=y;
- obj.IsShow=true;
- }
- this.DrawItem.push(obj);
- if (this.DrawCallback) this.DrawCallback(3, obj);
- }
- }
- this.GetMaxMin=function()
- {
- var range={ Min:null, Max:null };
- var xPointCount=this.ChartFrame.XPointCount;
- var start=this.Data.DataOffset;
- var end=start+xPointCount;
- for(var i in this.Texts)
- {
- var item=this.Texts[i];
- if (!IFrameSplitOperator.IsNumber(item.Index)) continue;
- if (item.Index>=start && item.Index<end)
- {
- if (range.Max==null) range.Max=item.Value;
- else if (range.Max<item.Value) range.Max=item.Value;
- if (range.Min==null) range.Min=item.Value;
- else if (range.Min>item.Value) range.Min=item.Value;
- }
- }
- return range;
- }
- }
- // 线段集合 支持横屏
- function ChartMultiLine()
- {
- this.newMethod = IChartPainting; //派生
- this.newMethod();
- delete this.newMethod;
- this.ClassName="ChartMultiLine";
- this.Lines = []; // [ {Point:[ {Index, Value }, ], Color: }, ]
- this.IsHScreen = false;
- this.LineWidth=1;
- this.LineDash;
- //箭头配置
- this.ArrawAngle=35; //三角斜边一直线夹角
- this.ArrawLength=10; //三角斜边长度
- this.ArrawLineWidth=5; //箭头粗细
- this.Arrow={ Start:false, End:false }; //Start=是否绘制开始箭头 <- End=是否绘制结束箭头 ->
- this.Draw = function ()
- {
- if (!this.IsShow || this.ChartFrame.IsMinSize) return;
- if (!this.Data || this.Data.length <= 0) return;
- this.IsHScreen = (this.ChartFrame.IsHScreen === true);
- var xPointCount = this.ChartFrame.XPointCount;
- var offset = this.Data.DataOffset;
- var drawLines = [];
- var arrowLines=[];
- for (var i=0; i<this.Lines.length; ++i)
- {
- var line = this.Lines[i];
- var drawPoints = { Point: [], Color: line.Color };
- var drawArrowPoints={ Start:[], End:[] };
- if (line.BGColor) drawPoints.BGColor=line.BGColor;
- for (var j=0;j<line.Point.length; ++j)
- {
- var point = line.Point[j];
- if (!IFrameSplitOperator.IsNumber(point.Index)) continue;
- var index = point.Index - offset;
- if (index >= 0 && index < xPointCount)
- {
- var x = this.ChartFrame.GetXFromIndex(index);
- var y = this.ChartFrame.GetYFromData(point.Value);
- var pointItem={X:x, Y:y, End:false };
- drawPoints.Point.push({ X: x, Y: y });
- if (j==0 || j==1) drawArrowPoints.Start.push(pointItem); //起始点
- if (j==line.Point.length-1 || j==line.Point.length-2) drawArrowPoints.End.push(pointItem); //结束点
- }
- else
- {
- if (drawPoints.Point.length>0) drawPoints.Point[drawPoints.Point.length-1].End=true; //点断开
- }
- }
- if (drawPoints.Point.length >= 2)
- {
- drawLines.push(drawPoints);
- arrowLines.push(drawArrowPoints);
- }
- }
- this.Canvas.save();
- for (var i=0; i<drawLines.length; ++i)
- {
- if (this.LineDash) this.Canvas.setLineDash(this.LineDash);
- if (IFrameSplitOperator.IsPlusNumber(this.LineWidth)) this.Canvas.lineWidth=this.LineWidth;
- else this.Canvas.lineWidth=1;
- var item = drawLines[i];
- this.DrawLine(item, arrowLines[i]);
- }
- this.Canvas.restore();
- }
- this.DrawLine = function (line, arrow)
- {
- if (line.BGColor) //背景色
- {
- this.Canvas.fillStyle=line.BGColor;
- for(var i=0; i<line.Point.length; ++i)
- {
- var item=line.Point[i];
- if (i==0)
- {
- this.Canvas.beginPath();
- if (this.IsHScreen) this.Canvas.moveTo(item.Y,item.X);
- else this.Canvas.moveTo(item.X,item.Y);
- }
- else
- {
- if (this.IsHScreen) this.Canvas.lineTo(item.Y,item.X);
- else this.Canvas.lineTo(item.X,item.Y);
- }
- }
- this.Canvas.closePath();
- this.Canvas.fill();
- }
- this.Canvas.strokeStyle = line.Color;
- var drawCount=0;
- for (var i=0; i<line.Point.length; ++i)
- {
- var item = line.Point[i];
- if (drawCount==0)
- {
- this.Canvas.beginPath();
- if (this.IsHScreen) this.Canvas.moveTo(item.Y, item.X);
- else this.Canvas.moveTo(item.X, item.Y);
- ++drawCount;
- }
- else
- {
- if (this.IsHScreen) this.Canvas.lineTo(item.Y, item.X);
- else this.Canvas.lineTo(item.X, item.Y);
- ++drawCount;
- }
- if (item.End==true) //点断了 要重新画
- {
- if (drawCount>0) this.Canvas.stroke();
- drawCount=0;
- }
- }
- if (drawCount>0) this.Canvas.stroke();
- //绘制箭头
- if (arrow.End.length==2 && this.Arrow.End==true)
- this.DrawArrow(arrow.End[0],arrow.End[1]);
- if (arrow.Start.length==2 && this.Arrow.Start==true)
- this.DrawArrow(arrow.Start[1],arrow.Start[0]);
- }
- this.DrawArrow=function(ptStart,ptEnd)
- {
- //计算箭头
- var theta=this.ArrawAngle; //三角斜边一直线夹角
- var headlen=this.ArrawLength; //三角斜边长度
- var angle = Math.atan2(ptStart.Y - ptEnd.Y, ptStart.X - ptEnd.X) * 180 / Math.PI,
- angle1 = (angle + theta) * Math.PI / 180,
- angle2 = (angle - theta) * Math.PI / 180,
- topX = headlen * Math.cos(angle1),
- topY = headlen * Math.sin(angle1),
- botX = headlen * Math.cos(angle2),
- botY = headlen * Math.sin(angle2);
- this.Canvas.beginPath();
- var arrowX = ptEnd.X + topX;
- var arrowY = ptEnd.Y + topY;
- this.Canvas.moveTo(arrowX,arrowY);
- this.Canvas.lineTo(ptEnd.X, ptEnd.Y);
- arrowX = ptEnd.X + botX;
- arrowY = ptEnd.Y + botY;
- this.Canvas.lineTo(arrowX,arrowY);
- this.Canvas.setLineDash([]);
- this.Canvas.lineWidth=this.ArrawLineWidth;
- this.Canvas.stroke();
- }
- this.GetMaxMin = function ()
- {
- var range = { Min: null, Max: null };
- var xPointCount = this.ChartFrame.XPointCount;
- var start = this.Data.DataOffset;
- var end = start + xPointCount;
- for (var i in this.Lines)
- {
- var line = this.Lines[i];
- for (var j in line.Point)
- {
- var point = line.Point[j];
- if (point.Index >= start && point.Index < end)
- {
- if (range.Max == null) range.Max = point.Value;
- else if (range.Max < point.Value) range.Max = point.Value;
- if (range.Min == null) range.Min = point.Value;
- else if (range.Min > point.Value) range.Min = point.Value;
- }
- }
- }
- return range;
- }
- }
- // 多个点集合2.0 支持横屏
- function ChartMultiPoint()
- {
- this.newMethod=IChartPainting; //派生
- this.newMethod();
- delete this.newMethod;
-
- this.ClassName="ChartMultiPoint";
- this.PointGroup=[]; // [ {Point:[ { {Date, Time, Value } }, ], Color: }, ]
- this.IsHScreen=false;
- this.LineWidth=1;
- this.PointRadius=5;
- this.MapCache=null; //key=date/date-time value={ Data:[] }
- this.GetKValue=ChartData.GetKValue;
- this.GetItem=function(kItem)
- {
- if (!this.MapCache || this.MapCache.size<=0) return null;
- var key=this.BuildKey(kItem);
- if (!this.MapCache.has(key)) return null;
- return this.MapCache.get(key);
- }
- this.BuildCacheData=function()
- {
- var mapData=new Map();
- this.MapCache=mapData;
- if (!IFrameSplitOperator.IsNonEmptyArray(this.PointGroup)) return;
- for(var i=0; i<this.PointGroup.length; ++i)
- {
- var groupItem=this.PointGroup[i];
- if (!groupItem || !IFrameSplitOperator.IsNonEmptyArray(groupItem.Point)) continue;
- var clrConfig= { Color:groupItem.Color, BGColor:groupItem.BGColor, LineWidth:this.LineWidth, Radius:this.PointRadius, Name:groupItem.Name };
- if (IFrameSplitOperator.IsNumber(groupItem.PointRadius)) clrConfig.Radius=groupItem.PointRadius;
- if (IFrameSplitOperator.IsNumber(groupItem.LineWidth)) clrConfig.LineWidth=groupItem.LineWidth;
-
- for(var j=0; j<groupItem.Point.length; ++j)
- {
- var point=groupItem.Point[j];
- var key=this.BuildKey(point);
-
- var item={ Data:point, ColorConfig:clrConfig }
- if (mapData.has(key))
- {
- var mapItem=mapData.get(key);
- mapItem.Data.push(item);
- }
- else
- {
- mapData.set(key,{ Data:[item] });
- }
- }
- }
- }
- this.Draw=function()
- {
- if (!this.IsShow || this.ChartFrame.IsMinSize) return;
- if (!this.Data || !IFrameSplitOperator.IsNonEmptyArray(this.Data.Data)) return; //k线数据
- if (!IFrameSplitOperator.IsNonEmptyArray(this.PointGroup)) return;
- if (!this.MapCache || this.MapCache.size<=0) return;
- this.IsHScreen=(this.ChartFrame.IsHScreen===true);
- var xPointCount=this.ChartFrame.XPointCount;
- var dataWidth=this.ChartFrame.DataWidth;
- var distanceWidth=this.ChartFrame.DistanceWidth;
- var isMinute=this.IsMinuteFrame();
- var border=this.GetBorder();
- if (this.IsHScreen)
- {
- var xOffset=border.TopEx+distanceWidth/2.0+g_JSChartResource.FrameLeftMargin;
- var chartright=border.BottomEx;
- var chartLeft=border.TopEx;
- }
- else
- {
- var xOffset=border.LeftEx+distanceWidth/2.0+g_JSChartResource.FrameLeftMargin;
- var chartright=border.RightEx;
- var chartLeft=border.LeftEx;
- }
- //计算所有的点位置
- var mapPoint=new Map();
- for(var i=this.Data.DataOffset,j=0;i<this.Data.Data.length && j<xPointCount;++i,++j,xOffset+=(dataWidth+distanceWidth))
- {
- var kItem=this.Data.Data[i];
- var key=this.BuildKey(kItem);
- if (!this.MapCache.has(key)) continue;
- var mapItem=this.MapCache.get(key);
- if (!IFrameSplitOperator.IsNonEmptyArray(mapItem.Data)) continue;
- if (isMinute)
- {
- var x=this.ChartFrame.GetXFromIndex(j);
- }
- else
- {
- var left=xOffset;
- var right=xOffset+dataWidth;
- if (right>chartright) break;
- var x=left+(right-left)/2;
- }
- this.CalculateItem(mapItem, kItem, x, mapPoint);
- }
- if (mapPoint.size<=0) return;
- this.Canvas.save();
- this.DrawAllPoint(mapPoint);
- this.Canvas.restore();
- }
- this.CalculateItem=function(groupItem, kItem, x, mapPoint)
- {
- for(var i=0; i<groupItem.Data.length; ++i)
- {
- var item=groupItem.Data[i];
- var value=item.Data.Value;
- if (IFrameSplitOperator.IsString(item.Data.Value)) value=this.GetKValue(kItem,item.Data.Value);
- if (!IFrameSplitOperator.IsNumber(value)) continue;
- var y=this.ChartFrame.GetYFromData(value,false);
- var strConfig=JSON.stringify(item.ColorConfig);
- if (!mapPoint.has(strConfig)) mapPoint.set(strConfig, { AryPoint:[]});
- var mapItem=mapPoint.get(strConfig);
- mapItem.AryPoint.push({ X:x, Y:y, Data:item });
- }
- }
- this.DrawAllPoint=function(mapPoint)
- {
- for(var mapItem of mapPoint)
- {
- var aryPoint=mapItem[1].AryPoint;
- if (!IFrameSplitOperator.IsNonEmptyArray(aryPoint)) continue;
- var config=null;
- this.Canvas.beginPath();
- var count=0;
- for(var i=0;i<aryPoint.length;++i)
- {
- var item=aryPoint[i];
- if (!config) config=item.Data.ColorConfig;
- if (this.IsHScreen)
- {
- this.Canvas.moveTo(item.Y+config.Radius,item.X);
- this.Canvas.arc(item.Y,item.X,config.Radius,0,360,false);
- }
- else
- {
- this.Canvas.moveTo(item.X+config.Radius,item.Y);
- this.Canvas.arc(item.X,item.Y,config.Radius,0,360,false);
- }
-
- ++count;
- }
- if (count>0 && config)
- {
- if (config.BGColor)
- {
- this.Canvas.fillStyle=config.BGColor; //背景填充颜色
- this.Canvas.fill();
- }
- if (config.Color)
- {
- this.Canvas.lineWidth=config.LineWidth;
- this.Canvas.strokeStyle=config.Color;
- this.Canvas.stroke();
- }
- }
- }
- }
- this.GetMaxMin=function()
- {
- var range={ Min:null, Max:null };
- if(!this.Data || !IFrameSplitOperator.IsNonEmptyArray(this.Data.Data)) return range;
- if (!this.MapCache || this.MapCache.size<=0) return;
- var xPointCount=this.ChartFrame.XPointCount;
- for(var i=this.Data.DataOffset,j=0, k=0;i<this.Data.Data.length && j<xPointCount;++i,++j)
- {
- var kItem=this.Data.Data[i];
- var key=this.BuildKey(kItem);
- if (!this.MapCache.has(key)) continue;
- var mapItem=this.MapCache.get(key);
- if (!IFrameSplitOperator.IsNonEmptyArray(mapItem.Data)) continue;
- for(k=0;k<mapItem.Data.length;++k)
- {
- var item=mapItem.Data[k];
- var value=item.Data.Value;
- if (IFrameSplitOperator.IsString(item.Data.Value)) value=this.GetKValue(kItem,item.Data.Value);
- if (!IFrameSplitOperator.IsNumber(value)) continue;
- if (range.Max==null) range.Max=value;
- else if (range.Max<value) range.Max=value;
- if (range.Min==null) range.Min=value;
- else if (range.Min>value) range.Min=value;
- }
- }
- return range;
- }
- }
- // 柱子集合2.0 支持横屏
- function ChartMultiBar()
- {
- this.newMethod = IChartPainting; //派生
- this.newMethod();
- delete this.newMethod;
- this.Bars = []; // [ {Point:[ {Date, Time, Value, Value2 }, ], Color:, Width: , Type: 0 实心 1 空心 }, ]
- this.IsHScreen = false;
- this.MapCache=null; //key=date/date-time value={ Data:[] }
- this.GetKValue=ChartData.GetKValue;
- this.GetItem=function(kItem)
- {
- if (!this.MapCache || this.MapCache.size<=0) return null;
- var key=this.BuildKey(kItem);
- if (!this.MapCache.has(key)) return null;
- return this.MapCache.get(key);
- }
- this.BuildCacheData=function()
- {
- var mapData=new Map();
- this.MapCache=mapData;
- if (!IFrameSplitOperator.IsNonEmptyArray(this.Bars)) return;
- for(var i=0; i<this.Bars.length; ++i)
- {
- var groupItem=this.Bars[i];
- if (!groupItem || !IFrameSplitOperator.IsNonEmptyArray(groupItem.Point)) continue;
- var clrConfig= { Color:groupItem.Color, Width:5, Name:groupItem.Name, Type:0 };
- if (IFrameSplitOperator.IsNumber(groupItem.Width)) clrConfig.Width=groupItem.Width;
- if (IFrameSplitOperator.IsNumber(groupItem.Type)) clrConfig.Type=groupItem.Type;
- for(var j=0; j<groupItem.Point.length; ++j)
- {
- var point=groupItem.Point[j];
- var key=this.BuildKey(point);
-
- var item={ Data:point, ColorConfig:clrConfig }
- if (mapData.has(key))
- {
- var mapItem=mapData.get(key);
- mapItem.Data.push(item);
- }
- else
- {
- mapData.set(key,{ Data:[item] });
- }
- }
- }
- }
- this.Draw = function ()
- {
- if (!this.IsShow || this.ChartFrame.IsMinSize) return;
- if (!this.Data || !IFrameSplitOperator.IsNonEmptyArray(this.Data.Data)) return; //k线数据
- if (!IFrameSplitOperator.IsNonEmptyArray(this.Bars)) return;
- if (!this.MapCache || this.MapCache.size<=0) return;
- this.IsHScreen=(this.ChartFrame.IsHScreen===true);
- var xPointCount=this.ChartFrame.XPointCount;
- var dataWidth=this.ChartFrame.DataWidth;
- var distanceWidth=this.ChartFrame.DistanceWidth;
- var isMinute=this.IsMinuteFrame();
- var border=this.GetBorder();
- if (this.IsHScreen)
- {
- var xOffset=border.TopEx+distanceWidth/2.0+g_JSChartResource.FrameLeftMargin;
- var chartright=border.BottomEx;
- var chartLeft=border.TopEx;
- }
- else
- {
- var xOffset=border.LeftEx+distanceWidth/2.0+g_JSChartResource.FrameLeftMargin;
- var chartright=border.RightEx;
- var chartLeft=border.LeftEx;
- }
- //计算所有柱子位置
- var mapBar=new Map();
- for(var i=this.Data.DataOffset,j=0;i<this.Data.Data.length && j<xPointCount;++i,++j,xOffset+=(dataWidth+distanceWidth))
- {
- var kItem=this.Data.Data[i];
- var key=this.BuildKey(kItem);
- if (!this.MapCache.has(key)) continue;
- var mapItem=this.MapCache.get(key);
- if (!IFrameSplitOperator.IsNonEmptyArray(mapItem.Data)) continue;
- if (isMinute)
- {
- var x=this.ChartFrame.GetXFromIndex(j);
- }
- else
- {
- var left=xOffset;
- var right=xOffset+dataWidth;
- if (right>chartright) break;
- var x=left+(right-left)/2;
- }
- this.CalculateItem(mapItem, kItem, x, mapBar);
- }
- if (mapBar.size<=0) return;
- this.Canvas.save();
- this.ClipClient(this.IsHScreen);
- this.DrawAllBar(mapBar);
- this.Canvas.restore();
- }
- this.CalculateItem=function(groupItem, kItem, x, mapBar)
- {
- for(var i=0; i<groupItem.Data.length; ++i)
- {
- var item=groupItem.Data[i];
- var value=item.Data.Value;
- if (IFrameSplitOperator.IsString(item.Data.Value)) value=this.GetKValue(kItem,item.Data.Value);
- if (!IFrameSplitOperator.IsNumber(value)) continue;
- var value2=item.Data.Value2;
- if (IFrameSplitOperator.IsString(item.Data.Value2)) value2=this.GetKValue(kItem,item.Data.Value2);
- if (!IFrameSplitOperator.IsNumber(value2)) continue;
- var y=this.ChartFrame.GetYFromData(value, false);
- var y2=this.ChartFrame.GetYFromData(value2, false);
- var strConfig=JSON.stringify(item.ColorConfig);
- if (!mapBar.has(strConfig)) mapBar.set(strConfig, { AryBar:[]});
- var mapItem=mapBar.get(strConfig);
- mapItem.AryBar.push({ X:x, Y:y, Y2:y2, Data:item });
- }
- }
- this.DrawAllBar=function(mapBar)
- {
- var dataWidth=this.ChartFrame.DataWidth;
- for(var mapItem of mapBar)
- {
- var aryBar=mapItem[1].AryBar;
- if (!IFrameSplitOperator.IsNonEmptyArray(aryBar)) continue;
- var config=null;
- var count=0;
- var drawType=-1; //1=直线 2=实心 3=空心
- var barWidth=dataWidth;
- this.Canvas.beginPath();
- for(var i=0;i<aryBar.length;++i)
- {
- var item=aryBar[i];
- if (!config)
- {
- barWidth=dataWidth;
- config=item.Data.ColorConfig;
- if (IFrameSplitOperator.IsNumber(config.Width)) barWidth=config.Width;
- if (barWidth>4)
- {
- if (config.Type==0) drawType=2; //实心
- else if (config.Type==1) drawType=3; //空心
- else continue;
- }
- else //太细了, 直线
- {
- drawType=1;
- }
- }
- if (drawType<=0) continue;
- if (drawType==1)
- {
- if (this.IsHScreen)
- {
- this.Canvas.moveTo(ToFixedPoint(item.Y),ToFixedPoint(item.X));
- this.Canvas.lineTo(ToFixedPoint(item.Y2),ToFixedPoint(item.X));
- }
- else
- {
- this.Canvas.moveTo(ToFixedPoint(item.X),ToFixedPoint(item.Y));
- this.Canvas.lineTo(ToFixedPoint(item.X),ToFixedPoint(item.Y2));
- }
- ++count;
- }
- else if (drawType==2) //实心
- {
- var x=item.X-(barWidth/2);
- var y=Math.min(item.Y,item.Y2);
- var barWidth=barWidth;
- var barHeight=Math.abs(item.Y-item.Y2);
- if (this.IsHScreen)
- this.Canvas.rect(ToFixedRect(y),ToFixedRect(x),ToFixedRect(barHeight),ToFixedRect(barWidth))
- else
- this.Canvas.rect(ToFixedRect(x),ToFixedRect(y),ToFixedRect(barWidth),ToFixedRect(barHeight))
- ++count;
- }
- else if (drawType==3) //空心
- {
- var x=item.X-(barWidth/2);
- var y=Math.min(item.Y,item.Y2);
- var barWidth=barWidth;
- var barHeight=Math.abs(item.Y-item.Y2);
- if (this.IsHScreen)
- this.Canvas.rect(ToFixedPoint(y),ToFixedPoint(x),ToFixedPoint(barHeight),ToFixedPoint(barWidth))
- else
- this.Canvas.rect(ToFixedPoint(x),ToFixedPoint(y),ToFixedPoint(barWidth),ToFixedPoint(barHeight))
- ++count;
- }
- }
- if (count>0 && drawType>0 && config)
- {
- if (drawType==1)
- {
- this.Canvas.lineWidth=1;
- this.Canvas.strokeStyle=config.Color;
- this.Canvas.stroke();
- }
- else if (drawType==2)
- {
- this.Canvas.fillStyle=config.Color; //背景填充颜色
- this.Canvas.fill();
- }
- else if (drawType==3)
- {
- this.Canvas.lineWidth=1;
- this.Canvas.strokeStyle=config.Color;
- this.Canvas.stroke();
- }
- }
- }
- }
- this.GetMaxMin = function ()
- {
- var range={ Min:null, Max:null };
- if(!this.Data || !IFrameSplitOperator.IsNonEmptyArray(this.Data.Data)) return range;
- if (!this.MapCache || this.MapCache.size<=0) return range;
- var xPointCount=this.ChartFrame.XPointCount;
- for(var i=this.Data.DataOffset,j=0, k=0;i<this.Data.Data.length && j<xPointCount;++i,++j)
- {
- var kItem=this.Data.Data[i];
- var key=this.BuildKey(kItem);
- if (!this.MapCache.has(key)) continue;
- var mapItem=this.MapCache.get(key);
- if (!IFrameSplitOperator.IsNonEmptyArray(mapItem.Data)) continue;
- for(k=0;k<mapItem.Data.length;++k)
- {
- var item=mapItem.Data[k];
- var value=item.Data.Value;
- if (IFrameSplitOperator.IsString(item.Data.Value)) value=this.GetKValue(kItem,item.Data.Value);
- if (!IFrameSplitOperator.IsNumber(value)) continue;
- var value2=item.Data.Value2;
- if (IFrameSplitOperator.IsString(item.Data.Value2)) value2=this.GetKValue(kItem,item.Data.Value2);
- if (!IFrameSplitOperator.IsNumber(value2)) continue;
- var minValue=Math.min(value, value2);
- var maxValue=Math.max(value, value2);
- if (range.Max==null) range.Max=maxValue;
- else if (range.Max<maxValue) range.Max=maxValue;
- if (range.Min==null) range.Min=minValue;
- else if (range.Min>minValue) range.Min=minValue;
- }
- }
- return range;
- }
- }
- //分钟信息地雷 支持横屏
- function ChartMinuteInfo()
- {
- this.newMethod = IChartPainting; //派生
- this.newMethod();
- delete this.newMethod;
- this.ClassName = "ChartMinuteInfo";
- this.Data = new Map() //Map key=date-time, value=[{Date, Time, Title, Type, ID:}]
- this.SourceData;
- this.ChartMinutePrice;
- this.YClose;
- this.TextColor = g_JSChartResource.MinuteInfo.TextColor;
- this.Font = g_JSChartResource.MinuteInfo.Font;
- this.PointColor = g_JSChartResource.MinuteInfo.PointColor;
- this.PointRadius=g_JSChartResource.MinuteInfo.PointRadius;
- this.LineColor = g_JSChartResource.MinuteInfo.LineColor;
- this.TextBGColor = g_JSChartResource.MinuteInfo.TextBGColor;
- this.TextHeight = 18;
- this.TextRectCache = [];
- this.InfoDrawCache = [];
- this.FrameBottom;
- this.FrameTop;
- this.FrameLeft;
- this.FrameRight;
- this.YOffset = 5;
- this.IsHScreen = false;
- this.SetOption = function (option)
- {
- if (option.TextColor) this.TextColor = option.TextColor;
- if (option.TextBGColor) this.TextBGColor = option.TextBGColor;
- if (option.Font) this.Font = option.Font;
- if (option.PointColor) this.PointColor = option.PointColor;
- if (option.LineColor) this.LineColor = option.LineColor;
- if (option.TextHeight > 0) this.TextHeight = option.TextHeight;
- }
- this.Draw = function ()
- {
- if (!this.ChartMinutePrice) return;
- if (!this.Data || this.Data.size <= 0) return;
- this.TextRectCache = [];
- this.InfoDrawCache = [];
- this.IsHScreen = (this.ChartFrame.IsHScreen === true);
- var xPointCount = this.ChartFrame.XPointCount;
- var minuteCount = this.ChartFrame.MinuteCount;
- this.FrameBottom = this.ChartBorder.GetBottom();
- this.FrameTop = this.ChartBorder.GetTop();
- this.FrameLeft = this.ChartBorder.GetLeft();
- this.FrameRight = this.ChartBorder.GetRight();
- if (this.IsHScreen)
- {
- this.FrameRight = this.ChartBorder.GetBottom();
- this.FrameLeft = this.ChartBorder.GetTop();
- this.FrameBottom = this.ChartBorder.GetLeft();
- this.FrameTop = this.ChartBorder.GetRight();
- }
- this.YClose = this.ChartMinutePrice.YClose;
- var data = this.ChartMinutePrice.Data;
- var isBeforeData = false;
- if (this.ChartMinutePrice.SourceData)
- {
- data = this.ChartMinutePrice.SourceData;
- isBeforeData = true;
- }
- this.Canvas.font = this.Font;
- for (var i = data.DataOffset, j = 0; i < data.Data.length && j < xPointCount; ++i, ++j)
- {
- var item = this.SourceData.Data[i];
- if (isBeforeData && item.Before) continue;
- if (!item) continue;
- var dateTime = item.DateTime;
- if (!this.Data.has(dateTime)) continue;
- if (this.IsHScreen)
- this.CalcuateInfoHScreenPosition(this.Data.get(dateTime), j, item);
- else
- this.CalcuateInfoPosition(this.Data.get(dateTime), j, item);
- }
- for (var i in this.InfoDrawCache)
- {
- var item = this.InfoDrawCache[i];
- this.DrawInfoLines(item);
- }
- for (var i in this.InfoDrawCache)
- {
- var item = this.InfoDrawCache[i];
- this.DrawInfoText(item);
- }
- this.TextRectCache = [];
- this.InfoDrawCache = [];
- }
- this.CalcuateInfoPosition = function (infoItem, index, minuteItem)
- {
- if (!infoItem || !infoItem.Data || infoItem.Data.length <= 0) return;
- var showItem = infoItem.Data[0];
- var textWidth = this.Canvas.measureText(showItem.Title).width + 4;
- var textHeight = this.TextHeight;
- var x = this.ChartFrame.GetXFromIndex(index);
- var y = this.ChartFrame.GetYFromData(minuteItem.Close);
- x = ToFixedPoint(x);
- var isDrawLeft = x < (this.FrameLeft + Math.abs(this.FrameLeft - this.FrameRight) / 2);
- var ARRAY_OFFSET = [2, 4, 3, 2, 3, 3, 2];
- var offset = textHeight + ARRAY_OFFSET[index % ARRAY_OFFSET.length];
- var yData =
- {
- Y:
- [
- { Value: y + (textHeight + this.YOffset), Offset: offset },
- { Value: y - (2 * textHeight + this.YOffset), Offset: -offset }
- ]
- };
- if (minuteItem.Close < this.YClose)
- yData.Y = yData.Y.reverse();
- var rtBorder = { X: x, Y: null, Width: textWidth, Height: textHeight };
- if (!isDrawLeft) rtBorder.X -= rtBorder.Width;
- this.FixTextRect(rtBorder, yData);
- var InfoDrawItem = { Border: rtBorder, Start: { X: x, Y: y }, IsLeft: isDrawLeft, Title: showItem.Title };
- if (showItem.Content) InfoDrawItem.Content=showItem.Content;
- if (showItem.Link) InfoDrawItem.Link=showItem.Link;
- if (showItem.Color) InfoDrawItem.Color=showItem.Color;
- if (showItem.BGColor) InfoDrawItem.BGColor=showItem.BGColor;
- this.InfoDrawCache.push(InfoDrawItem);
- this.TextRectCache.push(rtBorder);
- }
- this.CalcuateInfoHScreenPosition = function (infoItem, index, minuteItem)
- {
- if (!infoItem || !infoItem.Data || infoItem.Data.length <= 0) return;
- var showItem = infoItem.Data[0];
- var textHeight = this.Canvas.measureText(showItem.Title).width + 4;
- var textWidth = this.TextHeight;
- var y = this.ChartFrame.GetXFromIndex(index);
- var x = this.ChartFrame.GetYFromData(minuteItem.Close);
- y = ToFixedPoint(y);
- var isDrawLeft = y < (this.FrameLeft + Math.abs(this.FrameLeft - this.FrameRight) / 2);
- var ARRAY_OFFSET = [2, 4, 3, 2, 3, 3, 2];
- var offset = textWidth + ARRAY_OFFSET[index % ARRAY_OFFSET.length];
- var xData =
- {
- X:
- [
- { Value: x + (textWidth + this.YOffset), Offset: offset },
- { Value: x - (2 * textWidth + this.YOffset), Offset: -offset }
- ]
- };
- if (minuteItem.Close > this.YClose)
- xData.X = xData.X.reverse();
- var rtBorder = { X: null, Y: y, Width: textWidth, Height: textHeight };
- if (!isDrawLeft) rtBorder.Y -= rtBorder.Height;
- this.FixHScreenTextRect(rtBorder, xData);
- var InfoDrawItem = { Border: rtBorder, Start: { X: x, Y: y }, IsLeft: isDrawLeft, Title: showItem.Title };
- if (showItem.Content) InfoDrawItem.Content=showItem.Content;
- if (showItem.Link) InfoDrawItem.Link=showItem.Link;
- if (showItem.Color) InfoDrawItem.Color=showItem.Color;
- if (showItem.BGColor) InfoDrawItem.BGColor=showItem.BGColor;
- this.InfoDrawCache.push(InfoDrawItem);
- this.TextRectCache.push(rtBorder);
- }
- this.DrawInfoLines = function (item)
- {
- var rtBorder = item.Border;
- var isDrawLeft = item.IsLeft;
- this.Canvas.strokeStyle = this.LineColor;
- this.Canvas.beginPath();
- this.Canvas.moveTo(item.Start.X, item.Start.Y);
- if (isDrawLeft)
- {
- this.Canvas.lineTo(rtBorder.X, rtBorder.Y);
- }
- else
- {
- if (this.IsHScreen) this.Canvas.lineTo(rtBorder.X, rtBorder.Y + rtBorder.Height);
- else this.Canvas.lineTo(rtBorder.X + rtBorder.Width, rtBorder.Y);
- }
- this.Canvas.stroke();
- this.Canvas.fillStyle = this.PointColor;
- this.Canvas.beginPath();
- this.Canvas.arc(item.Start.X, item.Start.Y, this.PointRadius, 0, 2 * Math.PI);
- this.Canvas.closePath();
- this.Canvas.fill();
- }
- this.DrawInfoText = function (item)
- {
- var rtBorder = item.Border;
- var x = rtBorder.X, y = rtBorder.Y;
- if (item.BGColor) this.Canvas.fillStyle=item.BGColor
- else this.Canvas.fillStyle = this.TextBGColor;
- this.Canvas.fillRect(x, y, rtBorder.Width, rtBorder.Height);
- this.Canvas.strokeStyle = this.LineColor;
- this.Canvas.beginPath();
- this.Canvas.rect(x, y, rtBorder.Width, rtBorder.Height);
- this.Canvas.stroke();
- if (this.IsHScreen)
- {
- this.Canvas.save();
- this.Canvas.translate(rtBorder.X, rtBorder.Y);
- this.Canvas.rotate(90 * Math.PI / 180);
- x = 0; y = 0;
- }
- this.Canvas.textAlign = 'left'
- this.Canvas.textBaseline = 'middle';
- if (item.Color) this.Canvas.fillStyle=item.Color;
- else this.Canvas.fillStyle = this.TextColor;
- this.Canvas.font = this.Font;
- if (this.IsHScreen) this.Canvas.fillText(item.Title, x + 2, y - rtBorder.Width / 2);
- else this.Canvas.fillText(item.Title, x+2, y + rtBorder.Height / 2);
- if (this.IsHScreen) this.Canvas.restore();
- }
- this.FixTextRect = function (rect, yData)
- {
- for (var k in yData.Y)
- {
- var yItem = yData.Y[k];
- rect.Y = yItem.Value;
- var y;
- for (var j = 0; j < 10; ++j)
- {
- var isOverlap = false;
- for (var i in this.TextRectCache)
- {
- var item = this.TextRectCache[i];
- if (this.IsOverlap(item, rect))
- {
- isOverlap = true;
- break;
- }
- }
- if (isOverlap == false) return;
- y = rect.Y;
- y += yItem.Offset;
- if (y + rect.Height > this.FrameBottom || y < this.FrameTop) break;
- rect.Y = y;
- }
- }
- }
- this.FixHScreenTextRect = function (rect, xData)
- {
- for (var k in xData.X)
- {
- var xItem = xData.X[k];
- rect.X = xItem.Value;
- var x;
- for (var j = 0; j < 10; ++j)
- {
- var isOverlap = false;
- for (var i in this.TextRectCache)
- {
- var item = this.TextRectCache[i];
- if (this.IsOverlap(item, rect))
- {
- isOverlap = true;
- break;
- }
- }
- if (isOverlap == false) return;
- x = rect.X;
- x += xItem.Offset;
- if (x + rect.Width < this.FrameBottom || x > this.FrameTop) break;
- rect.X = x;
- }
- }
- }
- this.IsOverlap = function (rc1, rc2)
- {
- 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)
- return true;
- else
- return false;
- }
- this.GetMaxMin = function ()
- {
- var range = { Min: null, Max: null };
- return range;
- }
- }
- //买卖盘
- function ChartBuySell()
- {
- this.newMethod = ChartSingleText; //派生
- this.newMethod();
- delete this.newMethod;
- this.ClassName = "ChartBuySell";
- this.TextFont = g_JSChartResource.KLineTrain.Font; //"bold 14px arial"; //买卖信息字体
- this.LastDataIcon = g_JSChartResource.KLineTrain.LastDataIcon; //{Color:'rgb(0,0,205)',Text:'↓'};
- this.BuyIcon = g_JSChartResource.KLineTrain.BuyIcon; //{Color:'rgb(0,0,205)',Text:'B'};
- this.SellIcon = g_JSChartResource.KLineTrain.SellIcon; //{Color:'rgb(0,0,205)',Text:'S'};
- this.BuySellData = new Map(); //Key=数据索引index Value:Data:[ { Op: 买/卖 0=buy 1=sell, Date:, Time, Price: Vol:}, ]
- this.LastDataDrawType=0; //0=画在最后一个数据上 1=画在指定索引上
- this.LastDataIndex=-1;
- this.AddTradeItem = function (tradeItem)
- {
- if (this.BuySellData.has(tradeItem.Key))
- {
- var Trade = this.BuySellData.get(tradeItem.Key);
- Trade.Data.push(tradeItem);
- }
- else
- {
- this.BuySellData.set(tradeItem.Key, { Data: [tradeItem] });
- }
- }
- this.ClearTradeData = function ()
- {
- this.BuySellData = new Map();
- }
- this.Draw = function ()
- {
- if (!this.Data || !this.Data.Data) return;
- var isHScreen = (this.ChartFrame.IsHScreen === true);
- var dataWidth = this.ChartFrame.DataWidth;
- var distanceWidth = this.ChartFrame.DistanceWidth;
- var chartright = this.ChartBorder.GetRight();
- if (isHScreen === true) chartright = this.ChartBorder.GetBottom();
- var xPointCount = this.ChartFrame.XPointCount;
- var bottom = this.ChartBorder.GetBottomEx();
- var top = this.ChartBorder.GetTopEx();
- var height = this.ChartBorder.GetHeightEx();
- if (isHScreen)
- {
- top = this.ChartBorder.GetRightEx();
- bottom = this.ChartBorder.GetLeftEx();
- height = this.ChartBorder.GetWidthEx();
- }
- this.Canvas.font = this.TextFont;
- for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j)
- {
- var value = this.Data.Data[i];
- if (value == null) continue;
- if (x > chartright) break;
- var bDrawLastData=false;
- if (this.LastDataDrawType==1)
- {
- if (i==this.LastDataIndex) bDrawLastData=true;
- }
- else
- {
- if (i==this.Data.Data.length-1) bDrawLastData=true;
- }
- if (bDrawLastData)
- {
- var x = this.ChartFrame.GetXFromIndex(j);
- var yHigh = this.ChartFrame.GetYFromData(value.High);
- if (this.LastDataIcon.Text)
- {
- this.Canvas.textAlign = 'center';
- this.Canvas.textBaseline = 'bottom';
- this.Canvas.fillStyle = this.LastDataIcon.Color;
- this.Canvas.font = this.TextFont;
- this.DrawText(this.LastDataIcon.Text, x, yHigh, isHScreen);
- }
- else
- {
- var obj =
- {
- X: x, Top: top, Bottom: bottom, Height: height,
- DataWidth: dataWidth, Color: this.LastDataIcon.Color, IsHScreen: isHScreen,
- };
- this.DrawLastData(obj);
- }
- }
- var key = i;
- if (!this.BuySellData.has(key)) continue;
- var trade = this.BuySellData.get(key);
- var x = this.ChartFrame.GetXFromIndex(j);
- var yHigh = this.ChartFrame.GetYFromData(value.High);
- var yLow = this.ChartFrame.GetYFromData(value.Low);
- var drawInfo = [false, false]; //0=buy 1=sell
- for (var k in trade.Data)
- {
- if (drawInfo[0] == true && drawInfo[1] == true) break; //买卖图标只画一次
- var bsItem = trade.Data[k];
- if (bsItem.Op == 0 && drawInfo[0] == false) //买 标识在最低价上
- {
- this.Canvas.textAlign = 'center';
- this.Canvas.textBaseline = 'top';
- this.Canvas.fillStyle = this.BuyIcon.Color;
- this.DrawText(this.BuyIcon.Text, x, yLow, isHScreen);
- drawInfo[0] = true;
- }
- else if (bsItem.Op == 1 && drawInfo[1] == false) //卖 标识在最高价上
- {
- this.Canvas.textAlign = 'center';
- this.Canvas.textBaseline = 'bottom';
- this.Canvas.fillStyle = this.SellIcon.Color;
- this.DrawText(this.SellIcon.Text, x, yHigh, isHScreen);
- drawInfo[1] = true;
- }
- }
- }
- }
- this.DrawLastData=function(obj)
- {
- this.Canvas.fillStyle = obj.Color;
- var width = obj.DataWidth;
- if (this.LastDataIcon.Width >= 2 && this.LastDataIcon.Width < obj.DataWidth)
- width = this.LastDataIcon.Width;
- var left = obj.X - width / 2;
- if (obj.IsHScreen)
- {
- this.Canvas.fillRect(ToFixedRect(obj.Bottom), ToFixedRect(left), ToFixedRect(obj.Height), ToFixedRect(width));
- }
- else
- {
- var left = obj.X - width/2;
- this.Canvas.fillRect(ToFixedRect(left), ToFixedRect(obj.Top), ToFixedRect(width), ToFixedRect(obj.Height));
- }
- }
- }
- //分钟成交量
- function ChartMinuteVolumBar()
- {
- this.newMethod = IChartPainting; //派生
- this.newMethod();
- delete this.newMethod;
-
- this.UpColor = g_JSChartResource.UpBarColor;
- this.DownColor = g_JSChartResource.DownBarColor;
- this.UnchangeColor=g_JSChartResource.UnchagneBarColor; //平盘
- this.BarColorType=1; //柱子颜色显示类型 0=红绿 1=红绿白
- this.CustomColor=g_JSChartResource.Minute.VolBarColor;
- this.YClose; //前收盘
- this.Symbol;
- this.GetVolUnit=function()
- {
- var upperSymbol=this.Symbol?this.Symbol.toUpperCase():null;
- var unit=MARKET_SUFFIX_NAME.GetVolUnit(upperSymbol);
- return unit;
- }
- this.Draw = function ()
- {
- var isHScreen = (this.ChartFrame.IsHScreen === true)
- var chartright = this.ChartBorder.GetRight();
- if (isHScreen) chartright = this.ChartBorder.GetBottom();
- var xPointCount = this.ChartFrame.XPointCount;
- var yBottom = this.ChartFrame.GetYFromData(0);
- var yPrice = this.YClose; //上一分钟的价格
- var unit=this.GetVolUnit();
- if (this.CustomColor) this.Canvas.strokeStyle=this.CustomColor;
- for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j)
- {
- var item = this.Data.Data[i];
- if (!item || !item.Vol) continue;
-
- var y = this.ChartFrame.GetYFromData(item.Vol/unit);
- var x = this.ChartFrame.GetXFromIndex(i);
- if (x > chartright) break;
- //价格>=上一分钟价格 红色 否则绿色
- if (!this.CustomColor) this.Canvas.strokeStyle = this.GetMinuteBarColor(item.Close, yPrice);
- this.Canvas.beginPath();
- if (isHScreen)
- {
- this.Canvas.moveTo(y, ToFixedPoint(x));
- this.Canvas.lineTo(yBottom, ToFixedPoint(x));
- }
- else
- {
- this.Canvas.moveTo(ToFixedPoint(x), y);
- this.Canvas.lineTo(ToFixedPoint(x), yBottom);
- }
- this.Canvas.stroke();
- yPrice = item.Close;
- }
- }
- //连续交易成交量柱子颜色
- this.GetMinuteBarColor=function(price, yPrice)
- {
- if (this.BarColorType==1) //通达信模式
- {
- if (price>yPrice) return this.UpColor;
- else if (price<yPrice) return this.DownColor;
- else return this.UnchangeColor;
- }
- else //东方财富模式
- {
- return price >= yPrice ? this.UpColor:this.DownColor;
- }
- }
-
- this.GetMaxMin = function ()
- {
- var unit=this.GetVolUnit();
- var xPointCount = this.ChartFrame.XPointCount;
- var range = {};
- range.Min = 0;
- range.Max = null;
- for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j)
- {
- var item = this.Data.Data[i];
- if (!item || !item.Vol) continue;
- var value=item.Vol/unit;
- if (range.Max == null || range.Max < value) range.Max = value;
- }
-
- return range;
- }
- }
- //MACD森林线 支持横屏
- function ChartMACD()
- {
- this.newMethod = IChartPainting; //派生
- this.newMethod();
- delete this.newMethod;
- this.ClassName ='ChartMACD';
- this.UpColor = g_JSChartResource.UpBarColor;
- this.DownColor = g_JSChartResource.DownBarColor;
- this.LineWidth=1;
- this.Draw = function ()
- {
- if (this.ChartFrame.IsMinSize || !this.IsVisible) return;
- if (this.IsHideScriptIndex()) return;
- if (this.NotSupportMessage)
- {
- this.DrawNotSupportmessage();
- return;
- }
- if (this.ChartFrame.IsHScreen === true)
- {
- this.HScreenDraw();
- return;
- }
- var isMinute=this.IsMinuteFrame();
- var dataWidth = this.ChartFrame.DataWidth;
- var distanceWidth = this.ChartFrame.DistanceWidth;
- var xOffset=this.ChartBorder.GetLeft()+distanceWidth/2.0+g_JSChartResource.FrameLeftMargin;
- var chartright = this.ChartBorder.GetRight();
- var xPointCount = this.ChartFrame.XPointCount;
- var lineWidth=this.LineWidth;
- if (this.LineWidth==50) lineWidth=dataWidth;
- else if (lineWidth>dataWidth) lineWidth=dataWidth;
- this.Canvas.save();
- this.Canvas.lineWidth=lineWidth;
- var bFirstPoint = true;
- var drawCount = 0;
- var yBottom = this.ChartFrame.GetYFromData(0);
- for(var i=this.Data.DataOffset,j=0;i<this.Data.Data.length && j<xPointCount;++i,++j,xOffset+=(dataWidth+distanceWidth))
- //for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j)
- {
- var value = this.Data.Data[i];
- if (value == null) continue;
- if (isMinute)
- {
- var x = this.ChartFrame.GetXFromIndex(j);
- }
- else
- {
- var left=xOffset;
- var right=xOffset+dataWidth;
- if (right>chartright) break;
- var x=left+(right-left)/2;
- }
- var y = this.ChartFrame.GetYFromData(value);
- if (x > chartright) break;
- var xFix = parseInt(x.toString()) + 0.5; //毛边修正
- this.Canvas.beginPath();
- this.Canvas.moveTo(xFix, yBottom);
- this.Canvas.lineTo(xFix, y);
- if (value >= 0) this.Canvas.strokeStyle = this.UpColor;
- else this.Canvas.strokeStyle = this.DownColor;
- this.Canvas.stroke();
- this.Canvas.closePath();
- }
- this.Canvas.restore();
- }
- this.HScreenDraw = function ()
- {
- var isMinute=this.IsMinuteFrame();
- var dataWidth = this.ChartFrame.DataWidth;
- var distanceWidth = this.ChartFrame.DistanceWidth;
- var xOffset=this.ChartBorder.GetTop()+distanceWidth/2.0+g_JSChartResource.FrameLeftMargin;
- var chartright = this.ChartBorder.GetBottom();
- var xPointCount = this.ChartFrame.XPointCount;
- var yBottom = this.ChartFrame.GetYFromData(0);
- var lineWidth=this.LineWidth;
- if (this.LineWidth==50) lineWidth=dataWidth;
- else if (lineWidth>dataWidth) lineWidth=dataWidth;
- this.Canvas.save();
- this.Canvas.lineWidth=lineWidth;
- for(var i=this.Data.DataOffset,j=0;i<this.Data.Data.length && j<xPointCount;++i,++j,xOffset+=(dataWidth+distanceWidth))
- //for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j)
- {
- var value = this.Data.Data[i];
- if (value == null) continue;
- if (isMinute)
- {
- var x = this.ChartFrame.GetXFromIndex(j);
- }
- else
- {
- var left=xOffset;
- var right=xOffset+dataWidth;
- if (right>chartright) break;
- var x=left+(right-left)/2;
- }
- var y = this.ChartFrame.GetYFromData(value);
- if (x > chartright) break;
- this.Canvas.beginPath();
- this.Canvas.moveTo(yBottom, ToFixedPoint(x));
- this.Canvas.lineTo(y, ToFixedPoint(x));
- if (value >= 0) this.Canvas.strokeStyle = this.UpColor;
- else this.Canvas.strokeStyle = this.DownColor;
- this.Canvas.stroke();
- this.Canvas.closePath();
- }
- this.Canvas.restore();
- }
- }
- //堆积柱状图
- function ChartStackedBar()
- {
- this.newMethod=IChartPainting; //派生
- this.newMethod();
- delete this.newMethod;
- this.ClassName="ChartStackedBar";
- this.Data; //{ Data:[ [bar1, bar2], [bar1,bar2 ] ] };
- this.BarName=[];
- this.BarColor=['rgb(255,165,0)',"rgb(95,158,160)"];
- this.LineWidth=1;
- this.BarType=0; //0=线段 1=K线宽度一致
- this.IsHScreen;
- this.Draw=function()
- {
- if (!this.IsShow || this.ChartFrame.IsMinSize) return;
- if (!this.Data || !IFrameSplitOperator.IsNonEmptyArray(this.Data.Data)) return;
- this.IsHScreen=(this.ChartFrame.IsHScreen===true);
-
- var dataWidth=this.ChartFrame.DataWidth;
- var distanceWidth=this.ChartFrame.DistanceWidth;
- var xPointCount=this.ChartFrame.XPointCount;
- if (this.IsHScreen)
- {
- var border=this.ChartBorder.GetHScreenBorder();
- var xOffset=border.TopEx+distanceWidth/2.0+g_JSChartResource.FrameLeftMargin;
- var chartright=border.BottomEx;
- var top=border.RightEx;
- var bottom=border.LeftEx;
- }
- else
- {
- var border=this.ChartFrame.GetBorder();
- var xOffset=border.LeftEx+distanceWidth/2.0+g_JSChartResource.FrameLeftMargin;
- var chartright=border.RightEx;
- var top=border.TopEx;
- var bottom=border.BottomEx;
- }
- var isMinute=this.IsMinuteFrame();
-
- this.Canvas.save();
- if (this.BarType==1)
- {
-
- }
- else
- {
- if (this.LineWidth>0) this.Canvas.lineWidth=this.LineWidth;
- var lineWidth=this.Canvas.lineWidth;
- }
- var yZero=this.ChartFrame.GetYFromData(0);
- for(var i=this.Data.DataOffset,j=0;i<this.Data.Data.length && j<xPointCount;++i,++j,xOffset+=(dataWidth+distanceWidth))
- {
- var bars=this.Data.Data[i];
- if (!IFrameSplitOperator.IsNonEmptyArray(bars)) continue;
- if (isMinute)
- {
- var x=this.ChartFrame.GetXFromIndex(j);
- }
- else
- {
- var left=xOffset;
- var right=xOffset+dataWidth;
- if (right>chartright) break;
- var x=left+(right-left)/2;
- }
- if (x>chartright) break;
- if (this.BarType==1)
- {
- if (dataWidth>=4) //柱子太细就直接画竖线
- this.DrawKBarItem(bars, x, left, right, top, bottom, yZero, dataWidth);
- else
- this.DrawBarItem(bars, x, top, bottom, yZero, lineWidth);
- }
- else
- {
- this.DrawBarItem(bars, x, top, bottom, yZero, lineWidth);
- }
-
- }
-
- this.Canvas.restore();
- }
- this.DrawKBarItem=function(aryBar, x, left, right, top, bottom,yZero, barWidth)
- {
- var plusValue=0, yPlus=yZero; //正数
- var negativeValue=0, yNegative= yZero; //负数
- for(var i=0;i<aryBar.length;++i)
- {
- var item=aryBar[i];
- if (!IFrameSplitOperator.IsNumber(item)) continue;
- if(item==0) continue;
- this.Canvas.fillStyle=this.BarColor[i];
- if (item>0)
- {
- plusValue+=item;
- var y=this.ChartFrame.GetYFromData(plusValue);
- var rtBar={Left: left, Top:y, Width:barWidth, Height:(yPlus-y)};
- yPlus=y;
- }
- else
- {
- negativeValue+=item;
- var y=this.ChartFrame.GetYFromData(negativeValue);
- var rtBar={Left:left, Top:y, Width:barWidth, Height:(yNegative-y)};
- yNegative=y;
- }
- if (this.IsHScreen)
- this.Canvas.fillRect(rtBar.Top,rtBar.Left, rtBar.Height, rtBar.Width);
- else
- this.Canvas.fillRect(rtBar.Left, rtBar.Top, rtBar.Width, rtBar.Height);
- }
- }
- this.DrawBarItem=function(aryBar,x, top, bottom, yZero, lineWidth)
- {
- var x=ToFixedPoint(x);
- var plusValue=0, yPlus=yZero; //正数
- var negativeValue=0, yNegative=yZero; //负数
- for(var i=0;i<aryBar.length;++i)
- {
- var item=aryBar[i];
- if (!IFrameSplitOperator.IsNumber(item)) continue;
- if(item==0) continue;
- var line={};
- if (item>0)
- {
- plusValue+=item;
- var y=this.ChartFrame.GetYFromData(plusValue);
- var line={X:x, Y:yPlus, X2:x, Y2:y};
- yPlus=y;
- }
- else
- {
- negativeValue+=item;
- var y=this.ChartFrame.GetYFromData(negativeValue);
- var line={X:x, Y:yNegative, X2:x, Y2:y};
- yNegative=y;
- }
- this.Canvas.beginPath();
- if (this.IsHScreen)
- {
- this.Canvas.moveTo(line.Y,line.X);
- this.Canvas.lineTo(line.Y2,line.X2);
- }
- else
- {
- this.Canvas.moveTo(line.X,line.Y);
- this.Canvas.lineTo(line.X2,line.Y2);
- }
-
- this.Canvas.strokeStyle=this.BarColor[i];
- this.Canvas.stroke();
- }
- }
- this.GetMaxMin=function()
- {
- var xPointCount=this.ChartFrame.XPointCount;
- var range={};
- range.Min=null;
- range.Max=null;
- if(!this.Data || !this.Data.Data) return range;
- for(var i=this.Data.DataOffset,j=0;i<this.Data.Data.length && j<xPointCount;++i,++j)
- {
- var bars=this.Data.Data[i];
- if (!bars || !IFrameSplitOperator.IsNonEmptyArray(bars)) continue;
- var plusValue=0; //正数
- var negativeValue=0; //负数
- for(var k=0;k<bars.length;++k)
- {
- var barValue=bars[k];
- if (!IFrameSplitOperator.IsNumber(barValue)) continue;
- if (barValue==0) continue;
- if (barValue>0) plusValue+=barValue;
- else if (barValue<0) negativeValue+=barValue;
- }
- if (range.Max==null)
- {
- range.Max=plusValue;
- range.Min=negativeValue;
- }
- if (range.Max<plusValue) range.Max=plusValue;
- if (range.Min>negativeValue) range.Min=negativeValue;
- }
- return range;
- }
-
- }
- function ChartStepLine()
- {
- this.newMethod=IChartPainting; //派生
- this.newMethod();
- delete this.newMethod;
- this.ClassName='ChartStepLine'; //类名
- this.LineWidth=1; //线段宽度
- this.DotLine;
- this.IsHScreen;
- this.IsDotLine=false; //虚线
- this.Draw=function()
- {
- if (!this.IsShow || this.ChartFrame.IsMinSize) return;
- if (this.NotSupportMessage)
- {
- this.DrawNotSupportmessage();
- return;
- }
- if (!this.Data || !this.Data.Data) return;
- this.IsHScreen=(this.ChartFrame.IsHScreen===true);
- this.Canvas.save();
- this.DrawLine();
- this.Canvas.restore();
- }
- this.DrawLine=function()
- {
- var isMinute=this.IsMinuteFrame();
- var dataWidth=this.ChartFrame.DataWidth;
- var distanceWidth=this.ChartFrame.DistanceWidth;
- var xPointCount=this.ChartFrame.XPointCount;
- var lockRect=this.GetLockRect();
- if (this.IsHScreen)
- {
- var border=this.ChartBorder.GetHScreenBorder();
- var chartright=border.BottomEx;
- var xOffset=border.TopEx+distanceWidth/2.0+g_JSChartResource.FrameLeftMargin;
- if (lockRect) chartright=lockRect.Top;
- }
- else
- {
- var border=this.ChartBorder.GetBorder();
- var xOffset=border.LeftEx+distanceWidth/2.0+g_JSChartResource.FrameLeftMargin;
- var chartright=border.RightEx;
- if (lockRect) chartright=lockRect.Left;
- }
- if (this.LineWidth>0) this.Canvas.lineWidth=this.LineWidth;
- if (this.IsDotLine) this.Canvas.setLineDash(g_JSChartResource.DOTLINE.LineDash); //画虚线
- if (this.DotLine) this.Canvas.setLineDash(this.DotLine); //画虚线
- this.Canvas.strokeStyle=this.Color;
- var bFirstPoint=true;
- var drawCount=0;
- var prePoint={ X:null, Y:null };
- for(var i=this.Data.DataOffset; i>=0; --i)
- {
- var value=this.Data.Data[i];
- if (!IFrameSplitOperator.IsNumber(value)) continue;
- var y=this.GetYFromData(value,false);
- var x=null;
-
- if (isMinute) x=this.ChartFrame.GetXFromIndex(0);
- else x=xOffset;
- this.Canvas.beginPath();
- if (this.IsHScreen) this.Canvas.moveTo(y,x); //横屏坐标轴对调
- else this.Canvas.moveTo(x,y);
- bFirstPoint=false;
- prePoint.Y=y;
- prePoint.X=x;
- }
- for(var i=this.Data.DataOffset,j=0;i<this.Data.Data.length && j<xPointCount;++i,++j,xOffset+=(dataWidth+distanceWidth))
- {
- if (isMinute)
- {
- var x=this.ChartFrame.GetXFromIndex(j);
- }
- else
- {
- var left=xOffset;
- var right=xOffset+dataWidth;
- if (right>chartright) break;
- var x=left+(right-left)/2;
- }
- if (x>chartright) break;
- var value=this.Data.Data[i];
- if (!IFrameSplitOperator.IsNumber(value)) continue;
- var y=this.GetYFromData(value,false);
- if (bFirstPoint)
- {
- this.Canvas.beginPath();
- if (this.IsHScreen) this.Canvas.moveTo(y,x); //横屏坐标轴对调
- else this.Canvas.moveTo(x,y);
- bFirstPoint=false;
- prePoint.X=x;
- prePoint.Y=y;
- }
- else
- {
- if (this.IsHScreen)
- {
- this.Canvas.lineTo(prePoint.Y,x)
- this.Canvas.lineTo(y,x);
- }
- else
- {
- this.Canvas.lineTo(x,prePoint.Y)
- this.Canvas.lineTo(x,y);
- }
- prePoint.X=x;
- prePoint.Y=y;
- }
- ++drawCount;
- }
- if (drawCount>0) this.Canvas.stroke();
- }
- }
- ////////////////////////////////////////////////////////////////////////////////
- // 等待提示
- function ChartSplashPaint()
- {
- this.newMethod = IChartPainting; //派生
- this.newMethod();
- delete this.newMethod;
-
- this.Font = g_JSChartResource.DefaultTextFont; //字体
- this.TextColor = g_JSChartResource.DefaultTextColor; //文本颜色
- this.IsEnableSplash = false;
- this.SplashTitle = '数据加载中.....';
- this.HQChart;
- this.EnableSplash=function(bEnable)
- {
- this.IsEnableSplash=bEnable;
- if (this.HQChart)
- {
- var event=this.HQChart.GetEnableSplashEvent();
- if (event)
- {
- var data={ Enable:bEnable };
- event.Callback(event,data,this);
- }
- }
- }
- this.SetTitle=function(title)
- {
- this.SplashTitle=title;
- }
-
- this.Draw = function ()
- {
- if (!this.IsEnableSplash) return;
-
- if (this.Frame.IsHScreen === true)
- {
- this.HScreenDraw();
- return;
- }
-
- var xCenter = (this.Frame.ChartBorder.GetLeft() + this.Frame.ChartBorder.GetRight()) / 2;
- var yCenter = (this.Frame.ChartBorder.GetTop() + this.Frame.ChartBorder.GetBottom()) / 2;
- this.Canvas.textAlign = 'center';
- this.Canvas.textBaseline = 'middle';
- this.Canvas.fillStyle = this.TextColor;
- this.Canvas.font = this.Font;
- this.Canvas.fillText(this.SplashTitle, xCenter, yCenter);
- }
-
- this.HScreenDraw = function () //横屏
- {
- var xCenter = (this.Frame.ChartBorder.GetLeft() + this.Frame.ChartBorder.GetRight()) / 2;
- var yCenter = (this.Frame.ChartBorder.GetTop() + this.Frame.ChartBorder.GetBottom()) / 2;
-
- this.Canvas.save();
- this.Canvas.translate(xCenter, yCenter);
- this.Canvas.rotate(90 * Math.PI / 180); //数据和框子旋转180度
-
- this.Canvas.textAlign = 'center';
- this.Canvas.textBaseline = 'middle';
- this.Canvas.fillStyle = this.TextColor;
- this.Canvas.font = this.Font;
- this.Canvas.fillText(this.SplashTitle, 0, 0);
-
- this.Canvas.restore();
- }
- }
- //填充背景 支持横屏
- function ChartBackground()
- {
- this.newMethod=IChartPainting; //派生
- this.newMethod();
- delete this.newMethod;
- this.ClassName="ChartBackground";
- this.Color=null;
- this.ColorAngle=0; //0 竖向 1 横向
- this.IsDrawFirst = true; //面积图在K线前面画,否则回挡住K线的
- this.IsHScreen=false;
- this.Draw=function()
- {
- if (!this.IsShow || this.ChartFrame.IsMinSize) return;
- if (!this.Color) return;
- if (this.Color.length<=0) return;
- this.IsHScreen=(this.ChartFrame.IsHScreen===true);
- if (this.Color.length==2)
- {
- if (this.IsHScreen)
- {
- if (this.ColorAngle==0)
- {
- var ptStart={ X:this.ChartBorder.GetRight(), Y:this.ChartBorder.GetTopEx() };
- var ptEnd={ X:this.ChartBorder.GetLeft(), Y:this.ChartBorder.GetTopEx() };
- }
- else
- {
- var ptStart={ X:this.ChartBorder.GetLeft(), Y:this.ChartBorder.GetTopEx() };
- var ptEnd={ X:this.ChartBorder.GetLeft(), Y:this.ChartBorder.GetBottomEx() };
- }
- }
- else
- {
- if (this.ColorAngle==0)
- {
- var ptStart={ X:this.ChartBorder.GetLeft(), Y:this.ChartBorder.GetTopEx() };
- var ptEnd={ X:this.ChartBorder.GetLeft(), Y:this.ChartBorder.GetBottomEx() };
- }
- else
- {
- var ptStart={ X:this.ChartBorder.GetLeft(), Y:this.ChartBorder.GetTopEx() };
- var ptEnd={ X:this.ChartBorder.GetRight(), Y:this.ChartBorder.GetTopEx() };
- }
- }
-
- let gradient = this.Canvas.createLinearGradient(ptStart.X,ptStart.Y, ptEnd.X,ptEnd.Y);
- gradient.addColorStop(0, this.Color[0]);
- gradient.addColorStop(1, this.Color[1]);
- this.Canvas.fillStyle=gradient;
- }
- else if (this.Color.length==1)
- {
- this.Canvas.fillStyle=this.Color[0];
- }
- else
- {
- return;
- }
- if (this.Name=="DRAWGBK2" || this.Name=="KLINE_BG")
- {
- this.DrawRegion();
- return;
- }
- if (this.IsHScreen)
- {
- var left=this.ChartBorder.GetLeftEx();
- var top=this.ChartBorder.GetTop();
- var width=this.ChartBorder.GetWidthEx();
- var height=this.ChartBorder.GetHeight();
- }
- else
- {
- var left=this.ChartBorder.GetLeft();
- var top=this.ChartBorder.GetTopEx();
- var width=this.ChartBorder.GetWidth();
- var height=this.ChartBorder.GetHeightEx();
- }
- this.Canvas.fillRect(left, top,width, height);
- }
- this.DrawRegion=function()
- {
- var xPointCount=this.ChartFrame.XPointCount;
- var xOffset=this.ChartBorder.GetLeft()+distanceWidth/2.0+g_JSChartResource.FrameLeftMargin;
- var dataWidth=this.ChartFrame.DataWidth;
- var distanceWidth=this.ChartFrame.DistanceWidth;
- var top=this.ChartBorder.GetTopEx();
- var bottom=this.ChartBorder.GetBottomEx();
- if (this.IsHScreen)
- {
- top=this.ChartBorder.GetRightEx();
- bottom=this.ChartBorder.GetLeftEx();
- }
- var aryPoint=[]; //点坐标
- for(var i=this.Data.DataOffset,j=0;i<this.Data.Data.length && j<xPointCount;++i,++j,xOffset+=(dataWidth+distanceWidth))
- {
- var value=this.Data.Data[i];
- aryPoint[i]=null;
- if (!IFrameSplitOperator.IsNumber(value) || value<=0) continue;
- var x=this.ChartFrame.GetXFromIndex(j);
- var y=this.ChartFrame.GetYFromData(value.Value);
- if (this.IsHScreen)
- aryPoint[i]={ Line:{ X:bottom, Y:x }, Line2:{ X:top, Y:x } };
- else
- aryPoint[i]={ Line:{ X:x, Y:top }, Line2:{ X:x, Y:bottom } };
- }
- this.DrawBG(aryPoint);
- }
- this.DrawBG=function(aryPoint)
- {
- var dataWidth=this.ChartFrame.DataWidth;
- var distanceWidth=this.ChartFrame.DistanceWidth;
- var halfWidth=(distanceWidth+dataWidth)/2;
- var firstPoint=true;
- var pointCount=0;
- var aryLine2=[];
- var color=null;
- for(var i in aryPoint)
- {
- var item=aryPoint[i];
- if (!item || (color && item.Color!=color) )
- {
- if (pointCount>0)
- {
- for(var j=aryLine2.length-1; j>=0; --j)
- {
- var item2=aryLine2[j];
- if (this.IsHScreen)
- {
- this.Canvas.lineTo(item2.Line2.X, item2.Line2.Y+halfWidth);
- this.Canvas.lineTo(item2.Line2.X, item2.Line2.Y-halfWidth);
- }
- else
- {
- this.Canvas.lineTo(item2.Line2.X+halfWidth, item2.Line2.Y);
- this.Canvas.lineTo(item2.Line2.X-halfWidth, item2.Line2.Y);
- }
- }
- this.Canvas.closePath();
- this.Canvas.fill();
- }
- firstPoint=true;
- pointCount=0;
- aryLine2=[];
- color=null;
- }
- if (!item) continue;
- if (firstPoint)
- {
- this.Canvas.beginPath();
- if (this.IsHScreen)
- {
- this.Canvas.moveTo(item.Line.X, item.Line.Y-halfWidth);
- this.Canvas.lineTo(item.Line.X, item.Line.Y+halfWidth);
- }
- else
- {
- this.Canvas.moveTo(item.Line.X-halfWidth, item.Line.Y);
- this.Canvas.lineTo(item.Line.X+halfWidth, item.Line.Y);
- }
- firstPoint=false;
- color=item.Color;
- }
- else
- {
- if (this.IsHScreen)
- {
- this.Canvas.lineTo(item.Line.X, item.Line.Y-halfWidth);
- this.Canvas.lineTo(item.Line.X, item.Line.Y+halfWidth);
- }
- else
- {
- this.Canvas.lineTo(item.Line.X-halfWidth, item.Line.Y);
- this.Canvas.lineTo(item.Line.X+halfWidth, item.Line.Y);
- }
- }
- aryLine2.push(item);
- ++pointCount;
- }
- if (pointCount>0)
- {
- for(var j=aryLine2.length-1; j>=0; --j)
- {
- var item2=aryLine2[j];
- if (this.IsHScreen)
- {
- this.Canvas.lineTo(item2.Line2.X, item2.Line2.Y+halfWidth);
- this.Canvas.lineTo(item2.Line2.X, item2.Line2.Y-halfWidth);
- }
- else
- {
- this.Canvas.lineTo(item2.Line2.X+halfWidth, item2.Line2.Y);
- this.Canvas.lineTo(item2.Line2.X-halfWidth, item2.Line2.Y);
- }
-
- }
- this.Canvas.closePath();
- this.Canvas.fill();
- }
- }
- this.GetMaxMin=function()
- {
- return { Min:null, Max:null };
- }
- }
- //填充部分背景 支持横屏
- function ChartBackgroundDiv()
- {
- this.newMethod=IChartPainting; //派生
- this.newMethod();
- delete this.newMethod;
- this.ClassName="ChartBackgroundDiv";
- this.AryColor;
- this.ColorType=0;
- this.Draw=function()
- {
- if (!this.IsShow || this.ChartFrame.IsMinSize) return;
- if (!IFrameSplitOperator.IsNonEmptyArray(this.AryColor)) return;
- if (!this.Data || !this.Data.Data) return;
- var bHScreen=(this.ChartFrame.IsHScreen===true);
- var dataWidth=this.ChartFrame.DataWidth;
- var distanceWidth=this.ChartFrame.DistanceWidth;
- var xPointCount=this.ChartFrame.XPointCount;
- var border,xOffset, chartright, yTop, yBottom;
- if (bHScreen)
- {
- border=this.ChartBorder.GetHScreenBorder();
- xOffset=border.TopEx+distanceWidth/2.0+g_JSChartResource.FrameLeftMargin;
- chartright=border.BottomEx;
- yTop=border.LeftEx;
- yBottom=border.RightEx;
- }
- else
- {
- border=this.ChartBorder.GetBorder();
- xOffset=border.LeftEx+distanceWidth/2.0+g_JSChartResource.FrameLeftMargin;
- chartright=border.RightEx;
- yTop=border.TopEx;
- yBottom=border.BottomEx;
- }
- var rtBG=null //{ Left:null, Top:null, Right:null, Bottom:null };
- for(var i=this.Data.DataOffset,j=0;i<this.Data.Data.length && j<xPointCount;++i,++j,xOffset+=(dataWidth+distanceWidth))
- {
- var item=this.Data.Data[i];
- var left=xOffset;
- var right=xOffset+dataWidth;
- if (right>chartright) break;
- if (!item)
- {
- if (rtBG) this.DrawDiv(rtBG,bHScreen);
- rtBG=null;
- }
- else
- {
- var y=yTop;
- var y2=yBottom;
- if (IFrameSplitOperator.IsNonEmptyArray(item.AryValue))
- {
- var value=this.ChartFrame.GetYFromData(item.AryValue[0]);
- var value2=this.ChartFrame.GetYFromData(item.AryValue[1]);
- y=Math.min(value, value2);
- y2=Math.max(value, value2);
- }
- if (bHScreen)
- {
- if (!rtBG)
- {
- rtBG={ Left:y, Right:y2, Top:left, Bottom:right };
- }
- else
- {
- rtBG.Bottom=right;
- if (rtBG.Left>y) rtBG.Left=y;
- if (rtBG.Right<y2) rtBG.Right=y2;
- }
- }
- else
- {
- if (!rtBG)
- {
- rtBG={ Left:left, Right:right, Top:y, Bottom:y2 };
- }
- else
- {
- rtBG.Right=right;
- if (rtBG.Top>y) rtBG.Top=y;
- if (rtBG.Bottom<y2) rtBG.Bottom=y2;
- }
- }
- }
- }
- }
- this.DrawDiv=function(rtBG, bHScreen)
- {
- if (this.ColorType==2) //2=用COLOR1画框线
- {
- this.Canvas.strokeStyle = this.AryColor[0];
- this.Canvas.strokeRect(ToFixedPoint(rtBG.Left),ToFixedPoint(rtBG.Top),ToFixedRect(rtBG.Right-rtBG.Left),ToFixedRect(rtBG.Bottom-rtBG.Top));
- }
- else if (this.ColorType==3) //3=用COLOR1画框线,用COLOR2填充
- {
- this.Canvas.fillStyle=this.AryColor[1];
- this.Canvas.fillRect(ToFixedRect(rtBG.Left),ToFixedRect(rtBG.Top),ToFixedRect(rtBG.Right-rtBG.Left),ToFixedRect(rtBG.Bottom-rtBG.Top));
- this.Canvas.strokeStyle = this.AryColor[0];
- this.Canvas.strokeRect(ToFixedPoint(rtBG.Left),ToFixedPoint(rtBG.Top),ToFixedRect(rtBG.Right-rtBG.Left),ToFixedRect(rtBG.Bottom-rtBG.Top));
- }
- else if (this.ColorType==0 || this.ColorType==1) //0=上下渐进 1=左右渐进
- {
- var gradient=null;
- if (bHScreen)
- {
- if (this.ColorType==0)
- gradient = this.Canvas.createLinearGradient(rtBG.Left,rtBG.Top, rtBG.Right,rtBG.Top);
- else
- gradient = this.Canvas.createLinearGradient(rtBG.Left,rtBG.Top, rtBG.Left,rtBG.Bottom);
- }
- else
- {
- if (this.ColorType==0)
- gradient = this.Canvas.createLinearGradient(rtBG.Left,rtBG.Top, rtBG.Left,rtBG.Bottom);
- else
- gradient = this.Canvas.createLinearGradient(rtBG.Left,rtBG.Top, rtBG.Right,rtBG.Top);
- }
-
- gradient.addColorStop(0.5, this.AryColor[0]);
- gradient.addColorStop(1, this.AryColor[1]);
-
- this.Canvas.fillStyle=gradient;
- this.Canvas.fillRect(ToFixedRect(rtBG.Left),ToFixedRect(rtBG.Top),ToFixedRect(rtBG.Right-rtBG.Left),ToFixedRect(rtBG.Bottom-rtBG.Top));
- }
- else
- {
- return;
- }
- }
- }
- //锁 支持横屏
- function ChartLock()
- {
- this.newMethod=IChartPainting; //派生
- this.newMethod();
- delete this.newMethod;
- this.ClassName="ChartLock";
- this.AryData=null;
- this.LockRect=null; //上锁区域
- this.LockCount = 20; // 锁最新的几个数据
- this.BGColor = g_JSChartResource.IndexLock.BGColor;
- this.TextColor = g_JSChartResource.IndexLock.TextColor;
- this.Font = g_JSChartResource.IndexLock.Font;
- this.Title = g_JSChartResource.IndexLock.Title;
- this.LockID; //锁ID
- this.Callback; //回调
- this.IndexName; //指标名字
- this.IndexID; //指标ID
- this.MinWidthText=" 付费指标 "
- this.SetData=function(aryData)
- {
- this.AryData=aryData;
- if (IFrameSplitOperator.IsNonEmptyArray(this.AryData))
- {
- var item=this.AryData[0].Data; //取第一个锁
- this.LockCount = item.LockCount;
- this.BGColor = item.BGColor
- this.TextColor = item.TextColor
- this.Font = item.Font
- this.Title = item.Title
- this.LockID=item.LockID; //锁ID
- this.Callback=item.Callback; //回调
- this.IndexName=item.IndexName; //指标名字
- this.IndexID=item.IndexID; //指标ID
- }
- }
- this.CalculateTextSize=function(aryText, defaultFont, out)
- {
- if (!out || !IFrameSplitOperator.IsNonEmptyArray(aryText)) return false;
- this.Canvas.font=defaultFont;
- var defaultLineHeight=this.Canvas.measureText("擎").width; //行高
- var lineHeight=defaultLineHeight;
- var height=0, width=0;
- out.AryText=[];
- for(var i=0;i<aryText.length;++i)
- {
- var item=aryText[i];
- if (!item || (!item.Text && !item.Image)) continue;
- if (item.Image)
- {
- textWidth=item.Image.Width;
- lineHeight=item.Image.Height;
- }
- else
- {
- if (item.Font)
- {
- this.Canvas.font=item.Font;
- lineHeight=this.Canvas.measureText("擎").width;
- }
- else
- {
- this.Canvas.font=defaultFont;
- lineHeight=defaultLineHeight;
- }
- var textWidth=this.Canvas.measureText(item.Text).width;
- }
-
- var lineItem={ Text:item.Text, Width:textWidth, Height:lineHeight, Color:item.Color, TextMargin:{ Top:0, Bottom:0, Left:0, Right:0 }, YOffset:0 };
- if (IFrameSplitOperator.IsNumber(item.YOffset)) lineItem.YOffset=item.YOffset;
- if (item.Font) lineItem.Font=item.Font;
- if (IFrameSplitOperator.IsNumber(item.Align)) lineItem.Align=item.Align; //左右对齐 0=左 1=中 2=右
- if (item.Image) lineItem.Image=item.Image;
- if (item.TextMargin)
- {
- var margin=item.TextMargin;
- if (IFrameSplitOperator.IsNumber(margin.Top)) lineItem.TextMargin.Top=margin.Top;
- if (IFrameSplitOperator.IsNumber(margin.Bottom)) lineItem.TextMargin.Bottom=margin.Bottom;
- if (IFrameSplitOperator.IsNumber(margin.Left)) lineItem.TextMargin.Left=margin.Left;
- if (IFrameSplitOperator.IsNumber(margin.Right)) lineItem.TextMargin.Right=margin.Right;
- }
- lineItem.Height+=lineItem.TextMargin.Top+lineItem.TextMargin.Bottom;
- lineItem.Width+=lineItem.TextMargin.Left+lineItem.TextMargin.Right;
- if (width<lineItem.Width) width=lineItem.Width;
- out.AryText.push(lineItem);
- height+=lineItem.Height;
- }
- out.Width=width;
- out.Height=height;
- return true;
- }
- this.Draw=function(bDraw)
- {
- this.LockRect=null;
- if (!IFrameSplitOperator.IsNonEmptyArray(this.AryData)) return;
- var bHScreen=this.ChartFrame.IsHScreen;
- var bMinute=this.IsMinuteFrame();
- var dataWidth=this.ChartFrame.DataWidth;
- var distanceWidth=this.ChartFrame.DistanceWidth;
- var xPointCount=this.ChartFrame.XPointCount;
- var border=this.ChartFrame.GetBorder();
- if (bHScreen)
- {
- var chartright=border.BottomEx;
- var xOffset=border.TopEx+distanceWidth/2.0+g_JSChartResource.FrameLeftMargin;
- }
- else
- {
- var xOffset=border.LeftEx+distanceWidth/2.0+g_JSChartResource.FrameLeftMargin;
- var chartright=border.RightEx;
- }
- var kData=this.ChartFrame.Data;
- var left=xOffset;
- if (kData && IFrameSplitOperator.IsNonEmptyArray(kData.Data))
- {
- for(var i=kData.DataOffset,j=0;i<kData.Data.length-this.LockCount && j<xPointCount-this.LockCount;++i,++j,xOffset+=(dataWidth+distanceWidth))
- {
- var kItem=kData.Data[i];
- if (kItem.Open==null || kItem.High==null || kItem.Low==null || kItem.Close==null) continue;
- if (bMinute)
- {
- left=this.ChartFrame.GetXFromIndex(j);
- }
- else
- {
- left=xOffset;
- var right=xOffset+dataWidth;
- if (right>chartright) break;
- }
- }
- }
- this.Canvas.font=this.Font;
- var minWidth=this.Canvas.measureText(this.MinWidthText).width;
- var aryText=null;
- if (Array.isArray(this.Title)) aryText=this.Title;
- else aryText=[{Text:this.Title}];
-
- var outSize={ };
- if (!this.CalculateTextSize(aryText, this.Font, outSize)) outSize=null;;
- if (outSize && outSize.Width+8>minWidth) minWidth=outSize.Width+4; //确保文字可以显示
- if (bHScreen)
- {
- var rtBG={ Left:border.Left, Right:border.RightEx, Top:left, Bottom:border.Bottom };
- rtBG.Width=rtBG.Right-rtBG.Left;
- rtBG.Height=rtBG.Bottom-rtBG.Top;
- if (rtBG.Height<minWidth)
- {
- rtBG.Height=minWidth;
- rtBG.Top=rtBG.Bottom-rtBG.Height;
- }
- this.LockRect=rtBG; //保存上锁区域
- if (bDraw)
- {
- var bgColor=this.SetFillStyle(this.BGColor, rtBG.Left, rtBG.Top, rtBG.Right, rtBG.Top);
- this.Canvas.fillStyle =bgColor;
- this.Canvas.fillRect(rtBG.Left, rtBG.Top, rtBG.Width, rtBG.Height);
- }
- }
- else
- {
- var rtBG={ Left:left, Right:border.RightEx, Top:border.TopTitle, Bottom:border.Bottom };
- rtBG.Width=rtBG.Right-rtBG.Left;
- rtBG.Height=rtBG.Bottom-rtBG.Top;
- if (rtBG.Width<minWidth)
- {
- rtBG.Width=minWidth;
- rtBG.Left=rtBG.Right-rtBG.Width;
- }
- this.LockRect=rtBG; //保存上锁区域
- if (bDraw)
- {
- var bgColor=this.SetFillStyle(this.BGColor, rtBG.Left, rtBG.Top, rtBG.Left, rtBG.Bottom); //上下渐变
- this.Canvas.fillStyle =bgColor;
- this.Canvas.fillRect(rtBG.Left, rtBG.Top, rtBG.Width, rtBG.Height);
- }
- }
- if (!bDraw) return;
- if (!outSize) return;
- this.Canvas.textAlign='left';
- this.Canvas.textBaseline='bottom';
- this.Canvas.font = this.Font;
- if (bHScreen)
- {
- var top=rtBG.Top+(rtBG.Height-outSize.Width)/2;
- if (outSize.Width>rtBG.Height) top=rtBG.Bottom-outSize.Width;
- var left=rtBG.Left+(rtBG.Width-outSize.Height)/2;
- this.Canvas.save();
- this.Canvas.translate(left, top);
- this.Canvas.rotate(90 * Math.PI / 180);
- var left=0,top=0;
- }
- else
- {
- var left=rtBG.Left+(rtBG.Width-outSize.Width)/2;
- if (outSize.Width>rtBG.Width) left=rtBG.Right-outSize.Width;
- var top=rtBG.Top+(rtBG.Height-outSize.Height)/2;
- }
- var yText=top, xText=left;
- for(var i=0;i<outSize.AryText.length;++i)
- {
- var item=outSize.AryText[i];
- xText=left;
- if (item.Image)
- {
- if (item.Align===1)
- {
- if (outSize.Width>item.Width) xText+=(outSize.Width-item.Width)/2;
- }
- this.Canvas.drawImage(item.Image.Data, xText, yText, item.Image.Width, item.Image.Height);
- yText+=item.Height;
- }
- else
- {
- if (item.Color) this.Canvas.fillStyle=item.Color;
- else this.Canvas.fillStyle=this.TextColor;
- if (item.Font) this.Canvas.font = item.Font;
- else this.Canvas.font = this.Font;
- yText+=item.Height;
-
- if (item.Align===1)
- {
- if (outSize.Width>item.Width) xText+=(outSize.Width-item.Width)/2;
- }
- this.Canvas.fillText(item.Text, xText, yText+item.YOffset);
- }
- }
- if (bHScreen) this.Canvas.restore();
- }
- //x,y是否在上锁区域
- this.GetTooltipData=function(x,y,tooltip)
- {
- if (!this.LockRect) return false;
- if (Path2DHelper.PtInRect(x,y,this.LockRect))
- {
- tooltip.Data={ ID:this.LockID, Callback:this.Callback, IndexName:this.IndexName, IndexID:this.IndexID, Data:this.AryData };
- tooltip.ChartPaint=this;
- return true;
- }
-
- return false;
- }
- }
- //通达信语法 VOLSTICK 支持横屏
- function ChartVolStick()
- {
- this.newMethod = IChartPainting; //派生
- this.newMethod();
- delete this.newMethod;
- this.UpColor = g_JSChartResource.UpBarColor;
- this.DownColor = g_JSChartResource.DownBarColor;
- this.HistoryData; //历史数据
- this.KLineDrawType = 0;
- this.BarType; //柱子状态 1=实心 0=空心 2=涨实跌空 如果设置了这个属性, 属性KLineDrawType无效
- this.ClassName = 'ChartVolStick';
- this.MinBarWidth=g_JSChartResource.MinKLineBarWidth; //最小的柱子宽度
- this.Draw = function ()
- {
- if (!this.IsShow || this.ChartFrame.IsMinSize || !this.IsVisible) return;
- if (this.IsHideScriptIndex()) return;
- if (this.ChartFrame.IsHScreen === true)
- {
- this.HScreenDraw();
- return;
- }
- var dataWidth = this.ChartFrame.DataWidth;
- var distanceWidth = this.ChartFrame.DistanceWidth;
- var xOffset = this.ChartBorder.GetLeft() + distanceWidth / 2.0 + 2.0;
- var chartright = this.ChartBorder.GetRight();
- var xPointCount = this.ChartFrame.XPointCount;
- var yBottom = this.ChartFrame.GetYFromData(0);
- var isMinute=this.IsMinuteFrame();
- this.Canvas.save();
- if (dataWidth >= this.MinBarWidth)
- { //只有K线, 分时图dataWidth=1
- yBottom = ToFixedRect(yBottom);
- for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j, xOffset += (dataWidth + distanceWidth))
- {
- var value = this.Data.Data[i];
- var kItem = this.HistoryData.Data[i];
- if (value == null || kItem == null) continue;
- if (value===0) continue;
- var left = xOffset;
- var right = xOffset + dataWidth;
- if (right > chartright) break;
- var y = this.ChartFrame.GetYFromData(value);
- var barColor=this.GetBarColor(kItem);
- var bUp = barColor.IsUp;
- //高度调整为整数
- var height = ToFixedRect(Math.abs(yBottom - y)>=1 ? yBottom - y : 1);
- y = yBottom - height;
- var bSolidBar=this.IsSolidBar(bUp); //实心柱子
- if (bSolidBar)
- {
- this.Canvas.fillStyle=barColor.Color;
- this.Canvas.fillRect(ToFixedRect(left), y, ToFixedRect(dataWidth), height);
- }
- else
- {
- this.Canvas.strokeStyle=barColor.Color;
- this.Canvas.beginPath();
- this.Canvas.rect(ToFixedPoint(left), ToFixedPoint(y), ToFixedRect(dataWidth), height);
- this.Canvas.stroke();
- }
- }
- }
- else //太细了直接话线
- {
- var preKItem=null;
- var barColor=null;
- this.Canvas.lineWidth=1;
- for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j, xOffset += (dataWidth + distanceWidth))
- {
- var value = this.Data.Data[i];
- var kItem = this.HistoryData.Data[i];
- if (value == null || kItem == null) continue;
- var y = this.ChartFrame.GetYFromData(value);
- if (isMinute)
- {
- var x=this.ChartFrame.GetXFromIndex(j);
- }
- else
- {
- var left=xOffset;
- var right=xOffset+dataWidth;
- var x=left+(right-left)/2;
- }
- if (x > chartright) break;
- if (isMinute) barColor=this.GetMinuteBarColor(kItem,preKItem); //分时图颜色单独计算
- else barColor=this.GetBarColor(kItem);
-
- this.Canvas.strokeStyle=barColor.Color;
- //var x = this.ChartFrame.GetXFromIndex(j);
- this.Canvas.beginPath();
- this.Canvas.moveTo(ToFixedPoint(x), y);
- this.Canvas.lineTo(ToFixedPoint(x), yBottom);
- this.Canvas.stroke();
- preKItem=kItem;
- }
- }
- this.Canvas.restore();
- }
- this.GetBarColor=function(kItem)
- {
- if (kItem.Close>=kItem.Open) return { Color:this.UpColor, IsUp:true }; //颜色, 是否是上涨
- else return { Color:this.DownColor, IsUp:false };
- }
- this.GetMinuteBarColor=function(kItem, preItem)
- {
- var prePrice=kItem.YClose;
- if (preItem) prePrice=preItem.Close;
- if (kItem.Close>=prePrice) return { Color:this.UpColor, IsUp:true }; //颜色, 是否是上涨
- else return { Color:this.DownColor, IsUp:false };
- }
- //true=实心 false=空心
- this.IsSolidBar=function(bUp)
- {
- var bSolidBar=true; //实心柱子
-
- if (this.BarType===0 || this.BarType===1 || this.BarType===2)
- {
- if (this.BarType===0) //空心
- bSolidBar=false;
- else if (this.BarType===2) //涨实跌空
- bSolidBar=bUp;
- }
- else
- {
- if (this.KLineDrawType==6) //完全空心柱
- bSolidBar=false;
- else if (bUp && (this.KLineDrawType==1 || this.KLineDrawType==2 || this.KLineDrawType==3)) //空心柱子
- bSolidBar=false;
- }
-
- return bSolidBar;
- }
- this.HScreenDraw = function () //横屏画法
- {
- var dataWidth = this.ChartFrame.DataWidth;
- var distanceWidth = this.ChartFrame.DistanceWidth;
- var xOffset = this.ChartBorder.GetTop() + distanceWidth / 2.0 + 2.0;
- var chartBottom = this.ChartBorder.GetBottom();
- var xPointCount = this.ChartFrame.XPointCount;
- var isMinute=this.IsMinuteFrame();
- var yBottom = this.ChartFrame.GetYFromData(0);
- if (dataWidth >= this.MinBarWidth)
- {
- yBottom = ToFixedRect(yBottom);
- for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j, xOffset += (dataWidth + distanceWidth))
- {
- var value = this.Data.Data[i];
- var kItem = this.HistoryData.Data[i];
- if (value == null || kItem == null) continue;
- var left = xOffset;
- var right = xOffset + dataWidth;
- if (right > chartBottom) break;
- var y = this.ChartFrame.GetYFromData(value);
- var barColor=this.GetBarColor(kItem);
- var bUp=barColor.IsUp;
- //高度调整为整数
- var height = ToFixedRect(y - yBottom);
- var bSolidBar=this.IsSolidBar(bUp); //实心柱子
- if (bSolidBar)
- {
- this.Canvas.fillStyle=barColor.Color;
- this.Canvas.fillRect(yBottom, ToFixedRect(left), height, ToFixedRect(dataWidth));
- }
- else
- {
- this.Canvas.strokeStyle=barColor.Color;
- this.Canvas.beginPath();
- this.Canvas.rect(ToFixedPoint(yBottom), ToFixedPoint(left), height, ToFixedRect(dataWidth));
- this.Canvas.stroke();
- }
- }
- }
- else //太细了直接话线
- {
- var preKItem=null;
- var barColor=null;
- for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j, xOffset += (dataWidth + distanceWidth))
- {
- var value = this.Data.Data[i];
- var kItem = this.HistoryData.Data[i];
- if (value == null || kItem == null) continue;
- var y = this.ChartFrame.GetYFromData(value);
- if (isMinute)
- {
- var x=this.ChartFrame.GetXFromIndex(j);
- }
- else
- {
- var left=xOffset;
- var right=xOffset+dataWidth;
- var x=left+(right-left)/2;
- }
- if (x > chartBottom) break;
- if (isMinute) barColor=this.GetMinuteBarColor(kItem,preKItem); //分时图颜色单独计算
- else barColor=this.GetBarColor(kItem);
-
- this.Canvas.strokeStyle=barColor.Color;
- //var x = this.ChartFrame.GetXFromIndex(j);
- this.Canvas.beginPath();
- this.Canvas.moveTo(y, ToFixedPoint(x));
- this.Canvas.lineTo(yBottom, ToFixedPoint(x));
- this.Canvas.stroke();
- preKItem=kItem;
- }
- }
- }
- this.GetMaxMin = function ()
- {
- var xPointCount = this.ChartFrame.XPointCount;
- var range = { Min:null, Max:null };
-
- for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j)
- {
- var value = this.Data.Data[i];
- if (!IFrameSplitOperator.IsNumber(range.Max) || range.Max<value) range.Max=value;
- if (!IFrameSplitOperator.IsNumber(range.Min) || range.Min>value) range.Min=value
- }
- if (range.Max>0 && range.Min>0) range.Min=0;
- else if (range.Max<0 && range.Min<0) range.Max=0;
- return range;
- }
- }
- function ChartText()
- {
- this.newMethod = IChartPainting; //派生
- this.newMethod();
- delete this.newMethod;
-
- this.TextFont = "14px 微软雅黑";
-
- this.Draw = function ()
- {
- if (this.ChartFrame.IsMinSize) return;
- if (this.NotSupportMessage)
- {
- this.DrawNotSupportmessage();
- return;
- }
-
- if (!this.Data || !this.Data.Data) return;
-
- var dataWidth = this.ChartFrame.DataWidth;
- var distanceWidth = this.ChartFrame.DistanceWidth;
- var chartright = this.ChartBorder.GetRight();
- var xPointCount = this.ChartFrame.XPointCount;
-
- for (var i in this.Data.Data)
- {
- var value = this.Data.Data[i];
- if (value == null) continue;
-
- var price = value.Value;
- var position = value.Position;
-
- if (position == 'Left') {
- var x = this.ChartFrame.GetXFromIndex(0);
- var y = this.ChartFrame.GetYFromData(price);
-
- if (x > chartright) continue;
-
- this.Canvas.textAlign = 'left';
- this.Canvas.textBaseline = 'middle';
- this.Canvas.fillStyle = value.Color;
- this.Canvas.font = this.TextFont;
- this.Canvas.fillText(value.Message, x, y);
- }
- }
- }
-
- this.GetMaxMin = function ()
- {
- var xPointCount = this.ChartFrame.XPointCount;
- var range = {};
- range.Min = null;
- range.Max = null;
-
- if (!this.Data || !this.Data.Data) return range;
-
- for (var i in this.Data.Data)
- {
- var data = this.Data.Data[i];
- if (data == null || isNaN(data.Value)) continue;
-
- var value = data.Value;
-
- if (range.Max == null) range.Max = value;
- if (range.Min == null) range.Min = value;
-
- if (range.Max < value) range.Max = value;
- if (range.Min > value) range.Min = value;
- }
-
- return range;
- }
- }
- /* 水平面积 只有1个数据
- Data 数据结构
- Value, Value2 区间最大最小值
- Color=面积的颜色
- Title=标题 TitleColor=标题颜色
- 支持横屏
- */
- function ChartStraightArea()
- {
- this.newMethod = IChartPainting; //派生
- this.newMethod();
- delete this.newMethod;
-
- this.Color = "rgb(255,193,37)"; //线段颜色
- this.Font = '11px 微软雅黑';
-
- this.Draw = function ()
- {
- if (this.ChartFrame.IsMinSize) return;
- if (this.NotSupportMessage)
- {
- this.DrawNotSupportmessage();
- return;
- }
-
- if (!this.Data || !this.Data.Data) return;
-
- if (this.ChartFrame.IsHScreen === true)
- {
- this.HScreenDraw();
- return;
- }
-
- var dataWidth = this.ChartFrame.DataWidth;
- var distanceWidth = this.ChartFrame.DistanceWidth;
- var chartright = this.ChartBorder.GetRight();
- var bottom = this.ChartBorder.GetBottom();
- var left = this.ChartBorder.GetLeft();
- var xPointCount = this.ChartFrame.XPointCount;
-
- var xRight = this.ChartFrame.GetXFromIndex(xPointCount - 1);
-
- //画背景
- for (let i in this.Data.Data)
- {
- let item = this.Data.Data[i];
- if (item == null || isNaN(item.Value) || isNaN(item.Value2)) continue;
- if (item.Color == null) continue;
-
- let valueMax = Math.max(item.Value, item.Value2);
- let valueMin = Math.min(item.Value, item.Value2);
-
- let yTop = this.ChartFrame.GetYFromData(valueMax);
- let yBottom = this.ChartFrame.GetYFromData(valueMin);
-
- this.Canvas.fillStyle = item.Color;
- this.Canvas.fillRect(ToFixedRect(left), ToFixedRect(yTop), ToFixedRect(xRight - left), ToFixedRect(yBottom - yTop));
- }
-
- for (let i in this.Data.Data)
- {
- let item = this.Data.Data[i];
- if (item == null || isNaN(item.Value) || isNaN(item.Value2)) continue;
- if (item.Color == null) continue;
-
- let valueMax = Math.max(item.Value, item.Value2);
- let valueMin = Math.min(item.Value, item.Value2);
-
- let yTop = this.ChartFrame.GetYFromData(valueMax);
- let yBottom = this.ChartFrame.GetYFromData(valueMin);
-
- if (item.Title && item.TitleColor)
- {
- let x = xRight;
- if (item.Align == 'left')
- {
- this.Canvas.textAlign = 'left';
- x = left;
- }
- else
- {
- this.Canvas.textAlign = 'right';
- x = xRight;
- }
-
- this.Canvas.textBaseline = 'middle';
- this.Canvas.fillStyle = item.TitleColor;
- this.Canvas.font = this.Font;
- let y = yTop + (yBottom - yTop) / 2;
- this.Canvas.fillText(item.Title, x, y);
- }
- }
- }
-
- this.HScreenDraw = function ()
- {
- var bottom = this.ChartBorder.GetBottom();
- var top = this.ChartBorder.GetTop();
- var height = this.ChartBorder.GetHeight();
-
- for (let i in this.Data.Data)
- {
- let item = this.Data.Data[i];
- if (item == null || isNaN(item.Value) || isNaN(item.Value2)) continue;
- if (item.Color == null) continue;
-
- let valueMax = Math.max(item.Value, item.Value2);
- let valueMin = Math.min(item.Value, item.Value2);
-
- var yTop = this.ChartFrame.GetYFromData(valueMax);
- var yBottom = this.ChartFrame.GetYFromData(valueMin);
-
- this.Canvas.fillStyle = item.Color;
- this.Canvas.fillRect(ToFixedRect(yBottom), ToFixedRect(top), ToFixedRect(yTop - yBottom), ToFixedRect(height));
-
- if (item.Title && item.TitleColor)
- {
- var xText = yTop + (yBottom - yTop) / 2;
- var yText = bottom;
- this.Canvas.save();
- this.Canvas.translate(xText, yText);
- this.Canvas.rotate(90 * Math.PI / 180);
-
- this.Canvas.textAlign = 'right';
- this.Canvas.textBaseline = 'middle';
- this.Canvas.fillStyle = item.TitleColor;
- this.Canvas.font = this.Font;
- this.Canvas.fillText(item.Title, 0, -2);
-
- this.Canvas.restore();
- }
- }
- }
-
- this.GetMaxMin = function ()
- {
- var xPointCount = this.ChartFrame.XPointCount;
- var range = {};
- range.Min = null;
- range.Max = null;
-
- if (!this.Data || !this.Data.Data) return range;
-
- for (let i in this.Data.Data)
- {
- let item = this.Data.Data[i];
- if (item == null || isNaN(item.Value) || isNaN(item.Value2)) continue;
-
- let valueMax = Math.max(item.Value, item.Value2);
- let valueMin = Math.min(item.Value, item.Value2);
-
- if (range.Max == null) range.Max = valueMax;
- if (range.Min == null) range.Min = valueMin;
-
- if (range.Max < valueMax) range.Max = valueMax;
- if (range.Min > valueMin) range.Min = valueMin;
- }
- return range;
- }
- }
- // DRAWBAND 面积图 支持横屏
- function ChartBand()
- {
- this.newMethod = IChartPainting; //派生
- this.newMethod();
- delete this.newMethod;
- this.IsDrawFirst = true;
- this.ClassName="ChartBand";
- this.FirstColor = g_JSChartResource.Index.LineColor[0];
- this.SecondColor = g_JSChartResource.Index.LineColor[1];
-
- this.Draw = function ()
- {
- if (this.ChartFrame.IsMinSize) return;
- if (this.NotSupportMessage)
- {
- this.DrawNotSupportmessage();
- return;
- }
- var isHScreen=this.ChartFrame.IsHScreen;
- var dataWidth = this.ChartFrame.DataWidth;
- var distanceWidth = this.ChartFrame.DistanceWidth;
- var xPointCount = this.ChartFrame.XPointCount;
- var xOffset = this.ChartBorder.GetLeft() + distanceWidth / 2.0 + 2.0;
- var x = 0;
- var y = 0;
- var y2 = 0;
- var firstlinePoints = [];
- var secondlinePoints = [];
- var lIndex = 0;
- for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j, xOffset += (dataWidth + distanceWidth))
- {
- var value = this.Data.Data[i];
- if (value == null || value.Value == null || value.Value2 == null) continue;
- x = this.ChartFrame.GetXFromIndex(j);
- y = this.ChartFrame.GetYFromData(value.Value);
- y2 = this.ChartFrame.GetYFromData(value.Value2);
- if (isHScreen)
- {
- firstlinePoints[lIndex] = { x: y, y: x };
- secondlinePoints[lIndex] = { x: y2, y: x };
- }
- else
- {
- firstlinePoints[lIndex] = { x: x, y: y };
- secondlinePoints[lIndex] = { x: x, y: y2 };
- }
-
- lIndex++;
- }
- if (firstlinePoints.length>1 && secondlinePoints.length>1)
- {
- this.DrawBand(firstlinePoints, secondlinePoints);
- }
- }
- this.ClipTop=function(aryFrist)
- {
- var isHScreen=this.ChartFrame.IsHScreen;
- this.Canvas.beginPath();
- for(var i=0;i<aryFrist.length;++i)
- {
- if (i == 0)
- this.Canvas.moveTo(aryFrist[i].x, aryFrist[i].y);
- else
- this.Canvas.lineTo(aryFrist[i].x, aryFrist[i].y);
- }
- var ptStart=aryFrist[0];
- var ptEnd=aryFrist[aryFrist.length-1];
-
- if (isHScreen)
- {
- var xLeft=this.ChartBorder.GetRightEx();
- this.Canvas.lineTo(xLeft, ptEnd.y);
- this.Canvas.lineTo(xLeft, ptStart.y);
- }
- else
- {
- var yTop=this.ChartBorder.GetTopEx();
- this.Canvas.lineTo(ptEnd.x, yTop);
- this.Canvas.lineTo(ptStart.x, yTop);
- }
-
- this.Canvas.closePath();
- this.Canvas.clip();
- }
- this.ClipBottom=function(aryFrist)
- {
- var isHScreen=this.ChartFrame.IsHScreen;
- this.Canvas.beginPath();
- for(var i=0;i<aryFrist.length;++i)
- {
- if (i == 0)
- this.Canvas.moveTo(aryFrist[i].x, aryFrist[i].y);
- else
- this.Canvas.lineTo(aryFrist[i].x, aryFrist[i].y);
- }
- var ptStart=aryFrist[0];
- var ptEnd=aryFrist[aryFrist.length-1];
- if (isHScreen)
- {
- var xLeft=this.ChartBorder.GetLeftEx();
- this.Canvas.lineTo(xLeft, ptEnd.y);
- this.Canvas.lineTo(xLeft, ptStart.y);
- }
- else
- {
- var yBottom=this.ChartBorder.GetBottomEx();
- this.Canvas.lineTo(ptEnd.x, yBottom);
- this.Canvas.lineTo(ptStart.x, yBottom);
- }
-
- this.Canvas.closePath();
- //this.Canvas.fillStyle = "rgb(255,0,0)";
- //this.Canvas.fill();
- this.Canvas.clip();
- }
- this.DrawArea=function(aryFrist, arySecond, clrArea)
- {
- this.Canvas.beginPath();
- for(var i=0;i<aryFrist.length;++i)
- {
- if (i == 0)
- this.Canvas.moveTo(aryFrist[i].x, aryFrist[i].y);
- else
- this.Canvas.lineTo(aryFrist[i].x, aryFrist[i].y);
- }
- for (var i = arySecond.length-1; i >= 0; --i)
- {
- this.Canvas.lineTo(arySecond[i].x, arySecond[i].y);
- }
- this.Canvas.closePath();
- this.Canvas.fillStyle = clrArea;
- this.Canvas.fill();
- }
- this.DrawBand=function(aryFrist, arySecond)
- {
- if (this.FirstColor)
- {
- this.Canvas.save();
- this.ClipTop(aryFrist);
- this.DrawArea(aryFrist, arySecond, this.FirstColor);
- this.Canvas.restore();
- }
-
- if (this.SecondColor)
- {
- this.Canvas.save();
- this.ClipBottom(aryFrist);
- this.DrawArea(aryFrist, arySecond, this.SecondColor);
- this.Canvas.restore();
- }
- }
- this.GetMaxMin = function ()
- {
- var xPointCount = this.ChartFrame.XPointCount;
- var range = {};
- range.Min = null;
- range.Max = null;
- for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j)
- {
- var value = this.Data.Data[i];
- if (value == null || value.Value == null || value.Value2 == null) continue;
- var maxData = value.Value > value.Value2 ? value.Value : value.Value2;
- var minData = value.Value < value.Value2 ? value.Value : value.Value2;
- if (range.Max == null)
- range.Max = maxData;
- else if (range.Max < maxData)
- range.Max = maxData;
-
- if (range.Min == null)
- range.Min = minData;
- else if (range.Min > minData)
- range.Min = minData;
- }
- return range;
- }
- }
- //分钟线叠加 支持横屏
- function ChartOverlayMinutePriceLine()
- {
- this.newMethod = IChartPainting; //派生
- this.newMethod();
- delete this.newMethod;
-
- this.Color = "rgb(65,105,225)";
- this.MainData; //主图数据
-
- this.Name = "ChartOverlayMinutePriceLine";
- this.Title;
- this.Symbol; //叠加的股票代码
- this.YClose; //叠加的股票前收盘
- this.Status=OVERLAY_STATUS_ID.STATUS_NONE_ID;
- this.OverlayType=0; //叠加方式 0=百分比叠加 1=绝对叠加
-
- this.Draw = function ()
- {
- if (this.NotSupportMessage)
- {
- this.DrawNotSupportmessage();
- return;
- }
-
- var isHScreen = (this.ChartFrame.IsHScreen === true);
- var dataWidth = this.ChartFrame.DataWidth;
- var distanceWidth = this.ChartFrame.DistanceWidth;
- var chartright = this.ChartBorder.GetRight();
- if (isHScreen === true) chartright = this.ChartBorder.GetBottom();
- var xPointCount = this.ChartFrame.XPointCount;
- var minuteCount = this.ChartFrame.MinuteCount;
-
- var yClose=null, mainYClose=null;
- var bFirstPoint = true;
- var drawCount = 0, showValue=0, pointCount=0;
- for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j)
- {
- var item=this.Data.Data[i];
- if (item && IFrameSplitOperator.IsNumber(item.Close))
- {
- if (bFirstPoint) //百分比使用每天的昨收计算
- {
- yClose=item.YClose;
- var minItem=this.MainData.Data[i];
- mainYClose=minItem.YClose;
- }
- var value=item.Close;
- showValue=value; //绝对叠加
- if (this.OverlayType==0) showValue=value/yClose*mainYClose; //百分比
- var x = this.ChartFrame.GetXFromIndex(j);
- var y = this.ChartFrame.GetYFromData(showValue, false);
-
- if (bFirstPoint)
- {
- this.Canvas.strokeStyle = this.Color;
- this.Canvas.beginPath();
- if (isHScreen) this.Canvas.moveTo(y, x);
- else this.Canvas.moveTo(x, y);
- bFirstPoint = false;
- }
- else
- {
- if (isHScreen) this.Canvas.lineTo(y, x);
- else this.Canvas.lineTo(x, y);
- }
-
- ++drawCount;
- }
-
- ++pointCount;
- if (pointCount>=minuteCount) //上一天的数据和这天地数据线段要断开
- {
- bFirstPoint=true;
- pointCount=0;
- if (drawCount>0) this.Canvas.stroke();
- drawCount=0;
- }
- }
-
- if (drawCount > 0) this.Canvas.stroke();
- }
-
- this.GetMaxMin = function ()
- {
- var xPointCount = this.ChartFrame.XPointCount;
- var range={ Min:null, Max:null };
-
- var minuteCount=this.ChartFrame.MinuteCount;
- var yClose=null, mainYClose=null;
- var bFirstPoint=true;
- var pointCount=0;
- for(var i=this.Data.DataOffset,j=0;i<this.Data.Data.length && j<xPointCount;++i,++j)
- {
- var item=this.Data.Data[i];
- if (!item || !IFrameSplitOperator.IsNumber(item.Close))
- {
- ++pointCount;
- continue;
- }
- if (bFirstPoint)
- {
- yClose=item.YClose;
- var minItem=this.MainData.Data[i];
- mainYClose=minItem.YClose;
- bFirstPoint=false;
- }
- var value=item.Close;
- if (this.OverlayType==0) value=value/yClose*mainYClose;
- if (range.Max==null) range.Max=value;
- if (range.Min==null) range.Min=value;
- if (range.Max<value) range.Max=value;
- if (range.Min>value) range.Min=value;
- ++pointCount;
- if (pointCount>=minuteCount)
- {
- bFirstPoint=true;
- pointCount=0;
- }
- }
-
- return range;
- }
- }
- //线段 多数据(一个X点有多条Y数据) 支持横屏
- function ChartLineMultiData()
- {
- this.newMethod = IChartPainting; //派生
- this.newMethod();
- delete this.newMethod;
-
- this.Color = "rgb(255,193,37)"; //线段颜色
-
- this.Draw = function ()
- {
- if (this.NotSupportMessage)
- {
- this.DrawNotSupportmessage();
- return;
- }
-
- if (!this.Data || !this.Data.Data) return;
-
- var isHScreen = (this.ChartFrame.IsHScreen === true);
- var dataWidth = this.ChartFrame.DataWidth;
- var distanceWidth = this.ChartFrame.DistanceWidth;
- var chartright = this.ChartBorder.GetRight();
- if (isHScreen) chartright = this.ChartBorder.GetBottom();
- var xPointCount = this.ChartFrame.XPointCount;
-
- var bFirstPoint = true;
- var drawCount = 0;
- for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j)
- {
- var aryValue = this.Data.Data[i];
- if (aryValue == null) continue;
-
- var x = this.ChartFrame.GetXFromIndex(j);
- if (x > chartright) break;
-
- for (var index in aryValue)
- {
- var value = aryValue[index].Value;
- var y = this.ChartFrame.GetYFromData(value);
-
- if (bFirstPoint)
- {
- this.Canvas.strokeStyle = this.Color;
- this.Canvas.beginPath();
- if (isHScreen) this.Canvas.moveTo(y, x);
- else this.Canvas.moveTo(x, y);
- bFirstPoint = false;
- }
- else
- {
- if (isHScreen) this.Canvas.lineTo(y, x);
- else this.Canvas.lineTo(x, y);
- }
-
- ++drawCount;
- }
- }
-
- if (drawCount > 0) this.Canvas.stroke();
- }
-
- this.GetMaxMin = function ()
- {
- var xPointCount = this.ChartFrame.XPointCount;
- var range = {};
- range.Min = null;
- range.Max = null;
-
- if (!this.Data || !this.Data.Data) return range;
-
- for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j)
- {
- var aryValue = this.Data.Data[i];
- if (aryValue == null) continue;
-
- for (var index in aryValue)
- {
- var value = aryValue[index].Value;
- if (range.Max == null) range.Max = value;
- if (range.Min == null) range.Min = value;
-
- if (range.Max < value) range.Max = value;
- if (range.Min > value) range.Min = value;
- }
- }
- return range;
- }
- }
- //直线 水平直线 只有1个数据 支持横屏
- function ChartStraightLine()
- {
- this.newMethod = IChartPainting; //派生
- this.newMethod();
- delete this.newMethod;
-
- this.Color = "rgb(255,193,37)"; //线段颜色
-
- this.Draw = function ()
- {
- if (!this.Data || !this.Data.Data) return;
- if (this.Data.Data.length != 1) return;
-
- var isHScreen = this.ChartFrame.IsHScreen;
- var dataWidth = this.ChartFrame.DataWidth;
- var distanceWidth = this.ChartFrame.DistanceWidth;
- var chartright = this.ChartBorder.GetRight();
- if (isHScreen) chartright = this.ChartBorder.GetTop();
- var xPointCount = this.ChartFrame.XPointCount;
-
- var yValue = this.Data.Data[0];
- var y = this.ChartFrame.GetYFromData(yValue);
- var xLeft = this.ChartFrame.GetXFromIndex(0);
- var xRight = this.ChartFrame.GetXFromIndex(xPointCount - 1);
-
- var yFix = parseInt(y.toString()) + 0.5;
- this.Canvas.beginPath();
- if (isHScreen)
- {
- this.Canvas.moveTo(yFix, xLeft);
- this.Canvas.lineTo(yFix, xRight);
- }
- else
- {
- this.Canvas.moveTo(xLeft, yFix);
- this.Canvas.lineTo(xRight, yFix);
- }
- this.Canvas.strokeStyle = this.Color;
- this.Canvas.stroke();
- }
-
- this.GetMaxMin = function ()
- {
- var xPointCount = this.ChartFrame.XPointCount;
- var range = {};
- range.Min = null;
- range.Max = null;
-
- if (!this.Data || !this.Data.Data) return range;
- if (this.Data.Data.length != 1) return range;
-
- range.Min = this.Data.Data[0];
- range.Max = this.Data.Data[0];
-
- return range;
- }
- }
- //图标集合(2.0) 支持横屏
- function ChartMultiSVGIconV2()
- {
- this.newMethod=IChartPainting; //派生
- this.newMethod();
- delete this.newMethod;
- this.ClassName="ChartMultiSVGIconV2";
- this.AryIcon; //[ {Index:, Value:, Baseline:, Line:{ Color:, Dash:[虚线点], KData:"H/L", Offset:[5,10], Width:线粗细 }, Image:{ Data:Image图片, Width, Height } } ]
- this.IsHScreen=false;
- this.MapCache=null; //key=date/date-time value={ Data:[] }
- this.BuildKey=function(item)
- {
- if (IFrameSplitOperator.IsNumber(item.Time)) return `${item.Date}-${item.Time}`;
- else return item.Date;
- }
- this.BuildCacheData=function()
- {
- var mapData=new Map();
- this.MapCache=mapData;
- if (!IFrameSplitOperator.IsNonEmptyArray(this.AryIcon)) return;
- for(var i=0;i<this.AryIcon.length;++i)
- {
- var item=this.AryIcon[i];
- var key=this.BuildKey(item);
- if (mapData.has(key))
- {
- var mapItem=mapData.get(key);
- mapItem.Data.push(item);
- }
- else
- {
- mapData.set(key,{ Data:[item] });
- }
- }
- }
- this.ClipClient=function(isHScreen) //裁剪客户端
- {
- if (isHScreen==true)
- {
- var left=this.ChartBorder.GetLeft();
- var right=this.ChartBorder.GetRight();
- var top=this.ChartBorder.GetTop();
- var bottom=this.ChartBorder.GetBottom();
- }
- else
- {
- var left=this.ChartBorder.GetLeft();
- var right=this.ChartBorder.GetRight();
- var top=this.ChartBorder.GetTop();
- var bottom=this.ChartBorder.GetBottom();
- }
- this.Canvas.beginPath();
- this.Canvas.rect(left,top,(right-left),(bottom-top));
- //this.Canvas.stroke(); //调试用
- this.Canvas.clip();
- }
- this.Draw=function()
- {
- if (!this.IsShow || this.ChartFrame.IsMinSize || !this.IsVisible) return;
- if (this.IsHideScriptIndex()) return;
- if (!this.Data || !IFrameSplitOperator.IsNonEmptyArray(this.Data.Data)) return; //k线数据
- if (!this.Family) return;
- if (!this.MapCache || this.MapCache.size<=0) return;
- this.IsHScreen=(this.ChartFrame.IsHScreen===true);
- var xPointCount=this.ChartFrame.XPointCount;
- var dataWidth=this.ChartFrame.DataWidth;
- var distanceWidth=this.ChartFrame.DistanceWidth;
- var isMinute=this.IsMinuteFrame();
- var border=this.GetBorder();
- if (this.IsHScreen)
- {
- var xOffset=border.TopEx+distanceWidth/2.0+g_JSChartResource.FrameLeftMargin;
- var chartright=border.BottomEx;
- var chartLeft=border.TopEx;
- }
- else
- {
- var xOffset=border.LeftEx+distanceWidth/2.0+g_JSChartResource.FrameLeftMargin;
- var chartright=border.RightEx;
- var chartLeft=border.LeftEx;
- }
- this.Canvas.save();
- this.ClipClient(this.ChartFrame.IsHScreen);
- var drawInfo={ Left:chartLeft, Right:chartright, DataWidth:dataWidth, DistanceWidth:distanceWidth };
- for(var i=this.Data.DataOffset,j=0;i<this.Data.Data.length && j<xPointCount;++i,++j,xOffset+=(dataWidth+distanceWidth))
- {
- var kItem=this.Data.Data[i];
- var key=this.BuildKey(kItem);
- if (!this.MapCache.has(key)) continue;
- var mapItem=this.MapCache.get(key);
- if (isMinute)
- {
- var x=this.ChartFrame.GetXFromIndex(j);
- }
- else
- {
- var left=xOffset;
- var right=xOffset+dataWidth;
- if (right>chartright) break;
- var x=left+(right-left)/2;
- }
- this.DrawItem(mapItem, kItem, x, drawInfo);
- }
- this.Canvas.restore();
- }
- this.GetKValue=function(kItem, valueName)
- {
- switch(valueName)
- {
- case "HIGH":
- case "H":
- return kItem.High;
- case "L":
- case "LOW":
- return kItem.Low;
- case "C":
- case "CLOSE":
- return kItem.Close;
- case "O":
- case "OPEN":
- return KItem.Open;
- default:
- return null;
- }
- }
- this.DrawItem=function(groupItem, kItem, x, drawInfo)
- {
- if (!IFrameSplitOperator.IsNonEmptyArray(groupItem.Data)) return;
- //var left=drawInfo.Left, right=drawInfo.Right;
- //var dataWidth=drawInfo.DataWidth;
- //var distanceWidth=drawInfo.DistanceWidth;
- for(var i=0;i<groupItem.Data.length;++i)
- {
- var item=groupItem.Data[i];
- var value=item.Value;
- if (IFrameSplitOperator.IsString(item.Value)) value=this.GetKValue(kItem,item.Value);
- if (!IFrameSplitOperator.IsNumber(value)) continue;
- if (!item.Image) continue;
- var y=this.ChartFrame.GetYFromData(item.Value,false);
- var imageHeight=item.Image.Height;
- var imageWidth=item.Image.Width;
-
- if (this.IsHScreen)
- {
- var xImage=x-imageWidth/2, yImage=y;
- if (item.Baseline==1) yImage=y-imageHeight;
- else if (item.Baseline==2) yImage=y;
- else yImage=y-imageHeight/2;
- if (IFrameSplitOperator.IsNumber(item.YMove))
- {
- yImage-=item.YMove;
- y-=item.YMove;
- }
- //this.Canvas.drawImage(item.Image.Data, yImage, xImage,item.Image.Width, item.Image.Height);
-
- this.Canvas.save();
- this.Canvas.translate(yImage+imageWidth/2, xImage+imageHeight/2);
- this.Canvas.rotate(90 * Math.PI / 180);
- this.Canvas.drawImage(item.Image.Data, -imageWidth/2, -imageHeight/2, item.Image.Width, item.Image.Height);
- this.Canvas.restore();
-
- }
- else
- {
- var rtIcon=new RectV2(x-imageWidth/2,y-imageHeight/2,imageWidth,imageHeight);
- if (item.Baseline==1) rtIcon.Y=y;
- else if (item.Baseline==2) rtIcon.Y=y-imageHeight;
- else rtIcon.Y=y-imageHeight/2;
- if (IFrameSplitOperator.IsNumber(item.YMove))
- {
- y+=item.YMove;
- rtIcon.Y+=item.YMove;
- }
-
- this.Canvas.drawImage(item.Image.Data, rtIcon.X, rtIcon.Y, item.Image.Width, item.Image.Height);
- }
- if (item.Line)
- {
- var price=item.Line.KData=="H"? kItem.High:kItem.Low;
- var yPrice=this.ChartFrame.GetYFromData(price, false);
- var yText=y;
- if (Array.isArray(item.Line.Offset) && item.Line.Offset.length==2)
- {
- if (yText>yPrice) //文字在下方
- {
- yText-=item.Line.Offset[1];
- yPrice+=item.Line.Offset[0]
- }
- else if (yText<yPrice)
- {
- yText+=item.Line.Offset[1];
- yPrice-=item.Line.Offset[0]
- }
- }
- this.Canvas.save();
- if (item.Line.Dash) this.Canvas.setLineDash(item.Line.Dash); //虚线
- if (item.Line.Width>0) this.Canvas.lineWidth=item.Line.Width; //线宽
- this.Canvas.strokeStyle = item.Line.Color;
- this.Canvas.beginPath();
- if (this.IsHScreen)
- {
- this.Canvas.moveTo(yText, ToFixedPoint(x));
- this.Canvas.lineTo(yPrice,ToFixedPoint(x));
- }
- else
- {
- this.Canvas.moveTo(ToFixedPoint(x),yText);
- this.Canvas.lineTo(ToFixedPoint(x),yPrice);
- }
-
- this.Canvas.stroke();
- this.Canvas.restore();
- }
- }
- }
- this.GetMaxMin=function()
- {
- this.IsHScreen=(this.ChartFrame.IsHScreen===true);
- var range={ Min:null, Max:null };
- if(!this.Data || !IFrameSplitOperator.IsNonEmptyArray(this.Data.Data)) return range;
- if (!this.MapCache || this.MapCache.size<=0) return;
- var xPointCount=this.ChartFrame.XPointCount;
- for(var i=this.Data.DataOffset,j=0, k=0;i<this.Data.Data.length && j<xPointCount;++i,++j)
- {
- var kItem=this.Data.Data[i];
- var key=this.BuildKey(kItem);
- if (!this.MapCache.has(key)) continue;
- var mapItem=this.MapCache.get(key);
- if (!IFrameSplitOperator.IsNonEmptyArray(mapItem.Data)) continue;
- for(k=0;k<mapItem.Data.length;++k)
- {
- var item=mapItem.Data[k];
- var value=item.Value;
- if (IFrameSplitOperator.IsString(item.Value)) value=this.GetKValue(kItem,item.Value);
- if (!IFrameSplitOperator.IsNumber(value)) continue;
- if (range.Max==null) range.Max=value;
- else if (range.Max<value) range.Max=value;
- if (range.Min==null) range.Min=value;
- else if (range.Min>value) range.Min=value;
- }
- }
- return range;
- }
- }
- ///////////////////////////////////////////////////////////////////////////////////////////////////
- //十字光标
- function ChartCorssCursor()
- {
- this.Frame;
- this.Canvas; //画布
- this.HPenColor = g_JSChartResource.CorssCursorHPenColor; //水平线颜色
- this.HPenType = 0; //水平线样式 0=虚线 1=实线
- this.VPenColor = g_JSChartResource.CorssCursorVPenColor; //垂直线颜色
- this.VPenType = 0; //垂直线颜色 0=虚线 1=实线 2=K线宽度
- this.Font = g_JSChartResource.CorssCursorTextFont; //字体
- this.TextColor = g_JSChartResource.CorssCursorTextColor; //文本颜色
- this.TextBGColor = g_JSChartResource.CorssCursorBGColor; //文本背景色
- this.LineDash=g_JSChartResource.CorssCursorLineDash.slice(); //虚线
- this.TextHeight = 15; //文本字体高度
- this.LastPoint;
- this.CursorIndex; //当前数据的位置
- this.PointX;
- this.PointY;
- this.StringFormatX;
- this.StringFormatY;
- this.IsShow = true; //是否显示
- this.ShowTextMode = { Left: 1, Right: 1, Bottom: 1 }; //0=不显示 1=显示在框架外 2=显示在框架内
- this.TextFormat= { Right:0 }; //0=默认 1=价格显示(分时图才有用)
- this.IsShowCorss = true; //是否显示十字光标
- this.IsShowClose = false; //Y轴始终显示收盘价
- this.IsOnlyDrawMinute=false; //是否只能画在走势图价格线上
- this.IsFixXLastTime=false; //是否修正X轴,超出当前时间的,X轴调整到当前最后的时间.
- this.CorssPointConfig=
- {
- Enable:false,
- Center:CloneData(g_JSChartResource.CorssCursor.CorssPoint.Center),
- Border:CloneData(g_JSChartResource.CorssCursor.CorssPoint.Border)
- }
- this.BottomConfig=CloneData(g_JSChartResource.CorssCursor.BottomText); //底部输出配置
- this.LeftConfig=CloneData(g_JSChartResource.CorssCursor.LeftText);
- this.RightConfig=CloneData(g_JSChartResource.CorssCursor.RightText); //右侧输出配置
- this.BottomButton={ Enable:false, Rect:null }; //底部按钮
- //内部使用
- this.Close = null; //收盘价格
- this.Status=0; //当前状态 0=隐藏 1=显示
- this.GetCloseYPoint = function (index)
- {
- this.Close = null;
- if (!this.StringFormatX.Data) return null;
- var data = this.StringFormatX.Data;
- if (!data.Data || data.Data.length <= 0) return null;
- var dataIndex = data.DataOffset + index;
- if (dataIndex >= data.Data.length) dataIndex = data.Data.length - 1;
- if (dataIndex < 0) return null;
- var klineData = data.Data[dataIndex];
- if (!klineData) return null;
- this.Close = klineData.Close;
- var yPoint = this.Frame.GetYFromData(this.Close);
- return yPoint;
- }
- this.GetMinuteCloseYPoint=function(index)
- {
- if (!IFrameSplitOperator.IsNumber(index)) return null;
- index=parseInt(index.toFixed(0));
- if (!this.StringFormatX.Data) return null;
- var data = this.StringFormatX.Data;
- if (!data.Data || data.Data.length <= 0) return null;
- var dataIndex = data.DataOffset + index;
- if (dataIndex >= data.Data.length) dataIndex = data.Data.length - 1;
- if (dataIndex < 0) return null;
- var close = data.Data[dataIndex];
- if (!IFrameSplitOperator.IsNumber(index)) return null;
- this.Close=close;
- var yPoint = this.Frame.GetYFromData(this.Close);
- return yPoint;
- }
- this.FixMinuteLastTimeXPoint=function(index)
- {
- if (!IFrameSplitOperator.IsNumber(index)) return null;
- index=parseInt(index);
- if (!this.StringFormatX.Data) return null;
- var data = this.StringFormatX.Data;
- if (!data.Data || data.Data.length <= 0) return null;
- var dataIndex = data.DataOffset + index;
- if (dataIndex<data.Data.length) return null;
- dataIndex=data.Data.length - 1;
- dataIndex-=data.DataOffset;
- var xPoint=this.Frame.GetXFromIndex(dataIndex);
- return { X:xPoint, Index:dataIndex };
- }
- this.Draw = function ()
- {
- this.Status=JSCHART_CORSSCURSOR_STATUS_ID.NONE_ID;
- this.BottomButton.Rect=null;
-
- if (!this.LastPoint) return;
- var x = this.LastPoint.X;
- var y = this.LastPoint.Y;
- var isInClient = false;
- var rtClient = new Rect(this.Frame.ChartBorder.GetLeft(), this.Frame.ChartBorder.GetTop(), this.Frame.ChartBorder.GetWidth(), this.Frame.ChartBorder.GetHeight());
- isInClient = rtClient.IsPointIn(x, y);
- this.PointY = null;
- this.PointY == null;
- if (!isInClient) return;
- if (this.Frame.IsHScreen === true)
- {
- this.HScreenDraw();
- return;
- }
- var left = this.Frame.ChartBorder.GetLeft();
- var right = this.Frame.ChartBorder.GetRight();
- var top = this.Frame.ChartBorder.GetTopTitle();
- var bottom = this.Frame.ChartBorder.GetBottom();
- var rightWidth = this.Frame.ChartBorder.Right;
- var chartRight = this.Frame.ChartBorder.GetChartWidth();
- x = this.Frame.GetXFromIndex(this.CursorIndex); //手机端 十字只能画在K线上
- if (this.IsShowClose) //手机端 十字只能画在K线上
- {
- var yPoint = this.GetCloseYPoint(this.CursorIndex);
- if (yPoint != null) y = yPoint;
- }
- else if (this.IsOnlyDrawMinute)
- {
- var yPoint = this.GetMinuteCloseYPoint(this.CursorIndex);
- if (yPoint != null) y=yPoint;
- }
- if (this.IsFixXLastTime)
- {
- var value=this.FixMinuteLastTimeXPoint(this.CursorIndex)
- if (value)
- {
- x=value.X;
- this.CursorIndex=value.Index;
- }
- }
- this.PointY = [[left, y], [right, y]];
- this.PointX = [[x, top], [x, bottom]];
- if (this.IsShowCorss) //十字线
- {
- if (this.HPenType==1 || this.HPenType==0)
- {
- this.Canvas.strokeStyle = this.HPenColor;
- if (this.HPenType == 0) this.Canvas.setLineDash(this.LineDash); //虚线
- //this.Canvas.lineWidth=0.5
- this.Canvas.beginPath();
- this.Canvas.moveTo(left, ToFixedPoint(y));
- this.Canvas.lineTo(right, ToFixedPoint(y));
- this.Canvas.stroke();
- this.Canvas.setLineDash([]);
- }
-
- this.Canvas.save();
- this.Canvas.strokeStyle = this.VPenColor;
- if (this.VPenType == 0)
- {
- this.Canvas.setLineDash(this.LineDash); //虚线
- }
- else if (this.VPenType == 2)
- {
- let barWidth = this.Frame.SubFrame[0].Frame.DataWidth; //和K线一样宽度
- if (barWidth > 2) this.Canvas.lineWidth = barWidth;
- }
- this.Canvas.beginPath();
- if (this.Frame.SubFrame.length > 0)
- {
- for (var i in this.Frame.SubFrame)
- {
- var frame = this.Frame.SubFrame[i].Frame;
- top = frame.ChartBorder.GetTopTitle();
- bottom = frame.ChartBorder.GetBottom();
- this.Canvas.moveTo(ToFixedPoint(x), top);
- this.Canvas.lineTo(ToFixedPoint(x), bottom);
- }
- }
- else
- {
- this.Canvas.moveTo(ToFixedPoint(x), top);
- this.Canvas.lineTo(ToFixedPoint(x), bottom);
- }
- this.Status|=JSCHART_CORSSCURSOR_STATUS_ID.LINE_ID;
- this.Canvas.stroke();
- this.Canvas.restore();
- this.Canvas.save();
- this.DrawCorssPoint(x,y);
- this.Canvas.restore();
- }
- var xValue = this.Frame.GetXData(x);
- var yValueExtend = {};
- var yValue = this.Frame.GetYData(y, yValueExtend);
- this.StringFormatY.RValue = yValueExtend.RightYValue; //右侧子坐标
- if (this.IsShowClose && this.Close != null) yValue = this.Close;
- this.StringFormatX.Value = this.CursorIndex;
- this.StringFormatY.Value = yValue;
- this.StringFormatY.RValue=yValueExtend.RightYValue; //右侧子坐标
- this.StringFormatY.Point={X:x, Y:y};
- this.StringFormatY.FrameID = yValueExtend.FrameID;
- this.Canvas.font = this.Font;
- var textHeight=this.GetFontHeight();
- if (textHeight>this.TextHeight) this.TextHeight=textHeight;
- if (((this.ShowTextMode.Left == 1 && this.Frame.ChartBorder.Left >= 30) || this.ShowTextMode.Left == 2 ||
- (this.ShowTextMode.Right == 1 && this.Frame.ChartBorder.Right >= 30) || this.ShowTextMode.Right == 2) && this.StringFormatY.Operator())
- {
- var text = this.StringFormatY.Text;
- var textWidth = this.Canvas.measureText(text).width; //前后各空2个像素
- var textSize={ Width:textWidth+4, Height:this.TextHeight, Text:[] };
- var margin=this.LeftConfig.Margin;
- var textOffset=this.LeftConfig.TextOffset;
- var rtBG=null;
- if (this.Frame.ChartBorder.Left >= 30 && this.ShowTextMode.Left==1)
- {
- var rtBG={ Right:left, Width:textWidth+margin.Left+margin.Right, YCenter:y, Height:textHeight+margin.Top+margin.Bottom };
- rtBG.Left=rtBG.Right-rtBG.Width;
- rtBG.Top=rtBG.YCenter-rtBG.Height/2;
- rtBG.Bottom=rtBG.Top+rtBG.Height;
- if (rtBG.Left<0)
- {
- rtBG.Left=0;
- rtBG.Right=rtBG.Left+rtBG.Width;
- }
- this.Status|=JSCHART_CORSSCURSOR_STATUS_ID.LEFT_TEXT_ID;
- }
- else if (this.ShowTextMode.Left==2) //在框架内显示
- {
- var rtBG={ Left:left, Width:textWidth+margin.Left+margin.Right, YCenter:y, Height:textHeight+margin.Top+margin.Bottom };
- rtBG.Right=rtBG.Left+rtBG.Width;
- rtBG.Top=rtBG.YCenter-rtBG.Height/2;
- rtBG.Bottom=rtBG.Top+rtBG.Height;
- this.Status|=JSCHART_CORSSCURSOR_STATUS_ID.LEFT_INTER_TEXT_ID;
- }
- if (rtBG)
- {
- this.DrawTextBGRect(rtBG.Left,rtBG.Top,rtBG.Width,rtBG.Height);
- this.Canvas.textAlign="left";
- this.Canvas.textBaseline="bottom";
- this.Canvas.fillStyle=this.TextColor;
- this.Canvas.fillText(text,rtBG.Left+textOffset.X, rtBG.Bottom+textOffset.Y);
- }
- var complexText=
- {
- ShowType:0, //0=单行(默认) 1=多行
- Font:this.Font, Color:this.TextColor,
- Text:[ { Text:text, Margin:this.RightConfig.Margin, TextOffset:this.RightConfig.TextOffset } ],
- };
- var yTop=y-this.TextHeight/2;
- var textSize={ Width:0, Height:0, Text:[] };
- if (this.StringFormatY.PercentageText)
- {
- if (this.TextFormat.Right==0)
- {
- text=this.StringFormatY.PercentageText+'%';
- complexText.Text[0].Text=text;
- }
- }
- if (this.StringFormatY.RText)
- {
- text = this.StringFormatY.RText;
- complexText.Text[0].Text=text;
- }
- if (this.StringFormatY.RComplexText && IFrameSplitOperator.IsNonEmptyArray(this.StringFormatY.RComplexText.Text))
- {
- complexText=this.StringFormatY.RComplexText;
- if (!complexText.Font) complexText.Font=this.Font;
- if (!complexText.Font) complexText.Color=this.TextColor;
- }
-
- this.CalculateComplexTextSize(complexText, textSize);
- //计算右侧文本输出顶部位置
- function _Temp_CalculateRightTextBGTop(rtBG, complexText, defatulTextHeight)
- {
- if (complexText.ShowType==1)
- {
- var yValue=defatulTextHeight/2;
- if (IFrameSplitOperator.IsNonEmptyArray(textSize.Text) && textSize.Text[0])
- {
- var itemSize=textSize.Text[0];
- if (IFrameSplitOperator.IsNumber(itemSize.Height)) yValue=itemSize.Height/2;
- }
- rtBG.Top=rtBG.YCenter-yValue;
- rtBG.Bottom=rtBG.Top+rtBG.Height;
- }
- else
- {
- rtBG.Top=rtBG.YCenter-rtBG.Height/2;
- rtBG.Bottom=rtBG.Top+rtBG.Height;
- }
- }
- if (this.Frame.ChartBorder.Right >= 30 && this.ShowTextMode.Right == 1)
- {
- var rtBG={ Left:right+1, Width:textSize.Width, YCenter:y, Height:textSize.Height };
- rtBG.Right=rtBG.Left+rtBG.Width;
- _Temp_CalculateRightTextBGTop(rtBG, complexText, this.TextHeight);
-
- if (rtBG.Right>chartRight)
- {
- rtBG.Right=chartRight;
- rtBG.Left=rtBG.Right-rtBG.Width;
- }
- this.DrawTextBGRect(rtBG.Left,rtBG.Top,rtBG.Width,rtBG.Height);
- this.DrawComplexRightText(rtBG,complexText,textSize);
- this.Status|=JSCHART_CORSSCURSOR_STATUS_ID.RIGHT_TEXT_ID;
- }
- else if (this.ShowTextMode.Right == 2)
- {
- var rtBG={ Right:right, Width:textSize.Width, YCenter:y, Height:textSize.Height };
- rtBG.Left=rtBG.Right-rtBG.Width;
- _Temp_CalculateRightTextBGTop(rtBG, complexText, this.TextHeight);
- this.Canvas.fillStyle=this.TextBGColor;
- this.DrawTextBGRect(rtBG.Left,rtBG.Top,rtBG.Width,rtBG.Height);
- this.DrawComplexRightText(rtBG,complexText,textSize);
- this.Status|=JSCHART_CORSSCURSOR_STATUS_ID.RIGHT_INTER_TEXT_ID;
- }
- }
- //Bottom==8 自定义X轴文字位置
- if ((this.ShowTextMode.Bottom == 1 || this.ShowTextMode.Bottom==8) && this.StringFormatX.Operator())
- {
- var text = this.StringFormatX.Text;
- this.Canvas.font = this.Font;
- this.Canvas.fillStyle = this.TextBGColor;
- var textWidth = this.Canvas.measureText(text).width; //前后各空2个像素
- var margin=this.BottomConfig.Margin;
- var textOffset=this.BottomConfig.TextOffset;
- var rtBG=
- {
- Top:bottom, Height:margin.Top+margin.Bottom+textHeight,
- XCenter:x, Width:textWidth+margin.Left+margin.Right
- };
- rtBG.Bottom=rtBG.Top+rtBG.Height;
- rtBG.Left=rtBG.XCenter-rtBG.Width/2;
- rtBG.Right=rtBG.Left+rtBG.Width;
- if (rtBG.Left<=0)
- {
- rtBG.Left=0;
- rtBG.Right=rtBG.Left+rtBG.Width;
- }
- else if (rtBG.Right>=right)
- {
- rtBG.Right=right;
- rtBG.Left=rtBG.Right-rtBG.Width;
- }
- var bShowText=true;
- if (this.ShowTextMode.Bottom==2)
- {
- rtBG.Bottom=bottom;
- rtBG.Top=rtBG.Bottom-rtBG.Height;
- }
- else if (this.ShowTextMode.Bottom==8)
- {
- var event=this.GetEventCallback(JSCHART_EVENT_ID.ON_CUSTOM_CORSSCURSOR_POSITION);
- if (event && event.Callback)
- {
- var sendData={ RectText:rtBG, IsShowText:bShowText, X:x, Y:y };
- event.Callback(event, sendData, this);
- bShowText=sendData.IsShowText;
- }
- }
- //JSConsole.Chart.Log('[ChartCorssCursor::Draw] ',yCenter);
- if (bShowText)
- {
- this.DrawTextBGRect(rtBG.Left,rtBG.Top,rtBG.Width,rtBG.Height);
- this.Canvas.textAlign="left";
- this.Canvas.textBaseline="bottom";
- this.Canvas.fillStyle=this.TextColor;
- this.Canvas.fillText(text,rtBG.Left+textOffset.X,rtBG.Bottom+textOffset.Y,textWidth);
- var buttonData={X:x, Y:y, XValue:xValue, FrameID:yValueExtend.FrameID };
- if (this.StringFormatX.KItem) buttonData.KItem=this.StringFormatX.KItem;
- this.BottomButton.Rect=rtBG;
- this.BottomButton.Data=buttonData;
- this.Status|=JSCHART_CORSSCURSOR_STATUS_ID.BOTTOM_TEXT_ID;
- }
- }
- }
- this.GetFontHeight=function(font)
- {
- if (font) this.Canvas.font=font;
- var textHeight= this.Canvas.measureText("擎").width;
- return textHeight;
- }
- this.DrawTextBGRect=function(x,y, height, width)
- {
- this.Canvas.fillStyle=this.TextBGColor;
- this.Canvas.fillRect(ToFixedPoint(x),ToFixedPoint(y),ToFixedRect(height),ToFixedRect(width));
- //this.Canvas.fillRect(x,y,height,width);
- }
- this.CalculateComplexTextSize=function(complexText, size)
- {
- if (!complexText || !IFrameSplitOperator.IsNonEmptyArray(complexText.Text)) return;
- var showType=0;
- if (complexText.ShowType==1) showType=complexText.ShowType;
- if (showType==1) //多行
- {
- var textWidth=0, textHeight=0;
- for(var i=0; i<complexText.Text.length; ++i)
- {
- var item=complexText.Text[i];
- if (item.Font) this.Canvas.font=item.Font;
- else this.Canvas.font=complexText.Font;
- var itemWidth=this.Canvas.measureText(item.Text).width; //前后各空2个像素
- var itemHeight=this.GetFontHeight();
- if (item.Margin)
- {
- var margin=item.Margin;
- if (IFrameSplitOperator.IsNumber(margin.Left)) itemWidth+=margin.Left;
- if (IFrameSplitOperator.IsNumber(margin.Right)) itemWidth+=margin.Right;
- if (IFrameSplitOperator.IsNumber(margin.Top)) itemHeight+=margin.Top;
- if (IFrameSplitOperator.IsNumber(margin.Bottom)) itemHeight+=margin.Bottom;
- }
- size.Text[i]={ Width:itemWidth, Height:itemHeight }; //保存所有文字的大小信息
- if (textWidth<itemWidth) textWidth=itemWidth;
- textHeight+=itemHeight;
- }
- size.Width=textWidth;
- size.Height=textHeight;
- }
- else //水平 单行
- {
- var textWidth=0, textHeight=this.GetFontHeight();
- for(var i=0; i<complexText.Text.length; ++i)
- {
- var item=complexText.Text[i];
- if (item.Font) this.Canvas.font=item.Font;
- else this.Canvas.font=complexText.Font;
- var itemWidth=this.Canvas.measureText(item.Text).width; //前后各空2个像素
- var itemHeight=this.Canvas.measureText("擎").width;
- if (item.Margin)
- {
- var margin=item.Margin;
- if (IFrameSplitOperator.IsNumber(margin.Left)) itemWidth+=margin.Left;
- if (IFrameSplitOperator.IsNumber(margin.Right)) itemWidth+=margin.Right;
- if (IFrameSplitOperator.IsNumber(margin.Top)) itemHeight+=margin.Top;
- if (IFrameSplitOperator.IsNumber(margin.Bottom)) itemHeight+=margin.Bottom;
- }
- size.Text[i]={ Width:itemWidth, Height:itemHeight }; //保存所有文字的大小信息
- textWidth+=itemWidth;
- if (textHeight<itemHeight) textHeight=itemHeight;
- }
- size.Width=textWidth;
- size.Height=textHeight;
- }
- }
- this.DrawComplexTextV2=function(left, yTop, complexText, size)
- {
- this.Canvas.textAlign="left";
- this.Canvas.textBaseline="bottom";
- var showType=0;
- if (complexText.ShowType==1) showType=complexText.ShowType;
- if (showType==1) //多行
- {
- var xLeft=left;
- var yText=yTop; //顶
- for(var i=0; i<complexText.Text.length; ++i)
- {
- var item=complexText.Text[i];
- var itemSize=size.Text[i];
- if (item.Font) this.Canvas.font=item.Font;
- else this.Canvas.font=complexText.Font;
-
- if (item.Color) this.Canvas.fillStyle=item.Color;
- else this.Canvas.fillStyle=complexText.Color;
- var y=yText+itemSize.Height;
- var x=xLeft;
- if (item.Margin)
- {
- var margin=item.Margin;
- if (IFrameSplitOperator.IsNumber(margin.Bottom)) y-=margin.Bottom;
- if (IFrameSplitOperator.IsNumber(margin.Left)) x+=margin.Left;
- }
- this.Canvas.fillText(item.Text,x,y,itemSize.Width);
-
- yText+=itemSize.Height;
- }
- }
- else //水平 单行
- {
- var xText=left;
- var yBottom=yTop+size.Height;
- for(var i=0; i<complexText.Text.length; ++i)
- {
- var item=complexText.Text[i];
- var itemSize=size.Text[i];
- if (item.Font) this.Canvas.font=item.Font;
- else this.Canvas.font=complexText.Font;
-
- if (item.Color) this.Canvas.fillStyle=item.Color;
- else this.Canvas.fillStyle=complexText.Color;
- var y=yBottom;
- var x=xText;
- if (item.Margin)
- {
- var margin=item.Margin;
- if (IFrameSplitOperator.IsNumber(margin.Bottom)) y-=margin.Bottom;
- if (IFrameSplitOperator.IsNumber(margin.Left)) x+=margin.Left;
- }
- this.Canvas.fillText(item.Text,x,y,itemSize.Width);
-
- xText+=itemSize.Width;
- }
- }
- }
- this.DrawComplexRightText=function(rtBG, complexText, size)
- {
- this.Canvas.textAlign="left";
- this.Canvas.textBaseline="bottom";
- var showType=0;
- if (complexText.ShowType==1) showType=complexText.ShowType;
- if (showType==1) //多行
- {
- var xLeft=rtBG.Left;
- var yTop=rtBG.Top; //顶
- for(var i=0; i<complexText.Text.length; ++i)
- {
- var item=complexText.Text[i];
- var itemSize=size.Text[i];
- if (item.Font) this.Canvas.font=item.Font;
- else this.Canvas.font=complexText.Font;
-
- if (item.Color) this.Canvas.fillStyle=item.Color;
- else this.Canvas.fillStyle=complexText.Color;
- var y=yTop+itemSize.Height;
- var x=xLeft;
- if (item.TextOffset)
- {
- var textOffset=item.TextOffset;
- if (IFrameSplitOperator.IsNumber(textOffset.X)) x+=textOffset.X;
- if (IFrameSplitOperator.IsNumber(textOffset.Y)) y+=textOffset.Y;
- }
- this.Canvas.fillText(item.Text,x,y,itemSize.Width);
-
- yTop+=itemSize.Height;
- }
- }
- else //水平 单行
- {
- var xText=rtBG.Left;
- var yBottom=rtBG.Bottom;
- for(var i=0; i<complexText.Text.length; ++i)
- {
- var item=complexText.Text[i];
- var itemSize=size.Text[i];
- if (item.Font) this.Canvas.font=item.Font;
- else this.Canvas.font=complexText.Font;
-
- if (item.Color) this.Canvas.fillStyle=item.Color;
- else this.Canvas.fillStyle=complexText.Color;
- var x=xText;
- var y=yBottom;
- if (item.TextOffset)
- {
- var textOffset=item.TextOffset;
- if (IFrameSplitOperator.IsNumber(textOffset.X)) x+=textOffset.X;
- if (IFrameSplitOperator.IsNumber(textOffset.Y)) y+=textOffset.Y;
- }
-
- this.Canvas.fillText(item.Text,x,y,itemSize.Width);
-
- xText+=itemSize.Width;
- }
- }
- }
- this.HScreenDraw = function ()
- {
- this.Status=JSCHART_CORSSCURSOR_STATUS_ID.NONE_ID;
- var x = this.LastPoint.X;
- var y = this.LastPoint.Y;
- y = this.Frame.GetXFromIndex(this.CursorIndex); //手机端 十字只能画在K线上
- if (this.IsShowClose) //手机端 十字只能画在K线上
- {
- var yPoint = this.GetCloseYPoint(this.CursorIndex);
- if (yPoint != null) x = yPoint;
- }
- else if (this.IsOnlyDrawMinute)
- {
- var yPoint = this.GetMinuteCloseYPoint(this.CursorIndex);
- if (yPoint != null) x=yPoint;
- }
- var left = this.Frame.ChartBorder.GetLeft();
- var right = this.Frame.ChartBorder.GetRightEx();
- var top = this.Frame.ChartBorder.GetTop();
- var bottom = this.Frame.ChartBorder.GetBottom();
- var bottomWidth = this.Frame.ChartBorder.Bottom;
- this.PointY = [[left, y], [right, y]];
- this.PointX = [[x, top], [x, bottom]];
- if (this.IsShowCorss) //十字线
- {
- this.Canvas.save();
- this.Canvas.strokeStyle = this.HPenColor;
- if (this.HPenType == 0) this.Canvas.setLineDash(this.LineDash); //虚线
-
- //画竖线
- this.Canvas.beginPath();
- this.Canvas.moveTo(ToFixedPoint(x), top);
- this.Canvas.lineTo(ToFixedPoint(x), bottom);
- this.Canvas.stroke();
- this.Canvas.restore();
- this.Canvas.save();
- this.Canvas.strokeStyle = this.VPenColor;
- if (this.VPenType == 0)
- {
- this.Canvas.setLineDash(this.LineDash); //虚线
- }
- else if (this.VPenType == 2)
- {
- let barWidth = this.Frame.SubFrame[0].Frame.DataWidth; //和K线一样宽度
- if (barWidth > 2) this.Canvas.lineWidth = barWidth;
- }
- this.Canvas.beginPath();
- //画横线
- if (this.Frame.SubFrame.length > 0)
- {
- for (var i in this.Frame.SubFrame)
- {
- var frame = this.Frame.SubFrame[i].Frame;
- this.Canvas.moveTo(frame.ChartBorder.GetLeft(), ToFixedPoint(y));
- this.Canvas.lineTo(frame.ChartBorder.GetRightTitle(), ToFixedPoint(y));
- }
- }
- else
- {
- this.Canvas.moveTo(left, ToFixedPoint(y));
- this.Canvas.lineTo(right, ToFixedPoint(y));
- }
- this.Status|=JSCHART_CORSSCURSOR_STATUS_ID.LINE_ID;
- this.Canvas.stroke();
- this.Canvas.restore();
- this.Canvas.save();
- this.DrawCorssPoint(x,y);
- this.Canvas.restore();
- }
- var xValue = this.Frame.GetXData(y);
- var yValueExtend = {};
- var yValue = this.Frame.GetYData(x, yValueExtend);
- this.StringFormatX.Value = xValue;
- this.StringFormatY.Value = yValue;
- this.StringFormatY.RValue=yValueExtend.RightYValue; //右侧子坐标
- this.StringFormatY.Point={X:x, Y:y};
- this.StringFormatY.FrameID = yValueExtend.FrameID;
- if (((this.ShowTextMode.Left == 1 && this.Frame.ChartBorder.Top >= 30) || this.ShowTextMode.Left == 2 ||
- (this.ShowTextMode.Right == 1 && this.Frame.ChartBorder.Bottom >= 30) || this.ShowTextMode.Right == 2) && this.StringFormatY.Operator()) {
- var text = this.StringFormatY.Text;
- this.Canvas.font = this.Font;
- var textWidth = this.Canvas.measureText(text).width + 4; //前后各空2个像素
- if (this.Frame.ChartBorder.Top >= 30 && this.ShowTextMode.Left == 1)
- {
- var xText = x, yText = top;
- this.Canvas.save();
- this.Canvas.translate(xText, yText);
- this.Canvas.rotate(90 * Math.PI / 180); //数据和框子旋转180度
- this.Canvas.fillStyle = this.TextBGColor;
- if (top >= textWidth)
- {
- this.Canvas.fillRect(-textWidth, -(this.TextHeight / 2), textWidth, this.TextHeight);
- this.Canvas.textAlign = "right";
- this.Canvas.textBaseline = "middle";
- this.Canvas.fillStyle = this.TextColor;
- this.Canvas.fillText(text, -2, 0, textWidth);
- }
- else
- {
- this.Canvas.fillRect((textWidth - top), -(this.TextHeight / 2), -textWidth, this.TextHeight);
- this.Canvas.textAlign = "right";
- this.Canvas.textBaseline = "middle";
- this.Canvas.fillStyle = this.TextColor;
- this.Canvas.fillText(text, (textWidth - top) - 2, 0, textWidth);
- }
- this.Canvas.restore();
- this.Status|=JSCHART_CORSSCURSOR_STATUS_ID.LEFT_TEXT_ID;
- }
- else if (this.ShowTextMode.Left == 2)
- {
- var xText = x;
- var yText = top;
- this.Canvas.save();
- this.Canvas.translate(xText, yText);
- this.Canvas.rotate(90 * Math.PI / 180); //数据和框子旋转180度
- this.Canvas.fillStyle = this.TextBGColor;
- this.Canvas.fillRect(0, -(this.TextHeight / 2), textWidth, this.TextHeight);
- this.Canvas.textAlign = "left";
- this.Canvas.textBaseline = "middle";
- this.Canvas.fillStyle = this.TextColor;
- this.Canvas.fillText(text, 2, 0, textWidth);
- this.Canvas.restore();
- this.Status|=JSCHART_CORSSCURSOR_STATUS_ID.LEFT_INTER_TEXT_ID;
- }
- if (this.StringFormatY.RText)
- {
- text=this.StringFormatY.RText;
- var textWidth=this.Canvas.measureText(text).width+4; //前后各空2个像素
- }
- if (this.Frame.ChartBorder.Bottom >= 30 && this.ShowTextMode.Right == 1)
- {
- var xText = x, yText = bottom;
- this.Canvas.save();
- this.Canvas.translate(xText, yText);
- this.Canvas.rotate(90 * Math.PI / 180); //数据和框子旋转180度
- this.Canvas.fillStyle = this.TextBGColor;
- if (bottomWidth > textWidth)
- {
- this.Canvas.fillRect(0, -(this.TextHeight / 2), textWidth, this.TextHeight);
- this.Canvas.textAlign = "left";
- this.Canvas.textBaseline = "middle";
- this.Canvas.fillStyle = this.TextColor;
- this.Canvas.fillText(text, 2, 0, textWidth);
- }
- else
- {
- this.Canvas.fillRect((bottomWidth - textWidth), -(this.TextHeight / 2), textWidth, this.TextHeight);
- this.Canvas.textAlign = "left";
- this.Canvas.textBaseline = "middle";
- this.Canvas.fillStyle = this.TextColor;
- this.Canvas.fillText(text, (bottomWidth - textWidth) + 2, 0, textWidth);
- }
- this.Canvas.restore();
- this.Status|=JSCHART_CORSSCURSOR_STATUS_ID.RIGHT_TEXT_ID;
- }
- else if (this.ShowTextMode.Right == 2) {
- var xText = x;
- var yText = bottom;
- this.Canvas.save();
- this.Canvas.translate(xText, yText);
- this.Canvas.rotate(90 * Math.PI / 180); //数据和框子旋转180度
- this.Canvas.fillStyle = this.TextBGColor;
- this.Canvas.fillRect(0, -(this.TextHeight / 2), -textWidth, this.TextHeight);
- this.Canvas.textAlign = "right";
- this.Canvas.textBaseline = "middle";
- this.Canvas.fillStyle = this.TextColor;
- this.Canvas.fillText(text, -2, 0, textWidth);
- this.Canvas.restore();
- this.Status|=JSCHART_CORSSCURSOR_STATUS_ID.RIGHT_INTER_TEXT_ID;
- }
- }
- if ((this.ShowTextMode.Bottom === 1 ||this.ShowTextMode.Bottom==8) && this.StringFormatX.Operator())
- {
- var text = this.StringFormatX.Text;
- this.Canvas.font = this.Font;
- this.Canvas.fillStyle = this.TextBGColor;
- var textWidth = this.Canvas.measureText(text).width + 4; //前后各空2个像素
- var bShowText=true;
- var yText = y;
- var xText=left;
- if (this.ShowTextMode.Bottom==8)
- {
- var event=this.GetEventCallback(JSCHART_EVENT_ID.ON_CUSTOM_CORSSCURSOR_POSITION);
- if (event && event.Callback)
- {
- var sendData={ XText:xText, Height:this.TextHeight, IsShowText:bShowText };
- event.Callback(event, sendData, this);
- xText=sendData.XText;
- bShowText=sendData.IsShowText;
- }
- }
- if (bShowText)
- {
- if (y - textWidth / 2 < 3) //左边位置不够了, 顶着左边画
- {
- this.Canvas.save();
- this.Canvas.translate(xText, yText);
- this.Canvas.rotate(90 * Math.PI / 180); //数据和框子旋转180度
- this.Canvas.fillRect(0, 0, textWidth, this.TextHeight);
- this.Canvas.textAlign = "center";
- this.Canvas.textBaseline = "top";
- this.Canvas.fillStyle = this.TextColor;
- this.Canvas.fillText(text, 0, 0, textWidth);
- this.Canvas.restore();
- }
- else
- {
- this.Canvas.save();
- this.Canvas.translate(xText, yText);
- this.Canvas.rotate(90 * Math.PI / 180); //数据和框子旋转180度
- this.Canvas.fillRect(-(textWidth / 2), 0, textWidth, this.TextHeight);
- this.Canvas.textAlign = "center";
- this.Canvas.textBaseline = "top";
- this.Canvas.fillStyle = this.TextColor;
- this.Canvas.fillText(text, 0, 0, textWidth);
- this.Canvas.restore();
- }
- this.Status|=JSCHART_CORSSCURSOR_STATUS_ID.BOTTOM_TEXT_ID;
- }
- }
- }
- this.DrawCorssPoint=function(x,y)
- {
- var config=this.CorssPointConfig;
- if (!config.Enable) return;
- this.Canvas.beginPath();
- this.Canvas.arc(x,y,config.Center.Radius,0,360,false);
- this.Canvas.closePath();
- if (config.Center && config.Center.Color)
- {
- this.Canvas.fillStyle=config.Center.Color;
- this.Canvas.fill();
- }
-
- if (config.Border && config.Border.Color)
- {
- this.Canvas.strokeStyle=config.Border.Color;
- if (IFrameSplitOperator.IsNumber(config.Border.Width)) this.Canvas.lineWidth=config.Border.Width;
- this.Canvas.stroke();
- }
- }
- this.PtInButton=function(x,y)
- {
- var item=this.PtInButtomButton(x,y);
- if (item) return item;
- return null;
- }
- this.PtInButtomButton=function(x,y)
- {
- if (!this.BottomButton.Enable) return null;
- if (!this.BottomButton.Rect) return null;
- var rect=this.BottomButton.Rect;
- if (x>=rect.Left && x<=rect.Right && y>=rect.Top && y<=rect.Bottom)
- {
- return { Data:this.BottomButton.Data, Rect:rect , Type:2 }; //Type:1=右侧 2=底部
- }
- return null;
- }
- }
- //分钟线
- function ChartMinutePriceLine()
- {
- this.newMethod = ChartLine; //派生
- this.newMethod();
- delete this.newMethod;
- this.YClose;
- this.IsDrawArea = true; //是否画价格面积图
- this.AreaColor = 'rgba(0,191,255,0.1)';
- this.LastPoint={}; //最后一个点的信息 {X, Y, Data:, Value:, DateTime:YYYYMMDDHHMMSS }
-
- this.UpdateLastPoint=function(dateTime, x,y, item)
- {
- if (IFrameSplitOperator.IsNumber(this.LastPoint.DateTime) && this.LastPoint.DateTime>dateTime) return;
- this.LastPoint.DateTime=dateTime;
- this.LastPoint.X=x;
- this.LastPoint.Y=y;
- this.LastPoint.Data=item;
- this.LastPoint.Value=item.Value;
- }
- this.Draw = function ()
- {
- this.LastPoint={};
- if (this.NotSupportMessage)
- {
- this.DrawNotSupportmessage();
- return;
- }
- if (!this.IsShow) return;
- if (!this.Data) return;
- var isHScreen = (this.ChartFrame.IsHScreen === true);
- var dataWidth = this.ChartFrame.DataWidth;
- var distanceWidth = this.ChartFrame.DistanceWidth;
- var chartright = this.ChartBorder.GetRight();
- if (isHScreen === true) chartright = this.ChartBorder.GetBottom();
- var xPointCount = this.ChartFrame.XPointCount;
- var minuteCount = this.ChartFrame.MinuteCount;
- var bottom = this.ChartBorder.GetBottom();
- var left = this.ChartBorder.GetLeft();
- var bFirstPoint = true;
- var ptFirst = {}; //第1个点
- var drawCount = 0;
- var pointCount=0;
- this.Canvas.save();
- this.ClipClient(isHScreen); //裁剪区域 防止线段毛刺超出图形
- if (IFrameSplitOperator.IsPlusNumber(this.LineWidth>0)) this.Canvas.lineWidth=this.LineWidth;
- for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j)
- {
- var value = this.Data.Data[i];
- ++pointCount;
- if (value == null) continue;
- var x = this.ChartFrame.GetXFromIndex(j);
- var y = this.ChartFrame.GetYFromData(value);
- if (bFirstPoint)
- {
- this.Canvas.strokeStyle = this.Color;
- this.Canvas.beginPath();
- if (isHScreen) this.Canvas.moveTo(y, x);
- else this.Canvas.moveTo(x, y);
- bFirstPoint = false;
- ptFirst = { X: x, Y: y };
- }
- else
- {
- if (isHScreen) this.Canvas.lineTo(y, x);
- else this.Canvas.lineTo(x, y);
- }
- if (this.Source)
- {
- var item=this.Source.Data[i];
- var dateTime=item.Date*1000000+item.Time*100;
- this.UpdateLastPoint(dateTime, x,y, { Value:value, Index:i, Date:item.Date, Time:item.Time, Type:0, Explain:"盘中"});
- }
-
- ++drawCount;
- if (pointCount >= minuteCount) //上一天的数据和这天地数据线段要断开
- {
- bFirstPoint = true;
- this.Canvas.stroke();
- if (this.IsDrawArea) //画面积
- {
- if (isHScreen)
- {
- this.Canvas.lineTo(left, x);
- this.Canvas.lineTo(left, ptFirst.X);
- this.SetFillStyle(this.AreaColor, this.ChartBorder.GetRight(), bottom, this.ChartBorder.GetLeftEx(), bottom);
- }
- else
- {
- this.Canvas.lineTo(x, bottom);
- this.Canvas.lineTo(ptFirst.X, bottom);
- this.SetFillStyle(this.AreaColor, left, this.ChartBorder.GetTopEx(), left, bottom);
- }
- this.Canvas.fill();
- }
- drawCount = 0;
- pointCount=0;
- }
- }
- if (drawCount > 0)
- {
- if (drawCount==1) //如果线段只有1个点 线段无法画出来 直接画点
- {
- this.Canvas.beginPath();
- if (isHScreen)
- this.Canvas.arc(ptFirst.Y, ptFirst.X, 1,0,360, false);
- else
- this.Canvas.arc(ptFirst.X, ptFirst.Y, 1,0,360, false);
-
- this.Canvas.closePath();
- this.Canvas.fillStyle=this.Color;
- this.Canvas.fill();
- }
- else
- {
- this.Canvas.stroke();
- if (this.IsDrawArea) //画面积
- {
- if (isHScreen)
- {
- this.Canvas.lineTo(left, x);
- this.Canvas.lineTo(left, ptFirst.X);
- this.SetFillStyle(this.AreaColor, this.ChartBorder.GetRight(), bottom, this.ChartBorder.GetLeftEx(), bottom);
- }
- else
- {
- this.Canvas.lineTo(x, bottom);
- this.Canvas.lineTo(ptFirst.X, bottom);
- this.SetFillStyle(this.AreaColor, left, this.ChartBorder.GetTopEx(), left, bottom);
- }
- this.Canvas.fill();
- }
- }
- }
- this.Canvas.restore();
- if (this.Identify=="Minute-Line" && this.ChartFrame.GlobalOption)
- {
- var globalOption=this.ChartFrame.GlobalOption;
- globalOption.LatestPoint={ X:this.LastPoint.X, Y:this.LastPoint.Y };
- }
- }
- this.GetMaxMin = function ()
- {
- var xPointCount = this.ChartFrame.XPointCount;
- var range = {};
- if (this.YClose == null) return range;
- range.Min = this.YClose;
- range.Max = this.YClose;
- for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j)
- {
- var value = this.Data.Data[i];
- if (!value) continue;
- if (range.Max == null) range.Max = value;
- if (range.Min == null) range.Min = value;
- if (range.Max < value) range.Max = value;
- if (range.Min > value) range.Min = value;
- }
- if (range.Max == this.YClose && range.Min == this.YClose)
- {
- range.Max = this.YClose + this.YClose * 0.1;
- range.Min = this.YClose - this.YClose * 0.1;
- return range;
- }
- var distance = Math.max(Math.abs(this.YClose - range.Max), Math.abs(this.YClose - range.Min));
- range.Max = this.YClose + distance;
- range.Min = this.YClose - distance;
- return range;
- }
- }
- ////////////////////////////////////////////////////////////////////////////////
- //深度图十字光标
- function DepthChartCorssCursor()
- {
- this.Frame;
- this.Canvas; //画布
- this.Data;
- this.Symbol;
- this.HQChart;
- this.HPenType=0; //水平线样式 0=虚线 1=实线
- this.VPenType=0; //垂直线颜色 0=虚线 1=实线
- this.LineDash=g_JSChartResource.DepthCorss.LineDash;
- this.AskColor=g_JSChartResource.DepthCorss.AskColor.Line; //卖
- this.BidColor=g_JSChartResource.DepthCorss.BidColor.Line; //买
- this.LineWidth=g_JSChartResource.DepthCorss.LineWidth;
- this.IsShowTooltip=true;
- this.Tooltip=
- {
- LineHeight:g_JSChartResource.DepthCorss.Tooltip.LineHeight,
- Border:
- {
- Top:g_JSChartResource.DepthCorss.Tooltip.Border.Top,
- Left:g_JSChartResource.DepthCorss.Tooltip.Border.Left,
- Right:g_JSChartResource.DepthCorss.Tooltip.Border.Right,
- Bottom:g_JSChartResource.DepthCorss.Tooltip.Border.Bottom,
- ItemSpace: g_JSChartResource.DepthCorss.Tooltip.Border.ItemSpace
- },
- Font:g_JSChartResource.DepthCorss.Tooltip.Font,
- TextColor:g_JSChartResource.DepthCorss.Tooltip.TextColor,
- BGColor:g_JSChartResource.DepthCorss.Tooltip.BGColor
- }; // Width: Height:
- this.Font=g_JSChartResource.CorssCursorTextFont; //字体
- this.TextColor=g_JSChartResource.CorssCursorTextColor; //文本颜色
- this.TextBGColor=g_JSChartResource.CorssCursorBGColor; //文本背景色
- this.TextHeight=20; //文本字体高度
- this.LastPoint;
- this.PointX;
- this.PointY;
- this.StringFormatX;
- this.StringFormatY;
- this.IsShowCorss=true; //是否显示十字光标
- this.IsShow=true;
- this.GetVol=function(price, isAsk)
- {
- if (!this.Data) return null;
- var aryData=isAsk? this.Data.Asks:this.Data.Bids;
- if (!aryData || !Array.isArray(aryData) || aryData.length<=0) return null;
- for(var i in aryData)
- {
- var item=aryData[i];
- if (item.Price==price) return item.Vol;
- }
- return null;
- }
- this.Draw=function()
- {
- this.Status=0;
- if (!this.LastPoint) return;
- if (!this.Data) return;
- if (!this.IsShow) return;
- var x=this.LastPoint.X;
- var y=this.LastPoint.Y;
- var isInClient=false;
- var rtClient = new Rect(this.Frame.ChartBorder.GetLeft(), this.Frame.ChartBorder.GetTop(), this.Frame.ChartBorder.GetWidth(), this.Frame.ChartBorder.GetHeight());
- isInClient = rtClient.IsPointIn(x, y);
-
- this.PointY=null;
- this.PointY==null;
- if (!isInClient) return;
- if (this.Frame.IsHScreen===true)
- {
- return;
- }
- var left=this.Frame.ChartBorder.GetLeft();
- var right=this.Frame.ChartBorder.GetRight();
- var top=this.Frame.ChartBorder.GetTopTitle();
- var bottom=this.Frame.ChartBorder.GetBottom();
- var rightWidth=this.Frame.ChartBorder.Right;
- var chartRight=this.Frame.ChartBorder.GetChartWidth();
- var xValue=this.Frame.GetXData(x);
- var xInfo=this.Frame.GetXFromPrice(xValue); //调整价格到有数据的点上
- if (!xInfo) return;
- var yVol=this.GetVol(xInfo.Price, xInfo.IsAsk);
- y=this.Frame.GetYFromData(yVol); //调整Y轴, 让它在线段上
- xInfo.Vol=yVol;
- xInfo.Y=y;
-
- this.PointY=[[left,y],[right,y]];
- this.PointX=[[x,top],[x,bottom]];
- if (this.IsShowCorss)
- {
- if (xInfo.IsAsk) this.Canvas.strokeStyle=this.AskColor;
- else this.Canvas.strokeStyle=this.BidColor;
- this.Canvas.save();
- this.Canvas.lineWidth=this.LineWidth;
- var lineWidth=this.Canvas.lineWidth;
- if (this.HPenType==1 || this.HPenType==0) //0=实线 1=虚线
- {
- if (this.HPenType==0) this.Canvas.setLineDash(this.LineDash); //虚线
- var yFix=ToFixedPoint(y);
- this.Canvas.beginPath();
- this.Canvas.moveTo(left,yFix);
- this.Canvas.lineTo(right,yFix);
- this.Canvas.stroke();
- if (this.HPenType==0) this.Canvas.setLineDash([]);
- }
-
- if (this.VPenType==0) this.Canvas.setLineDash(this.LineDash); //虚线
- var xFix=ToFixedPoint(xInfo.X);
- this.Canvas.beginPath();
- this.Canvas.moveTo(xFix,top);
- this.Canvas.lineTo(xFix,bottom);
- this.Canvas.stroke();
- if (this.VPenType==0) this.Canvas.setLineDash([]);
- this.Canvas.restore();
- }
- if (this.HQChart)
- {
- var event=this.HQChart.GetEvent(JSCHART_EVENT_ID.ON_DRAW_DEPTH_TOOLTIP);
- if (event)
- {
- event.Callback(event,xInfo,this);
- }
- }
- if (this.IsShowTooltip)
- {
- var aryText=this.GetFormatTooltip(xInfo);
- this.DrawTooltip(aryText, xInfo);
- }
- }
- //[{Title:, TitleColor:, Text:, Color:}]
- this.GetFormatTooltip=function(drawData)
- {
- var aryText=[];
- var floatPrecision=2;
- if (this.Symbol) floatPrecision=JSCommonCoordinateData.GetfloatPrecision(this.Symbol); //价格小数位数
- var item=
- {
- Title:g_JSChartLocalization.GetText('Depth-Price',this.HQChart.LanguageID),
- TitleColor:this.Tooltip.TextColor,
- Text:drawData.Price.toFixed(floatPrecision),
- Color:this.Tooltip.TextColor
- };
- aryText.push(item);
- var item=
- {
- Title:g_JSChartLocalization.GetText('Depth-Sum',this.HQChart.LanguageID),
- TitleColor:this.Tooltip.TextColor,
- Text:drawData.Vol.toFixed(4),
- Color:this.Tooltip.TextColor
- };
- aryText.push(item);
- return aryText;
- }
- this.DrawTooltip=function(aryText,data)
- {
- if (!IFrameSplitOperator.IsNonEmptyArray(aryText)) return;
- this.Canvas.font=this.Tooltip.Font;
- var maxWidth=0, lineCount=0, itemCount=0;
- for(var i=0;i<aryText.length;++i)
- {
- var item=aryText[i];
- if (!item) continue;
- var isVaild=false;
- if (item.Title)
- {
- var textWidth=this.Canvas.measureText(item.Title).width;
- if (maxWidth<textWidth) maxWidth=textWidth;
- ++lineCount;
- isVaild=true;
- }
- if (item.Text)
- {
- var textWidth=this.Canvas.measureText(item.Text).width;
- if (maxWidth<textWidth) maxWidth=textWidth;
- ++lineCount;
- isVaild=true;
- }
- if (isVaild) ++itemCount;
- }
- if (maxWidth<=0 || lineCount<=0) return;
- var border=this.Tooltip.Border;
- var chartRight=this.Frame.ChartBorder.GetRight();
- var chartTop=this.Frame.ChartBorder.GetTop();
- this.Tooltip.LineHeight=this.Canvas.measureText("擎").width+2;
- this.Tooltip.Width=maxWidth+(border.Left+border.Right);
- this.Tooltip.Height=this.Tooltip.LineHeight*lineCount + (border.Top+border.Bottom) + (border.ItemSpace)*(itemCount-1);
- var left=data.X;
- var top=data.Y-this.Tooltip.Height
- if (left+this.Tooltip.Width>=chartRight) left=data.X-this.Tooltip.Width;
- if (top<chartTop) top=data.Y;
- this.Canvas.fillStyle=this.Tooltip.BGColor;
- this.Canvas.fillRect(left,top,this.Tooltip.Width,this.Tooltip.Height);
- this.Canvas.textBaseline="top";
- this.Canvas.textAlign="left";
- var x=border.Left+left;
- var y=border.Top+top;
- for(var i=0;i<aryText.length;++i)
- {
- var item=aryText[i];
- var isVaild=false;
- if (item.Title)
- {
- if (item.TitleColor) this.Canvas.fillStyle=item.TitleColor;
- else this.Canvas.fillStyle=this.Tooltip.TextColor;
- this.Canvas.fillText(item.Title,x,y);
- y+=this.Tooltip.LineHeight;
- isVaild=true;
- }
- if (item.Text)
- {
- if (item.Color) this.Canvas.fillStyle=item.Color;
- else this.Canvas.fillStyle=this.Tooltip.TextColor;
- this.Canvas.fillText(item.Text,x,y);
- y+=this.Tooltip.LineHeight;
- isVaild=true;
- }
- if (isVaild) y+=border.ItemSpace;
- }
-
- }
- }
- //深度图
- function ChartOrderbookDepth()
- {
- this.newMethod=IChartPainting; //派生
- this.newMethod();
- delete this.newMethod;
- this.ClassName="ChartOrderbookDepth";
- this.Data=null;
- this.AskColor={ Line:g_JSChartResource.DepthChart.AskColor.Line, Area:g_JSChartResource.DepthChart.AskColor.Area } //卖
- this.BidColor={ Line:g_JSChartResource.DepthChart.BidColor.Line, Area:g_JSChartResource.DepthChart.BidColor.Area } //买
- this.LineWidth=g_JSChartResource.DepthChart.LineWidth;
- this.Draw=function()
- {
- if (!this.Data) return;
- this.Canvas.save();
- this.Canvas.lineWidth=this.LineWidth;
- this.DrawArea(this.Data.Bids, this.BidColor.Line, this.BidColor.Area, true);
- this.DrawArea(this.Data.Asks, this.AskColor.Line, this.AskColor.Area, false);
- this.Canvas.restore();
- }
- this.DrawArea=function(aryData, colorLine, colorArea, isLeft)
- {
- var xRange=this.ChartFrame.VerticalRange;
- var aryPoint=[];
- for(var i in aryData)
- {
- var item=aryData[i];
- if (isLeft)
- {
- if (item.Price<xRange.Min) break;
- }
- else
- {
- if (item.Price>xRange.Max) break;
- }
- var x=this.ChartFrame.GetXFromIndex(item.Price);
- var y=this.ChartFrame.GetYFromData(item.Vol);
- aryPoint.push({X:x,Y:y});
- }
- if (aryPoint.length<=1) return;
- var left=this.ChartBorder.GetLeft();
- var bottom=this.ChartBorder.GetBottom();
- var right=this.ChartBorder.GetRight();
- this.Canvas.beginPath();
- this.Canvas.moveTo(aryPoint[0].X, bottom);
- for(var i in aryPoint)
- {
- var item=aryPoint[i];
- this.Canvas.lineTo(item.X,item.Y);
- }
- this.Canvas.lineTo(isLeft?left:right,aryPoint[aryPoint.length-1].Y);
- this.Canvas.lineTo(isLeft?left:right,bottom);
- this.Canvas.lineTo(aryPoint[0].X,bottom);
- this.Canvas.closePath();
- this.Canvas.fillStyle = colorArea;
- this.Canvas.fill();
- this.Canvas.beginPath();
- this.Canvas.moveTo(aryPoint[0].X, bottom);
- for(var i in aryPoint)
- {
- var item=aryPoint[i];
- this.Canvas.lineTo(item.X,item.Y);
- }
- this.Canvas.lineTo(isLeft?left:right,aryPoint[aryPoint.length-1].Y);
- this.Canvas.strokeStyle=colorLine;
- this.Canvas.stroke();
- }
- this.GetMaxMin=function()
- {
- var range={ Min:null, Max:null, XMin:null, XMax:null };
- var xRange=this.ChartFrame.VerticalRange;
- for(var i in this.Data.Asks)
- {
- var item=this.Data.Asks[i];
- if (item.Price>xRange.Max) break;
-
- if (range.XMin==null || range.XMin>item.Price) range.XMin=item.Price;
- if (range.XMax==null || range.XMax<item.Price) range.XMax=item.Price;
- if (range.Min==null || range.Min>item.Vol) range.Min=item.Vol;
- if (range.Max==null || range.Max<item.Vol) range.Max=item.Vol;
- }
- for(var i in this.Data.Bids)
- {
- var item=this.Data.Bids[i];
- if (item.Price<xRange.Min) break;
- if (range.XMin==null || range.XMin>item.Price) range.XMin=item.Price;
- if (range.XMax==null || range.XMax<item.Price) range.XMax=item.Price;
- if (range.Min==null || range.Min>item.Vol) range.Min=item.Vol;
- if (range.Max==null || range.Max<item.Vol) range.Max=item.Vol;
- }
- return range;
- }
- }
- ///////////////////////////////////////////////////////////////////////////////////////
- // 公共函数
- //修正线段有毛刺
- function ToFixedPoint(value)
- {
- //return value;
- return parseInt(value) + 0.5;
- }
- function ToFixedRect(value)
- {
- var rounded;
- return rounded = (0.5 + value) << 0;
- }
- //导出统一使用JSCommon命名空间名
- export
- {
- IChartPainting,
- ChartKLine,
- ChartColorKline,
- ChartLine,
- ChartArea,
- ChartStepLine,
- ChartSubLine,
- ChartSingleText,
- ChartDrawIcon,
- ChartDrawText,
- ChartDrawNumber,
- ChartPointDot,
- ChartStick,
- ChartLineStick,
- ChartStickLine,
- ChartBackground,
- ChartBackgroundDiv,
- ChartMinuteVolumBar,
- ChartOverlayKLine,
- ChartLock,
- ChartVolStick,
- ChartBand,
- ChartMinutePriceLine,
- ChartOverlayMinutePriceLine,
- ChartLineMultiData,
- ChartStraightLine,
- ChartMultiSVGIconV2,
- ChartMinuteInfo,
- ChartRectangle,
- ChartMultiText,
- ChartMultiLine,
- ChartMultiPoint,
- ChartMultiHtmlDom,
- ChartMultiBar,
- ChartBuySell,
- ChartMACD,
- ChartStackedBar,
- ChartText,
- ChartStraightArea,
- ChartCorssCursor,
- DepthChartCorssCursor,
- ChartOrderbookDepth,
- ChartSplashPaint,
- GetFontHeight,
- ColorToRGBA,
- ChartSingleLine,
- ChartPartLine,
- ChartDrawText_Fix,
- ChartDrawNumber_Fix
- };
|