123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305 |
- // Licensed to the .NET Foundation under one or more agreements.
- // The .NET Foundation licenses this file to you under the MIT license.
- // See the LICENSE file in the project root for more information.
- //
- // Purpose: Base class for all anotation objects. Provides
- // basic set of properties and methods.
- //
- using System;
- using System.Windows.Forms;
- using System.Collections;
- using System.ComponentModel;
- using System.Diagnostics;
- using System.Diagnostics.CodeAnalysis;
- using System.Drawing;
- using System.Drawing.Design;
- using System.Drawing.Drawing2D;
- using System.Globalization;
- using FastReport.DataVisualization.Charting.Utilities;
- namespace FastReport.DataVisualization.Charting
- {
- #region Enumerations
- /// <summary>
- /// Annotation object selection points style.
- /// </summary>
- /// <remarks>
- /// Enumeration is for internal use only and should not be part of the documentation.
- /// </remarks>
- internal enum SelectionPointsStyle
- {
- /// <summary>
- /// Selection points are displayed top left and bottom right corners
- /// </summary>
- TwoPoints,
- /// <summary>
- /// Selection points are displayed on all sides and corners of the rectangle.
- /// </summary>
- Rectangle,
- }
- /// <summary>
- /// Annotation object resizing\moving mode.
- /// </summary>
- /// <remarks>
- /// Enumeration is for internal use only and should not be part of the documentation.
- /// </remarks>
- internal enum ResizingMode
- {
- /// <summary>
- /// Top Left selection handle is used.
- /// </summary>
- TopLeftHandle = 0,
- /// <summary>
- /// Top selection handle is used.
- /// </summary>
- TopHandle = 1,
- /// <summary>
- /// Top Right selection handle is used.
- /// </summary>
- TopRightHandle = 2,
- /// <summary>
- /// Right selection handle is used.
- /// </summary>
- RightHandle = 3,
- /// <summary>
- /// Bottom Right selection handle is used.
- /// </summary>
- BottomRightHandle = 4,
- /// <summary>
- /// Bottom selection handle is used.
- /// </summary>
- BottomHandle = 5,
- /// <summary>
- /// Bottom Left selection handle is used.
- /// </summary>
- BottomLeftHandle = 6,
- /// <summary>
- /// Left selection handle is used.
- /// </summary>
- LeftHandle = 7,
- /// <summary>
- /// Anchor selection handle is used.
- /// </summary>
- AnchorHandle = 8,
- /// <summary>
- /// No selection handles used - moving mode.
- /// </summary>
- Moving = 16,
- /// <summary>
- /// Moving points of the annotation path.
- /// </summary>
- MovingPathPoints = 32,
- /// <summary>
- /// No moving or resizing.
- /// </summary>
- None = 64,
- }
- #endregion
- /// <summary>
- /// <b>Annotation</b> is an abstract class that defines properties and methods
- /// common to all annotations.
- /// </summary>
- /// <remarks>
- /// All annotations are derived from the <b>Annotation</b> class, which can be
- /// used to set properties common to all annotation objects (e.g. color, position,
- /// anchoring and others).
- /// </remarks>
- [
- SRDescription("DescriptionAttributeAnnotation_Annotation"),
- DefaultProperty("Name"),
- ]
- public abstract class Annotation : ChartNamedElement
- {
- #region Fields
- // Name of the chart area the annotation is clipped to
- private string _clipToChartArea = Constants.NotSetValue;
- // Indicates that annotation is selected
- private bool _isSelected = false;
- // Indicates that annotation size is defined in relative chart coordinates
- private bool _isSizeAlwaysRelative = true;
- // Position attribute fields
- private double _x = double.NaN;
- private double _y = double.NaN;
- private double _width = double.NaN;
- private double _height = double.NaN;
- // Annotation axes attaching fields
- private string _axisXName = String.Empty;
- private string _axisYName = String.Empty;
- private Axis _axisX = null;
- private Axis _axisY = null;
- // Visual attribute fields
- private bool _visible = true;
- private ContentAlignment _alignment = ContentAlignment.MiddleCenter;
- private Color _foreColor = Color.Black;
- private FontCache _fontCache = new FontCache();
- private Font _textFont;
- private TextStyle _textStyle = TextStyle.Default;
- internal Color lineColor = Color.Black;
- private int _lineWidth = 1;
- private ChartDashStyle _lineDashStyle = ChartDashStyle.Solid;
- private Color _backColor = Color.Empty;
- private ChartHatchStyle _backHatchStyle = ChartHatchStyle.None;
- private GradientStyle _backGradientStyle = GradientStyle.None;
- private Color _backSecondaryColor = Color.Empty;
- private Color _shadowColor = Color.FromArgb(128, 0, 0, 0);
- private int _shadowOffset = 0;
- // Anchor position attribute fields
- private string _anchorDataPointName = String.Empty;
- private DataPoint _anchorDataPoint = null;
- private DataPoint _anchorDataPoint2 = null;
- private double _anchorX = double.NaN;
- private double _anchorY = double.NaN;
- internal double anchorOffsetX = 0.0;
- internal double anchorOffsetY = 0.0;
- internal ContentAlignment anchorAlignment = ContentAlignment.BottomCenter;
- // Selection handles position (starting top-left and moving clockwise)
- internal RectangleF[] selectionRects = null;
- // Annotation tooltip
- private string _tooltip = String.Empty;
- // Selection handles size
- internal const int selectionMarkerSize = 6;
- // Pre calculated relative position of annotation and anchor point
- internal RectangleF currentPositionRel = new RectangleF(float.NaN, float.NaN, float.NaN, float.NaN);
- internal PointF currentAnchorLocationRel = new PointF(float.NaN, float.NaN);
- // Smart labels style
- private AnnotationSmartLabelStyle _smartLabelStyle = null;
- // Index of last selected point in the annotation path
- internal int currentPathPointIndex = -1;
- // Group this annotation belongs too
- internal AnnotationGroup annotationGroup = null;
- // Selection and editing permissions
- private bool _allowSelecting = false;
- private bool _allowMoving = false;
- private bool _allowAnchorMoving = false;
- private bool _allowResizing = false;
- private bool _allowTextEditing = false;
- private bool _allowPathEditing = false;
- // Indicates that annotation position was changed. Flag used to fire events.
- internal bool positionChanged = false;
- // Relative location of last placement position
- internal PointF lastPlacementPosition = PointF.Empty;
- // Relative location of annotation anchor, when it's started to move
- internal PointF startMoveAnchorLocationRel = PointF.Empty;
- // Relative position of annotation, when it's started to move/resize
- internal RectangleF startMovePositionRel = RectangleF.Empty;
- // Relative position of annotation, when it's started to move/resize
- internal GraphicsPath startMovePathRel = null;
- /// <summary>
- /// Limit of annotation width and height.
- /// </summary>
- internal static double WidthHightLimit = 290000000;
- #endregion
- #region Constructors
- /// <summary>
- /// Initializes a new instance of the <see cref="Annotation"/> class.
- /// </summary>
- protected Annotation()
- {
- _textFont = _fontCache.DefaultFont;
- }
- #endregion
- #region Properties
- #region Miscellaneous
- /// <summary>
- /// Gets or sets an annotation's unique name.
- /// </summary>
- /// <value>
- /// A <b>string</b> that represents an annotation's unique name.
- /// </value>
- [
- SRCategory("CategoryAttributeMisc"),
- Bindable(true),
- SRDescription("DescriptionAttributeName4"),
- ParenthesizePropertyNameAttribute(true),
- ]
- public override string Name
- {
- get
- {
- return base.Name;
- }
- set
- {
- base.Name = value;
- CallOnModifing();
- }
- }
- /// <summary>
- /// Gets or sets an annotation's type name.
- /// </summary>
- /// <remarks>
- /// This property is used to get the name of each annotation Style
- /// (e.g. Line, Rectangle, Ellipse).
- /// <para>
- /// This property is for internal use and is hidden at design and run time.
- /// </para>
- /// </remarks>
- [
- SRCategory("CategoryAttributeMisc"),
- Bindable(true),
- Browsable(false),
- EditorBrowsableAttribute(EditorBrowsableState.Never),
- DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden),
- SerializationVisibilityAttribute(SerializationVisibility.Hidden),
- SRDescription("DescriptionAttributeAnnotation_AnnotationType"),
- ]
- public abstract string AnnotationType
- {
- get;
- }
- /// <summary>
- /// Gets or sets the name of the chart area which an annotation is clipped to.
- /// </summary>
- /// <value>
- /// A string which represents the name of an existing chart area.
- /// </value>
- /// <remarks>
- /// If the chart area name is specified, an annotation will only be drawn inside the
- /// plotting area of the chart area specified. All parts of the annotation
- /// outside of the plotting area will be clipped.
- /// <para>
- /// To disable chart area clipping, set the property to "NotSet" or an empty string.
- /// </para>
- /// </remarks>
- [
- SRCategory("CategoryAttributeMisc"),
- DefaultValue(Constants.NotSetValue),
- SRDescription("DescriptionAttributeAnnotationClipToChartArea"),
- TypeConverter(typeof(LegendAreaNameConverter))
- ]
- virtual public string ClipToChartArea
- {
- get
- {
- return _clipToChartArea;
- }
- set
- {
- if (value != _clipToChartArea)
- {
- if (String.IsNullOrEmpty(value))
- {
- _clipToChartArea = Constants.NotSetValue;
- }
- else
- {
- if (Chart != null && Chart.ChartAreas != null)
- {
- Chart.ChartAreas.VerifyNameReference(value);
- }
- _clipToChartArea = value;
- }
- this.Invalidate();
- CallOnModifing();
- }
- }
- }
- /// <summary>
- /// Gets or sets the smart labels style of an annotation.
- /// </summary>
- /// <value>
- /// An <see cref="AnnotationSmartLabelStyle"/> object that represents an annotation's
- /// smart labels style properties.
- /// </value>
- /// <remarks>
- /// Smart labels are used to prevent an annotation from overlapping data point labels
- /// and other annotations.
- /// <para>
- /// Note that data point labels must also have smart labels enabled.
- /// </para>
- /// </remarks>
- [
- Browsable(true),
- SRCategory("CategoryAttributeMisc"),
- Bindable(true),
- SRDescription("DescriptionAttributeSmartLabels"),
- DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
- ]
- public AnnotationSmartLabelStyle SmartLabelStyle
- {
- get
- {
- if (this._smartLabelStyle == null)
- {
- this._smartLabelStyle = new AnnotationSmartLabelStyle(this);
- }
- return _smartLabelStyle;
- }
- set
- {
- value.chartElement = this;
- _smartLabelStyle = value;
- this.Invalidate();
- CallOnModifing();
- }
- }
- /// <summary>
- /// Gets the group, if any, the annotation belongs to.
- /// </summary>
- [
- Browsable(false),
- DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden),
- SerializationVisibilityAttribute(SerializationVisibility.Hidden),
- ]
- public AnnotationGroup AnnotationGroup
- {
- get { return this.annotationGroup; }
- }
- #endregion
- #region Position
- /// <summary>
- /// Gets or sets a flag that specifies whether the size of an annotation is always
- /// defined in relative chart coordinates.
- /// <seealso cref="Width"/>
- /// <seealso cref="Height"/>
- /// </summary>
- /// <value>
- /// <b>True</b> if an annotation's <see cref="Width"/> and <see cref="Height"/> are always
- /// in chart relative coordinates, <b>false</b> otherwise.
- /// </value>
- /// <remarks>
- /// An annotation's width and height may be set in relative chart or axes coordinates.
- /// By default, relative chart coordinates are used.
- /// <para>
- /// To use axes coordinates for size set the <b>IsSizeAlwaysRelative</b> property to
- /// <b>false</b> and either anchor the annotation to a data point or set the
- /// <see cref="AxisX"/> or <see cref="AxisY"/> properties.
- /// </para>
- /// </remarks>
- [
- SRCategory("CategoryAttributePosition"),
- DefaultValue(true),
- SRDescription("DescriptionAttributeSizeAlwaysRelative"),
- ]
- virtual public bool IsSizeAlwaysRelative
- {
- get
- {
- return _isSizeAlwaysRelative;
- }
- set
- {
- _isSizeAlwaysRelative = value;
- this.ResetCurrentRelativePosition();
- Invalidate();
- CallOnModifing();
- }
- }
- /// <summary>
- /// Gets or sets the X coordinate of an annotation.
- /// <seealso cref="AnchorDataPoint"/>
- /// <seealso cref="AnchorX"/>
- /// </summary>
- /// <value>
- /// A Double value that represents the X coordinate of an annotation.
- /// </value>
- /// <remarks>
- /// The X coordinate of an annotation is in relative chart coordinates or axes coordinates. Chart
- /// relative coordinates are used by default.
- /// <para>
- /// To use axes coordinates, anchor
- /// an annotation to a data point using the <see cref="AnchorDataPoint"/> property, or
- /// set the annotation axes using the <see cref="AxisX"/> or <see cref="AxisY"/> properties.
- /// </para>
- /// <para>
- /// Set the X position to Double.NaN ("NotSet") to achieve automatic position calculation
- /// when the annotation is anchored using the <see cref="AnchorDataPoint"/> property or
- /// the <see cref="AnchorX"/> and <see cref="AnchorY"/> properties.
- /// </para>
- /// </remarks>
- [
- SRCategory("CategoryAttributePosition"),
- DefaultValue(double.NaN),
- SRDescription("DescriptionAttributeAnnotationBaseX"),
- RefreshPropertiesAttribute(RefreshProperties.All),
- TypeConverter(typeof(DoubleNanValueConverter)),
- ]
- [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "X")]
- virtual public double X
- {
- get
- {
- return _x;
- }
- set
- {
- _x = value;
- this.ResetCurrentRelativePosition();
- Invalidate();
- CallOnModifing();
- }
- }
- /// <summary>
- /// Gets or sets the Y coordinate of an annotation.
- /// <seealso cref="AnchorDataPoint"/>
- /// <seealso cref="AnchorY"/>
- /// </summary>
- /// <value>
- /// A Double value that represents the Y coordinate of an annotation.
- /// </value>
- /// <remarks>
- /// The Y coordinate of an annotation is in relative chart coordinates or axes coordinates. Chart
- /// relative coordinates are used by default.
- /// <para>
- /// To use axes coordinates, anchor
- /// an annotation to a data point using the <see cref="AnchorDataPoint"/> property, or
- /// set the annotation axes using the <see cref="AxisX"/> or <see cref="AxisY"/> properties.
- /// </para>
- /// <para>
- /// Set the Y position to Double.NaN ("NotSet") to achieve automatic position calculation
- /// when the annotation is anchored using the <see cref="AnchorDataPoint"/> property or
- /// the <see cref="AnchorX"/> and <see cref="AnchorY"/> properties.
- /// </para>
- /// </remarks>
- [
- SRCategory("CategoryAttributePosition"),
- DefaultValue(double.NaN),
- SRDescription("DescriptionAttributeAnnotationBaseY"),
- RefreshPropertiesAttribute(RefreshProperties.All),
- TypeConverter(typeof(DoubleNanValueConverter)),
- ]
- [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Y")]
- virtual public double Y
- {
- get
- {
- return _y;
- }
- set
- {
- _y = value;
- this.ResetCurrentRelativePosition();
- Invalidate();
- CallOnModifing();
- }
- }
- /// <summary>
- /// Gets or sets an annotation's width.
- /// <seealso cref="IsSizeAlwaysRelative"/>
- /// <seealso cref="AxisX"/>
- /// </summary>
- /// <value>
- /// A Double value that represents an annotation's width.
- /// </value>
- /// <remarks>
- /// An annotation's width can be a negative value, in which case the annotation orientation
- /// is switched.
- /// <para>
- /// Annotation width can be in relative chart or axes coordinates. Chart
- /// relative coordinates are used by default.
- /// </para>
- /// <para>
- /// To use axes coordinates, anchor
- /// an annotation to a data point using the <see cref="AnchorDataPoint"/> property, or
- /// set the annotation axes using the <see cref="AxisX"/> or <see cref="AxisY"/> properties
- /// and set the <see cref="IsSizeAlwaysRelative"/> property to <b>false</b>.
- /// </para>
- /// <para>
- /// Set the width to Double.NaN ("NotSet") to achieve automatic size calculation for
- /// annotations with text. The size will automatically be calculated based on
- /// the annotation text and font size.
- /// </para>
- /// </remarks>
- [
- SRCategory("CategoryAttributePosition"),
- DefaultValue(double.NaN),
- SRDescription("DescriptionAttributeAnnotationWidth"),
- RefreshPropertiesAttribute(RefreshProperties.All),
- TypeConverter(typeof(DoubleNanValueConverter)),
- ]
- virtual public double Width
- {
- get
- {
- return _width;
- }
- set
- {
- if (value < -WidthHightLimit || value > WidthHightLimit)
- {
- throw new ArgumentException(SR.ExceptionValueMustBeInRange("Width", (-WidthHightLimit).ToString(CultureInfo.CurrentCulture), WidthHightLimit.ToString(CultureInfo.CurrentCulture)));
- }
- _width = value;
- this.ResetCurrentRelativePosition();
- Invalidate();
- CallOnModifing();
- }
- }
- /// <summary>
- /// Gets or sets an annotation's height.
- /// <seealso cref="IsSizeAlwaysRelative"/>
- /// <seealso cref="AxisY"/>
- /// </summary>
- /// <value>
- /// A Double value that represents an annotation's height.
- /// </value>
- /// <remarks>
- /// An annotation's height can be a negative value, in which case the annotation orientation
- /// is switched.
- /// <para>
- /// Annotation height can be in relative chart or axes coordinates. Chart
- /// relative coordinates are used by default.
- /// </para>
- /// <para>
- /// To use axes coordinates, anchor
- /// an annotation to a data point using the <see cref="AnchorDataPoint"/> property, or
- /// set the annotation axes using the <see cref="AxisX"/> or <see cref="AxisY"/> properties
- /// and set the <see cref="IsSizeAlwaysRelative"/> property to <b>false</b>.
- /// </para>
- /// <para>
- /// Set the height to Double.NaN ("NotSet") to achieve automatic size calculation for
- /// annotations with text. The size will automatically be calculated based on
- /// the annotation text and font size.
- /// </para>
- /// </remarks>
- [
- SRCategory("CategoryAttributePosition"),
- DefaultValue(double.NaN),
- SRDescription("DescriptionAttributeAnnotationHeight"),
- RefreshPropertiesAttribute(RefreshProperties.All),
- TypeConverter(typeof(DoubleNanValueConverter)),
- ]
- virtual public double Height
- {
- get
- {
- return _height;
- }
- set
- {
- if (value < -WidthHightLimit || value > WidthHightLimit)
- {
- throw new ArgumentException(SR.ExceptionValueMustBeInRange("Height", (-WidthHightLimit).ToString(CultureInfo.CurrentCulture), WidthHightLimit.ToString(CultureInfo.CurrentCulture)));
- }
- _height = value;
- this.ResetCurrentRelativePosition();
- Invalidate();
- CallOnModifing();
- }
- }
- /// <summary>
- /// Gets or sets an annotation position's right boundary.
- /// <seealso cref="IsSizeAlwaysRelative"/>
- /// <seealso cref="AxisX"/>
- /// </summary>
- /// <value>
- /// A Double value that represents the position of an annotation's right boundary.
- /// </value>
- /// <remarks>
- /// To use axes coordinates, anchor
- /// an annotation to a data point using the <see cref="AnchorDataPoint"/> property, or
- /// set the annotation axes using the <see cref="AxisX"/> or <see cref="AxisY"/> properties
- /// and set the <see cref="IsSizeAlwaysRelative"/> property to <b>false</b>.
- /// </remarks>
- [
- SRCategory("CategoryAttributePosition"),
- DefaultValue(double.NaN),
- SRDescription("DescriptionAttributeRight3"),
- RefreshPropertiesAttribute(RefreshProperties.All),
- Browsable(false),
- DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden),
- SerializationVisibilityAttribute(SerializationVisibility.Hidden),
- TypeConverter(typeof(DoubleNanValueConverter)),
- ]
- virtual public double Right
- {
- get
- {
- return _x + _width;
- }
- set
- {
- _width = value - _x;
- this.ResetCurrentRelativePosition();
- Invalidate();
- }
- }
- /// <summary>
- /// Gets or sets an annotation position's bottom boundary.
- /// <seealso cref="IsSizeAlwaysRelative"/>
- /// <seealso cref="AxisX"/>
- /// </summary>
- /// <value>
- /// A Double value that represents the position of an annotation's bottom boundary.
- /// </value>
- /// <remarks>
- /// To use axes coordinates, anchor
- /// an annotation to a data point using the <see cref="AnchorDataPoint"/> property, or
- /// set the annotation axes using the <see cref="AxisX"/> or <see cref="AxisY"/> properties
- /// and set the <see cref="IsSizeAlwaysRelative"/> property to <b>false</b>.
- /// </remarks>
- [
- SRCategory("CategoryAttributePosition"),
- DefaultValue(double.NaN),
- SRDescription("DescriptionAttributeBottom"),
- RefreshPropertiesAttribute(RefreshProperties.All),
- Browsable(false),
- DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden),
- SerializationVisibilityAttribute(SerializationVisibility.Hidden),
- TypeConverter(typeof(DoubleNanValueConverter)),
- ]
- virtual public double Bottom
- {
- get
- {
- return _y + _height;
- }
- set
- {
- _height = value - _y;
- this.ResetCurrentRelativePosition();
- Invalidate();
- }
- }
- #endregion
- #region Visual Attributes
- /// <summary>
- /// Gets or sets a flag that determines if an annotation is selected.
- /// <seealso cref="AllowSelecting"/>
- /// </summary>
- /// <value>
- /// <b>True</b> if the annotation is selected, <b>false</b> otherwise.
- /// </value>
- [
- SRCategory("CategoryAttributeAppearance"),
- DefaultValue(false),
- Browsable(false),
- SRDescription("DescriptionAttributeSelected"),
- ]
- virtual public bool IsSelected
- {
- get
- {
- return _isSelected;
- }
- set
- {
- _isSelected = value;
- Invalidate();
- }
- }
- /// <summary>
- /// Gets or sets an annotation selection points style.
- /// </summary>
- /// <value>
- /// A <see cref="SelectionPointsStyle"/> value that represents annotation
- /// selection style.
- /// </value>
- /// <remarks>
- /// This property is for internal use and is hidden at design and run time.
- /// </remarks>
- [
- SRCategory("CategoryAttributeAppearance"),
- DefaultValue(SelectionPointsStyle.Rectangle),
- ParenthesizePropertyNameAttribute(true),
- Browsable(false),
- EditorBrowsableAttribute(EditorBrowsableState.Never),
- DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden),
- SerializationVisibilityAttribute(SerializationVisibility.Hidden),
- SRDescription("DescriptionAttributeSelectionPointsStyle"),
- ]
- virtual internal SelectionPointsStyle SelectionPointsStyle
- {
- get
- {
- return SelectionPointsStyle.Rectangle;
- }
- }
- /// <summary>
- /// Gets or sets a flag that specifies whether an annotation is visible.
- /// </summary>
- /// <value>
- /// <b>True</b> if the annotation is visible, <b>false</b> otherwise.
- /// </value>
- [
- SRCategory("CategoryAttributeAppearance"),
- DefaultValue(true),
- SRDescription("DescriptionAttributeVisible"),
- ParenthesizePropertyNameAttribute(true),
- ]
- virtual public bool Visible
- {
- get
- {
- return _visible;
- }
- set
- {
- _visible = value;
- Invalidate();
- CallOnModifing();
- }
- }
- /// <summary>
- /// Gets or sets an annotation's content alignment.
- /// </summary>
- /// <value>
- /// A <see cref="ContentAlignment"/> value that represents the content alignment.
- /// </value>
- /// <remarks>
- /// This property is used to align text for <see cref="TextAnnotation"/>, <see cref="RectangleAnnotation"/>,
- /// <see cref="EllipseAnnotation"/> and <see cref="CalloutAnnotation"/> objects, and to align
- /// a non-scaled image inside an <see cref="ImageAnnotation"/> object.
- /// </remarks>
- [
- SRCategory("CategoryAttributeAppearance"),
- DefaultValue(typeof(ContentAlignment), "MiddleCenter"),
- SRDescription("DescriptionAttributeAlignment"),
- ]
- virtual public ContentAlignment Alignment
- {
- get
- {
- return _alignment;
- }
- set
- {
- _alignment = value;
- Invalidate();
- CallOnModifing();
- }
- }
- /// <summary>
- /// Gets or sets the text color of an annotation.
- /// <seealso cref="Font"/>
- /// </summary>
- /// <value>
- /// A <see cref="Color"/> value used for the text color of an annotation.
- /// </value>
- [
- SRCategory("CategoryAttributeAppearance"),
- DefaultValue(typeof(Color), "Black"),
- SRDescription("DescriptionAttributeForeColor"),
- TypeConverter(typeof(ColorConverter)),
- #if DESIGNER
- Editor(typeof(ChartColorEditor), typeof(UITypeEditor))
- #endif
- ]
- virtual public Color ForeColor
- {
- get
- {
- return _foreColor;
- }
- set
- {
- _foreColor = value;
- Invalidate();
- CallOnModifing();
- }
- }
- /// <summary>
- /// Gets or sets the font of an annotation's text.
- /// <seealso cref="ForeColor"/>
- /// </summary>
- /// <value>
- /// A <see cref="Font"/> object used for an annotation's text.
- /// </value>
- [
- SRCategory("CategoryAttributeAppearance"),
- DefaultValue(typeof(Font), "Microsoft Sans Serif, 8pt"),
- SRDescription("DescriptionAttributeTextFont"),
- ]
- virtual public Font Font
- {
- get
- {
- return _textFont;
- }
- set
- {
- _textFont = value;
- this.Invalidate();
- CallOnModifing();
- }
- }
- /// <summary>
- /// Gets or sets an annotation's text style.
- /// <seealso cref="Font"/>
- /// <seealso cref="ForeColor"/>
- /// </summary>
- /// <value>
- /// A <see cref="TextStyle"/> value used to draw an annotation's text.
- /// </value>
- [
- SRCategory("CategoryAttributeAppearance"),
- DefaultValue(typeof(TextStyle), "Default"),
- SRDescription("DescriptionAttributeTextStyle"),
- ]
- virtual public TextStyle TextStyle
- {
- get
- {
- return _textStyle;
- }
- set
- {
- _textStyle = value;
- Invalidate();
- CallOnModifing();
- }
- }
- /// <summary>
- /// Gets or sets the color of an annotation line.
- /// <seealso cref="LineWidth"/>
- /// <seealso cref="LineDashStyle"/>
- /// </summary>
- /// <value>
- /// A <see cref="Color"/> value used to draw an annotation line.
- /// </value>
- [
- SRCategory("CategoryAttributeAppearance"),
- DefaultValue(typeof(Color), "Black"),
- SRDescription("DescriptionAttributeLineColor"),
- TypeConverter(typeof(ColorConverter)),
- #if DESIGNER
- Editor(typeof(ChartColorEditor), typeof(UITypeEditor))
- #endif
- ]
- virtual public Color LineColor
- {
- get
- {
- return lineColor;
- }
- set
- {
- lineColor = value;
- Invalidate();
- CallOnModifing();
- }
- }
- /// <summary>
- /// Gets or sets the width of an annotation line.
- /// <seealso cref="LineColor"/>
- /// <seealso cref="LineDashStyle"/>
- /// </summary>
- /// <value>
- /// An integer value defining the width of an annotation line in pixels.
- /// </value>
- [
- SRCategory("CategoryAttributeAppearance"),
- DefaultValue(1),
- SRDescription("DescriptionAttributeLineWidth"),
- ]
- virtual public int LineWidth
- {
- get
- {
- return _lineWidth;
- }
- set
- {
- if (value < 0)
- {
- throw (new ArgumentOutOfRangeException("value", SR.ExceptionAnnotationLineWidthIsNegative));
- }
- _lineWidth = value;
- Invalidate();
- CallOnModifing();
- }
- }
- /// <summary>
- /// Gets or sets the style of an annotation line.
- /// <seealso cref="LineWidth"/>
- /// <seealso cref="LineColor"/>
- /// </summary>
- /// <value>
- /// A <see cref="ChartDashStyle"/> value used to draw an annotation line.
- /// </value>
- [
- SRCategory("CategoryAttributeAppearance"),
- DefaultValue(ChartDashStyle.Solid),
- SRDescription("DescriptionAttributeLineDashStyle"),
- ]
- virtual public ChartDashStyle LineDashStyle
- {
- get
- {
- return _lineDashStyle;
- }
- set
- {
- _lineDashStyle = value;
- Invalidate();
- CallOnModifing();
- }
- }
- /// <summary>
- /// Gets or sets the background color of an annotation.
- /// <seealso cref="BackSecondaryColor"/>
- /// <seealso cref="BackHatchStyle"/>
- /// <seealso cref="BackGradientStyle"/>
- /// </summary>
- /// <value>
- /// A <see cref="Color"/> value used for the background of an annotation.
- /// </value>
- [
- SRCategory("CategoryAttributeAppearance"),
- DefaultValue(typeof(Color), ""),
- SRDescription("DescriptionAttributeBackColor"),
- NotifyParentPropertyAttribute(true),
- TypeConverter(typeof(ColorConverter)),
- #if DESIGNER
- Editor(typeof(ChartColorEditor), typeof(UITypeEditor))
- #endif
- ]
- virtual public Color BackColor
- {
- get
- {
- return _backColor;
- }
- set
- {
- _backColor = value;
- Invalidate();
- CallOnModifing();
- }
- }
- /// <summary>
- /// Gets or sets the background hatch style of an annotation.
- /// <seealso cref="BackSecondaryColor"/>
- /// <seealso cref="BackColor"/>
- /// <seealso cref="BackGradientStyle"/>
- /// </summary>
- /// <value>
- /// A <see cref="ChartHatchStyle"/> value used for the background of an annotation.
- /// </value>
- /// <remarks>
- /// Two colors are used to draw the hatching, <see cref="BackColor"/> and <see cref="BackSecondaryColor"/>.
- /// </remarks>
- [
- SRCategory("CategoryAttributeAppearance"),
- DefaultValue(ChartHatchStyle.None),
- NotifyParentPropertyAttribute(true),
- SRDescription("DescriptionAttributeBackHatchStyle"),
- #if DESIGNER
- Editor(typeof(HatchStyleEditor), typeof(UITypeEditor))
- #endif
- ]
- virtual public ChartHatchStyle BackHatchStyle
- {
- get
- {
- return _backHatchStyle;
- }
- set
- {
- _backHatchStyle = value;
- Invalidate();
- CallOnModifing();
- }
- }
- /// <summary>
- /// Gets or sets the background gradient style of an annotation.
- /// <seealso cref="BackSecondaryColor"/>
- /// <seealso cref="BackColor"/>
- /// <seealso cref="BackHatchStyle"/>
- /// </summary>
- /// <value>
- /// A <see cref="GradientStyle"/> value used for the background of an annotation.
- /// </value>
- /// <remarks>
- /// Two colors are used to draw the gradient, <see cref="BackColor"/> and <see cref="BackSecondaryColor"/>.
- /// </remarks>
- [
- SRCategory("CategoryAttributeAppearance"),
- DefaultValue(GradientStyle.None),
- NotifyParentPropertyAttribute(true),
- SRDescription("DescriptionAttributeBackGradientStyle"),
- #if DESIGNER
- Editor(typeof(GradientEditor), typeof(UITypeEditor))
- #endif
- ]
- virtual public GradientStyle BackGradientStyle
- {
- get
- {
- return _backGradientStyle;
- }
- set
- {
- _backGradientStyle = value;
- Invalidate();
- CallOnModifing();
- }
- }
- /// <summary>
- /// Gets or sets the secondary background color of an annotation.
- /// <seealso cref="BackColor"/>
- /// <seealso cref="BackHatchStyle"/>
- /// <seealso cref="BackGradientStyle"/>
- /// </summary>
- /// <value>
- /// A <see cref="Color"/> value used for the secondary color of an annotation background with
- /// hatching or gradient fill.
- /// </value>
- /// <remarks>
- /// This color is used with <see cref="BackColor"/> when <see cref="BackHatchStyle"/> or
- /// <see cref="BackGradientStyle"/> are used.
- /// </remarks>
- [
- SRCategory("CategoryAttributeAppearance"),
- DefaultValue(typeof(Color), ""),
- NotifyParentPropertyAttribute(true),
- SRDescription("DescriptionAttributeBackSecondaryColor"),
- TypeConverter(typeof(ColorConverter)),
- #if DESIGNER
- Editor(typeof(ChartColorEditor), typeof(UITypeEditor))
- #endif
- ]
- virtual public Color BackSecondaryColor
- {
- get
- {
- return _backSecondaryColor;
- }
- set
- {
- _backSecondaryColor = value;
- Invalidate();
- CallOnModifing();
- }
- }
- /// <summary>
- /// Gets or sets the color of an annotation's shadow.
- /// <seealso cref="ShadowOffset"/>
- /// </summary>
- /// <value>
- /// A <see cref="Color"/> value used to draw an annotation's shadow.
- /// </value>
- [
- SRCategory("CategoryAttributeAppearance"),
- DefaultValue(typeof(Color), "128,0,0,0"),
- SRDescription("DescriptionAttributeShadowColor"),
- TypeConverter(typeof(ColorConverter)),
- #if DESIGNER
- Editor(typeof(ChartColorEditor), typeof(UITypeEditor))
- #endif
- ]
- virtual public Color ShadowColor
- {
- get
- {
- return _shadowColor;
- }
- set
- {
- _shadowColor = value;
- Invalidate();
- CallOnModifing();
- }
- }
- /// <summary>
- /// Gets or sets the offset between an annotation and its shadow.
- /// <seealso cref="ShadowColor"/>
- /// </summary>
- /// <value>
- /// An integer value that represents the offset between an annotation and its shadow.
- /// </value>
- [
- SRCategory("CategoryAttributeAppearance"),
- DefaultValue(0),
- SRDescription("DescriptionAttributeShadowOffset"),
- ]
- virtual public int ShadowOffset
- {
- get
- {
- return _shadowOffset;
- }
- set
- {
- _shadowOffset = value;
- Invalidate();
- CallOnModifing();
- }
- }
- #endregion
- #region Axes Attaching
- /// <summary>
- /// Gets or sets the name of the X axis which an annotation is attached to.
- /// </summary>
- /// <value>
- /// A string value that represents the name of the X axis which an annotation
- /// is attached to.
- /// </value>
- /// <remarks>
- /// This property is for internal use and is hidden at design and run time.
- /// </remarks>
- [
- SRCategory("CategoryAttributeAnchorAxes"),
- DefaultValue(""),
- Browsable(false),
- Bindable(false),
- EditorBrowsableAttribute(EditorBrowsableState.Never),
- SRDescription("DescriptionAttributeAxisXName"),
- ]
- virtual public string AxisXName
- {
- get
- {
- if (_axisXName.Length == 0 && _axisX != null)
- {
- _axisXName = GetAxisName(_axisX);
- }
- return _axisXName;
- }
- set
- {
- _axisXName = value;
- _axisX = null;
- this.ResetCurrentRelativePosition();
- Invalidate();
- }
- }
- /// <summary>
- /// Gets or sets the name of the Y axis which an annotation is attached to.
- /// </summary>
- /// <value>
- /// A string value that represents the name of the Y axis which an annotation
- /// is attached to.
- /// </value>
- /// <remarks>
- /// This property is for internal use and is hidden at design and run time.
- /// </remarks>
- [
- SRCategory("CategoryAttributeAnchorAxes"),
- Browsable(false),
- Bindable(false),
- EditorBrowsableAttribute(EditorBrowsableState.Never),
- DefaultValue(""),
- SRDescription("DescriptionAttributeAxisYName"),
- SerializationVisibilityAttribute(SerializationVisibility.Hidden),
- ]
- virtual public string AxisYName
- {
- get
- {
- // Always return empty string to prevent property serialization
- // "YAxisName" property will be used instead.
- return string.Empty;
- }
- set
- {
- this.YAxisName = value;
- }
- }
- /// <summary>
- /// Gets or sets the name of the Y axis which an annotation is attached to.
- /// NOTE: "AxisYName" property was used before but the name was changed to solve the
- /// duplicated hash value during the serialization with the "TitleSeparator" property.
- /// </summary>
- /// <value>
- /// A string value that represents the name of the Y axis which an annotation
- /// is attached to.
- /// </value>
- /// <remarks>
- /// This property is for internal use and is hidden at design and run time.
- /// </remarks>
- [
- SRCategory("CategoryAttributeAnchorAxes"),
- Browsable(false),
- Bindable(false),
- EditorBrowsableAttribute(EditorBrowsableState.Never),
- DefaultValue(""),
- SRDescription("DescriptionAttributeAxisYName"),
- ]
- virtual public string YAxisName
- {
- get
- {
- if (_axisYName.Length == 0 && _axisY != null)
- {
- _axisYName = GetAxisName(_axisY);
- }
- return _axisYName;
- }
- set
- {
- _axisYName = value;
- _axisY = null;
- this.ResetCurrentRelativePosition();
- Invalidate();
- }
- }
- /// <summary>
- /// Gets or sets the X axis which an annotation is attached to.
- /// <seealso cref="AxisY"/>
- /// <seealso cref="IsSizeAlwaysRelative"/>
- /// </summary>
- /// <value>
- /// <see cref="Axis"/> object which an annotation is attached to.
- /// </value>
- /// <remarks>
- /// When an annotation is attached to an axis, its X position is always in
- /// axis coordinates. To define an annotation's size in axis coordinates as well,
- /// make sure the <see cref="IsSizeAlwaysRelative"/> property is set to <b>false</b>.
- /// <para>
- /// Set this value to <b>null</b> or <b>nothing</b> to disable attachment to the axis.
- /// </para>
- /// </remarks>
- [
- SRCategory("CategoryAttributeAnchorAxes"),
- DefaultValue(null),
- DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden),
- SerializationVisibilityAttribute(SerializationVisibility.Hidden),
- SRDescription("DescriptionAttributeAxisX"),
- #if DESIGNER
- Editor(typeof(AnnotationAxisUITypeEditor), typeof(UITypeEditor)),
- #endif
- TypeConverter(typeof(AnnotationAxisValueConverter)),
- ]
- virtual public Axis AxisX
- {
- get
- {
- if (_axisX == null && _axisXName.Length > 0)
- {
- _axisX = GetAxisByName(_axisXName);
- }
- return _axisX;
- }
- set
- {
- _axisX = value;
- _axisXName = String.Empty;
- this.ResetCurrentRelativePosition();
- Invalidate();
- CallOnModifing();
- }
- }
- /// <summary>
- /// Gets or sets the Y axis which an annotation is attached to.
- /// <seealso cref="AxisX"/>
- /// <seealso cref="IsSizeAlwaysRelative"/>
- /// </summary>
- /// <value>
- /// <see cref="Axis"/> object which an annotation is attached to.
- /// </value>
- /// <remarks>
- /// When an annotation is attached to an axis, its Y position is always in
- /// axis coordinates. To define an annotation's size in axis coordinates as well,
- /// make sure <see cref="IsSizeAlwaysRelative"/> property is set to <b>false</b>.
- /// <para>
- /// Set this value to <b>null</b> or <b>nothing</b> to disable annotation attachment to an axis.
- /// </para>
- /// </remarks>
- [
- SRCategory("CategoryAttributeAnchorAxes"),
- DefaultValue(null),
- DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden),
- SerializationVisibilityAttribute(SerializationVisibility.Hidden),
- SRDescription("DescriptionAttributeAxisY"),
- #if DESIGNER
- Editor(typeof(AnnotationAxisUITypeEditor), typeof(UITypeEditor)),
- #endif
- TypeConverter(typeof(AnnotationAxisValueConverter)),
- ]
- virtual public Axis AxisY
- {
- get
- {
- if (_axisY == null && _axisYName.Length > 0)
- {
- _axisY = GetAxisByName(_axisYName);
- }
- return _axisY;
- }
- set
- {
- _axisY = value;
- _axisYName = String.Empty;
- this.ResetCurrentRelativePosition();
- Invalidate();
- CallOnModifing();
- }
- }
- #endregion
- #region Anchor
- /// <summary>
- /// Gets or sets the name of a data point which an annotation is anchored to.
- /// </summary>
- /// <value>
- /// A string value that represents the name of the data point which an
- /// annotation is anchored to.
- /// </value>
- /// <remarks>
- /// This property is for internal use and is hidden at design and run time.
- /// </remarks>
- [
- SRCategory("CategoryAttributeAnchor"),
- Browsable(false),
- Bindable(false),
- EditorBrowsableAttribute(EditorBrowsableState.Never),
- DefaultValue(""),
- SRDescription("DescriptionAttributeAnchorDataPointName"),
- ]
- virtual public string AnchorDataPointName
- {
- get
- {
- if (_anchorDataPointName.Length == 0 && _anchorDataPoint != null)
- {
- _anchorDataPointName = GetDataPointName(_anchorDataPoint);
- }
- return _anchorDataPointName;
- }
- set
- {
- _anchorDataPointName = value;
- _anchorDataPoint = null;
- this.ResetCurrentRelativePosition();
- Invalidate();
- }
- }
- /// <summary>
- /// Gets or sets the data point an annotation is anchored to.
- /// <seealso cref="AnchorAlignment"/>
- /// <seealso cref="AnchorOffsetX"/>
- /// <seealso cref="AnchorOffsetY"/>
- /// <seealso cref="AnchorX"/>
- /// <seealso cref="AnchorY"/>
- /// <seealso cref="SetAnchor(Charting.DataPoint)"/>
- /// <seealso cref="SetAnchor(Charting.DataPoint, Charting.DataPoint)"/>
- /// </summary>
- /// <value>
- /// A <see cref="DataPoint"/> object an annotation is anchored to.
- /// </value>
- /// <remarks>
- /// The annotation is anchored to the X and Y values of the specified data point,
- /// and automatically uses the same axes coordinates as the data point.
- /// <para>
- /// To automatically position an annotation relative to an anchor point, make sure
- /// its <see cref="X"/> and <see cref="Y"/> properties are set to <b>Double.NaN</b>.
- /// The <see cref="AnchorAlignment"/> property may be used to change an annotation's
- /// automatic position alignment to an anchor point. The <see cref="AnchorOffsetX"/> and
- /// <see cref="AnchorOffsetY"/> properties may be used to add extra spacing.
- /// </para>
- /// <para>
- /// When using this property, make sure the <see cref="AnchorX"/> and <see cref="AnchorY"/>
- /// properties are set to <b>Double.NaN</b> (they have precedence).
- /// </para>
- /// <para>
- /// Set this value to <b>null</b> or <b>nothing</b> to disable annotation anchoring to a data point.
- /// </para>
- /// </remarks>
- [
- SRCategory("CategoryAttributeAnchor"),
- DefaultValue(null),
- DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden),
- SerializationVisibilityAttribute(SerializationVisibility.Hidden),
- SRDescription("DescriptionAttributeAnchorDataPoint"),
- #if DESIGNER
- Editor(typeof(AnchorPointUITypeEditor), typeof(UITypeEditor)),
- #endif
- TypeConverter(typeof(AnchorPointValueConverter)),
- ]
- virtual public DataPoint AnchorDataPoint
- {
- get
- {
- if (_anchorDataPoint == null && _anchorDataPointName.Length > 0)
- {
- _anchorDataPoint = GetDataPointByName(_anchorDataPointName);
- }
- return _anchorDataPoint;
- }
- set
- {
- _anchorDataPoint = value;
- _anchorDataPointName = String.Empty;
- this.ResetCurrentRelativePosition();
- Invalidate();
- CallOnModifing();
- }
- }
- /// <summary>
- /// Gets or sets the X coordinate the annotation is anchored to.
- /// <seealso cref="AnchorY"/>
- /// <seealso cref="AnchorOffsetX"/>
- /// <seealso cref="AnchorOffsetY"/>
- /// <seealso cref="AnchorAlignment"/>
- /// <seealso cref="AnchorDataPoint"/>
- /// </summary>
- /// <value>
- /// A double value that represents the X coordinate which an annotation is anchored to.
- /// </value>
- /// <remarks>
- /// The annotation is anchored to the X coordinate specified in relative or axis coordinates,
- /// depending on the <see cref="AxisX"/> property value.
- /// <para>
- /// To automatically position an annotation relative to an anchor point, make sure
- /// its <see cref="X"/> property is set to <b>Double.NaN</b>.
- /// The <see cref="AnchorAlignment"/> property may be used to change the annotation's
- /// automatic position alignment to the anchor point. The <see cref="AnchorOffsetX"/> and
- /// <see cref="AnchorOffsetY"/> properties may be used to add extra spacing.
- /// </para>
- /// <para>
- /// This property has a higher priority than the <see cref="AnchorDataPoint"/> property.
- /// </para>
- /// <para>
- /// Set this value to <b>Double.NaN</b> to disable annotation anchoring to the value.
- /// </para>
- /// </remarks>
- [
- SRCategory("CategoryAttributeAnchor"),
- DefaultValue(double.NaN),
- SRDescription("DescriptionAttributeAnchorX"),
- RefreshPropertiesAttribute(RefreshProperties.All),
- TypeConverter(typeof(DoubleNanValueConverter)),
- ]
- virtual public double AnchorX
- {
- get
- {
- return _anchorX;
- }
- set
- {
- _anchorX = value;
- this.ResetCurrentRelativePosition();
- Invalidate();
- CallOnModifing();
- }
- }
- /// <summary>
- /// Gets or sets the Y coordinate which an annotation is anchored to.
- /// <seealso cref="AnchorY"/>
- /// <seealso cref="AnchorOffsetX"/>
- /// <seealso cref="AnchorOffsetY"/>
- /// <seealso cref="AnchorAlignment"/>
- /// <seealso cref="AnchorDataPoint"/>
- /// </summary>
- /// <value>
- /// A double value that represents the Y coordinate which an annotation is anchored to.
- /// </value>
- /// <remarks>
- /// The annotation is anchored to the Y coordinate specified in relative or axis coordinates,
- /// depending on the <see cref="AxisX"/> property value.
- /// <para>
- /// To automatically position an annotation relative to an anchor point, make sure
- /// its <see cref="Y"/> property is set to <b>Double.NaN</b>.
- /// The <see cref="AnchorAlignment"/> property may be used to change the annotation's
- /// automatic position alignment to the anchor point. The <see cref="AnchorOffsetX"/> and
- /// <see cref="AnchorOffsetY"/> properties may be used to add extra spacing.
- /// </para>
- /// <para>
- /// This property has a higher priority than the <see cref="AnchorDataPoint"/> property.
- /// </para>
- /// <para>
- /// Set this value to <b>Double.NaN</b> to disable annotation anchoring to the value.
- /// </para>
- /// </remarks>
- [
- SRCategory("CategoryAttributeAnchor"),
- DefaultValue(double.NaN),
- SRDescription("DescriptionAttributeAnchorY"),
- RefreshPropertiesAttribute(RefreshProperties.All),
- TypeConverter(typeof(DoubleNanValueConverter)),
- ]
- virtual public double AnchorY
- {
- get
- {
- return _anchorY;
- }
- set
- {
- _anchorY = value;
- this.ResetCurrentRelativePosition();
- Invalidate();
- CallOnModifing();
- }
- }
- /// <summary>
- /// Gets or sets the x-coordinate offset between the positions of an annotation and its anchor point.
- /// <seealso cref="AnchorOffsetY"/>
- /// <seealso cref="AnchorDataPoint"/>
- /// <seealso cref="AnchorX"/>
- /// <seealso cref="AnchorAlignment"/>
- /// </summary>
- /// <value>
- /// A double value that represents the x-coordinate offset between the positions of an annotation and its anchor point.
- /// </value>
- /// <remarks>
- /// The annotation must be anchored using the <see cref="AnchorDataPoint"/> or
- /// <see cref="AnchorX"/> properties, and its <see cref="X"/> property must be set
- /// to <b>Double.NaN</b>.
- /// </remarks>
- [
- SRCategory("CategoryAttributeAnchor"),
- DefaultValue(0.0),
- SRDescription("DescriptionAttributeAnchorOffsetX3"),
- RefreshPropertiesAttribute(RefreshProperties.All),
- ]
- virtual public double AnchorOffsetX
- {
- get
- {
- return anchorOffsetX;
- }
- set
- {
- if (value > 100.0 || value < -100.0)
- {
- throw (new ArgumentOutOfRangeException("value", SR.ExceptionAnnotationAnchorOffsetInvalid));
- }
- anchorOffsetX = value;
- this.ResetCurrentRelativePosition();
- Invalidate();
- CallOnModifing();
- }
- }
- /// <summary>
- /// Gets or sets the y-coordinate offset between the positions of an annotation and its anchor point.
- /// <seealso cref="Annotation.AnchorOffsetX"/>
- /// <seealso cref="Annotation.AnchorDataPoint"/>
- /// <seealso cref="Annotation.AnchorY"/>
- /// <seealso cref="Annotation.AnchorAlignment"/>
- /// </summary>
- /// <value>
- /// A double value that represents the y-coordinate offset between the positions of an annotation and its anchor point.
- /// </value>
- /// <remarks>
- /// Annotation must be anchored using <see cref="Annotation.AnchorDataPoint"/> or
- /// <see cref="Annotation.AnchorY"/> properties and it's <see cref="Annotation.Y"/> property must be set
- /// to <b>Double.NaN</b>.
- /// </remarks>
- [
- SRCategory("CategoryAttributeAnchor"),
- DefaultValue(0.0),
- SRDescription("DescriptionAttributeAnchorOffsetY3"),
- RefreshPropertiesAttribute(RefreshProperties.All),
- ]
- virtual public double AnchorOffsetY
- {
- get
- {
- return anchorOffsetY;
- }
- set
- {
- if (value > 100.0 || value < -100.0)
- {
- throw (new ArgumentOutOfRangeException("value", SR.ExceptionAnnotationAnchorOffsetInvalid));
- }
- anchorOffsetY = value;
- this.ResetCurrentRelativePosition();
- Invalidate();
- CallOnModifing();
- }
- }
- /// <summary>
- /// Gets or sets an annotation position's alignment to the anchor point.
- /// <seealso cref="AnchorX"/>
- /// <seealso cref="AnchorY"/>
- /// <seealso cref="AnchorDataPoint"/>
- /// <seealso cref="AnchorOffsetX"/>
- /// <seealso cref="AnchorOffsetY"/>
- /// </summary>
- /// <value>
- /// A <see cref="ContentAlignment"/> value that represents the annotation's alignment to
- /// the anchor point.
- /// </value>
- /// <remarks>
- /// The annotation must be anchored using either <see cref="AnchorDataPoint"/>, or the <see cref="AnchorX"/>
- /// and <see cref="AnchorY"/> properties. Its <see cref="X"/> and <see cref="Y"/>
- /// properties must be set to <b>Double.NaN</b>.
- /// </remarks>
- [
- SRCategory("CategoryAttributeAnchor"),
- DefaultValue(typeof(ContentAlignment), "BottomCenter"),
- SRDescription("DescriptionAttributeAnchorAlignment"),
- ]
- virtual public ContentAlignment AnchorAlignment
- {
- get
- {
- return anchorAlignment;
- }
- set
- {
- anchorAlignment = value;
- this.ResetCurrentRelativePosition();
- Invalidate();
- CallOnModifing();
- }
- }
- #endregion // Anchoring
- #region Editing Permissions
- /// <summary>
- /// Gets or sets a flag that specifies whether an annotation may be selected
- /// with a mouse by the end user.
- /// </summary>
- /// <value>
- /// <b>True</b> if the annotation may be selected, <b>false</b> otherwise.
- /// </value>
- [
- SRCategory("CategoryAttributeEditing"),
- DefaultValue(false),
- SRDescription("DescriptionAttributeAllowSelecting"),
- ]
- virtual public bool AllowSelecting
- {
- get
- {
- return _allowSelecting;
- }
- set
- {
- _allowSelecting = value;
- CallOnModifing();
- }
- }
- /// <summary>
- /// Gets or sets a flag that specifies whether an annotation may be moved
- /// with a mouse by the end user.
- /// </summary>
- /// <value>
- /// <b>True</b> if the annotation may be moved, <b>false</b> otherwise.
- /// </value>
- [
- SRCategory("CategoryAttributeEditing"),
- DefaultValue(false),
- SRDescription("DescriptionAttributeAllowMoving"),
- ]
- virtual public bool AllowMoving
- {
- get
- {
- return _allowMoving;
- }
- set
- {
- _allowMoving = value;
- CallOnModifing();
- }
- }
- /// <summary>
- /// Gets or sets a flag that specifies whether an annotation anchor may be moved
- /// with a mouse by the end user.
- /// </summary>
- /// <value>
- /// <b>True</b> if the annotation anchor may be moved, <b>false</b> otherwise.
- /// </value>
- [
- SRCategory("CategoryAttributeEditing"),
- DefaultValue(false),
- SRDescription("DescriptionAttributeAllowAnchorMoving3"),
- ]
- virtual public bool AllowAnchorMoving
- {
- get
- {
- return _allowAnchorMoving;
- }
- set
- {
- _allowAnchorMoving = value;
- CallOnModifing();
- }
- }
- /// <summary>
- /// Gets or sets a flag that specifies whether an annotation may be resized
- /// with a mouse by the end user.
- /// </summary>
- /// <value>
- /// <b>True</b> if the annotation may be resized, <b>false</b> otherwise.
- /// </value>
- [
- SRCategory("CategoryAttributeEditing"),
- DefaultValue(false),
- SRDescription("DescriptionAttributeAllowResizing"),
- ]
- virtual public bool AllowResizing
- {
- get
- {
- return _allowResizing;
- }
- set
- {
- _allowResizing = value;
- CallOnModifing();
- }
- }
- /// <summary>
- /// Gets or sets a flag that specifies whether an annotation's text may be edited
- /// when the end user double clicks on the text.
- /// </summary>
- /// <value>
- /// <b>True</b> if the annotation text may be edited, <b>false</b> otherwise.
- /// </value>
- [
- SRCategory("CategoryAttributeEditing"),
- DefaultValue(false),
- SRDescription("DescriptionAttributeAllowTextEditing"),
- ]
- virtual public bool AllowTextEditing
- {
- get
- {
- return _allowTextEditing;
- }
- set
- {
- _allowTextEditing = value;
- CallOnModifing();
- }
- }
- /// <summary>
- /// Gets or sets a flag that specifies whether a polygon annotation's points
- /// may be moved with a mouse by the end user.
- /// </summary>
- /// <value>
- /// <b>True</b> if the polygon annotation's points may be moved, <b>false</b> otherwise.
- /// </value>
- [
- SRCategory("CategoryAttributeEditing"),
- DefaultValue(false),
- SRDescription("DescriptionAttributeAllowPathEditing3"),
- ]
- virtual public bool AllowPathEditing
- {
- get
- {
- return _allowPathEditing;
- }
- set
- {
- _allowPathEditing = value;
- CallOnModifing();
- }
- }
- #endregion
- #region Interactivity
- /// <summary>
- /// Gets or sets an annotation's tooltip text.
- /// </summary>
- /// <value>
- /// A string value.
- /// </value>
- /// <remarks>
- /// Special keywords can be used in the text when an annotation is anchored to
- /// a data point using the <see cref="AnchorDataPoint"/> property. For a listing of
- /// these keywords, refer to the "Annotations" help topic.
- /// </remarks>
- [
- SRCategory("CategoryAttributeMisc"),
- DefaultValue(""),
- SRDescription("DescriptionAttributeToolTip"),
- ]
- virtual public string ToolTip
- {
- get
- {
- return _tooltip;
- }
- set
- {
- _tooltip = value;
- CallOnModifing();
- }
- }
- #endregion // Interactivity
- #endregion
- #region Methods
- #region Painting
- /// <summary>
- /// Paints the annotation object using the specified graphics.
- /// </summary>
- /// <param name="graphics">
- /// A <see cref="ChartGraphics"/> object used to paint the annotation object.
- /// </param>
- /// <param name="chart">
- /// Reference to the annotation's <see cref="Chart"/> control owner.
- /// </param>
- abstract internal void Paint(Chart chart, ChartGraphics graphics);
- /// <summary>
- /// Paints annotation selection markers.
- /// </summary>
- /// <param name="chartGraphics">Chart graphics used for painting.</param>
- /// <param name="rect">Selection rectangle.</param>
- /// <param name="path">Selection path.</param>
- virtual internal void PaintSelectionHandles(ChartGraphics chartGraphics, RectangleF rect, GraphicsPath path)
- {
- // Define markers appearance style
- Color markerBorderColor = Color.Black;
- Color markerColor = Color.FromArgb(200, 255, 255, 255);
- MarkerStyle markerStyle = MarkerStyle.Square;
- int markerSize = selectionMarkerSize;
- Boolean selected = this.IsSelected;
- SizeF markerSizeRel = chartGraphics.GetRelativeSize(new SizeF(markerSize, markerSize));
- if (this.Common.ProcessModePaint &&
- !this.Common.ChartPicture.isPrinting)
- {
- // Clear selection rectangles
- this.selectionRects = null;
- // Check if annotation is selected
- if (selected)
- {
- // Create selection rectangles
- this.selectionRects = new RectangleF[9];
- // Draw selection handles for single dimension annotations like line.
- if (this.SelectionPointsStyle == SelectionPointsStyle.TwoPoints)
- {
- // Save selection handles position in array elements 0 and 4
- this.selectionRects[(int)ResizingMode.TopLeftHandle] = new RectangleF(
- rect.X - markerSizeRel.Width / 2f,
- rect.Y - markerSizeRel.Height / 2f,
- markerSizeRel.Width,
- markerSizeRel.Height);
- this.selectionRects[(int)ResizingMode.BottomRightHandle] = new RectangleF(
- rect.Right - markerSizeRel.Width / 2f,
- rect.Bottom - markerSizeRel.Height / 2f,
- markerSizeRel.Width,
- markerSizeRel.Height);
- // Draw selection handle
- chartGraphics.DrawMarkerRel(
- rect.Location,
- markerStyle,
- markerSize,
- markerColor,
- markerBorderColor,
- 1,
- "",
- Color.Empty,
- 0,
- Color.FromArgb(128, 0, 0, 0),
- RectangleF.Empty);
- chartGraphics.DrawMarkerRel(
- new PointF(rect.Right, rect.Bottom),
- markerStyle,
- markerSize,
- markerColor,
- markerBorderColor,
- 1,
- "",
- Color.Empty,
- 0,
- Color.FromArgb(128, 0, 0, 0),
- RectangleF.Empty);
- }
- else if (this.SelectionPointsStyle == SelectionPointsStyle.Rectangle)
- {
- for (int index = 0; index < 8; index++)
- {
- // Get handle position
- PointF handlePosition = PointF.Empty;
- switch ((ResizingMode)index)
- {
- case ResizingMode.TopLeftHandle:
- handlePosition = rect.Location;
- break;
- case ResizingMode.TopHandle:
- handlePosition = new PointF(rect.X + rect.Width / 2f, rect.Y);
- break;
- case ResizingMode.TopRightHandle:
- handlePosition = new PointF(rect.Right, rect.Y);
- break;
- case ResizingMode.RightHandle:
- handlePosition = new PointF(rect.Right, rect.Y + rect.Height / 2f);
- break;
- case ResizingMode.BottomRightHandle:
- handlePosition = new PointF(rect.Right, rect.Bottom);
- break;
- case ResizingMode.BottomHandle:
- handlePosition = new PointF(rect.X + rect.Width / 2f, rect.Bottom);
- break;
- case ResizingMode.BottomLeftHandle:
- handlePosition = new PointF(rect.X, rect.Bottom);
- break;
- case ResizingMode.LeftHandle:
- handlePosition = new PointF(rect.X, rect.Y + rect.Height / 2f);
- break;
- }
- // Save selection handles position in array elements 0 and 4
- this.selectionRects[index] = new RectangleF(
- handlePosition.X - markerSizeRel.Width / 2f,
- handlePosition.Y - markerSizeRel.Height / 2f,
- markerSizeRel.Width,
- markerSizeRel.Height);
- // Draw selection handle
- chartGraphics.DrawMarkerRel(
- handlePosition,
- markerStyle,
- markerSize,
- markerColor,
- markerBorderColor,
- 1,
- "",
- Color.Empty,
- 0,
- Color.FromArgb(128, 0, 0, 0),
- RectangleF.Empty);
- }
- }
- //********************************************************************
- //** Draw anchor selection handle
- //********************************************************************
- // Get vertical and horizontal axis
- Axis vertAxis = null;
- Axis horizAxis = null;
- GetAxes(ref vertAxis, ref horizAxis);
- // Get anchor position
- double anchorX = double.NaN;
- double anchorY = double.NaN;
- bool relativeX = false;
- bool relativeY = false;
- this.GetAnchorLocation(ref anchorX, ref anchorY, ref relativeX, ref relativeY);
- // Convert anchor location to relative coordinates
- if (!double.IsNaN(anchorX) && !double.IsNaN(anchorY))
- {
- if (!relativeX && horizAxis != null)
- {
- anchorX = horizAxis.ValueToPosition(anchorX);
- }
- if (!relativeY && vertAxis != null)
- {
- anchorY = vertAxis.ValueToPosition(anchorY);
- }
- // Apply 3D transforamtion if required
- ChartArea chartArea = null;
- if (horizAxis != null && horizAxis.ChartArea != null)
- {
- chartArea = horizAxis.ChartArea;
- }
- if (vertAxis != null && vertAxis.ChartArea != null)
- {
- chartArea = vertAxis.ChartArea;
- }
- if (chartArea != null &&
- chartArea.Area3DStyle.Enable3D == true &&
- !chartArea.chartAreaIsCurcular &&
- chartArea.requireAxes &&
- chartArea.matrix3D.IsInitialized())
- {
- // Get anotation Z coordinate (use scene depth or anchored point Z position)
- float positionZ = chartArea.areaSceneDepth;
- if (this.AnchorDataPoint != null && this.AnchorDataPoint.series != null)
- {
- float depth = 0f;
- chartArea.GetSeriesZPositionAndDepth(
- this.AnchorDataPoint.series,
- out depth,
- out positionZ);
- positionZ += depth / 2f;
- }
- // Define 3D points of annotation object
- Point3D[] annot3DPoints = new Point3D[1];
- annot3DPoints[0] = new Point3D((float)anchorX, (float)anchorY, positionZ);
- // Tranform cube coordinates
- chartArea.matrix3D.TransformPoints(annot3DPoints);
- // Get transformed coordinates
- anchorX = annot3DPoints[0].X;
- anchorY = annot3DPoints[0].Y;
- }
- // Save selection handles position in array elements 0 and 4
- this.selectionRects[(int)ResizingMode.AnchorHandle] = new RectangleF(
- (float)anchorX - markerSizeRel.Width / 2f,
- (float)anchorY - markerSizeRel.Height / 2f,
- markerSizeRel.Width,
- markerSizeRel.Height);
- // Draw circular selection handle
- chartGraphics.DrawMarkerRel(
- new PointF((float)anchorX, (float)anchorY),
- MarkerStyle.Cross,
- selectionMarkerSize + 3,
- markerColor,
- markerBorderColor,
- 1,
- "",
- Color.Empty,
- 0,
- Color.FromArgb(128, 0, 0, 0),
- RectangleF.Empty);
- }
- //********************************************************************
- //** Draw path selection handles
- //********************************************************************
- if (path != null && AllowPathEditing)
- {
- // Create selection rectangles for each point
- PointF[] pathPoints = path.PathPoints;
- RectangleF[] newSelectionRects = new RectangleF[pathPoints.Length + 9];
- // Copy previous rectangles (first nine elements)
- for (int index = 0; index < this.selectionRects.Length; index++)
- {
- newSelectionRects[index] = this.selectionRects[index];
- }
- this.selectionRects = newSelectionRects;
- // Loop through all points
- for (int index = 0; index < pathPoints.Length; index++)
- {
- // Get handle position
- PointF handlePosition = chartGraphics.GetRelativePoint(pathPoints[index]);
- // Save selection handles position in array elements 0 and 4
- this.selectionRects[9 + index] = new RectangleF(
- handlePosition.X - markerSizeRel.Width / 2f,
- handlePosition.Y - markerSizeRel.Height / 2f,
- markerSizeRel.Width,
- markerSizeRel.Height);
- // Draw selection handle
- chartGraphics.DrawMarkerRel(
- handlePosition,
- MarkerStyle.Circle,
- selectionMarkerSize + 1,
- markerColor,
- markerBorderColor,
- 1,
- "",
- Color.Empty,
- 0,
- Color.FromArgb(128, 0, 0, 0),
- RectangleF.Empty);
- }
- }
- }
- }
- }
- #endregion
- #region Position and Size
- /// <summary>
- /// Resizes an annotation according to its content size.
- /// </summary>
- /// <remarks>
- /// Sets the annotation width and height to fit the specified text. This method applies to
- /// <see cref="TextAnnotation"/>, <see cref="RectangleAnnotation"/>, <see cref="EllipseAnnotation"/>
- /// and <see cref="CalloutAnnotation"/> objects only.
- /// </remarks>
- virtual public void ResizeToContent()
- {
- RectangleF position = GetContentPosition();
- if (!double.IsNaN(position.Width))
- {
- this.Width = position.Width;
- }
- if (!double.IsNaN(position.Height))
- {
- this.Height = position.Height;
- }
- }
- /// <summary>
- /// Gets an annotation's content position.
- /// </summary>
- /// <returns>Annotation's content size.</returns>
- virtual internal RectangleF GetContentPosition()
- {
- return new RectangleF(float.NaN, float.NaN, float.NaN, float.NaN);
- }
- /// <summary>
- /// Gets an annotation's anchor point location.
- /// </summary>
- /// <param name="anchorX">Returns the anchor X coordinate.</param>
- /// <param name="anchorY">Returns the anchor Y coordinate.</param>
- /// <param name="inRelativeAnchorX">Indicates if X coordinate is in relative chart coordinates.</param>
- /// <param name="inRelativeAnchorY">Indicates if Y coordinate is in relative chart coordinates.</param>
- private void GetAnchorLocation(ref double anchorX, ref double anchorY, ref bool inRelativeAnchorX, ref bool inRelativeAnchorY)
- {
- anchorX = this.AnchorX;
- anchorY = this.AnchorY;
- if (this.AnchorDataPoint != null &&
- this.AnchorDataPoint.series != null &&
- this.Chart != null &&
- this.Chart.chartPicture != null)
- {
- // Anchor data point is not allowed for gropped annotations
- if (this.AnnotationGroup != null)
- {
- throw (new InvalidOperationException(SR.ExceptionAnnotationGroupedAnchorDataPointMustBeEmpty));
- }
- // Get data point relative coordinate
- if (double.IsNaN(anchorX) || double.IsNaN(anchorY))
- {
- // Get X value from data point
- if (double.IsNaN(anchorX))
- {
- anchorX = this.AnchorDataPoint.positionRel.X;
- inRelativeAnchorX = true;
- }
- // Get Y value from data point
- if (double.IsNaN(anchorY))
- {
- anchorY = this.AnchorDataPoint.positionRel.Y;
- inRelativeAnchorY = true;
- }
- }
- }
- }
- /// <summary>
- /// Gets annotation object position in relative coordinates.
- /// </summary>
- /// <param name="location">Returns annotation location.</param>
- /// <param name="size">Returns annotation size.</param>
- /// <param name="anchorLocation">Returns annotation anchor point location.</param>
- virtual internal void GetRelativePosition(out PointF location, out SizeF size, out PointF anchorLocation)
- {
- bool saveCurrentPosition = true;
- //***********************************************************************
- //** Check if position was precalculated
- //***********************************************************************
- if (!double.IsNaN(currentPositionRel.X) && !double.IsNaN(currentPositionRel.X))
- {
- location = currentPositionRel.Location;
- size = currentPositionRel.Size;
- anchorLocation = currentAnchorLocationRel;
- return;
- }
- //***********************************************************************
- //** Get vertical and horizontal axis
- //***********************************************************************
- Axis vertAxis = null;
- Axis horizAxis = null;
- GetAxes(ref vertAxis, ref horizAxis);
- //***********************************************************************
- //** Check if annotation was anchored to 2 points.
- //***********************************************************************
- if (this._anchorDataPoint != null &&
- this._anchorDataPoint2 != null)
- {
- // Annotation size is in axis coordinates
- this.IsSizeAlwaysRelative = false;
- // Set annotation size
- this.Height =
- vertAxis.PositionToValue(this._anchorDataPoint2.positionRel.Y, false) -
- vertAxis.PositionToValue(this._anchorDataPoint.positionRel.Y, false);
- this.Width =
- horizAxis.PositionToValue(this._anchorDataPoint2.positionRel.X, false) -
- horizAxis.PositionToValue(this._anchorDataPoint.positionRel.X, false);
- // Reset second anchor point after setting width and height
- this._anchorDataPoint2 = null;
- }
- //***********************************************************************
- //** Flags which indicate that coordinate was already transformed
- //** into chart relative coordinate system.
- //***********************************************************************
- bool inRelativeX = false;
- bool inRelativeY = false;
- bool inRelativeWidth = (_isSizeAlwaysRelative) ? true : false;
- bool inRelativeHeight = (_isSizeAlwaysRelative) ? true : false;
- bool inRelativeAnchorX = false;
- bool inRelativeAnchorY = false;
- //***********************************************************************
- //** Get anchoring coordinates from anchored Data Point.
- //***********************************************************************
- double anchorX = this.AnchorX;
- double anchorY = this.AnchorY;
- GetAnchorLocation(ref anchorX, ref anchorY, ref inRelativeAnchorX, ref inRelativeAnchorY);
- //***********************************************************************
- //** Calculate scaling and translation for the annotations in the group.
- //***********************************************************************
- AnnotationGroup group = this.AnnotationGroup;
- PointF groupLocation = PointF.Empty;
- double groupScaleX = 1.0;
- double groupScaleY = 1.0;
- if (group != null)
- {
- // Do not save relative position of annotations inside the group
- saveCurrentPosition = false;
- // Take relative position of the group
- SizeF groupSize = SizeF.Empty;
- PointF groupAnchorLocation = PointF.Empty;
- group.GetRelativePosition(out groupLocation, out groupSize, out groupAnchorLocation);
- // Calculate Scale
- groupScaleX = groupSize.Width / 100.0;
- groupScaleY = groupSize.Height / 100.0;
- }
- //***********************************************************************
- //** Get annotation automatic size.
- //***********************************************************************
- double relativeWidth = this._width;
- double relativeHeight = this._height;
- // Get annotation content position
- RectangleF contentPosition = GetContentPosition();
- // Set annotation size if not set to custom value
- if (double.IsNaN(relativeWidth))
- {
- relativeWidth = contentPosition.Width;
- inRelativeWidth = true;
- }
- else
- {
- relativeWidth *= groupScaleX;
- }
- if (double.IsNaN(relativeHeight))
- {
- relativeHeight = contentPosition.Height;
- inRelativeHeight = true;
- }
- else
- {
- relativeHeight *= groupScaleY;
- }
- //***********************************************************************
- //** Provide "dummy" size at design time
- //***********************************************************************
- if (this.Chart != null && this.Chart.IsDesignMode())
- {
- if (this.IsSizeAlwaysRelative ||
- (vertAxis == null && horizAxis == null))
- {
- if (double.IsNaN(relativeWidth))
- {
- relativeWidth = 20.0;
- saveCurrentPosition = false;
- }
- if (double.IsNaN(relativeHeight))
- {
- relativeHeight = 20.0;
- saveCurrentPosition = false;
- }
- }
- }
- //***********************************************************************
- //** Get annotation location.
- //***********************************************************************
- double relativeX = this.X;
- double relativeY = this.Y;
- // Check if annotation location Y coordinate is defined
- if (double.IsNaN(relativeY) && !double.IsNaN(anchorY))
- {
- inRelativeY = true;
- double relativeAnchorY = anchorY;
- if (!inRelativeAnchorY && vertAxis != null)
- {
- relativeAnchorY = vertAxis.ValueToPosition(anchorY);
- }
- if (this.AnchorAlignment == ContentAlignment.TopCenter ||
- this.AnchorAlignment == ContentAlignment.TopLeft ||
- this.AnchorAlignment == ContentAlignment.TopRight)
- {
- relativeY = relativeAnchorY + this.AnchorOffsetY;
- relativeY *= groupScaleY;
- }
- else if (this.AnchorAlignment == ContentAlignment.BottomCenter ||
- this.AnchorAlignment == ContentAlignment.BottomLeft ||
- this.AnchorAlignment == ContentAlignment.BottomRight)
- {
- relativeY = relativeAnchorY - this.AnchorOffsetY;
- relativeY *= groupScaleY;
- if (relativeHeight != 0f && !double.IsNaN(relativeHeight))
- {
- if (inRelativeHeight)
- {
- relativeY -= relativeHeight;
- }
- else if (vertAxis != null)
- {
- float yValue = (float)vertAxis.PositionToValue(relativeY);
- float bottomRel = (float)vertAxis.ValueToPosition(yValue + relativeHeight);
- relativeY -= bottomRel - relativeY;
- }
- }
- }
- else
- {
- relativeY = relativeAnchorY + this.AnchorOffsetY;
- relativeY *= groupScaleY;
- if (relativeHeight != 0f && !double.IsNaN(relativeHeight))
- {
- if (inRelativeHeight)
- {
- relativeY -= relativeHeight / 2f;
- }
- else if (vertAxis != null)
- {
- float yValue = (float)vertAxis.PositionToValue(relativeY);
- float bottomRel = (float)vertAxis.ValueToPosition(yValue + relativeHeight);
- relativeY -= (bottomRel - relativeY) / 2f;
- }
- }
- }
- }
- else
- {
- relativeY *= groupScaleY;
- }
- // Check if annotation location X coordinate is defined
- if (double.IsNaN(relativeX) && !double.IsNaN(anchorX))
- {
- inRelativeX = true;
- double relativeAnchorX = anchorX;
- if (!inRelativeAnchorX && horizAxis != null)
- {
- relativeAnchorX = horizAxis.ValueToPosition(anchorX);
- }
- if (this.AnchorAlignment == ContentAlignment.BottomLeft ||
- this.AnchorAlignment == ContentAlignment.MiddleLeft ||
- this.AnchorAlignment == ContentAlignment.TopLeft)
- {
- relativeX = relativeAnchorX + this.AnchorOffsetX;
- relativeX *= groupScaleX;
- }
- else if (this.AnchorAlignment == ContentAlignment.BottomRight ||
- this.AnchorAlignment == ContentAlignment.MiddleRight ||
- this.AnchorAlignment == ContentAlignment.TopRight)
- {
- relativeX = relativeAnchorX - this.AnchorOffsetX;
- relativeX *= groupScaleX;
- if (relativeWidth != 0f && !double.IsNaN(relativeWidth))
- {
- if (inRelativeWidth)
- {
- relativeX -= relativeWidth;
- }
- else if (horizAxis != null)
- {
- float xValue = (float)horizAxis.PositionToValue(relativeX);
- relativeX -= horizAxis.ValueToPosition(xValue + relativeWidth) - relativeX;
- }
- }
- }
- else
- {
- relativeX = relativeAnchorX + this.AnchorOffsetX;
- relativeX *= groupScaleX;
- if (relativeWidth != 0f && !double.IsNaN(relativeWidth))
- {
- if (inRelativeWidth)
- {
- relativeX -= relativeWidth / 2f;
- }
- else if (horizAxis != null)
- {
- float xValue = (float)horizAxis.PositionToValue(relativeX);
- relativeX -= (horizAxis.ValueToPosition(xValue + relativeWidth) - relativeX) / 2f;
- }
- }
- }
- }
- else
- {
- relativeX *= groupScaleX;
- }
- // Translate
- relativeX += groupLocation.X;
- relativeY += groupLocation.Y;
- //***********************************************************************
- //** Get annotation automatic location.
- //***********************************************************************
- // Set annotation size if not set to custom value
- if (double.IsNaN(relativeX))
- {
- relativeX = contentPosition.X * groupScaleX;
- inRelativeX = true;
- }
- if (double.IsNaN(relativeY))
- {
- relativeY = contentPosition.Y * groupScaleY;
- inRelativeY = true;
- }
- //***********************************************************************
- //** Convert coordinates from axes values to relative coordinates.
- //***********************************************************************
- // Check if values are set in axis values
- if (horizAxis != null)
- {
- if (!inRelativeX)
- {
- relativeX = horizAxis.ValueToPosition(relativeX);
- }
- if (!inRelativeAnchorX)
- {
- anchorX = horizAxis.ValueToPosition(anchorX);
- }
- if (!inRelativeWidth)
- {
- relativeWidth = horizAxis.ValueToPosition(
- horizAxis.PositionToValue(relativeX, false) + relativeWidth) - relativeX;
- }
- }
- if (vertAxis != null)
- {
- if (!inRelativeY)
- {
- relativeY = vertAxis.ValueToPosition(relativeY);
- }
- if (!inRelativeAnchorY)
- {
- anchorY = vertAxis.ValueToPosition(anchorY);
- }
- if (!inRelativeHeight)
- {
- relativeHeight = vertAxis.ValueToPosition(
- vertAxis.PositionToValue(relativeY, false) + relativeHeight) - relativeY;
- }
- }
- bool isTextAnnotation = this is TextAnnotation;
- //***********************************************************************
- //** Apply 3D transforamtion if required
- //***********************************************************************
- ChartArea chartArea = null;
- if (horizAxis != null && horizAxis.ChartArea != null)
- {
- chartArea = horizAxis.ChartArea;
- }
- if (vertAxis != null && vertAxis.ChartArea != null)
- {
- chartArea = vertAxis.ChartArea;
- }
- if (chartArea != null &&
- chartArea.Area3DStyle.Enable3D == true &&
- !chartArea.chartAreaIsCurcular &&
- chartArea.requireAxes &&
- chartArea.matrix3D.IsInitialized())
- {
- // Get anotation Z coordinate (use scene depth or anchored point Z position)
- float positionZ = chartArea.areaSceneDepth;
- if (this.AnchorDataPoint != null && this.AnchorDataPoint.series != null)
- {
- float depth = 0f;
- chartArea.GetSeriesZPositionAndDepth(
- this.AnchorDataPoint.series,
- out depth,
- out positionZ);
- positionZ += depth / 2f;
- }
- // Define 3D points of annotation object
- Point3D[] annot3DPoints = new Point3D[3];
- annot3DPoints[0] = new Point3D((float)relativeX, (float)relativeY, positionZ);
- annot3DPoints[1] = new Point3D((float)(relativeX + relativeWidth), (float)(relativeY + relativeHeight), positionZ);
- annot3DPoints[2] = new Point3D((float)anchorX, (float)anchorY, positionZ);
- // Tranform cube coordinates
- chartArea.matrix3D.TransformPoints(annot3DPoints);
- // Get transformed coordinates
- relativeX = annot3DPoints[0].X;
- relativeY = annot3DPoints[0].Y;
- anchorX = annot3DPoints[2].X;
- anchorY = annot3DPoints[2].Y;
- // Don't adjust size for text annotation
- if (!(isTextAnnotation && this.IsSizeAlwaysRelative))
- {
- relativeWidth = annot3DPoints[1].X - relativeX;
- relativeHeight = annot3DPoints[1].Y - relativeY;
- }
- }
- //***********************************************************************
- //** Provide "dummy" position at design time
- //***********************************************************************
- if (this.Chart != null && this.Chart.IsDesignMode())
- {
- if (double.IsNaN(relativeX))
- {
- relativeX = groupLocation.X;
- saveCurrentPosition = false;
- }
- if (double.IsNaN(relativeY))
- {
- relativeY = groupLocation.Y;
- saveCurrentPosition = false;
- }
- if (double.IsNaN(relativeWidth))
- {
- relativeWidth = 20.0 * groupScaleX;
- saveCurrentPosition = false;
- }
- if (double.IsNaN(relativeHeight))
- {
- relativeHeight = 20.0 * groupScaleY;
- saveCurrentPosition = false;
- }
- }
- //***********************************************************************
- //** Initialize returned values
- //***********************************************************************
- location = new PointF((float)relativeX, (float)relativeY);
- size = new SizeF((float)relativeWidth, (float)relativeHeight);
- anchorLocation = new PointF((float)anchorX, (float)anchorY);
- //***********************************************************************
- //** Adjust text based annotaion position using SmartLabelStyle.
- //***********************************************************************
- // Check if smart labels are enabled
- if (this.SmartLabelStyle.Enabled && isTextAnnotation &&
- group == null)
- {
- // Anchor point must be set
- if (!double.IsNaN(anchorX) && !double.IsNaN(anchorY) &&
- double.IsNaN(this.X) && double.IsNaN(this.Y))
- {
- if (this.Chart != null &&
- this.Chart.chartPicture != null)
- {
- // Remember old movement distance restriction
- double oldMinMovingDistance = this.SmartLabelStyle.MinMovingDistance;
- double oldMaxMovingDistance = this.SmartLabelStyle.MaxMovingDistance;
- // Increase annotation moving restrictions according to the anchor offset
- PointF anchorOffsetAbs = this.GetGraphics().GetAbsolutePoint(
- new PointF((float)this.AnchorOffsetX, (float)this.AnchorOffsetY));
- float maxAnchorOffsetAbs = Math.Max(anchorOffsetAbs.X, anchorOffsetAbs.Y);
- if (maxAnchorOffsetAbs > 0.0)
- {
- this.SmartLabelStyle.MinMovingDistance += maxAnchorOffsetAbs;
- this.SmartLabelStyle.MaxMovingDistance += maxAnchorOffsetAbs;
- }
- // Adjust label position using SmartLabelStyle algorithm
- LabelAlignmentStyles labelAlignment = LabelAlignmentStyles.Bottom;
- using (StringFormat format = new StringFormat())
- {
- SizeF markerSizeRel = new SizeF((float)this.AnchorOffsetX, (float)this.AnchorOffsetY);
- PointF newlocation = this.Chart.chartPicture.annotationSmartLabel.AdjustSmartLabelPosition(
- this.Common,
- this.Chart.chartPicture.ChartGraph,
- chartArea,
- this.SmartLabelStyle,
- location,
- size,
- format,
- anchorLocation,
- markerSizeRel,
- labelAlignment,
- (this is CalloutAnnotation));
- // Restore old movement distance restriction
- this.SmartLabelStyle.MinMovingDistance = oldMinMovingDistance;
- this.SmartLabelStyle.MaxMovingDistance = oldMaxMovingDistance;
- // Check if annotation should be hidden
- if (newlocation.IsEmpty)
- {
- location = new PointF(float.NaN, float.NaN);
- }
- else
- {
- // Get new position using alignment in format
- RectangleF newPosition = this.Chart.chartPicture.annotationSmartLabel.GetLabelPosition(
- this.Chart.chartPicture.ChartGraph,
- newlocation,
- size,
- format,
- false);
- // Set new location
- location = newPosition.Location;
- }
- }
- }
- }
- else
- {
- // Add annotation position into the list (to prevent overlapping)
- using (StringFormat format = new StringFormat())
- {
- this.Chart.chartPicture.annotationSmartLabel.AddSmartLabelPosition(
- this.Chart.chartPicture.ChartGraph,
- location,
- size,
- format);
- }
- }
- }
- //***********************************************************************
- //** Save calculated position
- //***********************************************************************
- if (saveCurrentPosition)
- {
- currentPositionRel = new RectangleF(location, size);
- currentAnchorLocationRel = new PointF(anchorLocation.X, anchorLocation.Y);
- }
- }
- /// <summary>
- /// Set annotation object position using rectangle in relative coordinates.
- /// Automatically converts relative coordinates to axes values if required.
- /// </summary>
- /// <param name="position">Position in relative coordinates.</param>
- /// <param name="anchorPoint">Anchor location in relative coordinates.</param>
- internal void SetPositionRelative(RectangleF position, PointF anchorPoint)
- {
- SetPositionRelative(position, anchorPoint, false);
- }
- /// <summary>
- /// Set annotation object position using rectangle in relative coordinates.
- /// Automatically converts relative coordinates to axes values if required.
- /// </summary>
- /// <param name="position">Position in relative coordinates.</param>
- /// <param name="anchorPoint">Anchor location in relative coordinates.</param>
- /// <param name="userInput">Indicates if position changing was a result of the user input.</param>
- internal void SetPositionRelative(RectangleF position, PointF anchorPoint, bool userInput)
- {
- double newX = position.X;
- double newY = position.Y;
- double newRight = position.Right;
- double newBottom = position.Bottom;
- double newWidth = position.Width;
- double newHeight = position.Height;
- double newAnchorX = anchorPoint.X;
- double newAnchorY = anchorPoint.Y;
- //***********************************************************************
- //** Set pre calculated position and anchor location
- //***********************************************************************
- this.currentPositionRel = new RectangleF(position.Location, position.Size);
- this.currentAnchorLocationRel = new PointF(anchorPoint.X, anchorPoint.Y);
- //***********************************************************************
- //** Get vertical and horizontal axis
- //***********************************************************************
- Axis vertAxis = null;
- Axis horizAxis = null;
- GetAxes(ref vertAxis, ref horizAxis);
- //***********************************************************************
- //** Disable anchoring to point and axes in 3D
- //** This is done due to the issues of moving elements in 3D space.
- //***********************************************************************
- ChartArea chartArea = null;
- if (horizAxis != null && horizAxis.ChartArea != null)
- {
- chartArea = horizAxis.ChartArea;
- }
- if (vertAxis != null && vertAxis.ChartArea != null)
- {
- chartArea = vertAxis.ChartArea;
- }
- if (chartArea != null && chartArea.Area3DStyle.Enable3D == true)
- {
- // If anchor point was set - get its relative position and use it as an anchor point
- if (this.AnchorDataPoint != null)
- {
- bool inRelativeCoordX = true;
- bool inRelativeCoordY = true;
- this.GetAnchorLocation(ref newAnchorX, ref newAnchorY, ref inRelativeCoordX, ref inRelativeCoordY);
- this.currentAnchorLocationRel = new PointF((float)newAnchorX, (float)newAnchorY);
- }
- // In 3D always use relative annotation coordinates
- // Disconnect annotation from axes and anchor point
- this.AnchorDataPoint = null;
- this.AxisX = null;
- this.AxisY = null;
- horizAxis = null;
- vertAxis = null;
- }
- //***********************************************************************
- //** Convert relative coordinates to axis values
- //***********************************************************************
- if (horizAxis != null)
- {
- newX = horizAxis.PositionToValue(newX, false);
- if (!double.IsNaN(newAnchorX))
- {
- newAnchorX = horizAxis.PositionToValue(newAnchorX, false);
- }
- // Adjust for the IsLogarithmic axis
- if (horizAxis.IsLogarithmic)
- {
- newX = Math.Pow(horizAxis.logarithmBase, newX);
- if (!double.IsNaN(newAnchorX))
- {
- newAnchorX = Math.Pow(horizAxis.logarithmBase, newAnchorX);
- }
- }
- if (!this.IsSizeAlwaysRelative)
- {
- if (float.IsNaN(position.Right) &&
- !float.IsNaN(position.Width) &&
- !float.IsNaN(anchorPoint.X))
- {
- newRight = horizAxis.PositionToValue(anchorPoint.X + position.Width, false);
- if (horizAxis.IsLogarithmic)
- {
- newRight = Math.Pow(horizAxis.logarithmBase, newRight);
- }
- newWidth = newRight - newAnchorX;
- }
- else
- {
- newRight = horizAxis.PositionToValue(position.Right, false);
- if (horizAxis.IsLogarithmic)
- {
- newRight = Math.Pow(horizAxis.logarithmBase, newRight);
- }
- newWidth = newRight - newX;
- }
- }
- }
- if (vertAxis != null)
- {
- newY = vertAxis.PositionToValue(newY, false);
- if (!double.IsNaN(newAnchorY))
- {
- newAnchorY = vertAxis.PositionToValue(newAnchorY, false);
- }
- // NOTE: Fixes issue #4113
- // Adjust for the IsLogarithmic axis
- if (vertAxis.IsLogarithmic)
- {
- newY = Math.Pow(vertAxis.logarithmBase, newY);
- if (!double.IsNaN(newAnchorY))
- {
- newAnchorY = Math.Pow(vertAxis.logarithmBase, newAnchorY);
- }
- }
- if (!this.IsSizeAlwaysRelative)
- {
- if (float.IsNaN(position.Bottom) &&
- !float.IsNaN(position.Height) &&
- !float.IsNaN(anchorPoint.Y))
- {
- newBottom = vertAxis.PositionToValue(anchorPoint.Y + position.Height, false);
- if (vertAxis.IsLogarithmic)
- {
- newBottom = Math.Pow(vertAxis.logarithmBase, newBottom);
- }
- newHeight = newBottom - newAnchorY;
- }
- else
- {
- newBottom = vertAxis.PositionToValue(position.Bottom, false);
- if (vertAxis.IsLogarithmic)
- {
- newBottom = Math.Pow(vertAxis.logarithmBase, newBottom);
- }
- newHeight = newBottom - newY;
- }
- }
- }
- // Fire position changing event when position changed by user.
- if (userInput)
- {
- // Set flag that annotation position was changed
- this.positionChanged = true;
- // Fire position changing event
- if (this.Chart != null)
- {
- AnnotationPositionChangingEventArgs args = new AnnotationPositionChangingEventArgs();
- args.NewLocationX = newX;
- args.NewLocationY = newY;
- args.NewSizeWidth = newWidth;
- args.NewSizeHeight = newHeight;
- args.NewAnchorLocationX = newAnchorX;
- args.NewAnchorLocationY = newAnchorY;
- args.Annotation = this;
- if (this.Chart.OnAnnotationPositionChanging(ref args))
- {
- // Get user changed position/anchor
- newX = args.NewLocationX;
- newY = args.NewLocationY;
- newWidth = args.NewSizeWidth;
- newHeight = args.NewSizeHeight;
- newAnchorX = args.NewAnchorLocationX;
- newAnchorY = args.NewAnchorLocationY;
- }
- }
- }
- // Adjust location & size
- this.X = newX;
- this.Y = newY;
- this.Width = newWidth;
- this.Height = newHeight;
- this.AnchorX = newAnchorX;
- this.AnchorY = newAnchorY;
- // Invalidate annotation
- this.Invalidate();
- return;
- }
- /// <summary>
- /// Adjust annotation location and\or size as a result of user action.
- /// </summary>
- /// <param name="movingDistance">Distance to resize/move the annotation.</param>
- /// <param name="resizeMode">Resizing mode.</param>
- virtual internal void AdjustLocationSize(SizeF movingDistance, ResizingMode resizeMode)
- {
- AdjustLocationSize(movingDistance, resizeMode, true);
- }
- /// <summary>
- /// Adjust annotation location and\or size as a result of user action.
- /// </summary>
- /// <param name="movingDistance">Distance to resize/move the annotation.</param>
- /// <param name="resizeMode">Resizing mode.</param>
- /// <param name="pixelCoord">Distance is in pixels, otherwise relative.</param>
- virtual internal void AdjustLocationSize(SizeF movingDistance, ResizingMode resizeMode, bool pixelCoord)
- {
- AdjustLocationSize(movingDistance, resizeMode, pixelCoord, false);
- }
- /// <summary>
- /// Adjust annotation location and\or size as a result of user action.
- /// </summary>
- /// <param name="movingDistance">Distance to resize/move the annotation.</param>
- /// <param name="resizeMode">Resizing mode.</param>
- /// <param name="pixelCoord">Distance is in pixels, otherwise relative.</param>
- /// <param name="userInput">Indicates if position changing was a result of the user input.</param>
- virtual internal void AdjustLocationSize(SizeF movingDistance, ResizingMode resizeMode, bool pixelCoord, bool userInput)
- {
- if (!movingDistance.IsEmpty)
- {
- // Convert pixel coordinates into relative
- if (pixelCoord)
- {
- movingDistance = Chart.chartPicture.ChartGraph.GetRelativeSize(movingDistance);
- }
- // Get annotation position in relative coordinates
- PointF firstPoint = PointF.Empty;
- PointF anchorPoint = PointF.Empty;
- SizeF size = SizeF.Empty;
- if (userInput)
- {
- if (this.startMovePositionRel.X == 0f &&
- this.startMovePositionRel.Y == 0f &&
- this.startMovePositionRel.Width == 0f &&
- this.startMovePositionRel.Height == 0f)
- {
- GetRelativePosition(out firstPoint, out size, out anchorPoint);
- this.startMovePositionRel = new RectangleF(firstPoint, size);
- this.startMoveAnchorLocationRel = new PointF(anchorPoint.X, anchorPoint.Y);
- }
- firstPoint = this.startMovePositionRel.Location;
- size = this.startMovePositionRel.Size;
- anchorPoint = this.startMoveAnchorLocationRel;
- }
- else
- {
- GetRelativePosition(out firstPoint, out size, out anchorPoint);
- }
- if (resizeMode == ResizingMode.TopLeftHandle)
- {
- firstPoint.X -= movingDistance.Width;
- firstPoint.Y -= movingDistance.Height;
- size.Width += movingDistance.Width;
- size.Height += movingDistance.Height;
- }
- else if (resizeMode == ResizingMode.TopHandle)
- {
- firstPoint.Y -= movingDistance.Height;
- size.Height += movingDistance.Height;
- }
- else if (resizeMode == ResizingMode.TopRightHandle)
- {
- firstPoint.Y -= movingDistance.Height;
- size.Width -= movingDistance.Width;
- size.Height += movingDistance.Height;
- }
- else if (resizeMode == ResizingMode.RightHandle)
- {
- size.Width -= movingDistance.Width;
- }
- else if (resizeMode == ResizingMode.BottomRightHandle)
- {
- size.Width -= movingDistance.Width;
- size.Height -= movingDistance.Height;
- }
- else if (resizeMode == ResizingMode.BottomHandle)
- {
- size.Height -= movingDistance.Height;
- }
- else if (resizeMode == ResizingMode.BottomLeftHandle)
- {
- firstPoint.X -= movingDistance.Width;
- size.Width += movingDistance.Width;
- size.Height -= movingDistance.Height;
- }
- else if (resizeMode == ResizingMode.LeftHandle)
- {
- firstPoint.X -= movingDistance.Width;
- size.Width += movingDistance.Width;
- }
- else if (resizeMode == ResizingMode.AnchorHandle)
- {
- anchorPoint.X -= movingDistance.Width;
- anchorPoint.Y -= movingDistance.Height;
- }
- else if (resizeMode == ResizingMode.Moving)
- {
- firstPoint.X -= movingDistance.Width;
- firstPoint.Y -= movingDistance.Height;
- }
- // Make sure we do not override automatic Width and Heigth
- if (resizeMode == ResizingMode.Moving)
- {
- if (double.IsNaN(this.Width))
- {
- size.Width = float.NaN;
- }
- if (double.IsNaN(this.Height))
- {
- size.Height = float.NaN;
- }
- }
- // Make sure we do not override automatic X and Y
- if (resizeMode == ResizingMode.AnchorHandle)
- {
- if (double.IsNaN(this.X))
- {
- firstPoint.X = float.NaN;
- }
- if (double.IsNaN(this.Y))
- {
- firstPoint.Y = float.NaN;
- }
- }
- else if (double.IsNaN(this.AnchorX) || double.IsNaN(this.AnchorY))
- {
- anchorPoint = new PointF(float.NaN, float.NaN);
- }
- // Set annotation position from rectangle in relative coordinates
- SetPositionRelative(new RectangleF(firstPoint, size), anchorPoint, userInput);
- }
- return;
- }
- #endregion
- #region Anchor Point and Axes Converters
- /// <summary>
- /// Checks if annotation draw anything in the anchor position (except selection handle)
- /// </summary>
- /// <returns>True if annotation "connects" itself and anchor point visually.</returns>
- virtual internal bool IsAnchorDrawn()
- {
- return false;
- }
- /// <summary>
- /// Gets data point by name.
- /// </summary>
- /// <param name="dataPointName">Data point name to find.</param>
- /// <returns>Data point.</returns>
- internal DataPoint GetDataPointByName(string dataPointName)
- {
- DataPoint dataPoint = null;
- if (Chart != null && dataPointName.Length > 0)
- {
- // Split series name and point index
- int separatorIndex = dataPointName.IndexOf("\\r", StringComparison.Ordinal);
- if (separatorIndex > 0)
- {
- string seriesName = dataPointName.Substring(0, separatorIndex);
- string pointIndex = dataPointName.Substring(separatorIndex + 2);
- int index = 0;
- if (int.TryParse(pointIndex, NumberStyles.Any, CultureInfo.InvariantCulture, out index))
- {
- dataPoint = Chart.Series[seriesName].Points[index];
- }
- }
- }
- return dataPoint;
- }
- /// <summary>
- /// Gets axis by name.
- /// </summary>
- /// <param name="axisName">Axis name to find.</param>
- /// <returns>Data point.</returns>
- private Axis GetAxisByName(string axisName)
- {
- Debug.Assert(axisName != null, "GetAxisByName: handed a null axis name");
- Axis axis = null;
- try
- {
- if (Chart != null && axisName.Length > 0)
- {
- // Split series name and point index
- int separatorIndex = axisName.IndexOf("\\r", StringComparison.Ordinal);
- if (separatorIndex > 0)
- {
- string areaName = axisName.Substring(0, separatorIndex);
- string axisType = axisName.Substring(separatorIndex + 2);
- switch ((AxisName)Enum.Parse(typeof(AxisName), axisType))
- {
- case (AxisName.X):
- axis = Chart.ChartAreas[areaName].AxisX;
- break;
- case (AxisName.Y):
- axis = Chart.ChartAreas[areaName].AxisY;
- break;
- case (AxisName.X2):
- axis = Chart.ChartAreas[areaName].AxisX2;
- break;
- case (AxisName.Y2):
- axis = Chart.ChartAreas[areaName].AxisY2;
- break;
- }
- }
- }
- }
- catch (ArgumentNullException)
- {
- axis = null;
- }
- catch (ArgumentException)
- {
- axis = null;
- }
- return axis;
- }
- /// <summary>
- /// Gets data point unique name.
- /// </summary>
- /// <param name="dataPoint">Data point to get the name for.</param>
- /// <returns>Data point name.</returns>
- internal string GetDataPointName(DataPoint dataPoint)
- {
- string name = String.Empty;
- if (dataPoint.series != null)
- {
- int pointIndex = dataPoint.series.Points.IndexOf(dataPoint);
- if (pointIndex >= 0)
- {
- name = dataPoint.series.Name +
- "\\r" +
- pointIndex.ToString(CultureInfo.InvariantCulture);
- }
- }
- return name;
- }
- /// <summary>
- /// Gets axis unique name.
- /// </summary>
- /// <param name="axis">Axis to get the name for.</param>
- /// <returns>Axis name.</returns>
- private string GetAxisName(Axis axis)
- {
- string name = String.Empty;
- if (axis.ChartArea != null)
- {
- name = axis.ChartArea.Name +
- "\\r" +
- axis.AxisName.ToString();
- }
- return name;
- }
- #endregion
- #region Z Order Methods
- /// <summary>
- /// Sends an annotation to the back of all annotations.
- /// <seealso cref="BringToFront"/>
- /// </summary>
- virtual public void SendToBack()
- {
- // Find collection of annotation objects this annotation belongs too
- AnnotationCollection collection = null;
- if (Chart != null)
- {
- collection = Chart.Annotations;
- }
- // Check if annotation belongs to the group
- AnnotationGroup group = AnnotationGroup;
- if (group != null)
- {
- collection = group.Annotations;
- }
- // Check if annotation is found
- if (collection != null)
- {
- Annotation annot = collection.FindByName(this.Name);
- if (annot != null)
- {
- // Reinsert annotation at the beginning of the collection
- collection.Remove(annot);
- collection.Insert(0, annot);
- }
- }
- }
- /// <summary>
- /// Brings an annotation to the front of all annotations.
- /// <seealso cref="SendToBack"/>
- /// </summary>
- virtual public void BringToFront()
- {
- // Find collection of annotation objects this annotation belongs too
- AnnotationCollection collection = null;
- if (Chart != null)
- {
- collection = Chart.Annotations;
- }
- // Check if annotation belongs to the group
- AnnotationGroup group = AnnotationGroup;
- if (group != null)
- {
- collection = group.Annotations;
- }
- // Check if annotation is found
- if (collection != null)
- {
- Annotation annot = collection.FindByName(this.Name);
- if (annot != null)
- {
- // Reinsert annotation at the end of the collection
- collection.Remove(annot);
- collection.Add(this);
- }
- }
- }
- #endregion // Z Order Methods
- #region Group Related Methods
- #endregion // Group Related Methods
- #region SmartLabelStyle methods
- /// <summary>
- /// Adds anchor position to the list. Used to check SmartLabelStyle overlapping.
- /// </summary>
- /// <param name="list">List to add to.</param>
- internal void AddSmartLabelMarkerPositions(ArrayList list)
- {
- // Anchor position is added to the list of non-overlapped markers
- if (this.Visible && this.IsAnchorDrawn())
- {
- // Get vertical and horizontal axis
- Axis vertAxis = null;
- Axis horizAxis = null;
- GetAxes(ref vertAxis, ref horizAxis);
- // Get anchor position
- double anchorX = double.NaN;
- double anchorY = double.NaN;
- bool relativeX = false;
- bool relativeY = false;
- this.GetAnchorLocation(ref anchorX, ref anchorY, ref relativeX, ref relativeY);
- // Convert anchor location to relative coordinates
- if (!double.IsNaN(anchorX) && !double.IsNaN(anchorY))
- {
- if (!relativeX && horizAxis != null)
- {
- anchorX = horizAxis.ValueToPosition(anchorX);
- }
- if (!relativeY && vertAxis != null)
- {
- anchorY = vertAxis.ValueToPosition(anchorY);
- }
- // Apply 3D transforamtion if required
- ChartArea chartArea = null;
- if (horizAxis != null && horizAxis.ChartArea != null)
- {
- chartArea = horizAxis.ChartArea;
- }
- if (vertAxis != null && vertAxis.ChartArea != null)
- {
- chartArea = vertAxis.ChartArea;
- }
- if (chartArea != null &&
- chartArea.Area3DStyle.Enable3D == true &&
- !chartArea.chartAreaIsCurcular &&
- chartArea.requireAxes &&
- chartArea.matrix3D.IsInitialized())
- {
- // Get anotation Z coordinate (use scene depth or anchored point Z position)
- float positionZ = chartArea.areaSceneDepth;
- if (this.AnchorDataPoint != null && this.AnchorDataPoint.series != null)
- {
- float depth = 0f;
- chartArea.GetSeriesZPositionAndDepth(
- this.AnchorDataPoint.series,
- out depth,
- out positionZ);
- positionZ += depth / 2f;
- }
- // Define 3D points of annotation object
- Point3D[] annot3DPoints = new Point3D[1];
- annot3DPoints[0] = new Point3D((float)anchorX, (float)anchorY, positionZ);
- // Tranform cube coordinates
- chartArea.matrix3D.TransformPoints(annot3DPoints);
- // Get transformed coordinates
- anchorX = annot3DPoints[0].X;
- anchorY = annot3DPoints[0].Y;
- }
- // Save selection handles position in array elements 0 and 4
- if (this.GetGraphics() != null)
- {
- SizeF markerSizeRel = this.GetGraphics().GetRelativeSize(
- new SizeF(1f, 1f));
- RectangleF anchorRect = new RectangleF(
- (float)anchorX - markerSizeRel.Width / 2f,
- (float)anchorY - markerSizeRel.Height / 2f,
- markerSizeRel.Width,
- markerSizeRel.Height);
- list.Add(anchorRect);
- }
- }
- }
- }
- #endregion
- #region Public Anchoring Methods
- /// <summary>
- /// Anchors an annotation to a data point.
- /// <seealso cref="AnchorDataPoint"/>
- /// <seealso cref="AnchorX"/>
- /// <seealso cref="AnchorY"/>
- /// </summary>
- /// <param name="dataPoint">
- /// <see cref="DataPoint"/> to be anchored to.
- /// </param>
- /// <remarks>
- /// Anchors an annotation to the specified data point.
- /// </remarks>
- public void SetAnchor(DataPoint dataPoint)
- {
- SetAnchor(dataPoint, null);
- }
- /// <summary>
- /// Anchors an annotation to two data points.
- /// <seealso cref="AnchorDataPoint"/>
- /// <seealso cref="AnchorX"/>
- /// <seealso cref="AnchorY"/>
- /// </summary>
- /// <param name="dataPoint1">
- /// First anchor <see cref="DataPoint"/>.
- /// </param>
- /// <param name="dataPoint2">
- /// Second anchor <see cref="DataPoint"/>.
- /// </param>
- /// <remarks>
- /// Anchors an annotation's top/left and bottom/right corners to the
- /// specified data points.
- /// </remarks>
- public void SetAnchor(DataPoint dataPoint1, DataPoint dataPoint2)
- {
- // Set annotation position to automatic
- this.X = double.NaN;
- this.Y = double.NaN;
- // Reset anchor point if any
- this.AnchorX = double.NaN;
- this.AnchorY = double.NaN;
- // Set anchor point
- this.AnchorDataPoint = dataPoint1;
- // Get vertical and horizontal axis
- Axis vertAxis = null;
- Axis horizAxis = null;
- GetAxes(ref vertAxis, ref horizAxis);
- // Set Width and Height in axis coordinates
- if (dataPoint2 != null && dataPoint1 != null)
- {
- this._anchorDataPoint2 = dataPoint2;
- }
- // Invalidate annotation
- this.Invalidate();
- }
- #endregion // Public Anchoring Methods
- #region Placement Methods
- /// <summary>
- /// Begins end user placement of an annotation using the mouse.
- /// </summary>
- /// <remarks>
- /// When this method is called, the end user is allowed to place an annotation using the
- /// mouse.
- /// <para>
- /// Placement will finish when the end user specifies all required points, or
- /// the <see cref="EndPlacement"/> method is called.</para>
- /// </remarks>
- virtual public void BeginPlacement()
- {
- // Can't place annotations inside the group
- if (this.AnnotationGroup != null)
- {
- throw (new InvalidOperationException(SR.ExceptionAnnotationGroupedUnableToStartPlacement));
- }
- if (this.Chart != null)
- {
- // Set the annotation object which is currently placed
- this.Chart.Annotations.placingAnnotation = this;
- }
- else
- {
- throw (new InvalidOperationException(SR.ExceptionAnnotationNotInCollection));
- }
- }
- /// <summary>
- /// Ends user placement of an annotation.
- /// </summary>
- /// <remarks>
- /// Ends an annotation placement operation previously started by a
- /// <see cref="BeginPlacement"/> method call.
- /// <para>
- /// Calling this method is not required, since placement will automatically
- /// end when an end user enters all required points. However, it is useful when an annotation
- /// placement operation needs to be aborted for some reason.
- /// </para>
- /// </remarks>
- virtual public void EndPlacement()
- {
- if (this.Chart != null)
- {
- // Reset currently placed annotation object
- this.Chart.Annotations.placingAnnotation = null;
- // Restore default cursor
- this.Chart.Cursor = this.Chart.defaultCursor;
- // Clear last placement mouse position
- this.lastPlacementPosition = PointF.Empty;
- // Fire annotation placed event
- this.Chart.OnAnnotationPlaced(this);
- }
- }
- /// <summary>
- /// Handles mouse down event during annotation placement.
- /// </summary>
- /// <param name="point">Mouse cursor position in pixels.</param>
- /// <param name="buttons">Mouse button down.</param>
- internal virtual void PlacementMouseDown(PointF point, MouseButtons buttons)
- {
- if (buttons == MouseButtons.Right)
- {
- // Stop any pacement
- this.EndPlacement();
- }
- if (buttons == MouseButtons.Left &&
- IsValidPlacementPosition(point.X, point.Y))
- {
- if (this.lastPlacementPosition.IsEmpty)
- {
- // Remeber position where mouse was clicked
- this.lastPlacementPosition = this.GetGraphics().GetRelativePoint(point);
- // Get annotation position in relative coordinates
- PointF firstPoint = PointF.Empty;
- PointF anchorPoint = PointF.Empty;
- SizeF size = SizeF.Empty;
- this.GetRelativePosition(out firstPoint, out size, out anchorPoint);
- // Set annotation X, Y coordinate
- if (this.AllowMoving)
- {
- firstPoint = this.GetGraphics().GetRelativePoint(point);
- // Do not change default position
- if (double.IsNaN(this.AnchorX))
- {
- anchorPoint.X = float.NaN;
- }
- if (double.IsNaN(this.AnchorY))
- {
- anchorPoint.Y = float.NaN;
- }
- }
- else if (this.AllowAnchorMoving)
- {
- anchorPoint = this.GetGraphics().GetRelativePoint(point);
- // Do not change default position
- if (double.IsNaN(this.X))
- {
- firstPoint.X = float.NaN;
- }
- if (double.IsNaN(this.Y))
- {
- firstPoint.Y = float.NaN;
- }
- }
- // Do not change default size
- if (double.IsNaN(this.Width))
- {
- size.Width = float.NaN;
- }
- if (double.IsNaN(this.Height))
- {
- size.Height = float.NaN;
- }
- // Set annotation position
- this.positionChanged = true;
- this.SetPositionRelative(
- new RectangleF(firstPoint, size),
- anchorPoint,
- true);
- // Invalidate and update the chart
- if (Chart != null)
- {
- Invalidate();
- Chart.UpdateAnnotations();
- }
- }
- }
- }
- /// <summary>
- /// Handles mouse up event during annotation placement.
- /// </summary>
- /// <param name="point">Mouse cursor position in pixels.</param>
- /// <param name="buttons">Mouse button Up.</param>
- /// <returns>Return true when placing finished.</returns>
- internal virtual bool PlacementMouseUp(PointF point, MouseButtons buttons)
- {
- bool result = false;
- if (buttons == MouseButtons.Left)
- {
- // Get annotation position in relative coordinates
- PointF firstPoint = PointF.Empty;
- PointF anchorPoint = PointF.Empty;
- SizeF size = SizeF.Empty;
- this.GetRelativePosition(out firstPoint, out size, out anchorPoint);
- if (this.AllowResizing)
- {
- PointF pointRel = this.GetGraphics().GetRelativePoint(point);
- size = new SizeF(
- pointRel.X - this.lastPlacementPosition.X,
- pointRel.Y - this.lastPlacementPosition.Y);
- }
- else
- {
- // Do not change default size
- if (double.IsNaN(this.Width))
- {
- size.Width = float.NaN;
- }
- if (double.IsNaN(this.Height))
- {
- size.Height = float.NaN;
- }
- }
- // Do not change default position
- if (double.IsNaN(this.X))
- {
- firstPoint.X = float.NaN;
- }
- if (double.IsNaN(this.Y))
- {
- firstPoint.Y = float.NaN;
- }
- if (double.IsNaN(this.AnchorX))
- {
- anchorPoint.X = float.NaN;
- }
- if (double.IsNaN(this.AnchorY))
- {
- anchorPoint.Y = float.NaN;
- }
- // Set annotation position
- this.positionChanged = true;
- this.SetPositionRelative(
- new RectangleF(firstPoint, size),
- anchorPoint,
- true);
- // End placement
- if (!size.IsEmpty || !this.AllowResizing)
- {
- result = true;
- this.EndPlacement();
- }
- // Invalidate and update the chart
- if (Chart != null)
- {
- Invalidate();
- Chart.UpdateAnnotations();
- }
- }
- return result;
- }
- /// <summary>
- /// Handles mouse move event during annotation placement.
- /// </summary>
- /// <param name="point">Mouse cursor position in pixels.</param>
- internal virtual void PlacementMouseMove(PointF point)
- {
- // Check if annotation was moved
- if (this.GetGraphics() != null &&
- !this.lastPlacementPosition.IsEmpty)
- {
- // Get annotation position in relative coordinates
- PointF firstPoint = PointF.Empty;
- PointF anchorPoint = PointF.Empty;
- SizeF size = SizeF.Empty;
- this.GetRelativePosition(out firstPoint, out size, out anchorPoint);
- if (this.AllowResizing)
- {
- PointF pointRel = this.GetGraphics().GetRelativePoint(point);
- size = new SizeF(
- pointRel.X - this.lastPlacementPosition.X,
- pointRel.Y - this.lastPlacementPosition.Y);
- }
- // Do not change default position
- if (double.IsNaN(this.X))
- {
- firstPoint.X = float.NaN;
- }
- if (double.IsNaN(this.Y))
- {
- firstPoint.Y = float.NaN;
- }
- if (double.IsNaN(this.AnchorX))
- {
- anchorPoint.X = float.NaN;
- }
- if (double.IsNaN(this.AnchorY))
- {
- anchorPoint.Y = float.NaN;
- }
- // Set annotation position
- this.positionChanged = true;
- this.SetPositionRelative(
- new RectangleF(firstPoint, size),
- anchorPoint,
- true);
- // Invalidate and update the chart
- if (this.Chart != null)
- {
- Invalidate();
- this.Chart.UpdateAnnotations();
- }
- }
- }
- /// <summary>
- /// Checks if specified position is valid for placement.
- /// </summary>
- /// <param name="x">X coordinate.</param>
- /// <param name="y">Y coordinate.</param>
- /// <returns>True if annotation can be placed at specified coordinates.</returns>
- virtual internal bool IsValidPlacementPosition(float x, float y)
- {
- if (this.Chart != null &&
- this.GetGraphics() != null)
- {
- // Check if cursor is over the area where placement allowed
- // If so - change cursor to cross
- RectangleF placementRect = new RectangleF(0f, 0f, 100f, 100f);
- if (this.ClipToChartArea.Length > 0 &&
- this.ClipToChartArea != Constants.NotSetValue)
- {
- ChartArea area = Chart.ChartAreas[this.ClipToChartArea];
- placementRect = area.PlotAreaPosition.ToRectangleF();
- }
- placementRect = this.GetGraphics().GetAbsoluteRectangle(placementRect);
- if (placementRect.Contains(x, y))
- {
- return true;
- }
- }
- return false;
- }
- #endregion // Placement Methods
- #region Helper Methods
- /// <summary>
- /// Helper method that checks if annotation is visible.
- /// </summary>
- /// <returns>True if annotation is visible.</returns>
- internal bool IsVisible()
- {
- if (this.Visible)
- {
- if (this.Chart != null)
- {
- // Check if annotation is anchored to the data point
- ChartArea area = null;
- if (this.AnchorDataPoint != null &&
- this.AnchorDataPoint.series != null)
- {
- if (this.Chart.ChartAreas.IndexOf(this.AnchorDataPoint.series.ChartArea) >= 0)
- {
- area = this.Chart.ChartAreas[this.AnchorDataPoint.series.ChartArea];
- }
- }
- if (area == null &&
- this._anchorDataPoint2 != null &&
- this._anchorDataPoint2.series != null)
- {
- if (this.Chart.ChartAreas.IndexOf(this._anchorDataPoint2.series.ChartArea) >= 0)
- {
- area = this.Chart.ChartAreas[this._anchorDataPoint2.series.ChartArea];
- }
- }
- // Check if annotation uses chart area axis values
- if (area == null && this.AxisX != null)
- {
- area = this.AxisX.ChartArea;
- }
- if (area == null && this.AxisY != null)
- {
- area = this.AxisY.ChartArea;
- }
- // Check if associated area is visible
- if (area != null &&
- !area.Visible)
- {
- return false;
- }
- }
- return true;
- }
- return false;
- }
- /// <summary>
- /// Resets pre-calculated annotation position.
- /// </summary>
- internal void ResetCurrentRelativePosition()
- {
- this.currentPositionRel = new RectangleF(float.NaN, float.NaN, float.NaN, float.NaN);
- this.currentAnchorLocationRel = new PointF(float.NaN, float.NaN);
- }
- /// <summary>
- /// Replaces predefined keyword inside the string with their values if
- /// annotation is anchored to the data point.
- /// </summary>
- /// <param name="strOriginal">Original string with keywords.</param>
- /// <returns>Modified string.</returns>
- internal string ReplaceKeywords(string strOriginal)
- {
- if (this.AnchorDataPoint != null)
- {
- return this.AnchorDataPoint.ReplaceKeywords(strOriginal);
- }
- return strOriginal;
- }
- /// <summary>
- /// Checks if anchor point of the annotation is visible.
- /// </summary>
- /// <returns>True if anchor point is visible.</returns>
- internal bool IsAnchorVisible()
- {
- // Get axes objects
- Axis vertAxis = null;
- Axis horizAxis = null;
- GetAxes(ref vertAxis, ref horizAxis);
- // Get anchor position
- bool inRelativeAnchorX = false;
- bool inRelativeAnchorY = false;
- double anchorX = this.AnchorX;
- double anchorY = this.AnchorY;
- GetAnchorLocation(ref anchorX, ref anchorY, ref inRelativeAnchorX, ref inRelativeAnchorY);
- // Check if anchor is set
- if (!double.IsNaN(anchorX) && !double.IsNaN(anchorY))
- {
- // Check if anchor is in axes coordinates
- if (this.AnchorDataPoint != null ||
- this.AxisX != null ||
- this.AxisY != null)
- {
- // Convert anchor point to relative coordinates
- if (!inRelativeAnchorX && horizAxis != null)
- {
- anchorX = horizAxis.ValueToPosition(anchorX);
- }
- if (!inRelativeAnchorY && vertAxis != null)
- {
- anchorY = vertAxis.ValueToPosition(anchorY);
- }
- // Get chart area
- ChartArea chartArea = null;
- if (horizAxis != null)
- {
- chartArea = horizAxis.ChartArea;
- }
- if (chartArea == null && vertAxis != null)
- {
- chartArea = vertAxis.ChartArea;
- }
- // Apply 3D transforamtion if required
- if (chartArea != null && chartArea.Area3DStyle.Enable3D == true)
- {
- if (!chartArea.chartAreaIsCurcular &&
- chartArea.requireAxes &&
- chartArea.matrix3D.IsInitialized())
- {
- // Get anotation Z coordinate (use scene depth or anchored point Z position)
- float positionZ = chartArea.areaSceneDepth;
- if (this.AnchorDataPoint != null && this.AnchorDataPoint.series != null)
- {
- float depth = 0f;
- chartArea.GetSeriesZPositionAndDepth(
- this.AnchorDataPoint.series,
- out depth,
- out positionZ);
- positionZ += depth / 2f;
- }
- // Define 3D points of annotation object
- Point3D[] annot3DPoints = new Point3D[1];
- annot3DPoints[0] = new Point3D((float)anchorX, (float)anchorY, positionZ);
- // Tranform cube coordinates
- chartArea.matrix3D.TransformPoints(annot3DPoints);
- // Get transformed coordinates
- anchorX = annot3DPoints[0].X;
- anchorY = annot3DPoints[0].Y;
- }
- }
- // Get plot rectangle position and inflate it slightly
- // to solve any float rounding issues.
- RectangleF rect = chartArea.PlotAreaPosition.ToRectangleF();
- rect.Inflate(0.00001f, 0.00001f);
- // Check if anchor point is in the plotting area
- if (!rect.Contains((float)anchorX, (float)anchorY))
- {
- return false;
- }
- }
- }
- return true;
- }
- /// <summary>
- /// Returns chart graphics objects.
- /// </summary>
- /// <returns>Chart graphics object.</returns>
- internal ChartGraphics GetGraphics()
- {
- if (this.Common != null)
- {
- return this.Common.graph;
- }
- return null;
- }
- /// <summary>
- /// Checks if provided pixel coordinate is contained in one of the
- /// selection handles rectangle.
- /// </summary>
- /// <param name="point">Coordinate in pixels.</param>
- /// <returns>Resizing mode.</returns>
- internal ResizingMode GetSelectionHandle(PointF point)
- {
- ResizingMode resizingMode = ResizingMode.None;
- if (this.Common != null &&
- this.Common.graph != null)
- {
- // Convert point to relative coordinates
- point = this.Common.graph.GetRelativePoint(point);
- // Check if point is in one of the selection handles
- if (this.selectionRects != null)
- {
- for (int index = 0; index < this.selectionRects.Length; index++)
- {
- if (!this.selectionRects[index].IsEmpty &&
- this.selectionRects[index].Contains(point))
- {
- if (index > (int)ResizingMode.AnchorHandle)
- {
- resizingMode = ResizingMode.MovingPathPoints;
- this.currentPathPointIndex = index - 9;
- }
- else
- {
- resizingMode = (ResizingMode)index;
- }
- }
- }
- }
- }
- return resizingMode;
- }
- /// <summary>
- /// Gets data point X or Y axis.
- /// </summary>
- /// <param name="dataPoint">Data point to get the axis for.</param>
- /// <param name="axisName">X or Y axis to get.</param>
- /// <returns>Data point axis.</returns>
- private Axis GetDataPointAxis(DataPoint dataPoint, AxisName axisName)
- {
- if (dataPoint != null && dataPoint.series != null && Chart != null)
- {
- // Get data point chart area
- ChartArea chartArea = Chart.ChartAreas[dataPoint.series.ChartArea];
- // Get point X axis
- if ((axisName == AxisName.X || axisName == AxisName.X2) &&
- !chartArea.switchValueAxes)
- {
- return chartArea.GetAxis(axisName, dataPoint.series.XAxisType, dataPoint.series.XSubAxisName);
- }
- else
- {
- return chartArea.GetAxis(axisName, dataPoint.series.YAxisType, dataPoint.series.YSubAxisName);
- }
- }
- return null;
- }
- /// <summary>
- /// Gets annotation vertical and horizontal axes.
- /// </summary>
- /// <param name="vertAxis">Returns annotation vertical axis or null.</param>
- /// <param name="horizAxis">Returns annotation horizontal axis or null.</param>
- internal void GetAxes(ref Axis vertAxis, ref Axis horizAxis)
- {
- vertAxis = null;
- horizAxis = null;
- if (this.AxisX != null && this.AxisX.ChartArea != null)
- {
- if (this.AxisX.ChartArea.switchValueAxes)
- {
- vertAxis = this.AxisX;
- }
- else
- {
- horizAxis = this.AxisX;
- }
- }
- if (this.AxisY != null && this.AxisY.ChartArea != null)
- {
- if (this.AxisY.ChartArea.switchValueAxes)
- {
- horizAxis = this.AxisY;
- }
- else
- {
- vertAxis = this.AxisY;
- }
- }
- // Get axes from attached data point
- if (this.AnchorDataPoint != null)
- {
- if (horizAxis == null)
- {
- horizAxis = GetDataPointAxis(this.AnchorDataPoint, AxisName.X);
- // For chart types like Bar, RangeBar and others, position of X and Y axes are flipped
- if (horizAxis != null && horizAxis.ChartArea != null && horizAxis.ChartArea.switchValueAxes)
- {
- horizAxis = GetDataPointAxis(this.AnchorDataPoint, AxisName.Y);
- }
- }
- if (vertAxis == null)
- {
- vertAxis = GetDataPointAxis(this.AnchorDataPoint, AxisName.Y);
- // For chart types like Bar, RangeBar and others, position of X and Y axes are flipped
- if (vertAxis != null && vertAxis.ChartArea != null && vertAxis.ChartArea.switchValueAxes)
- {
- vertAxis = GetDataPointAxis(this.AnchorDataPoint, AxisName.X);
- }
- }
- }
- // No axes coordinate system for grouped annotations
- if (vertAxis != null || horizAxis != null)
- {
- if (this.AnnotationGroup != null)
- {
- throw (new InvalidOperationException(SR.ExceptionAnnotationGroupedAxisMustBeEmpty));
- }
- }
- }
- #endregion
- #endregion
- #region IDisposable Members
- /// <summary>
- /// Releases unmanaged and - optionally - managed resources
- /// </summary>
- /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
- protected override void Dispose(bool disposing)
- {
- if (disposing)
- {
- //Free managed resources
- if (_fontCache != null)
- {
- _fontCache.Dispose();
- _fontCache = null;
- }
- }
- base.Dispose(disposing);
- }
- #endregion
- }
- /// <summary>
- /// This class is used to stores position changing event data for an annotation.
- /// </summary>
- /// <remarks>
- /// Provides additional data like the new annotation and anchor position when an end user
- /// is moving the annotation with the mouse.
- /// <para>
- /// Can be used to restrict annotation movement, or snap the annotation position to
- /// specific points.
- /// </para>
- /// </remarks>
- [
- SRDescription("DescriptionAttributeAnnotationPositionChangingEventArgs_AnnotationPositionChangingEventArgs"),
- ]
- public class AnnotationPositionChangingEventArgs : EventArgs
- {
- #region Fields
- private Annotation _Annotation = null;
- /// <summary>
- /// Gets or sets the annotation the event is fired for.
- /// </summary>
- public Annotation Annotation
- {
- get { return _Annotation; }
- set { _Annotation = value; }
- }
- private double _NewLocationX = 0.0;
- /// <summary>
- /// Gets or sets the new X location of the annotation.
- /// </summary>
- public double NewLocationX
- {
- get { return _NewLocationX; }
- set { _NewLocationX = value; }
- }
- private double _NewLocationY = 0.0;
- /// <summary>
- /// Gets or sets the new Y location of the annotation.
- /// </summary>
- public double NewLocationY
- {
- get { return _NewLocationY; }
- set { _NewLocationY = value; }
- }
- private double _NewSizeWidth = 0.0;
- /// <summary>
- /// Gets or sets the new width of the annotation.
- /// </summary>
- public double NewSizeWidth
- {
- get { return _NewSizeWidth; }
- set { _NewSizeWidth = value; }
- }
- private double _NewSizeHeight = 0.0;
- /// <summary>
- /// Gets or sets the new height of the annotation.
- /// </summary>
- public double NewSizeHeight
- {
- get { return _NewSizeHeight; }
- set { _NewSizeHeight = value; }
- }
- private double _NewAnchorLocationX = 0.0;
- /// <summary>
- /// Gets or sets the new annotation anchor point X location.
- /// </summary>
- public double NewAnchorLocationX
- {
- get { return _NewAnchorLocationX; }
- set { _NewAnchorLocationX = value; }
- }
- private double _NewAnchorLocationY = 0.0;
- /// <summary>
- /// Gets or sets the new annotation anchor point Y location.
- /// </summary>
- public double NewAnchorLocationY
- {
- get { return _NewAnchorLocationY; }
- set { _NewAnchorLocationY = value; }
- }
- #endregion // Fields
- #region Properties
- /// <summary>
- /// Gets or sets the new location and size of the annotation.
- /// </summary>
- [
- Browsable(false),
- EditorBrowsableAttribute(EditorBrowsableState.Never),
- ]
- public RectangleF NewPosition
- {
- get
- {
- return new RectangleF(
- (float)this.NewLocationX,
- (float)this.NewLocationY,
- (float)this.NewSizeWidth,
- (float)this.NewSizeHeight);
- }
- set
- {
- this.NewLocationX = value.X;
- this.NewLocationY = value.Y;
- this.NewSizeWidth = value.Width;
- this.NewSizeHeight = value.Height;
- }
- }
- /// <summary>
- /// Gets or sets the new anchor location of the annotation.
- /// </summary>
- [
- Browsable(false),
- EditorBrowsableAttribute(EditorBrowsableState.Never),
- ]
- public PointF NewAnchorLocation
- {
- get
- {
- return new PointF(
- (float)this.NewAnchorLocationX,
- (float)this.NewAnchorLocationY);
- }
- set
- {
- this.NewAnchorLocationX = value.X;
- this.NewAnchorLocationY = value.Y;
- }
- }
- #endregion // Properties
- }
- }
|