| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194 |
- using Microsoft.VisualBasic.CompilerServices;
- using MuchInfo.Chart.Data.EnumTypes;
- using MuchInfo.Chart.Data.Interfaces;
- using MuchInfo.Chart.Data.Models;
- using MuchInfo.Chart.FormulaEdit;
- using MuchInfo.Chart.Infrastructure.Data;
- using MuchInfo.Chart.Infrastructure.Helpers;
- using MuchInfo.Chart.Infrastructure.Utilities;
- using MuchInfo.Chart.WPF.Controls.Drawing;
- using MuchInfo.Chart.WPF.Controls.QuickTimeSpan;
- using MuchInfo.Chart.WPF.Controls.ValueScaling;
- using MuchInfo.Chart.WPF.Helpers;
- using MuchInfo.Chart.WPF.Primitives;
- using MuchInfo.Chart.WPF.Primitives.Drawing;
- using MuchInfo.Chart.WPF.Primitives.Interfaces;
- using System;
- using System.Collections.Generic;
- using System.Globalization;
- using System.Linq;
- using System.Runtime.CompilerServices;
- using System.Threading.Tasks;
- using System.Windows;
- using System.Windows.Controls;
- using System.Windows.Controls.Primitives;
- using System.Windows.Input;
- using System.Windows.Media;
- using System.Windows.Shapes;
- using System.Windows.Threading;
- using Xceed.Wpf.Toolkit;
- namespace MuchInfo.Chart.WPF
- {
- #region Delegates
- /// <summary>
- /// 通过CycleType加载历史周期数据
- /// </summary>
- /// <param name="exchangeCode">交易所代码</param>
- /// <param name="goodsCode">商品代码</param>
- /// <param name="type">周期</param>
- /// <param name="startTime">起始时间</param>
- /// <param name="endTime">结束时间</param>
- /// <param name="topN">数据前N条</param>
- /// <returns>List{ILineDataPoint}.</returns>
- public delegate List<ILineDataPoint> LoadHistoryCycleDataByCycleTypeEventHandler(int exchangeCode, string goodsCode, CycleType type, TimeSpan timeSpan, DateTime startTime, DateTime endTime, int topN);
- #endregion Delegates
- /// <summary>
- /// WPF图表控件
- /// </summary>
- public class Chart : Control
- {
- #region 依赖属性
- /// <summary>
- /// 左右键增减周期值
- /// </summary>
- public static readonly DependencyProperty LeftRightKeyToAccelerationProperty =
- DependencyProperty.Register("LeftRightKeyToAcceleration", typeof(int), typeof(Chart), new PropertyMetadata(10));
- /// <summary>
- /// 鼠标滚轮加速缩放因数
- /// </summary>
- public static readonly DependencyProperty AcceleratedWheelFactorProperty =
- DependencyProperty.Register("AcceleratedWheelFactor", typeof(int), typeof(Chart), new PropertyMetadata(10));
- /// <summary>
- /// 鼠标滚轮加速缩放键
- /// </summary>
- public static readonly DependencyProperty AcceleratedWheelModifierKeysProperty =
- DependencyProperty.Register("AcceleratedWheelModifierKeys", typeof(ModifierKeys), typeof(Chart),
- new PropertyMetadata(ModifierKeys.Control));
- /// <summary>
- /// 背景色
- /// </summary>
- public static readonly DependencyProperty ChartBackgroundProperty =
- DependencyProperty.Register("ChartBackground", typeof(SolidColorBrush), typeof(Chart),
- new PropertyMetadata(new SolidColorBrush(Colors.Black),
- new PropertyChangedCallback(Chart.ChartFontSizeProperty_Changed)));
- /// <summary>
- /// 字体大小
- /// </summary>
- public static readonly DependencyProperty ChartFontSizeProperty = DependencyProperty.Register("ChartFontSize",
- typeof(double), typeof(Chart),
- new PropertyMetadata(12d, new PropertyChangedCallback(Chart.ChartFontSizeProperty_Changed)));
- /// <summary>
- /// 绘图类型
- /// </summary>
- public static readonly DependencyProperty ChartLanguageProperty = DependencyProperty.Register("ChartLanguage",
- typeof(ChartLanguageType), typeof(Chart),
- new PropertyMetadata(ChartLanguageType.SimplifiedChinese,
- new PropertyChangedCallback(Chart.ChartLanguageProperty_Changed)));
- /// <summary>
- /// The chart time span property
- /// </summary>
- public static readonly DependencyProperty ChartTimeSpanProperty = DependencyProperty.Register("ChartTimeSpan",
- typeof(TimeSpan), typeof(Chart),
- new PropertyMetadata(default(TimeSpan), Chart.ChartTimeSpanProperty_Changed));
- /// <summary>
- /// The current goods property
- /// </summary>
- public static readonly DependencyProperty CurrentGoodsProperty = DependencyProperty.Register("CurrentGoods",
- typeof(GoodsInfo), typeof(Chart), new PropertyMetadata(null, Chart.CurrentGoodsProperty_Changed));
- /// <summary>
- /// 商品周期
- /// </summary>
- public static readonly DependencyProperty CycleTypeProperty = DependencyProperty.Register("CycleType",
- typeof(CycleType), typeof(Chart),
- new PropertyMetadata(CycleType.Minute, new PropertyChangedCallback(Chart.ChartCycleTypeProperty_Changed)));
- /// <summary>
- /// 商品周期集合
- /// </summary>
- public static readonly DependencyProperty CycleItemsProperty =
- DependencyProperty.Register("CycleItems", typeof(List<CycleType>),
- typeof(Chart), new PropertyMetadata(new List<CycleType>(), new PropertyChangedCallback(Chart.ChartCycleTypeItemsProperty_Changed)));
- /// <summary>
- /// 当前Tik数据,只需更新Tik数据即可,控件自动累加
- /// </summary>
- public BarDataPoint CurrentTik
- {
- get { return (BarDataPoint)GetValue(CurrentTikProperty); }
- set { SetValue(CurrentTikProperty, value); }
- }
- public static readonly DependencyProperty CurrentTikProperty =
- DependencyProperty.Register("CurrentTik", typeof(BarDataPoint), typeof(Chart),
- new PropertyMetadata(null, new PropertyChangedCallback(Chart.ChartTikProperty_Changed)));
- /// <summary>
- /// 画线工具位置
- /// </summary>
- public static readonly DependencyProperty DrawingToolPositionProperty =
- DependencyProperty.Register("DrawingToolPosition", typeof(DrawingToolPositionType), typeof(Chart),
- new PropertyMetadata(DrawingToolPositionType.Left,
- new PropertyChangedCallback(Chart.DrawingToolPositionProperty_Changed)));
- /// <summary>
- /// 当前画线工具:可通过设置值来模拟画线工具单击事件
- /// </summary>
- public static readonly DependencyProperty DrawingToolTypeProperty =
- DependencyProperty.Register("DrawingToolType", typeof(DrawingToolType), typeof(Chart),
- new PropertyMetadata(DrawingToolType.Cross, new PropertyChangedCallback(Chart.DrawingToolType_Changed)));
- /// <summary>
- /// 蜡烛图叠加是否填充
- /// </summary>
- public static readonly DependencyProperty FillComparisonCandleProperty =
- DependencyProperty.Register("FillComparisonCandle", typeof(bool), typeof(Chart),
- new PropertyMetadata(false, Chart.ChartProperty_Changed));
- /// <summary>
- /// 网格透明度
- /// </summary>
- public static readonly DependencyProperty GridOpacityProperty = DependencyProperty.Register("GridOpacity",
- typeof(double), typeof(Chart),
- new PropertyMetadata(0.15d, new PropertyChangedCallback(Chart.ChartProperty_Changed)));
- /// <summary>
- /// 绘图类型
- /// </summary>
- public static readonly DependencyProperty LinePlotTypeProperty = DependencyProperty.Register("LinePlotType",
- typeof(LinePlotType), typeof(Chart),
- new PropertyMetadata(LinePlotType.Candlestick,
- new PropertyChangedCallback(Chart.ChartLineTypePlotProperty_Changed)));
- /// <summary>
- /// 最大加载数据条数
- /// </summary>
- public static readonly DependencyProperty MaxLoadRecordCountProperty =
- DependencyProperty.Register("MaxLoadRecordCount", typeof(int), typeof(Chart), new PropertyMetadata(500));
- /// <summary>
- /// 最大显示数据条数
- /// </summary>
- public static readonly DependencyProperty MaxRecordCountProperty = DependencyProperty.Register(
- "MaxRecordCount", typeof(int), typeof(Chart),
- new PropertyMetadata(1000, new PropertyChangedCallback(Chart.ChartMinMaxRecordProperty_Changed)));
- /// <summary>
- /// 最小显示数据条数
- /// </summary>
- public static readonly DependencyProperty MinRecordCountProperty = DependencyProperty.Register(
- "MinRecordCount", typeof(int), typeof(Chart),
- new PropertyMetadata(50, new PropertyChangedCallback(Chart.ChartMinMaxRecordProperty_Changed)));
- /// <summary>
- /// 显示数据条数
- /// </summary>
- public static readonly DependencyProperty RecordCountProperty = DependencyProperty.Register("RecordCount",
- typeof(int), typeof(Chart),
- new PropertyMetadata(100, new PropertyChangedCallback(Chart.ChartRecordCountProperty_Changed)));
- /// <summary>
- /// 是否显示画线工具
- /// </summary>
- public static readonly DependencyProperty ShowDrawingToolProperty =
- DependencyProperty.Register("ShowDrawingTool", typeof(Visibility), typeof(Chart),
- new PropertyMetadata(Visibility.Visible,
- new PropertyChangedCallback(ElementInvalidator.PropertyChanged_InvalidateMeasureArrange)));
- /// <summary>
- /// 画图工具是否可用
- /// </summary>
- public bool DrawingToolIsEnabled
- {
- get { return (bool)GetValue(DrawingToolIsEnabledProperty); }
- set { SetValue(DrawingToolIsEnabledProperty, value); }
- }
- public static readonly DependencyProperty DrawingToolIsEnabledProperty =
- DependencyProperty.Register("DrawingToolIsEnabled", typeof(bool), typeof(Chart), new PropertyMetadata(true));
- /// <summary>
- /// 最多可显示多少个ChartPane
- /// </summary>
- public int MaxChartPaneCount
- {
- get { return (int)GetValue(MaxChartPaneCountProperty); }
- set { SetValue(MaxChartPaneCountProperty, value); }
- }
- public static readonly DependencyProperty MaxChartPaneCountProperty =
- DependencyProperty.Register("MaxChartPaneCount", typeof(int), typeof(Chart), new PropertyMetadata(5));
- /// <summary>
- /// 设置分时图网格与刻度的坐标
- /// </summary>
- public Brush TimeSharingGridBrush
- {
- get { return (Brush)GetValue(TimeSharingGridBrushProperty); }
- set { SetValue(TimeSharingGridBrushProperty, value); }
- }
- public static readonly DependencyProperty TimeSharingGridBrushProperty =
- DependencyProperty.Register("TimeSharingGridBrush", typeof(Brush), typeof(Chart),
- new PropertyMetadata(Brushes.Red));
- /// <summary>
- /// 设置合适的边距缓冲区
- /// </summary>
- public int RightBuffer
- {
- get { return (int)GetValue(RightBufferProperty); }
- set { SetValue(RightBufferProperty, value); }
- }
- public static readonly DependencyProperty RightBufferProperty =
- DependencyProperty.Register("RightBuffer", typeof(int), typeof(Chart), new PropertyMetadata(20));
- public Visibility CycleBarVisibility
- {
- get { return (Visibility)GetValue(CycleBarVisibilityProperty); }
- set { SetValue(CycleBarVisibilityProperty, value); }
- }
- // Using a DependencyProperty as the backing store for CycleBarVisibility. This enables animation, styling, binding, etc...
- public static readonly DependencyProperty CycleBarVisibilityProperty =
- DependencyProperty.Register("CycleBarVisibility", typeof(Visibility), typeof(Chart), new PropertyMetadata(Visibility.Visible, new PropertyChangedCallback(Chart.ChartCycleBarVisibity)));
-
- /// <summary>
- /// 加载历史周期数据 By CycleType
- /// </summary>
- public LoadHistoryCycleDataByCycleTypeEventHandler LoadHistoryCycleDataByCycleType;
- /// <summary>
- /// drawLINE
- /// </summary>
- private static IDrawingTool _oldDrawingTool;
- //头容器
- private StackPanel _chartHeaderStackPanel;
- //chart pane容器
- private Grid _chartPanesGrid;
- private ChartToolbarExpander _chartToolbarExpander;
- private List<ComparisonGoods> _comparisonGoodsList;
- private DateTime _crossDateTime;
- /// <summary>
- /// 十字光标鼠标按下状态
- /// </summary>
- private bool _crossFlag;
- //十字光标容器
- private Canvas _crossHairGrid;
- private Path _crossPath;
- private Line _hline = new Line(); //横线
- private Line _vline = new Line(); //竖线
- /// <summary>
- /// 十字光标面板x坐标
- /// </summary>
- private double _crossX;
- private IDrawingTool _currentDrawingTool;
- private double _currentX;
- private double _currentY;
- //数据滑块容器
- private StackPanel _dateChartSliderStackPanel;
- private DateScaleDisplay _dateScaleDisplay;
- private Button _downloadMoreButton;
- private TextBlock _downloadMoreButtonPlaceHolder;
- private ChartDrawingToolbar _drawingToolbar;
- //画线工具容器
- private StackPanel _drawingToolStackPanel;
- //商品信息
- private GoodsInfo _goodsInfo;
- ///指标器容器
- //private ComboBox _indicatorComboBox;
- public Grid _mainGrid;
- private BusyIndicator _exportBusyIndicator;
- /// <summary>
- /// 上一个鼠标样式
- /// </summary>
- private PointerType _oldPointerType;
- private Grid _pointerGrid;
- private Popup _pointerPopup;
- /// <summary>
- /// 当前鼠标样式,初始为显示十字光标
- /// </summary>
- private PointerType _pointerType;
- private Popup _popup;
- /// <summary>
- /// The timespan control
- /// </summary>
- private QuickTimeSpan _timeSpanControl;
- //显示标签控件
- //private TextBlock _symbolTextBlock;
- private Image _toolImage;
- /// <summary>
- /// 当前图中添加图表容器
- /// </summary>
- private List<ChartPane> _chartPanes = new List<ChartPane>();
- private DispatcherTimer _timeSharingTimer;
- private DisplayFormula timeSharingFormulaModel; //分时图实体,用于更新当前分时图数据
- private DisplayFormula _tikFormulaModel; //即时图,更新Tik图表数据
- private DisplayFormula _minuteFormulaModel; //
- private Dictionary<string, DisplayFormula> _comparisonFommulaHsSet = new Dictionary<string, DisplayFormula>();
- private List<ChartPane> _chartCachePanes = new List<ChartPane>(); //缓存切换周期时商品状态
- private static readonly object _lockObject = new Object();
- #endregion Fields
- #region Constructors
- /// <summary>
- /// 静态构造函数
- /// </summary>
- static Chart()
- {
- DefaultStyleKeyProperty.OverrideMetadata(typeof(Chart), new FrameworkPropertyMetadata(typeof(Chart)));
- }
- /// <summary>
- /// 构造函数
- /// </summary>
- public Chart()
- {
- this.Focusable = true;
- //默认加载简体中文
- LanguageManager.SetLanguage(CultureInfo.InstalledUICulture.Name);
- _dateScaleDisplay = new DateScaleDisplay(this);
- DateScaler = new AllDateScaler(this);
- _toolImage = new Image();
- DateChartSlider = new DateChartSlider(this);
- TimeSpanPicker = new QuickTimeSpan(this);
- RightBuffer = 0;
- //ChartRedrawTimer.Interval = new TimeSpan(0, 0, 0, 0, ChartRedrawSpeed);
- _oldDrawingTool = new DrawingTrendLine();
- _pointerType = PointerType.CursorWithData;
- _oldPointerType = PointerType.CursorWithData;
- LockPainting = false;
- ComparisionDictionary = new Dictionary<string, List<ILineDataPoint>>();
- _timeSharingTimer = new DispatcherTimer();
- _timeSharingTimer.Interval = new TimeSpan(0, 0, 1, 0);
- _timeSharingTimer.Tick += _timeSharingTimer_Tick;
- ComparisionTimeShareDic = new Dictionary<string, List<ILineDataPoint>>();
- }
- #endregion Constructors
- #region Properties
- #region Public Properties
- /// <summary>
- /// ChartRedrawSpeed,图表重绘速度,用于鼠标拖动,画图工具拖动等,单位为毫秒
- /// </summary>
- public int ChartRedrawSpeed = 1000 / 30;
- /// <summary>
- /// ChartRedrawTimer,图表重绘定时器
- /// </summary>
- DispatcherTimer ChartRedrawTimer = new DispatcherTimer();
- private const string _defaoltIndecator = "EMA4,MACD";
- private DateTime _goodsQuoteTime; //分时图行情时间
- /// <summary>
- /// 左右键增减周期值
- /// </summary>
- public int LeftRightKeyToAcceleration
- {
- get { return (int)GetValue(LeftRightKeyToAccelerationProperty); }
- set { SetValue(LeftRightKeyToAccelerationProperty, value); }
- }
- /// <summary>
- /// 加速因数
- /// </summary>
- public int AcceleratedWheelFactor
- {
- get
- {
- return (int)base.GetValue(Chart.AcceleratedWheelFactorProperty);
- }
- set
- {
- base.SetValue(Chart.AcceleratedWheelFactorProperty, value);
- }
- }
- /// <summary>
- /// 加速鼠标中键缩放键
- /// </summary>
- public ModifierKeys AcceleratedWheelModifierKeys
- {
- get
- {
- return (ModifierKeys)base.GetValue(Chart.AcceleratedWheelModifierKeysProperty);
- }
- set
- {
- base.SetValue(Chart.AcceleratedWheelModifierKeysProperty, value);
- }
- }
- /// <summary>
- /// 获取或设置一个用于描述控件背景的画笔。
- /// </summary>
- public SolidColorBrush ChartBackground
- {
- get
- {
- return (SolidColorBrush)base.GetValue(Chart.ChartBackgroundProperty);
- }
- set
- {
- base.SetValue(Chart.ChartBackgroundProperty, value);
- }
- }
- /// <summary>
- /// Gets the color of the chart background.
- /// </summary>
- public Color ChartBackgroundColor
- {
- get
- {
- return ColorHelper.ColorFromBrush(ChartBackground);
- }
- }
- /// <summary>
- /// 获取或设置字号。
- /// </summary>
- public double ChartFontSize
- {
- get
- {
- var value = (double)base.GetValue(Chart.ChartFontSizeProperty);
- if (value <= 0) value = 12;
- return value;
- }
- set
- {
- if (value <= 0) value = 12;
- base.SetValue(Chart.ChartFontSizeProperty, value);
- }
- }
- /// <summary>
- /// 图表语言类型
- /// </summary>
- public ChartLanguageType ChartLanguage
- {
- get
- {
- return (ChartLanguageType)base.GetValue(Chart.ChartLanguageProperty);
- }
- set
- {
- base.SetValue(Chart.ChartLanguageProperty, value);
- }
- }
- /// <summary>
- /// Gets or sets the chart time span.
- /// </summary>
- /// <value>The chart time span.</value>
- public TimeSpan ChartTimeSpan
- {
- get { return (TimeSpan)GetValue(ChartTimeSpanProperty); }
- set { SetValue(ChartTimeSpanProperty, value); }
- }
- public IDrawingTool CurrentDrawingTool
- {
- get
- {
- return _currentDrawingTool;
- }
- set
- {
- _currentDrawingTool = value;
- bool flag = value != null;
- if (flag)
- {
- PointerType = PointerType.Drawing;
- }
- }
- }
- ///// <summary>
- ///// 商品信息
- //// </summary>
- public GoodsInfo CurrentGoods
- {
- get { return (GoodsInfo)GetValue(CurrentGoodsProperty); }
- set { SetValue(CurrentGoodsProperty, value); }
- }
- /// <summary>
- /// 商品周期
- /// </summary>
- public List<CycleType> CycleItems
- {
- get { return (List<CycleType>)GetValue(CycleItemsProperty); }
- set { SetValue(CycleItemsProperty, value); }
- }
- /// <summary>
- /// 根据周期生成TimeSpan
- /// </summary>
- public TimeSpan CurrentTimeFrame
- {
- get
- {
- switch (CycleType)
- {
- case CycleType.Minute:
- return new TimeSpan(0, 1, 0);
- case CycleType.Minute3:
- return new TimeSpan(0, 3, 0);
- case CycleType.Minute5:
- return new TimeSpan(0, 5, 0);
- case CycleType.Minute10:
- return new TimeSpan(0, 10, 0);
- case CycleType.Minute15:
- return new TimeSpan(0, 15, 0);
- case CycleType.Minute30:
- return new TimeSpan(0, 30, 0);
- case CycleType.Minute60:
- return new TimeSpan(1, 0, 0);
- case CycleType.Minute90:
- return new TimeSpan(1, 30, 0);
- case CycleType.Minute120:
- return new TimeSpan(2, 0, 0);
- case CycleType.Minute180:
- return new TimeSpan(3, 0, 0);
- case CycleType.Minute240:
- return new TimeSpan(4, 0, 0);
- case CycleType.Hour:
- return new TimeSpan(1, 0, 0);
- case CycleType.Day:
- return new TimeSpan(1, 0, 0, 0);
- case CycleType.Week:
- return new TimeSpan(7, 0, 0, 0, 0);
- case CycleType.Month:
- return new TimeSpan(30, 0, 0, 0);
- case CycleType.Quarter:
- return new TimeSpan(90, 0, 0, 0);
- case CycleType.Year:
- return new TimeSpan(255, 0, 0, 0);
- case CycleType.Custom:
- return ChartTimeSpan;
- default:
- //分时图为1分
- return new TimeSpan(0, 1, 0);
- }
- }
- }
- /// <summary>
- /// 是否在周期内
- /// </summary>
- public bool IsNotInCycle(DateTime tikTime, ref DateTime CycleDate)
- {
- var Rlt = default(bool);
- if (DataSet != null && DataSet.DataPoints != null && DataSet.DataPoints.Count() > 0 && tikTime != DateTime.MinValue)
- {
- var dt = DataSet.DataPoints.Last().Date;
- var ts = tikTime - dt;
- var newDt = new DateTime(dt.Year, dt.Month, dt.Day, dt.Hour, dt.Minute, 0).AddMinutes(CurrentTimeFrame.TotalMinutes);
- switch (CycleType)
- {
- case CycleType.Minute:
- case CycleType.Minute3:
- case CycleType.Minute5:
- case CycleType.Minute10:
- case CycleType.Minute15:
- case CycleType.Minute30:
- case CycleType.Minute60:
- case CycleType.Minute90:
- case CycleType.Minute120:
- case CycleType.Minute180:
- case CycleType.Minute240:
- case CycleType.Custom:
- case CycleType.Hour:
- Rlt = tikTime >= newDt;
- if (Rlt)
- {
- CycleDate = new DateTime(dt.Year, dt.Month, dt.Day, dt.Hour, dt.Minute, 0).AddMinutes((Math.Floor((ts.TotalMinutes / CurrentTimeFrame.TotalMinutes)) * CurrentTimeFrame.TotalMinutes));
- }
- break;
- case CycleType.Day:
- Rlt = tikTime >= new DateTime(dt.Year, dt.Month, dt.Day ).AddDays(1);
- if (Rlt)
- {
- CycleDate = new DateTime(dt.Year, dt.Month, dt.Day).AddDays((Math.Floor((ts.TotalDays / CurrentTimeFrame.TotalDays)) * CurrentTimeFrame.TotalDays));
- }
- break;
- case CycleType.Week:
- Rlt = tikTime >= new DateTime(dt.Year, dt.Month, dt.Day ).AddDays((7 - ((int)(DayOfWeek)dt.DayOfWeek)));
- if (Rlt)
- {
- CycleDate = new DateTime(dt.Year, dt.Month, dt.Day).AddDays((Math.Floor((ts.TotalDays / CurrentTimeFrame.TotalDays)) * CurrentTimeFrame.TotalDays));
- }
- break;
- case CycleType.Month:
- Rlt = tikTime >= new DateTime(dt.Year, dt.Month , 1).AddMonths(1);
- if (Rlt)
- {
- CycleDate = new DateTime(dt.Year, tikTime.Month, 1);
- }
- break;
- case CycleType.Quarter:
- Rlt = tikTime >= new DateTime(dt.Year, dt.Month , 1).AddMonths(3);
- if (Rlt)
- {
- var mm = (Math.Floor((ts.TotalDays / CurrentTimeFrame.TotalDays)) * CurrentTimeFrame.TotalDays);
- CycleDate = new DateTime(dt.Year, dt.Month, 1).AddDays(mm);
- }
- break;
- case CycleType.Year:
- Rlt = tikTime >= new DateTime(dt.Year + 1, 1, 1);
- if (Rlt)
- {
- CycleDate = new DateTime(tikTime.Year, 1, 1);
- }
- break;
- default:
- Rlt = false;
- break;
- }
- //Console.WriteLine("time:{0} tikTime:{1} newdate Rlt:{2} RltTime:{3}", dt.ToString(), tikTime.ToString(), newDt.ToString(), Rlt.ToString(), CycleDate.ToString());
- }
- return Rlt;
- }
- /// <summary>
- /// 商品周期
- /// </summary>
- public CycleType CycleType
- {
- get
- {
- return (CycleType)base.GetValue(Chart.CycleTypeProperty);
- }
- set
- {
- if (value != CycleType.Custom)
- {
- ChartTimeSpan = default(TimeSpan);
- }
- base.SetValue(Chart.CycleTypeProperty, value);
- }
- }
- /// <summary>
- /// 数据滑块
- /// </summary>
- public DateChartSlider DateChartSlider
- {
- get;
- set;
- }
- /// <summary>
- /// Gets the drawing min chart span percent.
- /// </summary>
- public float DrawingMinChartSpanPercent
- {
- get
- {
- return 5f;
- }
- }
- /// <summary>
- /// 画线工具位置
- /// </summary>
- public DrawingToolPositionType DrawingToolPosition
- {
- get
- {
- return (DrawingToolPositionType)base.GetValue(Chart.DrawingToolPositionProperty);
- }
- set
- {
- base.SetValue(Chart.DrawingToolPositionProperty, value);
- }
- }
- /// <summary>
- /// 当前画线工具
- /// </summary>
- public DrawingToolType DrawingToolType
- {
- get
- {
- return (DrawingToolType)base.GetValue(Chart.DrawingToolTypeProperty);
- }
- set
- {
- base.SetValue(Chart.DrawingToolTypeProperty, value);
- }
- }
- /// <summary>
- /// 蜡烛图叠加是否填充
- /// </summary>
- public bool FillComparisonCandle
- {
- get { return (bool)GetValue(FillComparisonCandleProperty); }
- set { SetValue(FillComparisonCandleProperty, value); }
- }
- /// <summary>
- /// 获取或设置一个用于描述控件背景的画笔。
- /// </summary>
- public double GridOpacity
- {
- get
- {
- return (double)base.GetValue(Chart.GridOpacityProperty);
- }
- set
- {
- base.SetValue(Chart.GridOpacityProperty, value);
- }
- }
- /// <summary>
- /// Gets a value indicating whether this instance is dark background.
- /// </summary>
- public bool IsDarkBackground
- {
- get
- {
- var brush = ChartBackground as SolidColorBrush;
- if (brush != null)
- {
- return ColorHelper.ColorIsDark(brush.Color);
- }
- return false;
- }
- }
- /// <summary>
- /// Gets a value indicating whether [limit drawings by span].
- /// </summary>
- public bool LimitDrawingsBySpan
- {
- get
- {
- return true;
- }
- }
- /// <summary>
- /// 获取或设置一个用于描述控件背景的画笔。
- /// </summary>
- public LinePlotType LinePlotType
- {
- get
- {
- return (LinePlotType)base.GetValue(Chart.LinePlotTypeProperty);
- }
- set
- {
- base.SetValue(Chart.LinePlotTypeProperty, value);
- }
- }
- /// <summary>
- /// 最大加载数据条数
- /// </summary>
- public int MaxLoadRecordCount
- {
- get { return (int)GetValue(MaxLoadRecordCountProperty); }
- set { SetValue(MaxLoadRecordCountProperty, value); }
- }
- /// <summary>
- /// 最大条数
- /// </summary>
- public int MaxRecordCount
- {
- get
- {
- return (int)base.GetValue(Chart.MaxRecordCountProperty);
- }
- set
- {
- base.SetValue(Chart.MaxRecordCountProperty, value);
- }
- }
- /// <summary>
- /// 最小条数
- /// </summary>
- public int MinRecordCount
- {
- get
- {
- return (int)base.GetValue(Chart.MinRecordCountProperty);
- }
- set
- {
- base.SetValue(Chart.MinRecordCountProperty, value);
- }
- }
- /// <summary>
- /// 返回叠加商品
- /// </summary>
- public List<ComparisonGoods> ComparisonGoodsList
- {
- get
- {
- return _comparisonGoodsList;
- }
- }
- /// <summary>
- /// 分时图使用的显示最大点数据,根据开收盘时间计算
- /// </summary>
- private int _timeSharingMaxPointCount = 60;
- internal int MaxRecordCountInternal
- {
- get
- {
- if (CycleType == CycleType.TimeSharing)
- {
- return _timeSharingMaxPointCount;
- }
- else
- {
- return MaxRecordCount;
- }
- }
- }
- internal int MinRecordCountInternal
- {
- get
- {
- if (CycleType == CycleType.TimeSharing)
- {
- return _timeSharingMaxPointCount;
- }
- else
- {
- return MinRecordCount;
- }
- }
- }
- internal int RecordCountInternal
- {
- get
- {
- if (CycleType == CycleType.TimeSharing)
- {
- return _timeSharingMaxPointCount;
- }
- else
- {
- return RecordCount;
- }
- }
- }
- /// <summary>
- /// Gets or sets the type of the pointer.
- /// </summary>
- /// <value>The type of the pointer.</value>
- public PointerType PointerType
- {
- get
- {
- return _pointerType;
- }
- set
- {
- bool flag = value != _pointerType;
- if (flag)
- {
- bool flag2 = value != PointerType.Drawing && value != PointerType.Erase;
- if (flag2)
- {
- _oldPointerType = value;
- }
- _pointerType = value;
- flag2 = (_pointerType != PointerType.Drawing);
- if (flag2)
- {
- CurrentDrawingTool = null;
- }
- }
- }
- }
- /// <summary>
- /// 显示数据条数
- /// </summary>
- public int RecordCount
- {
- get
- {
- return (int)base.GetValue(Chart.RecordCountProperty);
- }
- set
- {
- base.SetValue(Chart.RecordCountProperty, value);
- }
- }
- /// <summary>
- /// Gets or sets the show drawing tool.
- /// </summary>
- public Visibility ShowDrawingTool
- {
- get
- {
- return (Visibility)base.GetValue(Chart.ShowDrawingToolProperty);
- }
- set
- {
- base.SetValue(Chart.ShowDrawingToolProperty, value);
- }
- }
- /// <summary>
- /// Gets or sets a value indicating whether [show legend arrows].
- /// </summary>
- public bool ShowLegendArrows
- {
- get;
- set;
- }
- /// <summary>
- /// Gets or sets the time span picker.
- /// </summary>
- public QuickTimeSpan TimeSpanPicker
- {
- get
- {
- return _timeSpanControl;
- }
- set
- {
- _timeSpanControl = value;
- }
- }
- #endregion Public Properties
- #region Internal Properties
- /// <summary>
- /// 叠加商品字典
- /// </summary>
- internal Dictionary<string, List<ILineDataPoint>> ComparisionDictionary
- {
- get;
- set;
- }
- /// <summary>
- /// 分时图商品字典
- /// </summary>
- internal Dictionary<string, List<ILineDataPoint>> ComparisionTimeShareDic
- {
- get;
- set;
- }
- /// <summary>
- /// Gets the current symbol.
- /// </summary>
- internal string CurrentSymbol
- {
- get
- {
- var goods = CurrentGoods;
- if (goods == null || string.IsNullOrWhiteSpace(goods.Symbol)) return string.Empty;
- return goods.Symbol;
- }
- }
- /// <summary>
- /// 数据集
- /// </summary>
- internal ChartDataSet DataSet
- {
- get;
- set;
- }
- /// <summary>
- /// Gets or sets the date scaler.
- /// </summary>
- internal IDateScaler DateScaler
- {
- get;
- set;
- }
- private int _offSetNum = 0;
- /// <summary>
- /// Gets or sets a value indicating whether [lock painting].
- /// </summary>
- internal bool LockPainting
- {
- get;
- set;
- }
- /// <summary>
- /// 是否为分时图,控制部分内容不显示
- /// </summary>
- //internal bool IsTimeShare
- //{
- // get;
- // set;
- //}
- #endregion Internal Properties
- #endregion Properties
- #region Methods
- #region Public Methods
- /// <summary>
- /// 添加指标窗口
- /// </summary>
- public void AddIndicator()
- {
- //todo:
- //var formula = new FormulaModel();
- //formula.FormulaName = indicatorType;
- //var displayFormula = new DisplayFormula(formula, DataSet, this);
- // AddPlot(displayFormula, null);
- var listPlots = DisplayFormula.CreateDisplayFormula(DataSet, this);
- if (listPlots != null)
- {
- ChartPane pane = null;
- foreach (var displayFormula in listPlots)
- {
- pane = AddFormula(displayFormula, false, pane);
- }
- }
- Refresh(true);
- }
- /// <summary>
- /// 清除叠加商品
- /// </summary>
- public void ClearComparison()
- {
- if (_comparisonGoodsList != null) _comparisonGoodsList.Clear();
- if ((ComparisionDictionary == null || !ComparisionDictionary.Any()) &&
- (ComparisionTimeShareDic == null || !ComparisionTimeShareDic.Any())) return;
- ComparisionDictionary.Clear();
- var mainScalelayer = GetMainScaleLayer();
- if (mainScalelayer == null) return;
- var plots = mainScalelayer.AllPlots.Where(z => z is ComparisonPlot);
- if (plots == null || !plots.Any()) return;
- var comparsions = plots.ToList();
- foreach (var comparison in comparsions)
- {
- comparison.Delete();
- }
- mainScalelayer.ComparisonFormulas.Clear();
- //清除分时图叠加
- if (ComparisionTimeShareDic != null && ComparisionTimeShareDic.Any())
- {
- ComparisionTimeShareDic.Clear();
- }
- if (_comparisonFommulaHsSet != null && _comparisonFommulaHsSet.Any())
- {
- _comparisonFommulaHsSet.Clear();
- }
- if (timeSharingFormulaModel != null)
- {
- var compesionsPlots = timeSharingFormulaModel.ScaleLayer.AllPlots.Where(z => z is ComparisonPlot);
- if (compesionsPlots.Any()) return;
- comparsions = compesionsPlots.ToList();
- foreach (var comparison in comparsions)
- {
- comparison.Delete();
- }
- }
- Refresh();
- }
- /// <summary>
- /// 在派生类中重写后,每当应用程序代码或内部进程调用 <see cref="M:System.Windows.FrameworkElement.ApplyTemplate" />,都将调用此方法。
- /// </summary>
- public override void OnApplyTemplate()
- {
- base.OnApplyTemplate();
- try
- {
- BuildParts();
- //初始化画图工具栏
- InitializeDrawingTool();
- //添加历史价格图和成交量图
- AddDefaultIndicators();
- //添加图表底部控件
- BuildBottomControls();
- }
- catch { ;}
- }
- /// <summary>
- /// 设置叠加商品
- /// </summary>
- /// <param name="goodsList">The goods list.</param>
- public void SetComparisonGoodsList(List<ComparisonGoods> goodsList)
- {
- Dispatcher.BeginInvoke(new Action(() =>
- {
- if (goodsList == null || !goodsList.Any()) return;
- ClearComparison();
- if (this.CycleType == CycleType.TimeSharing)
- {
- foreach (var goods in goodsList)
- {
- AddComparisonFormula(null, null, goods);
- }
- _comparisonGoodsList = goodsList;
- Refresh(true);
- return;
- }
- //Clear里有清空变量,放在后面
- _comparisonGoodsList = goodsList;
- var chartPane = GetMainChartPane(); //要叠加的容器
- foreach (var goods in goodsList)
- {
- //不叠加空和自己
- if (goods == null || string.IsNullOrWhiteSpace(goods.Symbol) ||
- string.CompareOrdinal(goods.Symbol, CurrentSymbol) == 0) continue;
- var dataPoints = LoadComparisonDataSet(goods);
- if (dataPoints == null) continue;
- ComparisionDictionary.Add(goods.Symbol, dataPoints);
- //添加叠加商品
- if (chartPane != null)
- {
- AddComparisonFormula(new ChartDataSet(dataPoints), chartPane, goods);
- }
- }
- Refresh(true);
- }), DispatcherPriority.Background);
- }
- /// <summary>
- /// 更新数据集合-行情组件取服务数据回发时调用
- /// </summary>
- /// <param name="points">The points.</param>
- public void UpdateDataPoints(IEnumerable<ILineDataPoint> points)
- {
- Task.Factory.StartNew(new Action(() =>
- {
- var lineDataPoints = points == null ? null : points.ToList();
- if (lineDataPoints == null || !lineDataPoints.Any()) return;
- DataSet = DataSet ?? new ChartDataSet();
- //集合都要按时间顺排序,才能画图
- var oldDataPoints = DataSet.DataPoints ?? new List<ILineDataPoint>();
- var totalDataPoints = lineDataPoints.Union(oldDataPoints, new DataPointComparer<ILineDataPoint>());
- DataSet.DataPoints = CaclulateCycleDataIncrease(totalDataPoints.OrderBy(z => z.Date).ToList());
- Dispatcher.BeginInvoke(new Action(() =>
- {
- var allDateScaler = (AllDateScaler)DateScaler;
- allDateScaler.SetDates(DataSet.DataPoints, CurrentTimeFrame, false);
- Refresh(true);
- //刷新叠加商品
- RefreshComparsionGoods();
- }), DispatcherPriority.Background);
- }));
- }
- /// <summary>
- /// 更新数据集合-行情组件取服务数据回发时调用
- /// </summary>
- /// <param name="points">The points.</param>
- public void UpdateTimeSharingDataPoints(IEnumerable<ILineDataPoint> points)
- {
- Dispatcher.BeginInvoke(new Action(() =>
- {
- var lineDataPoints = points == null ? null : points.ToList();
- if (lineDataPoints == null || !lineDataPoints.Any()) return;
- DataSet = DataSet ?? new ChartDataSet();
- //集合都要按时间顺排序,才能画图
- DataSet.DataPoints = points.OrderBy(z => z.Date).ToList();
- if (timeSharingFormulaModel == null) return;
- {
- timeSharingFormulaModel.UpdateTimeSharingData(DataSet);
- }
- Refresh(true);
- }), DispatcherPriority.Background);
- }
- /// <summary>
- /// 更新叠加商品数据集合
- /// </summary>
- /// <param name="comparisonSymbol">The comparison symbol.</param>
- /// <param name="points">The points.</param>
- public void UpdateComparisonDataPoints(string comparisonSymbol, IEnumerable<ILineDataPoint> points)
- {
- Dispatcher.BeginInvoke(new Action(() =>
- {
- if (_comparisonGoodsList == null || !_comparisonGoodsList.Any()) return;
- var comparisonGoods = _comparisonGoodsList.FirstOrDefault(z => z.Symbol == comparisonSymbol);
- if (comparisonGoods == null) return;
- //集合都要按时间顺排序,才能画图
- var dataPoints = points ?? new List<ILineDataPoint>();
- var oldDataPoints = ComparisionDictionary[comparisonSymbol] ?? new List<ILineDataPoint>();
- var totalDataPoints =
- dataPoints.Union(oldDataPoints, new DataPointComparer<ILineDataPoint>())
- .OrderBy(z => z.Date)
- .ToList();
- //目前只能一个商品叠加,更新的时候清除所有
- var list = new List<ComparisonGoods>();
- list.AddRange(_comparisonGoodsList);
- #region 商品叠加
- ClearComparison();
- _comparisonGoodsList = list;
- ComparisionDictionary.Add(comparisonSymbol, totalDataPoints);
- var disPlayFormula = new DisplayFormula(new FormulaModel("main"), new ChartDataSet(totalDataPoints), this, comparisonGoods);
- var scaleLayer = GetMainScaleLayer();
- if (scaleLayer == null) return;
- disPlayFormula.PlotBases.Clear();
- scaleLayer.ComparisonFormulas.Clear();
- foreach (var indicator in disPlayFormula.FormulaModel.IndicatorList)
- {
- var comparisonPlot = new ComparisonPlot(indicator, this, comparisonGoods)
- {
- IsActive = true,
- ScaleLayer = scaleLayer
- };
- scaleLayer.AllPlots.Add(comparisonPlot);
- disPlayFormula.PlotBases.Add(comparisonPlot); //添加到公式中
- }
- scaleLayer.ComparisonFormulas.Add(disPlayFormula);
- disPlayFormula.ScaleLayer = scaleLayer;
- #endregion
- Refresh(true);
- }), DispatcherPriority.Background);
- }
- /// <summary>
- /// 导出数据到Excel
- /// </summary>
- public void ExportToExcel()
- {
- //正在下载数据则返回
- if (_exportBusyIndicator.IsBusy) return;
- if (this.CurrentGoods == null) return;
- if (this.DataSet == null || this.DataSet.DataPoints == null || !this.DataSet.DataPoints.Any()) return;
- var width = this.ActualWidth;
- this.Width = width;
- var displayName = string.IsNullOrWhiteSpace(this.CurrentGoods.DisplayName)
- ? this.CurrentGoods.GoodsCode
- : this.CurrentGoods.DisplayName;
- var exportHelper = new ExportHelper();
- exportHelper.OnStartExport += OnStartExport;
- exportHelper.OnExportCompleted += OnExportCompleted;
- exportHelper.ExportToExcel(displayName, CycleType, this.DataSet.DataPoints, this.CurrentGoods.MinUnit);
- }
- /// <summary>
- /// 数据导出开始
- /// </summary>
- /// <param name="sender">The sender.</param>
- /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
- private void OnStartExport(object sender, EventArgs e)
- {
- //要在SaveFileDiaolog关闭后再启动BusyIndicator,否则界面会有SaveFileDiaolog窗口的黑影
- _exportBusyIndicator.IsBusy = true;
- }
- /// <summary>
- /// 数据导出完成
- /// </summary>
- /// <param name="message">The message.</param>
- /// <param name="caption">The caption.</param>
- private void OnExportCompleted(string message, string caption)
- {
- _exportBusyIndicator.IsBusy = false;
- //message为空,只不弹出信息
- if (string.IsNullOrWhiteSpace(message)) return;
- System.Windows.MessageBox.Show(Application.Current.MainWindow, message, caption);
- }
- #endregion Public Methods
- #region Internal Methods
- /// <summary>
- /// sts.
- /// </summary>
- /// <param name="parent">The parent.</param>
- /// <param name="indicatorModel">The indicator model.</param>
- /// <param name="AllowDefaults">if set to <c>true</c> [allow defaults].</param>
- /// <returns>PlotBase.</returns>
- internal PlotBase AddChildPlot(LinePlot parent, IndicatorModel indicatorModel, bool AllowDefaults)
- {
- ScaleLayer scaleLayer = parent.ScaleLayer;
- bool flag = scaleLayer != null;
- PlotBase result = null;
- if (flag)
- {
- //bool flag2 = aCalc is ILineCalculation;
- //if (flag2)
- //{
- var linePlot = new LinePlot(indicatorModel, parent.GetChart());
- //flag2 = (aCalc is calcVolumeAtPrice);
- //if (flag2)
- //{
- // linePlot.PlotOpacity = ((calcVolumeAtPrice)aCalc).DefaultOpacity();
- //}
- linePlot.InitAsNew();
- //if (AllowDefaults)
- //{
- // WebChart_5948(linePlot);
- //}
- // scaleLayer.AddPlot(linePlot);
- linePlot.ScaleLayer = scaleLayer;
- result = linePlot;
- //}
- //else
- //{
- //flag2 = (aCalc is IChannelCalc);
- //if (flag2)
- //{
- // ChannelPlot channelPlot = new ChannelPlot(parent.LinePlot_4866(), (IChannelCalc)aCalc);
- // channelPlot.InitAsNew();
- // if (AllowDefaults)
- // {
- // WebChart_5948(channelPlot);
- // }
- // scaleLayer.ScaleLayer_5530(channelPlot);
- // channelPlot.ScaleLayer = scaleLayer;
- // WebChart_2077 = true;
- // result = channelPlot;
- //}
- //else
- //{
- // flag2 = (aCalc is ITwoLineCalc);
- // if (flag2)
- // {
- // TwoLinePlot twoLinePlot = new TwoLinePlot(parent.LinePlot_4866(), (ITwoLineCalc)aCalc);
- // twoLinePlot.InitAsNew();
- // if (AllowDefaults)
- // {
- // WebChart_5948(twoLinePlot);
- // }
- // scaleLayer.ScaleLayer_5530(twoLinePlot);
- // twoLinePlot.ScaleLayer = scaleLayer;
- // WebChart_2077 = true;
- // result = twoLinePlot;
- // }
- //}
- //}
- }
- return result;
- }
- /// <summary>
- /// 添加叠加商品
- /// </summary>
- public void AddComparisonFormula(ILineDataSet dataSet, ChartPane addToPane, GoodsInfo goodsInfo)
- {
- if (this.CycleType == CycleType.TimeSharing && this.timeSharingFormulaModel != null)
- {
- if (goodsInfo == null || goodsInfo.GoodsCode == this.CurrentGoods.GoodsCode ||
- ComparisionTimeShareDic.ContainsKey(goodsInfo.GoodsCode)) return;
- var dataList = OnLoadHistoryTimeSpaningCycleData(CurrentGoods, _timeSharingMaxPointCount, timeSharingFormulaModel.OpenTime,
- timeSharingFormulaModel.CloseTime);
- var diplayformula = DisplayFormula.TimeSharingLineFormula(this, goodsInfo, dataList);
- ComparisionTimeShareDic[goodsInfo.GoodsCode] = dataList;
- CreateComparisonPlot(diplayformula, this.timeSharingFormulaModel.ScaleLayer);
- }
- else
- {
- var disPlayFormula = new DisplayFormula(new FormulaModel("main"), dataSet, this, goodsInfo);
- ChartPane pane = addToPane;
- bool flag = addToPane == null;
- if (flag)
- {
- pane = new ChartPane(this);
- }
- flag = (addToPane == null);
- if (flag)
- {
- //取最大grid高度做*
- var stars = _chartPanesGrid.RowDefinitions.Count > 0 ? _chartPanesGrid.RowDefinitions.Max(z => z.Height.Value) : 1.0;
- AddChartPane(pane, stars);
- }
- var scaleLayer = GetMainScaleLayer();
- if (scaleLayer == null) return;
- disPlayFormula.PlotBases.Clear();
- scaleLayer.ComparisonFormulas.Clear();
- foreach (var indicator in disPlayFormula.FormulaModel.IndicatorList)
- {
- var comparisonPlot = new ComparisonPlot(indicator, this, goodsInfo);
- comparisonPlot.IsActive = true;
- comparisonPlot.ScaleLayer = scaleLayer;
- scaleLayer.AllPlots.Add(comparisonPlot);
- disPlayFormula.PlotBases.Add(comparisonPlot); //添加到公式中
- }
- scaleLayer.ComparisonFormulas.Add(disPlayFormula);
- disPlayFormula.ScaleLayer = scaleLayer;
- }
- }
- /// <summary>
- /// 移除叠加商品
- /// </summary>
- public void RemoveComparisonForLuma()
- {
- }
- /// <summary>
- /// 添加图例
- /// </summary>
- /// <param name="formula"></param>
- /// <param name="childTarget"></param>
- internal void AddPlot(DisplayFormula formula, PlotBase childTarget)
- {
- bool flag = formula == null;
- if (!flag)
- {
- flag = (childTarget != null && childTarget.ScaleLayer != null &&
- childTarget.ScaleLayer.GetChartPane() != null);
- if (flag)
- {
- var addToPane = childTarget.ScaleLayer.GetChartPane();
- AddFormula(formula, true, addToPane);
- }
- else
- {
- AddFormula(formula, true);
- }
- }
- }
- internal List<ChartPane> AllPanes()
- {
- var list = new List<ChartPane>();
- if (_chartPanesGrid == null || _chartPanesGrid.Children == null || _chartPanesGrid.Children.Count == 0)
- return list;
- list.AddRange(_chartPanesGrid.Children.OfType<ChartPane>());
- return list;
- }
- /// <summary>
- /// 下载前N条数据(N = MaxLoadRecordCount)
- /// </summary>
- internal void DownloadNextDataBlock()
- {
- var goods = CurrentGoods;
- var exchangeCode = CurrentGoods.ExchangeCode;
- var goodsCode = CurrentGoods.GoodsCode;
- var cycleType = CycleType;
- var timeSpan = CurrentTimeFrame;
- var maxLoadRecordCount = MaxLoadRecordCount;
- Task.Factory.StartNew(new Action(() =>
- {
- //数据集有值,取最小时间, 无值,取当前时间
- var maxTime = (DataSet != null && DataSet.DataPoints != null && DataSet.DataPoints.Any())
- ? DataSet.DataPoints.Min(z => z.Date)
- : DateTime.Now;
- //减去周期ticks,作为当前下载最大值
- maxTime = maxTime.AddTicks(-timeSpan.Ticks);
- if (DataSet == null)
- {
- DataSet = new ChartDataSet();
- }
- List<ILineDataPoint> newData = null;
- var cycleTypeHandler = LoadHistoryCycleDataByCycleType;
- if (cycleTypeHandler != null)
- {
- newData = cycleTypeHandler(exchangeCode, goodsCode, cycleType,
- timeSpan, DateTime.MinValue, maxTime, maxLoadRecordCount);
- }
- var dataPoints = new List<ILineDataPoint>();
- if (newData != null && newData.Any())
- {
- dataPoints.AddRange(CaclulateCycleDataIncrease(newData));
- if (DataSet.DataPoints != null && dataPoints.Any())
- {
- //只更新前面数据块第一条数据涨幅
- var firstOld = DataSet.DataPoints[0] as IOHLCDataPoint;
- var lastNew = newData[newData.Count - 1] as IOHLCDataPoint;
- if (firstOld != null && lastNew != null)
- {
- firstOld.Increase = lastNew.Close.Equals(0)
- ? 0f
- : (firstOld.Close - lastNew.Close) / lastNew.Close;
- firstOld.IncreaseValue = lastNew.Close.Equals(0) ? 0f : (firstOld.Close - lastNew.Close);
- }
- dataPoints.AddRange(DataSet.DataPoints);
- }
- DataSet.DataPoints = dataPoints.OrderBy(z => z.Date).ToList();
- Dispatcher.BeginInvoke(new Action(() =>
- {
- var allDateScaler = (AllDateScaler)DateScaler;
- allDateScaler.SetDates(DataSet.DataPoints, timeSpan, false);
- //前一数据块的最后时间做为当前的结束时间
- allDateScaler.DesiredEndDate = maxTime.AddTicks(timeSpan.Ticks);
- Refresh(true);
- //刷新叠加商品
- RefreshComparsionGoods();
- }), DispatcherPriority.Background);
- }
- }));
- }
- /// <summary>
- /// 若画图则隐藏十字光标
- /// </summary>
- internal void DrawingToolExecute()
- {
- if (PointerType != PointerType.Drawing)
- {
- if (_crossHairGrid.Visibility == Visibility.Collapsed)
- {
- _crossHairGrid.Visibility = Visibility.Visible;
- }
- //TODO:更改所有控件的背景颜色
- var panes = AllPanes();
- foreach (var chartPane in panes)
- {
- chartPane.OnDrawing();
- }
- }
- else
- {
- if (_crossHairGrid.Visibility == Visibility.Visible)
- {
- _crossHairGrid.Visibility = Visibility.Collapsed;
- }
- }
- }
- internal double GetChartPanelOffset()
- {
- return _chartPanesGrid.ColumnDefinitions[0].ActualWidth;
- }
- /// <summary>
- /// 得到的图表窗格的宽度.
- /// </summary>
- /// <returns>System.Double.</returns>
- internal double GetChartPaneWidth()
- {
- //0:左纵坐标, 1:Chart, 2:右纵坐标
- return Math.Round(_chartPanesGrid.ColumnDefinitions[1].ActualWidth) - RightBuffer;
- }
- /// <summary>
- /// 获取当前已打开的主图LinePlot
- /// </summary>
- /// <returns>PlotBase.</returns>
- internal T GetPlot<T>(string formulaName) where T : PlotBase
- {
- var panes = AllPanes();
- if (panes == null || !panes.Any()) return default(T);
- var name = formulaName.ToLower();
- foreach (var chartPane in panes)
- {
- var scaleLayers = chartPane.AllScaleLayers;
- if (scaleLayers == null || !scaleLayers.Any()) continue;
- foreach (var scaleLayer in scaleLayers)
- {
- var plots = scaleLayer.AllPlots;
- if (plots == null || !plots.Any()) continue;
- foreach (var plot in plots)
- {
- if (plot != null && (plot is T) && plot.Indicator.ParentFormula.FormulaName.ToLower() == name) return plot as T;
- }
- }
- }
- return null;
- }
- private ScaleLayer GetMainScaleLayer()
- {
- var panes = AllPanes();
- if (panes == null || !panes.Any()) return null;
- foreach (var chartPane in panes)
- {
- var scaleLayers = chartPane.AllScaleLayers;
- if (scaleLayers == null || !scaleLayers.Any()) continue;
- foreach (var scaleLayer in scaleLayers)
- {
- var formulas = scaleLayer.AllDisplayFormula;
- if (formulas == null || !formulas.Any()) continue;
- foreach (var formula in formulas)
- {
- if (formula != null && formula.FormulaModel.IsMain)
- {
- return scaleLayer;
- }
- }
- }
- }
- return null;
- }
- /// <summary>
- /// 初始化画图工具栏
- /// </summary>
- internal void InitializeDrawingTool()
- {
- if (_drawingToolStackPanel == null) return;
- if (_drawingToolbar == null) _drawingToolbar = new ChartDrawingToolbar(this);
- if (_chartToolbarExpander == null) _chartToolbarExpander = new ChartToolbarExpander(_drawingToolbar);
- //隐藏画线工具展开按钮
- _chartToolbarExpander.Visibility = Visibility.Hidden;
- switch (DrawingToolPosition)
- {
- case DrawingToolPositionType.Left:
- _drawingToolStackPanel.SetValue(Grid.RowProperty, 0);
- _drawingToolStackPanel.SetValue(Grid.RowSpanProperty, 4);
- _drawingToolStackPanel.SetValue(Grid.ColumnProperty, 0);
- _drawingToolStackPanel.Orientation = Orientation.Vertical;
- _drawingToolStackPanel.HorizontalAlignment = HorizontalAlignment.Left;
- _drawingToolbar.UpdateLayout(Orientation.Vertical);
- break;
- case DrawingToolPositionType.Right:
- _drawingToolStackPanel.SetValue(Grid.RowProperty, 0);
- _drawingToolStackPanel.SetValue(Grid.RowSpanProperty, 4);
- _drawingToolStackPanel.SetValue(Grid.ColumnProperty, 2);
- _drawingToolStackPanel.Orientation = Orientation.Vertical;
- _drawingToolStackPanel.HorizontalAlignment = HorizontalAlignment.Right;
- _drawingToolbar.UpdateLayout(Orientation.Vertical);
- break;
- case DrawingToolPositionType.Top:
- _drawingToolStackPanel.SetValue(Grid.RowProperty, 1);
- _drawingToolStackPanel.SetValue(Grid.RowSpanProperty, 1);
- _drawingToolStackPanel.SetValue(Grid.ColumnProperty, 1);
- _drawingToolStackPanel.Orientation = Orientation.Horizontal;
- _drawingToolStackPanel.HorizontalAlignment = HorizontalAlignment.Stretch;
- _chartToolbarExpander.VerticalAlignment = VerticalAlignment.Top;
- _drawingToolbar.UpdateLayout(Orientation.Horizontal);
- break;
- case DrawingToolPositionType.Bottom:
- _drawingToolStackPanel.SetValue(Grid.RowProperty, 3);
- _drawingToolStackPanel.SetValue(Grid.RowSpanProperty, 1);
- _drawingToolStackPanel.SetValue(Grid.ColumnProperty, 1);
- _drawingToolStackPanel.Orientation = Orientation.Horizontal;
- _drawingToolStackPanel.HorizontalAlignment = HorizontalAlignment.Stretch;
- _chartToolbarExpander.VerticalAlignment = VerticalAlignment.Top;
- _drawingToolbar.UpdateLayout(Orientation.Horizontal);
- break;
- }
- if (!_drawingToolStackPanel.Children.Contains(_chartToolbarExpander))
- _drawingToolStackPanel.Children.Add(_chartToolbarExpander);
- if (!_drawingToolStackPanel.Children.Contains(_drawingToolbar))
- _drawingToolStackPanel.Children.Add(_drawingToolbar);
- }
- private int i = 0;
- private double currentX = 0;
- private double currentY = 0;
- /// <summary>
- /// 刷新图表
- /// </summary>
- /// <param name="isUpdataSet">if set to <c>true</c> [is updata set].</param>
- internal void Refresh(bool isUpdataSet = false)
- {
- lock (_lockObject)
- {
- if (!LockPainting)
- {
- Dispatcher.BeginInvoke(new Action<bool>(DrawingChart), DispatcherPriority.Background, isUpdataSet);
- }
- }
- }
- internal void RemoveChartPane(ChartPane aPane)
- {
- int num = Conversions.ToInteger(aPane.GetValue(Grid.RowProperty));
- _chartPanesGrid.Children.Remove(aPane);
- _chartPanes.Remove(aPane);
- if (aPane.RightScaleControl != null)
- {
- _chartPanesGrid.Children.Remove(aPane.RightScaleControl);
- }
- if (aPane.LeftScaleControl != null)
- {
- _chartPanesGrid.Children.Remove(aPane.LeftScaleControl);
- }
- _chartPanesGrid.RowDefinitions.RemoveAt(num);
- UIElement currentSplitter = null;
- foreach (var uiElement in _chartPanesGrid.Children)
- {
- var current = uiElement as UIElement;
- if (current != null &&
- (current is ChartPane || current is ValueScaleDisplayCollection || current is GridSplitter))
- {
- int rowIndex = Conversions.ToInteger(current.GetValue(Grid.RowProperty));
- if (rowIndex < 1) continue;
- if (rowIndex > num)
- {
- current.SetValue(Grid.RowProperty, rowIndex - 2 < 0 ? 0 : rowIndex - 2);
- }
- else if (rowIndex == num - 1 && current is GridSplitter)
- {
- currentSplitter = current;
- }
- }
- }
- if (currentSplitter != null)
- {
- _chartPanesGrid.Children.Remove(currentSplitter);
- _chartPanesGrid.RowDefinitions.RemoveAt(num - 1);
- }
- aPane.RemoveAllScaleLayers();
- Refresh(true);
- }
- internal void SetCursorImagePos(bool showIt, MouseEventArgs e)
- {
- if (showIt)
- {
- switch (PointerType)
- {
- case PointerType.CursorWithData:
- _crossHairGrid.Cursor = Cursors.Arrow;
- _chartPanesGrid.Cursor = Cursors.Arrow;
- _toolImage.Source = null;
- break;
- case PointerType.Cursor:
- _crossHairGrid.Cursor = Cursors.Arrow;
- _chartPanesGrid.Cursor = Cursors.Arrow;
- _toolImage.Source = null;
- break;
- case PointerType.Pan:
- _crossHairGrid.Cursor = Cursors.Hand;
- _chartPanesGrid.Cursor = Cursors.Hand;
- _toolImage.Source = null;
- break;
- case PointerType.Erase:
- _crossHairGrid.Cursor = Cursors.Arrow;
- _toolImage.Source = ImageHelper.GetImage("Eraser.png");
- break;
- case PointerType.Drawing:
- _toolImage.Source = CurrentDrawingTool == null ? null : CurrentDrawingTool.Icon();
- break;
- }
- if (_toolImage.Source == null)
- {
- CleanQuoteBoard();
- }
- else
- {
- if (_popup == null)
- {
- _popup = new Popup
- {
- Child = _toolImage,
- Placement = PlacementMode.Relative,
- AllowsTransparency = true
- };
- _chartPanesGrid.Children.Add(_popup);
- _popup.IsOpen = true;
- }
- }
- }
- else
- {
- CleanQuoteBoard();
- }
- //}
- if (showIt && e != null && _toolImage.Source != null)
- {
- Point position = e.GetPosition(_chartPanesGrid);
- _popup.HorizontalOffset = (position.X + 8.0);
- _popup.VerticalOffset = (position.Y - 8.0);
- }
- else
- {
- if (!showIt)
- {
- CleanQuoteBoard();
- }
- }
- }
- /// <summary>
- /// 设置当前画图工具为null
- /// </summary>
- internal void SetDrawingTool()
- {
- _oldDrawingTool = CurrentDrawingTool;
- CurrentDrawingTool = null;
- _pointerType = _oldPointerType;
- DrawingToolExecute();
- var panes = AllPanes();
- foreach (var current in panes)
- {
- current.OnDrawing();
- }
- _drawingToolbar.ButtonPress();
- }
- /// <summary>
- /// 显示/隐藏Download More Button
- /// </summary>
- /// <param name="isShow">if set to <c>true</c> [is show].</param>
- internal void ShowDownloadButton(bool isShow)
- {
- if (isShow)
- {
- _downloadMoreButton.Width = DateChartSlider.Height;
- _downloadMoreButton.Height = DateChartSlider.Height;
- _downloadMoreButton.Visibility = Visibility.Visible;
- }
- else
- {
- _downloadMoreButton.Visibility = Visibility.Collapsed;
- }
- }
- #endregion Internal Methods
- #region Protected Methods
- /// <summary>
- /// 鼠标滚轮事件
- /// </summary>
- /// <param name="e">包含事件数据的 <see cref="T:System.Windows.Input.MouseWheelEventArgs" />。</param>
- protected override void OnMouseWheel(MouseWheelEventArgs e)
- {
- e.Handled = true;
- var factor = 1;
- if ((Keyboard.Modifiers & AcceleratedWheelModifierKeys) == AcceleratedWheelModifierKeys)
- {
- factor = AcceleratedWheelFactor;
- }
- int num = DateScaler.NumBars + (factor) * (int)Math.Round((double)e.Delta / 120.0);
- num = num < 5 ? 5 : num;
- var scalerCount = DateScaler.Count();
- num = num > scalerCount ? scalerCount : num;
- DateScaler.NumBars = num;
- Refresh();
- }
- #endregion Protected Methods
- #region Private Static Methods
- private static void ChartFontSizeProperty_Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
- {
- var chart = d as Chart;
- if (chart == null) return;
- UpdateDrawingTool(chart);
- }
- private static void ChartLanguageProperty_Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
- {
- ChartLanguageType language;
- if (!Enum.TryParse(e.NewValue.ToString(), out language))
- {
- language = ChartLanguageType.SimplifiedChinese;
- }
- switch (language)
- {
- case ChartLanguageType.SimplifiedChinese:
- LanguageManager.SetLanguage("zh-CN");
- break;
- case ChartLanguageType.TraditionalChinese:
- LanguageManager.SetLanguage("zh-TW");
- break;
- case ChartLanguageType.English:
- LanguageManager.SetLanguage("en-US");
- break;
- default:
- LanguageManager.SetLanguage("zh-CN");
- break;
- }
- var chart = d as Chart;
- if (chart == null) return;
- UpdateDrawingTool(chart);
- }
- private static void ChartLineTypePlotProperty_Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
- {
- var chart = (Chart)d;
- //更新plot type
- var newValue = (LinePlotType)e.NewValue;
- var pricePlot = chart.GetPlot<LinePlot>("main");
- if (pricePlot != null && pricePlot.Indicator != null) pricePlot.Indicator.LinePlotType = newValue;
- var comparisonPlot = chart.GetPlot<ComparisonPlot>("main");
- if (comparisonPlot != null && comparisonPlot.Indicator != null) comparisonPlot.Indicator.LinePlotType = newValue;
- chart.Refresh();
- }
- private static void ChartCycleBarVisibity(DependencyObject d, DependencyPropertyChangedEventArgs e)
- {
- var chart = (Chart)d;
- if (chart.TimeSpanPicker != null)
- {
- chart.TimeSpanPicker.Visibility = (Visibility)e.NewValue;
- }
-
- }
- /// <summary>
- /// 图的最小最大记录改变.
- /// </summary>
- /// <param name="d">The d.</param>
- /// <param name="e">The <see cref="DependencyPropertyChangedEventArgs"/> instance containing the event data.</param>
- private static void ChartMinMaxRecordProperty_Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
- {
- var chart = (Chart)d;
- var numBars = chart.DateScaler.NumBars;
- var oldNum = (int)e.OldValue;
- var newNum = (int)e.NewValue;
- //numBars为矩形柱间距,矩形柱数量实际要-1
- if (numBars == 4 || numBars == oldNum - 1)
- {
- chart.DateScaler.NumBars = newNum - 1;
- chart.Refresh();
- }
- }
- /// <summary>
- /// Charts the property_ changed.
- /// </summary>
- /// <param name="d">The d.</param>
- /// <param name="e">The <see cref="DependencyPropertyChangedEventArgs"/> instance containing the event data.</param>
- private static void ChartProperty_Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
- {
- var chart = (Chart)d;
- if (chart == null) return;
- if ((e.Property == FillComparisonCandleProperty && chart.LinePlotType == LinePlotType.Candlestick &&
- chart.ComparisionDictionary.Any())
- || e.Property != FillComparisonCandleProperty)
- {
- chart.Refresh();
- }
- }
- /// <summary>
- /// Charts the record count property_ changed.
- /// </summary>
- /// <param name="d">The d.</param>
- /// <param name="e">The <see cref="DependencyPropertyChangedEventArgs"/> instance containing the event data.</param>
- private static void ChartRecordCountProperty_Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
- {
- var chart = (Chart)d;
- //numBars为矩形柱间距,矩形柱数量实际要-1
- chart.DateScaler.NumBars = (int)e.NewValue - 1;
- chart.Refresh();
- }
- /// <summary>
- /// Charts the time span property_ changed.
- /// </summary>
- /// <param name="d">The d.</param>
- /// <param name="e">The <see cref="DependencyPropertyChangedEventArgs"/> instance containing the event data.</param>
- private static void ChartTimeSpanProperty_Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
- {
- var chart = (Chart)d;
- if (chart == null) return;
- if (chart.ChartTimeSpan != default(TimeSpan))
- {
- if (chart.CycleType == CycleType.Custom)
- {
- //直接调用
- chart.CycleTypePropertyChanged(false);
- }
- else
- {
- //通过设置CycleType触发数据下载
- chart.CycleType = CycleType.Custom;
- }
- }
- }
- /// <summary>
- /// Currents the goods property_ changed.
- /// </summary>
- /// <param name="d">The d.</param>
- /// <param name="e">The <see cref="DependencyPropertyChangedEventArgs"/> instance containing the event data.</param>
- private static void CurrentGoodsProperty_Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
- {
- var chart = (Chart)d;
- if (chart == null) return;
- // chart.ClearComparison();
- chart.OnCycleTypeChanged(true);
- }
- /// <summary>
- /// 周期属性改变后回调函数
- /// </summary>
- /// <param name="d">The Dependency Object.</param>
- /// <param name="e">The <see cref="DependencyPropertyChangedEventArgs"/> instance containing the event data.</param>
- private static void ChartCycleTypeProperty_Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
- {
- var chart = (Chart)d;
- if (chart == null) return;
- chart.CycleTypePropertyChanged(CycleType.TimeSharing.Equals(e.OldValue) || CycleType.Tik.Equals(e.OldValue));
- }
- /// <summary>
- /// 周期集合属性改变后回调函数
- /// </summary>
- /// <param name="d">The Dependency Object.</param>
- /// <param name="e">The <see cref="DependencyPropertyChangedEventArgs"/> instance containing the event data.</param>
- private static void ChartCycleTypeItemsProperty_Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
- {
- var chart = (Chart)d;
- if (chart == null || chart.TimeSpanPicker == null) return;
- }
- /// <summary>
- /// Tik属性改变后回调函数
- /// </summary>
- private static void ChartTikProperty_Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
- {
- var chart = (Chart)d;
- if (chart == null) return;
- if (chart.CurrentTik != null && chart.DataSet != null && chart.DataSet.DataPoints != null && chart.DataSet.DataPoints.Count() > 0)
- {
- var lastTik = chart.DataSet.DataPoints.Last() as BarDataPoint;
- var date = default(DateTime);
- if (chart.IsNotInCycle(chart.CurrentTik.Date, ref date))
- {
- var item = new BarDataPoint(date, chart.CurrentTik.Open, chart.CurrentTik.High, chart.CurrentTik.Low, chart.CurrentTik.Close, chart.CurrentTik.Volume,
- chart.CurrentTik.Turnover, chart.CurrentTik.HoldVolume);
- chart.DataSet.DataPoints.Add(item);
- chart.SetDatesAndRefresh(true,false);
- }
- else
- {
- var barPointTmp = chart.DataSet.DataPoints.Last() as BarDataPoint;
- barPointTmp.Close = chart.CurrentTik.Close;
- barPointTmp.High = chart.CurrentTik.Value > lastTik.High ? chart.CurrentTik.Value : lastTik.High;
- barPointTmp.Low = chart.CurrentTik.Value < lastTik.Low ? chart.CurrentTik.Value : lastTik.Low;
- barPointTmp.HoldVolume = chart.CurrentTik.HoldVolume;
- barPointTmp.Turnover = chart.CurrentTik.Turnover;
- barPointTmp.Volume += chart.CurrentTik.Volume;
- chart.SetDatesAndRefresh(true, false);
- }
- }
- }
- /// <summary>
- /// Drawings the tool position property_ changed.
- /// </summary>
- /// <param name="d">The d.</param>
- /// <param name="e">The <see cref="DependencyPropertyChangedEventArgs"/> instance containing the event data.</param>
- private static void DrawingToolPositionProperty_Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
- {
- var chart = (Chart)d;
- chart.InitializeDrawingTool();
- }
- /// <summary>
- /// Currents the drawing tool type_ changed.
- /// </summary>
- /// <param name="d">The d.</param>
- /// <param name="e">The <see cref="DependencyPropertyChangedEventArgs"/> instance containing the event data.</param>
- private static void DrawingToolType_Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
- {
- var chart = (Chart)d;
- if (chart == null || chart._drawingToolbar == null) return;
- var button = chart._drawingToolbar.GetToolbarButton(chart.DrawingToolType);
- if (button == null) return;
- button.ButtonClick();
- }
- /// <summary>
- /// Updates the drawing tool.
- /// </summary>
- /// <param name="chart">The chart.</param>
- private static void UpdateDrawingTool(Chart chart)
- {
- if (chart == null) return;
- //更新画图工具
- if (chart._drawingToolStackPanel != null)
- {
- chart._drawingToolStackPanel.Children.Clear();
- chart._drawingToolbar = new ChartDrawingToolbar(chart);
- chart._chartToolbarExpander = new ChartToolbarExpander(chart._drawingToolbar);
- chart.InitializeDrawingTool();
- }
- //更新图表
- chart.Refresh();
- }
- #endregion Private Static Methods
- #region Private Methods
- /// <summary>
- /// 刷新叠加商品
- /// </summary>
- private void RefreshComparsionGoods()
- {
- if (_comparisonGoodsList != null && _comparisonGoodsList.Any())
- {
- var list = new List<ComparisonGoods>();
- list.AddRange(_comparisonGoodsList);
- SetComparisonGoodsList(list);
- }
- }
- /// <summary>
- /// 获取主图所在的图表容器
- /// </summary>
- /// <returns></returns>
- private ChartPane GetMainChartPane()
- {
- foreach (var chartPane in _chartPanes)
- {
- if (IsMainChartPane(chartPane)) return chartPane;
- }
- return null;
- }
- /// <summary>
- /// 判断是否是主图容器
- /// </summary>
- /// <param name="chartPane"></param>
- /// <returns></returns>
- private bool IsMainChartPane(ChartPane chartPane)
- {
- foreach (var scaleLayer in chartPane.AllScaleLayers)
- {
- foreach (var displayFormula in scaleLayer.AllDisplayFormula)
- {
- if (displayFormula.FormulaModel != null && displayFormula.FormulaModel.IsMain)
- {
- return true;
- }
- }
- }
- return false;
- }
- /// <summary>
- /// 添加pane(图例)
- /// </summary>
- /// <param name="p"></param>
- /// <param name="stars"></param>
- /// <returns></returns>
- private ChartPane AddChartPane(ChartPane p, double stars, bool isMain = false)
- {
- int count = _chartPanesGrid.RowDefinitions.Count;
- if (count > 0)
- {
- AddRowDefinition(count, 1, GridUnitType.Auto);
- var splitter = new GridSplitter();
- splitter.IsTabStop = (false);
- splitter.Background = (new SolidColorBrush(ColorHelper.DimGray));
- splitter.SetValue(Grid.RowProperty, count);
- splitter.SetValue(Grid.ColumnProperty, 1);
- splitter.SetValue(Grid.ColumnSpanProperty, 2);
- splitter.HorizontalAlignment = HorizontalAlignment.Stretch;
- splitter.VerticalAlignment = VerticalAlignment.Center;
- splitter.Height = (2.0);
- splitter.Cursor = Cursors.SizeNS;
- splitter.Margin = new Thickness(0, 2, 0, 2);
- _chartPanesGrid.Children.Add(splitter);
- //AddRowDefinition(count + 1, stars <= 0.0 ? 1.0 : stars, GridUnitType.Star);
- AddRowDefinition(count + 1, isMain ? 2 : 1, GridUnitType.Star);
- }
- else
- {
- AddRowDefinition(count, isMain ? 2 : 1, GridUnitType.Star);
- //AddRowDefinition(count, stars <= 0.0 ? 1.0 : stars, GridUnitType.Star);
- }
- p.SetValue(Grid.RowProperty, count > 0 ? count + 1 : 0);
- p.SetValue(Grid.ColumnProperty, 1);
- _chartPanesGrid.Children.Add(p);
- _chartPanes.Add(p);
- if (p.RightScaleControl != null)
- {
- p.RightScaleControl.SetValue(Grid.RowProperty, count > 0 ? count + 1 : 0);
- p.RightScaleControl.SetValue(Grid.ColumnProperty, 2);
- _chartPanesGrid.Children.Add(p.RightScaleControl);
- }
- if (p.LeftScaleControl != null)
- {
- p.LeftScaleControl.SetValue(Grid.RowProperty, count > 0 ? count + 1 : 0);
- p.LeftScaleControl.SetValue(Grid.ColumnProperty, 0);
- _chartPanesGrid.Children.Add(p.LeftScaleControl);
- }
- return p;
- }
- /// <summary>
- /// 添加默认指标器-历史价格,成交量
- /// </summary>
- private void AddDefaultIndicators()
- {
- AddFormula(new DisplayFormula(new FormulaModel("Main"), DataSet, this), true);
- var indecators = _defaoltIndecator.Split(',');
- foreach (var indecator in indecators)
- {
- AddIndicatorByName(indecator, false);
- }
- var menuItem = FormulaHelper.CreateIndicatorMenu("", IndicatorItemClick);
- menuItem.Header = "指标";
- this.ContextMenu = new ContextMenu();
- this.ContextMenu.Items.Add(menuItem);
- var menuItem1 = new MenuItem() { Header = "编辑参数" };
- this.ContextMenu.Items.Add(menuItem1);
- menuItem1.Click += menuItem1_Click;
- var MainItem = new MenuItem() { Header = "清除主图" };
- this.ContextMenu.Items.Add(MainItem);
- MainItem.Click += MainItem_Click;
- //打开公式管理器
- MainItem = new MenuItem() { Header = "公式管理" };
- this.ContextMenu.Items.Add(MainItem);
- MainItem.Click += (cs, ce) =>
- {
- OpenFormulEditer();
- };
- }
- //清楚主图中的指标
- void MainItem_Click(object sender, RoutedEventArgs e)
- {
- ClearMainPaneIndicator();
- }
- /// <summary>
- /// 设置当前公式的参数
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- void menuItem1_Click(object sender, RoutedEventArgs e)
- {
- SetCurrectFormulaParam();
- }
- //选择指标菜单时触发的事件处理
- private void IndicatorItemClick(object sender, RoutedEventArgs e)
- {
- var selectItem = sender as MenuItem;
- if (selectItem != null && selectItem.Tag is ProgramModel)
- {
- var formulaModel = (selectItem.Tag as ProgramModel);
- AddIndicatorByName(formulaModel.Name);
- }
- }
- private void AddFormula(DisplayFormula displayFormula, bool allowDefaults)
- {
- AddFormula(displayFormula, allowDefaults, null, true);
- }
- public ChartPane AddFormula(DisplayFormula displayFormula, bool allowDefaults, ChartPane addToPane, bool isMain = false)
- {
- ChartPane pane = addToPane;
- bool flag = addToPane == null;
- if (flag)
- {
- pane = new ChartPane(this);
- //取最大grid高度做*
- var stars = _chartPanesGrid.RowDefinitions.Count > 0
- ? _chartPanesGrid.RowDefinitions.Max(z => z.Height.Value)
- : 1.0;
- AddChartPane(pane, stars, isMain);
- }
- ScaleLayer scaleLayer = null;
- if (flag)
- {
- scaleLayer = new ScaleLayer();
- pane.AddScaleLayer(scaleLayer);
- }
- else
- {
- if (IsMainChartPane(pane))
- {
- scaleLayer = GetMainScaleLayer();
- }
- else
- {
- scaleLayer = new ScaleLayer();
- pane.AddScaleLayer(scaleLayer);
- }
- }
- displayFormula.PlotBases.Clear();
- scaleLayer.AllDisplayFormula.Add(displayFormula);
- displayFormula.ScaleLayer = scaleLayer;
- pane.DisplayFristGrid();
- return pane;
- }
- /// <summary>
- /// 添加指标时如主图指标则添加到主图,副图指标添加或替换.副图不能添加超过允许最大数量
- /// </summary>
- /// <param name="displayFormula">指标公式</param>
- /// <param name="allowDefaults"></param>
- /// <param name="addToPane"></param>
- /// <returns></returns>
- public ChartPane AddFormulaFromPane(DisplayFormula displayFormula)
- {
- ChartPane pane = null;
- var flag = displayFormula.FormulaModel.IsMainIndicator;
- //var scaleLayer = new ScaleLayer();
- ScaleLayer scaleLayer = new ScaleLayer();
- if (flag)
- {
- pane = GetMainChartPane();
- scaleLayer = GetMainScaleLayer();
- }
- else
- {
- var maxChart = MaxChartPaneCount > 0 && _chartPanes.Count >= MaxChartPaneCount;
- if (!maxChart) //超过最大数量限制
- {
- pane = new ChartPane(this);
- //取最大grid高度做*
- var stars = _chartPanesGrid.RowDefinitions.Count > 0
- ? _chartPanesGrid.RowDefinitions.Max(z => z.Height.Value)
- : 1.0;
- AddChartPane(pane, stars);
- }
- else
- {
- pane = _chartPanes[_chartPanes.Count - 1];
- pane.RemoveAllScaleLayers();
- }
- scaleLayer = new ScaleLayer();
- pane.AddScaleLayer(scaleLayer);
- }
- displayFormula.PlotBases.Clear();
- scaleLayer.AllDisplayFormula.Add(displayFormula);
- displayFormula.ScaleLayer = scaleLayer;
- pane.DisplayFristGrid();
- return pane;
- }
- /// <summary>
- /// 在ChartCont指点位置插入一行
- /// </summary>
- /// <param name="index"></param>
- /// <param name="value"></param>
- /// <param name="type"></param>
- private void AddRowDefinition(int index, double value, GridUnitType type)
- {
- var rowDefinition = new RowDefinition { Height = new GridLength(value, type) };
- _chartPanesGrid.RowDefinitions.Insert(index, rowDefinition);
- }
- /// <summary>
- /// 添加图表底部控件
- /// </summary>
- private void BuildBottomControls()
- {
- var grid = new Grid();
- grid.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(1, GridUnitType.Auto) });
- grid.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(1, GridUnitType.Star) });
- //隐藏用hidden,不用Collapsed,需要用来占位
- _downloadMoreButtonPlaceHolder = new TextBlock() { Visibility = Visibility.Hidden };
- _downloadMoreButton = new Button()
- {
- Visibility = Visibility.Collapsed
- };
- _downloadMoreButton.Click -= DownloadMoreButton_Click;
- _downloadMoreButton.Click += DownloadMoreButton_Click;
- _downloadMoreButton.MouseEnter -= DownloadMoreButton_MouseEnter;
- _downloadMoreButton.MouseEnter += DownloadMoreButton_MouseEnter;
- _downloadMoreButton.SetValue(Grid.ColumnProperty, 0);
- _downloadMoreButtonPlaceHolder.SetValue(Grid.ColumnProperty, 0);
- var style = (Style)FindResource("LeftArrowButton");
- _downloadMoreButton.Style = style;
- var gridRight = new Grid();
- gridRight.Children.Add(DateChartSlider);
- gridRight.Children.Add(TimeSpanPicker); //不再大小图表上显示周期
- gridRight.SetValue(Grid.ColumnProperty, 1);
- grid.Children.Add(gridRight);
- var gridLeft = new Grid { HorizontalAlignment = HorizontalAlignment.Right };
- gridLeft.Children.Add(_downloadMoreButton);
- gridLeft.Children.Add(_downloadMoreButtonPlaceHolder);
- gridLeft.SetValue(Grid.ColumnProperty, 0);
- grid.Children.Add(gridLeft);
- _dateChartSliderStackPanel.Children.Add(_dateScaleDisplay);
- _dateChartSliderStackPanel.Children.Add(grid);
- }
- /// <summary>
- /// 生成控件
- /// </summary>
- private void BuildParts()
- {
- _exportBusyIndicator = (BusyIndicator)TreeHelper.TemplateFindName("PART_BusyIndicator", this);
- _exportBusyIndicator.IsBusy = false;
- _exportBusyIndicator.BusyContent = LanguageManager.FindResource(LanguageConst.ExportWaiting);
- _mainGrid = (Grid)TreeHelper.TemplateFindName("PART_MainGrid", this);
- _mainGrid.MouseEnter -= MainGrid_MouseEnter;
- _mainGrid.MouseEnter += MainGrid_MouseEnter;
- _mainGrid.MouseMove -= MainGrid_MouseMove;
- _mainGrid.MouseMove += MainGrid_MouseMove;
- _mainGrid.MouseDown -= _mainGrid_MouseDown;
- _mainGrid.MouseDown += _mainGrid_MouseDown;
- _mainGrid.PreviewKeyDown += _mainGrid_PreviewKeyDown;
- _chartHeaderStackPanel = (StackPanel)TreeHelper.TemplateFindName("PART_HeaderStackPanel", this);
- _drawingToolStackPanel = (StackPanel)TreeHelper.TemplateFindName("PART_DrawingToolStackPanel", this);
- _chartPanesGrid = (Grid)TreeHelper.TemplateFindName("PART_ChartPanesGrid", this);
- _dateChartSliderStackPanel =
- (StackPanel)TreeHelper.TemplateFindName("PART_DateChartSliderStackPanel", this);
- _crossHairGrid = (Canvas)TreeHelper.TemplateFindName("PART_CrossHairGrid", this);
- _crossHairGrid.LostMouseCapture -= CrossHairGrid_LostMouseCapture;
- _crossHairGrid.LostMouseCapture += CrossHairGrid_LostMouseCapture;
- _crossHairGrid.MouseEnter -= CrossHairGrid_MouseEnter;
- _crossHairGrid.MouseEnter += CrossHairGrid_MouseEnter;
- _crossHairGrid.MouseLeave -= CrossHairGrid_MouseLeave;
- _crossHairGrid.MouseLeave += CrossHairGrid_MouseLeave;
- _crossHairGrid.MouseLeftButtonDown -= CrossHairGrid_MouseLeftButtonDown;
- _crossHairGrid.MouseLeftButtonDown += CrossHairGrid_MouseLeftButtonDown;
- _crossHairGrid.MouseLeftButtonUp -= CrossHairGrid_MouseLeftButtonUp;
- _crossHairGrid.MouseLeftButtonUp += CrossHairGrid_MouseLeftButtonUp;
- _crossHairGrid.MouseMove -= CrossHairGrid_MouseMove;
- _crossHairGrid.MouseMove += CrossHairGrid_MouseMove;
- _pointerPopup = (Popup)TreeHelper.TemplateFindName("PART_PointerPopup", this);
- _pointerGrid = (Grid)TreeHelper.TemplateFindName("PART_PointerGrid", this);
- }
- void _mainGrid_PreviewKeyDown(object sender, KeyEventArgs e)
- {
- //鼠标上键
- if (Keyboard.IsKeyDown(Key.Down))
- {
- this._crossHairGrid_IsDoubleClick = false;
- this.HiddenCrossHairGrid();
- if (this.RecordCount + this.LeftRightKeyToAcceleration < this.MaxRecordCount)
- {
- this.RecordCount += this.LeftRightKeyToAcceleration;
- }
- else
- {
- this.RecordCount = this.MaxRecordCount;
- }
- }
- else if (Keyboard.IsKeyDown(Key.Up)) //鼠标下键
- {
- this._crossHairGrid_IsDoubleClick = false;
- this.HiddenCrossHairGrid();
- if (this.RecordCount - this.LeftRightKeyToAcceleration > this.MinRecordCount)
- {
- this.RecordCount -= this.LeftRightKeyToAcceleration;
- }
- else
- {
- this.RecordCount = this.MinRecordCount;
- }
- }
- else if (Keyboard.IsKeyDown(Key.Left)) //鼠标左键
- {
- Mouse.OverrideCursor = Cursors.None;
- this.DrawingCross(false);
- }
- else if (Keyboard.IsKeyDown(Key.Right)) //鼠标右键
- {
- Mouse.OverrideCursor = Cursors.None;
- this.DrawingCross(true);
- }
- else if (Keyboard.IsKeyDown(Key.Escape))
- {
- this._crossHairGrid_IsDoubleClick = false;
- this.HiddenCrossHairGrid();
- Mouse.OverrideCursor = Cursors.Arrow;
- }
- e.Handled = true;
- }
- private void _mainGrid_MouseDown(object sender, MouseButtonEventArgs e)
- {
- _mainGrid.Focusable = true;
- FocusManager.SetFocusedElement(_mainGrid, _mainGrid);
- }
- /// <summary>
- /// 获取和设置the root panel
- /// 代替PopupManager.PopupRoot,一个应用程序多图表时,popup只针对当前图表
- /// </summary>
- internal Panel RootPanel
- {
- get
- {
- return _mainGrid;
- }
- }
- /// <summary>
- /// 计算历史周期涨幅
- /// </summary>
- /// <returns>IList{ILineDataPoint}.</returns>
- private List<ILineDataPoint> CaclulateCycleDataIncrease(List<ILineDataPoint> source)
- {
- return source;
- }
- /// <summary>
- /// 计算分时数据涨幅
- /// </summary>
- /// <param name="source">The source.</param>
- private void CaclulateTikDataIncrease(IList<ILineDataPoint> source)
- {
- if (source == null || !source.Any()) return;
- foreach (var lineDataPoint in source)
- {
- var current = lineDataPoint as IOHLCDataPoint;
- if (current == null) continue;
- current.Increase = CurrentGoods.PreClose.Equals(0)
- ? 0f
- : (current.Close - CurrentGoods.PreClose) / CurrentGoods.PreClose;
- current.IncreaseValue = CurrentGoods.PreClose.Equals(0) ? 0f : (current.Close - CurrentGoods.PreClose);
- }
- }
- /// <summary>
- /// 清除报价牌
- /// </summary>
- private void CleanQuoteBoard()
- {
- bool flag = _popup != null;
- if (flag)
- {
- _popup.Child = (null);
- _chartPanesGrid.Children.Remove(_popup);
- _popup = null;
- }
- }
- private void CrossHairGrid_LostMouseCapture(object sender, MouseEventArgs e)
- {
- if (CurrentGoods == null || string.IsNullOrWhiteSpace(CurrentGoods.Symbol)) return;
- if (_crossFlag)
- {
- if (PointerType != PointerType.Pan)
- {
- _crossHairGrid.Children.Clear();
- var panes = AllPanes();
- foreach (var chartPane in panes)
- {
- var layers = chartPane.AllScaleLayers;
- if (layers == null || !layers.Any()) continue;
- foreach (var scaleLayer in layers)
- {
- var left = scaleLayer.GetLeftValueScaleDisplay();
- var right = scaleLayer.GetRightValueScaleDisplay();
- if (left != null) left.BuildYList();
- if (right != null) right.BuildYList();
- }
- }
- }
- _crossFlag = false;
- _pointerPopup.IsOpen = false;
- if (_mainGrid.Children.Contains(_pointerPopup))
- {
- _mainGrid.Children.Remove(_pointerPopup);
- }
- }
- }
- private void CrossHairGrid_MouseEnter(object sender, MouseEventArgs e)
- {
- if (CurrentGoods == null || string.IsNullOrWhiteSpace(CurrentGoods.Symbol)) return;
- SetCursorImagePos(true, e);
- DrawingToolExecute();
- }
- private void CrossHairGrid_MouseLeave(object sender, MouseEventArgs e)
- {
- if (CurrentGoods == null || string.IsNullOrWhiteSpace(CurrentGoods.Symbol)) return;
- SetCursorImagePos(false, e);
- }
- private int _crossHairGrid_ClickTik = 0;
- public bool _crossHairGrid_IsDoubleClick = false;
- private void CrossHairGrid_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
- {
- _crossHairGrid_ClickTik += 1;
- DispatcherTimer timer = new DispatcherTimer();
- timer.Interval = new TimeSpan(0, 0, 0, 0, 300);
- timer.Tick += (cs, ce) =>
- {
- timer.IsEnabled = false;
- _crossHairGrid_ClickTik = 0;
- };
- timer.IsEnabled = true;
- if (_crossHairGrid_ClickTik % 2 == 0)
- {
- timer.IsEnabled = false;
- _crossHairGrid_ClickTik = 0;
- _crossHairGrid_IsDoubleClick = !_crossHairGrid_IsDoubleClick;
- if (CurrentGoods == null || string.IsNullOrWhiteSpace(CurrentGoods.Symbol))
- {
- return;
- }
- else
- {
- if (Keyboard.Modifiers == (ModifierKeys)2 && _oldDrawingTool != null)
- {
- SetDrawingTool(_oldDrawingTool);
- var panes = AllPanes();
- foreach (var current in panes)
- {
- Point position = e.GetPosition(current.PaintArea);
- if (position.X >= 0.0 && position.Y >= 0.0 && position.X <= current.PaintArea.ActualWidth &&
- position.Y <= current.PaintArea.ActualHeight)
- {
- current.SimulateDrawingMouseDown(RuntimeHelpers.GetObjectValue(sender), e);
- break;
- }
- }
- }
- else
- {
- _crossHairGrid.CaptureMouse();
- _crossFlag = true;
- if (PointerType == PointerType.Pan)
- {
- _crossX = (float)e.GetPosition(_crossHairGrid).X;
- _crossDateTime = DateScaler.DateFromX(_crossX);
- }
- else
- {
- if (PointerType == PointerType.CursorWithData)
- {
- _pointerPopup.IsOpen = true;
- }
- if (_crossHairGrid.Children.Count == 0)
- {
- _crossHairGrid.Children.Add(_hline);
- _crossHairGrid.Children.Add(_vline);
- }
- DrawingCross(e);
- }
- }
- }
- }
- }
- private void CrossHairGrid_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
- {
- if (CurrentGoods == null || string.IsNullOrWhiteSpace(CurrentGoods.Symbol)) return;
- if (_crossFlag)
- {
- if (!_crossHairGrid_IsDoubleClick)
- {
- _crossHairGrid.ReleaseMouseCapture();
- if (PointerType == PointerType.Pan)
- {
- MoveChartPane(e);
- }
- else
- {
- _crossHairGrid.Children.Clear();
- var panes = AllPanes();
- var scaleLayerList = panes.Select(chartPane => chartPane.AllScaleLayers)
- .Where(layers => layers != null && layers.Any())
- .SelectMany(layers => layers)
- .ToList();
- foreach (var scaleLayer in scaleLayerList)
- {
- scaleLayer.GetRightValueScaleDisplay().BuildYList();
- scaleLayer.GetLeftValueScaleDisplay().BuildYList();
- }
- }
- _crossFlag = false;
- _pointerPopup.IsOpen = false;
- }
- }
- }
- public void HiddenCrossHairGrid()
- {
- _crossHairGrid.ReleaseMouseCapture();
- _pointerPopup.IsOpen = false;
- }
- DateTime LastRedrawTime = DateTime.Now;
- private Point lastPoint = new Point();
- private void CrossHairGrid_MouseMove(object sender, MouseEventArgs e)
- {
- Mouse.OverrideCursor = Cursors.Arrow;
- if (CurrentGoods == null || string.IsNullOrWhiteSpace(CurrentGoods.Symbol))
- {
- return;
- }
- if (_crossHairGrid_IsDoubleClick)
- {
- this.Cursor = Cursors.None;
- }
- else
- {
- this.Cursor = Cursors.Arrow;
- }
- SetCursorImagePos(true, e);
- if (_crossFlag)
- {
- if (PointerType == PointerType.Pan)
- {
- MoveChartPane(e);
- }
- else
- {
- DrawingCross(e);
- }
- }
- }
- /// <summary>
- /// Handles the Click event of the _downloadMoreButton control.
- /// </summary>
- /// <param name="sender">The source of the event.</param>
- /// <param name="e">The <see cref="RoutedEventArgs" /> instance containing the event data.</param>
- private void DownloadMoreButton_Click(object sender, RoutedEventArgs e)
- {
- _downloadMoreButton.Visibility = Visibility.Collapsed;
- DownloadNextDataBlock();
- }
- private void DownloadMoreButton_MouseEnter(object sender, MouseEventArgs e)
- {
- _downloadMoreButton.ToolTip =
- string.Format(LanguageManager.FindResource(LanguageConst.ToolTip_DownloadMore), MaxLoadRecordCount);
- }
- /// <summary>
- /// 更新图表
- /// </summary>
- private void DrawingChart(bool isUpdataSet)
- {
- if (_chartPanesGrid == null) return;
- if (CycleType == CycleType.TimeSharing)
- {
- DrawingTimeShareChart();
- return; //分时图不使用这个方法更新图表
- }
- var allDateScaler = (AllDateScaler)DateScaler;
- var width = (int)GetChartPaneWidth();
- width = Math.Max(0, width);
- var left = (float)GetChartPanelOffset();
- allDateScaler.SetPlotInfo(width, left);
- _dateScaleDisplay.BuildCanvas(allDateScaler, left, width, false);
- //DateChartSlider.Margin = new Thickness(left, 0, 0, 0);
- _downloadMoreButtonPlaceHolder.Width = left;
- DateChartSlider.BuildDateChartSlider();
- ShowDownloadButton(allDateScaler.StartDateIndex == 0);
- var chartPanes = _chartPanesGrid.Children.OfType<ChartPane>();
- var childrenCount = chartPanes.Count();
- var paneIndex = 0;
- if (CycleType == CycleType.Tik)
- {
- foreach (var current in _chartPanesGrid.Children)
- {
- var pane = current as ChartPane;
- if (pane != null)
- {
- //最后一个ChartPane时更新
- pane.RefreshChartFlag = true;
- pane.BuildTimeShareChartPane(allDateScaler, _dateScaleDisplay);
- }
- }
- }
- else
- {
- foreach (var current in chartPanes)
- {
- paneIndex++;
- if (current != null)
- {
- //最后一个ChartPane时更新
- current.RefreshChartFlag = paneIndex == childrenCount;
- current.BuildChartPane(allDateScaler, _dateScaleDisplay, isUpdataSet);
- }
- }
- }
- }
- /// <summary>
- /// 创建分时图
- /// </summary>
- private void DrawingTimeShareChart()
- {
- if (_chartPanesGrid == null) return;
- var width = (int)GetChartPaneWidth();
- width = Math.Max(0, width);
- var left = (float)GetChartPanelOffset();
- var allDateScaler = CreateDateScaler(width, left);
- DateScaler = allDateScaler;
- _dateScaleDisplay.BuildTimeShareCanvas(allDateScaler, left, width, false,
- CurrentGoods.OpenCloseTimes, this);
- int paneIndex = 0;
- foreach (var current in _chartPanesGrid.Children)
- {
- var pane = current as ChartPane;
- if (pane != null)
- {
- //最后一个ChartPane时更新
- pane.RefreshChartFlag = paneIndex == 1;
- pane.BuildTimeShareChartPane(allDateScaler, _dateScaleDisplay);
- paneIndex++;
- }
- }
- }
- /// <summary>
- /// 创建分时图的时间轴
- /// </summary>
- private AllDateScaler CreateDateScaler(int width, float left)
- {
- int count = SetCountPoint();
- var dateScaler = new AllDateScaler(this)
- {
- NumBars = count,
- DesiredEndDate = DateTime.Today.AddMinutes(count),
- };
- dateScaler.SetPlotInfo(width, left);
- var dataPoints = new List<ILineDataPoint>();
- if (CurrentGoods == null || CurrentGoods.OpenCloseTimes == null) return dateScaler;
- var timeSpan = TimeSpan.Zero;
- foreach (var openCloseTimes in CurrentGoods.OpenCloseTimes)
- {
- timeSpan = openCloseTimes.CloseTime - openCloseTimes.OpenTime;
- for (int i = 0; i <= timeSpan.TotalMinutes; i++)
- {
- dataPoints.Add(new BarDataPoint(openCloseTimes.OpenTime.AddMinutes(i), 0));
- }
- }
- dateScaler.SetDates(dataPoints, CurrentTimeFrame, false);
- return dateScaler;
- }
- /// <summary>
- /// 十字光标按下时画交叉线
- /// </summary>
- /// <param name="e">The <see cref="MouseEventArgs"/> instance containing the event data.</param>
- private void DrawingCross(MouseEventArgs e)
- {
- var position = e.GetPosition(_crossHairGrid);
- _currentX = position.X;
- _currentY = position.Y;
- currentX = _currentX;
- currentY = _currentY;
- _offSetNum = 0;
- //限制超出ChartPane时十字光标的显示-新增OriginalDateValue, OriginalDateFromX
- var start = DateScaler.OriginalDateValue(DateScaler.StartDateIndex);
- var end = DateScaler.OriginalDateValue(DateScaler.EndDateIndex);
- var distance = DateScaler.DistanceBetweenDates();
- _currentX -= (float)distance / 2;
- var aDate = (_currentX <= 0 || _currentX < distance) ? start : DateScaler.OriginalDateFromX(_currentX - 5);
- if (aDate.Equals(DateTime.MinValue) || aDate > end)
- {
- aDate = end;
- }
- if (aDate.Equals(DateTime.MinValue) || aDate < start)
- {
- aDate = start;
- }
- //显示报价牌
- ShowQuoteBoard(aDate);
- var num = (float)((int)Math.Round((double)DateScaler.XforDate(aDate)));
- //5.0f 是PART_ChartPanesGrid的Margin, 0.5f在LinePlot/DateScaleDisplay里都加有0.5的微调
- //另外加上左边纵坐标引起的位移
- num = num + 5f + 0.5f + (float)GetChartPanelOffset();
- var y = _currentY < 0 ? 0 : _currentY;
- var with = _crossHairGrid.ActualWidth;
- var height = _crossHairGrid.ActualHeight;
- var brush = IsDarkBackground
- ? (new SolidColorBrush(Colors.White))
- : (new SolidColorBrush(Colors.Black));
- _hline.X1 = 0;
- _hline.X2 = with;
- _hline.Y1 = y;
- _hline.Y2 = y;
- _hline.Stroke = brush;
- _vline.X1 = num;
- _vline.X2 = num;
- _vline.Y1 = 0;
- _vline.Y2 = height;
- _vline.Stroke = brush;
- var panes = AllPanes();
- foreach (var current in panes)
- {
- var position2 = e.GetPosition(current);
- bool flag = position2.Y >= 0.0 && position2.Y <= current.ActualHeight;
- var layers = current.AllScaleLayers;
- if (layers == null || !layers.Any()) continue;
- foreach (var scaleLayer in layers)
- {
- var left = scaleLayer.GetLeftValueScaleDisplay();
- var right = scaleLayer.GetRightValueScaleDisplay();
- if (flag)
- {
- if (left != null) left.BuildYList((float)position2.Y);
- if (right != null) right.BuildYList((float)position2.Y);
- }
- else
- {
- if (left != null) left.BuildYList();
- if (right != null) right.BuildYList();
- }
- }
- }
- }
- /// <summary>
- /// 十字光标按下时画交叉线
- /// </summary>
- /// <param name="e">The <see cref="MouseEventArgs"/> instance containing the event data.</param>
- public void DrawingCross(bool isAddTime = true)
- {
- _offSetNum += isAddTime ? 1 : -1;
- var aDate = DateScaler.OriginalDateFromX(currentX - 5, _offSetNum);
- if (DateScaler.XforDate(aDate) < 0)
- {
- _offSetNum += (!isAddTime) ? 1 : -1;
- return;
- }
- if (DateScaler.XforDate(aDate) > _chartPanesGrid.ActualWidth)
- {
- _offSetNum += (!isAddTime) ? 1 : -1;
- return;
- }
- //显示报价牌
- ShowQuoteBoard(aDate);
- var num = (float)((int)Math.Round((double)DateScaler.XforDate(aDate)));
- //5.0f 是PART_ChartPanesGrid的Margin, 0.5f在LinePlot/DateScaleDisplay里都加有0.5的微调
- //另外加上左边纵坐标引起的位移
- num = num + 5f + 0.5f + (float)GetChartPanelOffset();
- var y = _currentY < 0 ? 0 : _currentY;
- var with = _crossHairGrid.ActualWidth;
- var height = _crossHairGrid.ActualHeight;
- var brush = IsDarkBackground ? (new SolidColorBrush(Colors.White)) : (new SolidColorBrush(Colors.Black));
- _hline.X1 = 0;
- _hline.X2 = with;
- _hline.Y1 = y;
- _hline.Y2 = y;
- _hline.Stroke = brush;
- _vline.X1 = num;
- _vline.X2 = num;
- _vline.Y1 = 0;
- _vline.Y2 = height;
- _vline.Stroke = brush;
- var panes = AllPanes();
- foreach (var current in panes)
- {
- bool flag = currentY >= 0.0 && currentY <= current.ActualHeight;
- var layers = current.AllScaleLayers;
- if (layers == null || !layers.Any()) continue;
- foreach (var scaleLayer in layers)
- {
- var left = scaleLayer.GetLeftValueScaleDisplay();
- var right = scaleLayer.GetRightValueScaleDisplay();
- if (flag)
- {
- if (left != null) left.BuildYList((float)currentY);
- if (right != null) right.BuildYList((float)currentY);
- }
- else
- {
- if (left != null) left.BuildYList();
- if (right != null) right.BuildYList();
- }
- }
- }
- }
- /// <summary>
- /// 加载叠加商品数据
- /// </summary>
- /// <param name="comparisonGoods">The comparison goods.</param>
- /// <returns>IList{ILineDataPoint}.</returns>
- private List<ILineDataPoint> LoadComparisonDataSet(ComparisonGoods comparisonGoods)
- {
- //历史数据回补后叠加商品记录条数以当前主商品记录条数为准
- var flag = DataSet == null || DataSet.DataPoints == null || !DataSet.DataPoints.Any();
- if (flag) return null;
- var count = DataSet.DataPoints.Count;
- var endTime = DataSet.DataPoints.Max(z => z.Date);
- return OnLoadHistoryCycleData(comparisonGoods, CycleType, CurrentTimeFrame, MaxLoadRecordCount, endTime);
- }
- /// <summary>
- /// Loads the configs from XML.
- /// </summary>
- /// <param name="configName">Name of the config.</param>
- private void LoadConfigsFromXml(string configName)
- {
- //to-do:
- }
- /// <summary>
- /// Handles the MouseEnter event of the MainGrid control.
- /// </summary>
- /// <param name="sender">The source of the event.</param>
- /// <param name="e">The <see cref="MouseEventArgs"/> instance containing the event data.</param>
- private void MainGrid_MouseEnter(object sender, MouseEventArgs e)
- {
- if (CurrentDrawingTool != null)
- {
- SetDrawingTool(CurrentDrawingTool);
- }
- else
- {
- DrawingToolExecute();
- }
- }
- /// <summary>
- /// Handles the MouseMove event of the MainGrid control.
- /// </summary>
- /// <param name="sender">The source of the event.</param>
- /// <param name="e">The <see cref="MouseEventArgs"/> instance containing the event data.</param>
- private void MainGrid_MouseMove(object sender, MouseEventArgs e)
- {
- if (CurrentDrawingTool != null)
- {
- SetDrawingTool(CurrentDrawingTool);
- }
- else
- {
- DrawingToolExecute();
- }
- //Console.WriteLine("鼠标移动开始:" + startTime);
- //timer.IsEnabled = false;
- //startTime = DateTime.Now;
- //timer.IsEnabled = true;
- }
- /// <summary>
- /// Pane工具相当于移动时间滑块
- /// </summary>
- /// <param name="e">The <see cref="MouseEventArgs"/> instance containing the event data.</param>
- private void MoveChartPane(MouseEventArgs e)
- {
- DateTime desiredEndDate = DateScaler.DesiredEndDate;
- float num = DateScaler.XforDate(_crossDateTime);
- var num2 = (float)(_crossHairGrid.ActualWidth / (double)DateScaler.NumBars);
- var num3 = (float)(e.GetPosition(_crossHairGrid).X - (double)num);
- var num4 = checked((int)Math.Round((double)unchecked((float)DateScaler.EndDateIndex - num3 / num2)));
- var count = DateScaler.Count();
- bool flag = num4 >= count;
- DateScaler.DesiredEndDate = flag ? DateTime.MaxValue : DateScaler.DateValue(num4);
- if (!DateScaler.DesiredEndDate.Equals(desiredEndDate))
- {
- Refresh();
- }
- }
- /// <summary>
- /// 清除图表容器,切换周期时使用
- /// </summary>
- private void ChangePanesClear()
- {
- _chartPanes.Clear();
- _chartPanesGrid.Children.Clear();
- _chartPanesGrid.RowDefinitions.Clear();
- }
- /// <summary>
- /// Called when [cycle type changed].
- /// </summary>
- /// <param name="refreshNow">if set to <c>true</c> [refresh now].</param>
- /// <param name="isFromTimesharing">是否是从分时图中切换</param>
- private void OnCycleTypeChanged(bool refreshNow, bool isFromTimesharing = false)
- {
- if (CurrentGoods == null) return;
- var cycleType = CycleType;
- var timeSpan = CurrentTimeFrame;
- var goods = CurrentGoods;
- var maxLoadRecordCount = MaxLoadRecordCount;
- Dispatcher.BeginInvoke(new Action(() =>
- {
- DataSet = new ChartDataSet();
- switch (cycleType)
- {
- case CycleType.TimeSharing:
- ChangePanesClear();
- DateChartSlider.Visibility = Visibility.Collapsed;
- _downloadMoreButton.Visibility = Visibility.Collapsed;
- OpenTimeSharePlot(CurrentGoods);
- _timeSharingTimer.Start(); //开始定时器补数据
- SetDatesAndRefresh(refreshNow);
- break;
- case CycleType.Tik:
- ChangePanesClear();
- // DateChartSlider.Visibility = Visibility.Collapsed;
- DateChartSlider.Visibility = Visibility.Visible;
- _downloadMoreButton.Visibility = Visibility.Collapsed;
- _timeSharingTimer.Stop();
- CreateTikChart(CurrentGoods);
- SetDatesAndRefresh(refreshNow);
- break;
- default:
- ////数据源更改,计算涨幅
- if (isFromTimesharing)
- {
- ChangePanesClear();
- foreach (var chartPane in _chartCachePanes)
- {
- //取最大grid高度做*
- var stars = _chartPanesGrid.RowDefinitions.Count > 0
- ? _chartPanesGrid.RowDefinitions.Max(z => z.Height.Value)
- : 1.0;
- AddChartPane(chartPane, stars, IsMainChartPane(chartPane));
- }
- }
- //CreateMinuteChart(CurrentGoods);
- _timeSharingTimer.Stop();
- DateChartSlider.Visibility = Visibility.Visible;
- DataSet.DataPoints = CaclulateCycleDataIncrease(OnLoadHistoryCycleData(goods, cycleType, timeSpan, maxLoadRecordCount, DateTime.Now));
- SetDatesAndRefresh(refreshNow);
- break;
- }
- }), DispatcherPriority.Background);
- }
- /// <summary>
- /// 设置日期和刷新.
- /// </summary>
- /// <param name="refreshNow">if set to <c>true</c> [refresh now].</param>
- private void SetDatesAndRefresh(bool refreshNow,bool isupdateBar=true)
- {
- Dispatcher.BeginInvoke(new Action(() =>
- {
- var allDateScaler = (AllDateScaler)DateScaler;
- allDateScaler.SetDates(DataSet.DataPoints, CurrentTimeFrame, false);
- //numBars为矩形柱间距,矩形柱数量实际要-1
- if (isupdateBar)
- {
- allDateScaler.NumBars = RecordCountInternal - 1;
- }
- // if (refreshNow) Refresh(true);
- if (DataSet.DataPoints != null && DataSet.DataPoints.Any())
- { Refresh(refreshNow); }
- }), DispatcherPriority.Background);
- }
- /// <summary>
- /// Cycles the type property changed.
- /// </summary>
- /// <param name="isFromTimesharing">是否是从分时图中切换</param>
- private void CycleTypePropertyChanged(bool isFromTimesharing)
- {
- Dispatcher.BeginInvoke(new Action(() =>
- {
- if (CycleType.TimeSharing == CycleType)
- {
- _chartCachePanes.Clear();
- foreach (var chartPane in _chartPanes)
- {
- if (!chartPane.IsTimeSpaning)
- {
- _chartCachePanes.Add(chartPane);
- }
- }
- }
- if (_comparisonGoodsList == null || !_comparisonGoodsList.Any())
- {
- OnCycleTypeChanged(true, isFromTimesharing);
- }
- else
- {
- OnCycleTypeChanged(false, isFromTimesharing);
- //刷新叠加商品
- RefreshComparsionGoods();
- }
- //更新底部快捷周期状态
- // TimeSpanPicker.UpdateCyleType(CycleType);
- }), DispatcherPriority.Background);
- }
- /// <summary>
- /// Called when [load goods data].
- /// </summary>
- /// <param name="goods">The goods.</param>
- /// <param name="totalCount">The total count.</param>
- /// <param name="endTime">The end time.</param>
- /// <returns>ChartDataSet.</returns>
- private List<ILineDataPoint> OnLoadHistoryCycleData(GoodsInfo goods, CycleType cycleType, TimeSpan timeSpan, int totalCount, DateTime endTime)
- {
- List<ILineDataPoint> result = null;
- var cycleTypeHandler = LoadHistoryCycleDataByCycleType;
- if (cycleTypeHandler != null)
- {
- result = cycleTypeHandler(goods.ExchangeCode, goods.GoodsCode, cycleType, timeSpan,
- DateTime.MinValue, endTime, totalCount);
- }
- //集合都要按时间顺排序,才能画图
- return result == null ? null : result.OrderBy(z => z.Date).ToList();
- }
- /// <summary>
- /// 获取分时图的数据分钟数据
- /// </summary>
- /// <param name="goods">The goods.</param>
- /// <param name="totalCount">The total count.</param>
- /// <param name="startTime">开始时间</param>
- /// <param name="endTime">The end time.</param>
- /// <returns>ChartDataSet.</returns>
- private List<ILineDataPoint> OnLoadHistoryTimeSpaningCycleData(GoodsInfo goods, int totalCount,
- DateTime startTime, DateTime endTime)
- {
- List<ILineDataPoint> result = null;
- var cycleTypeHandler = LoadHistoryCycleDataByCycleType;
- if (cycleTypeHandler != null)
- {
- result = cycleTypeHandler(goods.ExchangeCode, goods.GoodsCode, CycleType.Minute, CurrentTimeFrame, startTime,
- endTime, totalCount);
- }
- //集合都要按时间顺排序,才能画图
- return result == null ? null : result.OrderBy(z => z.Date).ToList();
- }
- /// <summary>
- /// 更改时间间隔后执行
- /// </summary>
- /// <param name="cycleType">Type of the cycle.</param>
- private void OnTimeSpanChanged(CycleType cycleType)
- {
- DateScaler.DesiredEndDate = DateTime.MaxValue; //必须设为最大值
- CycleType = cycleType;
- }
- /// <summary>
- /// 设置当前画线工具,并处理它与图例间的变动
- /// </summary>
- /// <param name="aDrawing"></param>
- private void SetDrawingTool(IDrawingTool aDrawing)
- {
- CurrentDrawingTool = aDrawing;
- DrawingToolExecute();
- var chartPanes = AllPanes();
- foreach (var chartPane in chartPanes)
- {
- chartPane.OnDrawing();
- }
- }
- /// <summary>
- /// 显示当前时间的报价牌
- /// </summary>
- /// <param name="aDate">A date.</param>
- private void ShowQuoteBoard(DateTime aDate)
- {
- if (_pointerPopup.IsOpen && !aDate.Equals(DateTime.MinValue))
- {
- var list = new List<ControlPair>();
- ControlPair controlPair = null;
- var controlPair2 = new ControlPair();
- var textBlock = new TextBlock
- {
- Text = aDate.ToString("yyyy-MM-dd ddd HH:mm:ss"),
- //aDate.ToString(aDate.TimeOfDay.Ticks == 0L ? "yyyy-MM-dd ddd" : "yyyy-MM-dd ddd hh:mm:ss"),
- Foreground =
- IsDarkBackground
- ? (new SolidColorBrush(Colors.White))
- : (new SolidColorBrush(Colors.Black)),
- HorizontalAlignment = HorizontalAlignment.Center
- };
- controlPair2.ControlLeft = textBlock;
- list.Add(controlPair2);
- var panes = AllPanes();
- foreach (var current in panes)
- {
- bool flag = false;
- var scaleLayers = current.AllScaleLayers;
- if (scaleLayers != null && scaleLayers.Any())
- {
- foreach (var scaleLayer in scaleLayers)
- {
- var allFormulas = new List<DisplayFormula>(scaleLayer.AllDisplayFormula);
- allFormulas.AddRange(scaleLayer.ComparisonFormulas);
- if (!allFormulas.Any()) continue;
- foreach (var formula in allFormulas)
- {
- //plot.PlotBase_5031(aDate, IsDarkBackground, SymbolManager.Manager().SymbolPrecision(CurrentSymbol) > 2)
- var controlPairs = formula.GetControlPairs(aDate, IsDarkBackground, this.CurrentGoods.MinUnit);
- if (controlPairs != null && controlPairs.Any())
- {
- flag = true;
- if (controlPair != null)
- {
- list.Add(controlPair);
- controlPair = null;
- }
- list.AddRange(controlPairs);
- }
- }
- }
- }
- if (flag)
- {
- controlPair = new ControlPair()
- {
- ControlLeft = new Border()
- {
- Margin = new Thickness(0.0, 2.0, 0.0, 2.0),
- Height = 2.0,
- BorderThickness = new Thickness(1.0),
- BorderBrush = new SolidColorBrush(ColorHelper.DimGray)
- }
- };
- }
- }
- _pointerGrid.RowDefinitions.Clear();
- _pointerGrid.Children.Clear();
- int num = 0;
- foreach (var current in list)
- {
- var rowDefinition = new RowDefinition { Height = new GridLength(1.0, 0) };
- _pointerGrid.RowDefinitions.Add(rowDefinition);
- if (current.ControlLeft != null)
- {
- current.ControlLeft.SetValue(Control.FontSizeProperty, ChartFontSize);
- if (current.ControlRight == null)
- {
- current.ControlLeft.SetValue(Grid.RowProperty, num);
- current.ControlLeft.SetValue(Grid.ColumnSpanProperty, 2);
- _pointerGrid.Children.Add(current.ControlLeft);
- }
- else
- {
- current.ControlRight.SetValue(Control.FontSizeProperty, ChartFontSize);
- current.ControlLeft.SetValue(Grid.RowProperty, num);
- current.ControlRight.SetValue(Grid.RowProperty, num);
- current.ControlRight.SetValue(Grid.ColumnProperty, 1);
- _pointerGrid.Children.Add(current.ControlLeft);
- _pointerGrid.Children.Add(current.ControlRight);
- }
- }
- num++;
- }
- //_pointerGrid.UpdateLayout();
- //左边纵坐标宽度
- var buffer = GetChartPanelOffset();
- if (_pointerGrid.ActualWidth + buffer > (double)_currentX)
- {
- _pointerPopup.HorizontalOffset = (_pointerGrid.ActualWidth + buffer);
- }
- else
- {
- _pointerPopup.HorizontalOffset = buffer;
- }
- }
- }
- #endregion Private Methods
- #region 分时图
- private void _timeSharingTimer_Tick(object sender, EventArgs e)
- {
- //todo:修改使用行情时间
- var updateTime = _goodsQuoteTime.AddMinutes(1);
- //var updateTime = DateTime.Now.AddSeconds(-DateTime.Now.Second);
- if (DataSet == null || DataSet.DataPoints == null || !DataSet.DataPoints.Any())
- {
- //没有数据源无法补数据
- _timeSharingTimer.Stop();
- }
- else
- {
- var lastPoint = DataSet.DataPoints[DataSet.DataPoints.Count - 1];
- var dataPoint = new BarDataPoint(lastPoint.Date, lastPoint.Value); ;
- var timeSpan = updateTime - dataPoint.Date;
- if (timeSpan.TotalSeconds >= 60)
- {
- dataPoint.Date = updateTime;
- dataPoint.Volume = 0;
- UpdateTimeShareData(dataPoint, this.CurrentGoods.GoodsCode);
- }
- UpdateTimerComparisonShareing(updateTime); //定时器更新叠加数据
- }
- }
- /// <summary>
- /// 定时器更新叠加商品数据
- /// </summary>
- /// <param name="updateTime">更新时间</param>
- private void UpdateTimerComparisonShareing(DateTime updateTime)
- {
- if (this.ComparisionTimeShareDic != null)
- {
- var keyList = this.ComparisionTimeShareDic.Keys.ToList();
- foreach (var goodsCodeKey in keyList)
- {
- if (this.ComparisionTimeShareDic[goodsCodeKey].Any())
- {
- var lastPoint = this.ComparisionTimeShareDic[goodsCodeKey][
- this.ComparisionTimeShareDic[goodsCodeKey].Count - 1];
- var dataPoint = new BarDataPoint(lastPoint.Date, lastPoint.Value); ;
- var timeSpan = updateTime - dataPoint.Date;
- if (timeSpan.TotalSeconds >= 60)
- {
- dataPoint.Date = updateTime;
- UpdateComparisonData(goodsCodeKey, (IBarDataPoint)dataPoint);
- }
- }
- }
- }
- }
- /// <summary>
- /// 更新实时数据数据集
- /// </summary>
- /// <param name="barDataPoint">新添加的数据</param>
- /// <param name="goodsCode">更新数据的商品代码</param>
- public void UpdateTimeShareData(IBarDataPoint barDataPoint, string goodsCode)
- {
- if (barDataPoint == null) return;
- //格式化时间
- barDataPoint.Date = barDataPoint.Date.Date.AddMinutes((int)barDataPoint.Date.TimeOfDay.TotalMinutes);
- this.Dispatcher.BeginInvoke(new Action(() =>
- {
- if (this.CurrentGoods != null && goodsCode == this.CurrentGoods.GoodsCode)
- {
- if (DataSet == null)
- {
- DataSet = new ChartDataSet();
- }
- if (DataSet.DataPoints == null)
- {
- DataSet.DataPoints = new List<ILineDataPoint>();
- }
- if (DataSet.DataPoints.Any())
- {
- var volData = DataSet.DataPoints[DataSet.DataPoints.Count - 1];
- var timeSpan = barDataPoint.Date.AddSeconds(-barDataPoint.Date.Second) -
- volData.Date.AddSeconds(-barDataPoint.Date.Second);
- int count = (int)timeSpan.TotalMinutes;
- if (count < 0)
- {
- return;
- }
- if (count == 0)
- {
- DataSet.DataPoints[DataSet.DataPoints.Count - 1] = barDataPoint;
- }
- else
- {
- if (count >= 2 && count <= 1440) //使用定时器时更新可能不会出现这情况
- {
- var repairPoint = DataSet.DataPoints[DataSet.DataPoints.Count - 1];
- var repairBarPoint = repairPoint as IBarDataPoint;
- if (repairBarPoint != null)
- {
- repairBarPoint.Volume = 0;
- }
- for (int i = 0; i < count - 1; i++)
- {
- DataSet.DataPoints.Add(repairBarPoint);
- }
- }
- DataSet.DataPoints.Add(barDataPoint);
- }
- }
- else
- {
- DataSet.DataPoints.Add(barDataPoint);
- }
- if (timeSharingFormulaModel != null)
- {
- timeSharingFormulaModel.UpdatePointSharing(barDataPoint);
- }
- }
- else
- {
- UpdateComparisonData(goodsCode, barDataPoint);
- }
- Refresh(true);
- }));
- }
- /// <summary>
- /// 更新叠加商品分时图
- /// </summary>
- /// <param name="goodsCode">商品代码</param>
- /// <param name="barDataPoint"></param>
- private void UpdateComparisonData(string goodsCode, IBarDataPoint barDataPoint)
- {
- //更新叠加分时图数据
- if (ComparisionTimeShareDic.ContainsKey(goodsCode))
- {
- barDataPoint.Date = barDataPoint.Date.Date.AddMinutes((int)barDataPoint.Date.TimeOfDay.TotalMinutes);
- ComparisionTimeShareDic[goodsCode] = ComparisionTimeShareDic[goodsCode] ?? new List<ILineDataPoint>();
- if (ComparisionTimeShareDic[goodsCode].Any())
- {
- var volData = ComparisionTimeShareDic[goodsCode][ComparisionTimeShareDic[goodsCode].Count - 1];
- var timeSpan = barDataPoint.Date.AddSeconds(-barDataPoint.Date.Second) -
- volData.Date.AddSeconds(-barDataPoint.Date.Second);
- int count = (int)timeSpan.TotalMinutes;
- if (count < 0)
- {
- return;
- }
- else if (count == 0)
- {
- ComparisionTimeShareDic[goodsCode][ComparisionTimeShareDic[goodsCode].Count - 1] = barDataPoint;
- }
- else
- {
- if (count >= 2 && count <= 1440) //使用定时器时更新可能不会出现这情况
- {
- var repairPoint = ComparisionTimeShareDic[goodsCode][ComparisionTimeShareDic[goodsCode].Count - 1];
- for (int i = 0; i < count - 1; i++)
- {
- ComparisionTimeShareDic[goodsCode].Add(repairPoint);
- }
- }
- ComparisionTimeShareDic[goodsCode].Add(barDataPoint);
- }
- }
- else
- {
- ComparisionTimeShareDic[goodsCode].Add(barDataPoint);
- }
- if (this._comparisonFommulaHsSet != null && _comparisonFommulaHsSet.ContainsKey(goodsCode))
- {
- _comparisonFommulaHsSet[goodsCode].UpdateComparsionPoint(barDataPoint);
- }
- }
- }
- /// <summary>
- /// 更新单笔数据
- /// </summary>
- /// <param name="barDataPoint">tik数据</param>
- /// <param name="goodsCode"></param>
- public void UpdateTikData(IBarDataPoint barDataPoint, string goodsCode)
- {
- if (barDataPoint == null) return;
- if (this.CurrentGoods != null && goodsCode == this.CurrentGoods.GoodsCode)
- {
- if (DataSet == null)
- {
- DataSet = new ChartDataSet();
- }
- if (DataSet.DataPoints == null)
- {
- DataSet.DataPoints = new List<ILineDataPoint>();
- }
- DataSet.DataPoints.Add(barDataPoint);
- if (_tikFormulaModel != null)
- {
- _tikFormulaModel.UdpdateTickPoint(barDataPoint);
- Refresh(true);
- }
- }
- }
- /// <summary>
- /// 更新单笔数据
- /// </summary>
- public void UpdateMinuteData(IBarDataPoint barDataPoint, string goodsCode)
- {
- DataSet.DataPoints = CaclulateCycleDataIncrease(OnLoadHistoryCycleData(CurrentGoods, CycleType, CurrentTimeFrame, MaxLoadRecordCount, DateTime.Now));
- SetDatesAndRefresh(true);
- }
- /// <summary>
- /// 设置分时图当前点的数量
- /// </summary>
- /// <returns>当前数量</returns>
- private int SetCountPoint()
- {
- if (CurrentGoods == null || CurrentGoods.OpenCloseTimes == null) return 0;
- var timeSpan = TimeSpan.Zero;
- foreach (var openCloseTime in CurrentGoods.OpenCloseTimes)
- {
- timeSpan += openCloseTime.CloseTime - openCloseTime.OpenTime;
- }
- var count = (int)timeSpan.TotalMinutes + CurrentGoods.OpenCloseTimes.Count; //加上每段时间需加1
- _timeSharingMaxPointCount = count;
- return count;
- }
- /// <summary>
- /// 打开分时图
- /// </summary>
- /// <param name="goodsInfo">分时图商品</param>
- public void OpenTimeSharePlot(GoodsInfo goodsInfo)
- {
- var pane = new ChartPane(this, true);
- //取最大grid高度做*
- var stars = _chartPanesGrid.RowDefinitions.Count > 0
- ? _chartPanesGrid.RowDefinitions.Max(z => z.Height.Value)
- : 1.0;
- AddChartPane(pane, stars);
- SetCountPoint();
- var getEndDatatime = DateTime.Now;
- var startDateTime = DateTime.Now.Date;
- if (CurrentGoods.OpenCloseTimes != null &&
- CurrentGoods.OpenCloseTimes.Any()) //取当前开收市时间
- {
- getEndDatatime = CurrentGoods.OpenCloseTimes[CurrentGoods.OpenCloseTimes.Count - 1].CloseTime;
- startDateTime = CurrentGoods.OpenCloseTimes[0].OpenTime;
- }
- DataSet.DataPoints = OnLoadHistoryTimeSpaningCycleData(CurrentGoods, _timeSharingMaxPointCount, startDateTime,
- getEndDatatime);
- // GetComparisonDataSet(_timeSharingMaxPointCount, startDateTime, getEndDatatime);
- //OnLoadHistoryTimeSpaningCycleData(CurrentGoods, _timeSharingMaxPointCount, startDateTime, getEndDatatime);
- var scaleLayer = new ScaleLayer();
- var displayFormula = new DisplayFormula(DataSet, this, goodsInfo)
- {
- OpenTime = startDateTime,
- CloseTime = getEndDatatime,
- };
- timeSharingFormulaModel = displayFormula;
- scaleLayer.AllDisplayFormula.Add(displayFormula);
- displayFormula.ScaleLayer = scaleLayer;
- displayFormula.IsTimeShare = true;
- pane.AddScaleLayer(scaleLayer);
- var plots = new List<PlotBase>();
- foreach (var indicator in displayFormula.FormulaModel.IndicatorList)
- {
- if (!indicator.VolBar) //是否为成交量
- {
- var linePlot = new LinePlot(indicator, this) { ScaleLayer = scaleLayer };
- scaleLayer.AllPlots.Add(linePlot);
- plots.Add(linePlot);
- }
- else
- {
- //成交量显示在下方
- //var volScaleLayer = new ScaleLayer();
- //var volpane = new ChartPane(this);
- ////取最大grid高度做*
- //var start = _chartPanesGrid.RowDefinitions.Count > 0
- // ? _chartPanesGrid.RowDefinitions.Max(z => z.Height.Value)
- // : 1.0;
- //AddChartPane(volpane, start);
- //volpane.AddScaleLayer(volScaleLayer);
- //var linePlot = new LinePlot(indicator, this);
- //volScaleLayer.AllPlots.Add(linePlot);
- //linePlot.ScaleLayer = volScaleLayer;
- //plots.Add(linePlot);
- }
- }
- //添加叠加分时图
- GetComparisonDataSet(_timeSharingMaxPointCount, startDateTime, getEndDatatime, scaleLayer);
- displayFormula.PlotBases = plots;
- // DrawingTimeShareChart();
- }
- /// <summary>
- /// 显示即时图
- /// </summary>
- /// <param name="goodsInfo">商品</param>
- public void CreateTikChart(GoodsInfo goodsInfo)
- {
- var pane = new ChartPane(this);
- //取最大grid高度做*
- var stars = _chartPanesGrid.RowDefinitions.Count > 0
- ? _chartPanesGrid.RowDefinitions.Max(z => z.Height.Value)
- : 1.0;
- AddChartPane(pane, stars);
- var getEndDatatime = DateTime.Now;
- var startDateTime = DateTime.Now.Date;
- if (CurrentGoods.OpenCloseTimes != null &&
- CurrentGoods.OpenCloseTimes.Any()) //取当前开收市时间
- {
- getEndDatatime = CurrentGoods.OpenCloseTimes[CurrentGoods.OpenCloseTimes.Count - 1].CloseTime;
- startDateTime = CurrentGoods.OpenCloseTimes[0].OpenTime;
- }
- DataSet.DataPoints = OnLoadHistoryTimeSpaningCycleData(CurrentGoods, _timeSharingMaxPointCount, startDateTime,
- getEndDatatime);
- var scaleLayer = new ScaleLayer();
- var formula = DisplayFormula.CreateTikChartFormula(this, goodsInfo, DataSet.DataPoints);
- scaleLayer.AllDisplayFormula.Add(formula);
- formula.ScaleLayer = scaleLayer;
- pane.AddScaleLayer(scaleLayer);
- _tikFormulaModel = formula;
- var plots = new List<PlotBase>();
- foreach (var indicator in formula.FormulaModel.IndicatorList)
- {
- var linePlot = new LinePlot(indicator, this) { ScaleLayer = scaleLayer };
- scaleLayer.AllPlots.Add(linePlot);
- plots.Add(linePlot);
- }
- formula.PlotBases = plots;
- }
- /// <summary>
- /// 获取叠加商品数据
- /// </summary>
- /// <param name="dataCount">取数据量</param>
- /// <param name="startTime">开始时间</param>
- /// <param name="endDateTime">结束时间</param>
- private void GetComparisonDataSet(int dataCount, DateTime startTime, DateTime endDateTime, ScaleLayer comparisonLayer)
- {
- ComparisionTimeShareDic.Clear();
- _comparisonFommulaHsSet.Clear();
- if (_comparisonGoodsList == null) return;
- foreach (var goodseItem in _comparisonGoodsList)
- {
- var lineDataList = OnLoadHistoryTimeSpaningCycleData(goodseItem, dataCount, startTime,
- endDateTime);
- ComparisionTimeShareDic[goodseItem.GoodsCode] = lineDataList;
- }
- var formulas = DisplayFormula.TimeSharingFormulas(_comparisonGoodsList, this, ComparisionTimeShareDic);
- foreach (var displayFormula in formulas)
- {
- CreateComparisonPlot(displayFormula, comparisonLayer);
- }
- }
- /// <summary>
- ///创建图形,添加到层中
- /// </summary>
- /// <param name="displayFormula">公式模型</param>
- /// <param name="comparisonLayer">公式层</param>
- private void CreateComparisonPlot(DisplayFormula displayFormula, ScaleLayer comparisonLayer)
- {
- displayFormula.PlotBases = new List<PlotBase>();
- _comparisonFommulaHsSet[displayFormula.ComparionGoodsInfo.GoodsCode] = displayFormula;
- comparisonLayer.ComparisonFormulas.Add(displayFormula);
- foreach (var indicator in displayFormula.FormulaModel.IndicatorList)
- {
- var linePlot = new ComparisonPlot(indicator, this, displayFormula.ComparionGoodsInfo) { ScaleLayer = comparisonLayer };
- linePlot.IsActive = true;
- comparisonLayer.AllPlots.Add(linePlot);
- displayFormula.PlotBases.Add(linePlot);
- }
- }
- #endregion
- #region 指标
- /// <summary>
- /// 设置当前公式参数
- /// </summary>
- public void SetCurrectFormulaParam()
- {
- if (this._chartPanes != null && _chartPanes.Any())
- {
- var scaleLayers = new List<ScaleLayer>();
- var displayFormulas = new List<DisplayFormula>();
- foreach (var chartPane in _chartPanes)
- {
- if (chartPane.AllScaleLayers != null
- && chartPane.AllScaleLayers.Any())
- {
- scaleLayers.AddRange(chartPane.AllScaleLayers);
- }
- }
- foreach (var scaleLayer in scaleLayers)
- {
- if (scaleLayer.AllDisplayFormula != null && scaleLayer.AllDisplayFormula.Any())
- {
- displayFormulas.AddRange(scaleLayer.AllDisplayFormula);
- }
- }
- if (displayFormulas.Any())
- {
- var formulaModels = displayFormulas.Select((displayFormula) => displayFormula.FormulaModel).ToList();
- var programModels = formulaModels.Select((formulaModel) => formulaModel.EditProgram).ToList();
- programModels = programModels.Where((model) => model != null).ToList();
- var paramsSetPage = new ParamsSetPage(programModels);
- var program = paramsSetPage.ShowDialog();
- if (program.HasValue && program.Value == true) //更新图表
- {
- foreach (var displayFormula in displayFormulas) //设置公式参数
- {
- displayFormula.FormulaModel.SetParamValue();
- displayFormula.Calculation();
- }
- this.Refresh(true);
- }
- }
- }
- }
- /// <summary>
- /// 打开公式编辑器
- /// </summary>
- public void OpenFormulEditer()
- {
- if (this._chartPanes != null && _chartPanes.Any())
- {
- var scaleLayers = new List<ScaleLayer>();
- var displayFormulas = new List<DisplayFormula>();
- foreach (var chartPane in _chartPanes)
- {
- if (chartPane.AllScaleLayers != null
- && chartPane.AllScaleLayers.Any())
- {
- scaleLayers.AddRange(chartPane.AllScaleLayers);
- }
- }
- foreach (var scaleLayer in scaleLayers)
- {
- if (scaleLayer.AllDisplayFormula != null && scaleLayer.AllDisplayFormula.Any())
- {
- displayFormulas.AddRange(scaleLayer.AllDisplayFormula);
- }
- }
- if (displayFormulas.Any())
- {
- var formulaModels = displayFormulas.Select((displayFormula) => displayFormula.FormulaModel).ToList();
- var programModels = formulaModels.Select((formulaModel) => formulaModel.EditProgram).ToList();
- programModels = programModels.Where((model) => model != null).ToList();
- var vm = new EditFormulaViewModel(programModels);
- vm.OpenEditer();
- foreach (var displayFormula in displayFormulas) //设置公式参数
- {
- displayFormula.FormulaModel.SetParamValue();
- displayFormula.Calculation();
- }
- this.Refresh(true);
- }
- }
- }
- /// <summary>
- /// 清除主图中指标
- /// </summary>
- public void ClearMainPaneIndicator()
- {
- var pane = GetMainChartPane();
- if (pane != null)
- {
- foreach (var scaleLayer in pane.AllScaleLayers)
- {
- scaleLayer.ClearFormulas();
- }
- this.Refresh();
- }
- }
- /// <summary>
- /// 通过名称添加指标
- /// </summary>
- /// <param name="formulaName">指标名称</param>
- /// <param name="refresh">是否立刻刷新图表</param>
- public void AddIndicatorByName(string formulaName, bool refresh = true)
- {
- var formula = FormulaHelper.GetFormulaByName(formulaName, string.Empty);
- if (formula != null)
- {
- var displayFormula = new DisplayFormula(formula, DataSet, this);
- AddFormulaFromPane(displayFormula);
- displayFormula.SetSource(DataSet, false);
- if (refresh)
- {
- Refresh(true);
- }
- }
- }
- /// <summary>
- /// 添加指标
- /// </summary>
- /// <param name="Program">指标配置</param>
- public void AddIndicator(ProgramModel program)
- {
- var formulaModel = program.CovertToFormulaModel();
- var displayFormula = new DisplayFormula(formulaModel, DataSet, this);
- AddFormulaFromPane(displayFormula);
- displayFormula.SetSource(DataSet, false);
- Refresh(true);
- }
- #endregion
- #endregion Methods
- }
- }
|