Xamarin Public Jenkins (auto-signing) 536cd135cc Imported Upstream version 5.4.0.167
Former-commit-id: 5624ac747d633e885131e8349322922b6a59baaa
2017-08-21 15:34:15 +00:00

911 lines
25 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//-------------------------------------------------------------
// <copyright company=Microsoft Corporation>
// Copyright © Microsoft Corporation. All Rights Reserved.
// </copyright>
//-------------------------------------------------------------
// @owner=alexgor, deliant
//=================================================================
// File: LineAnnotation.cs
//
// Namespace: System.Web.UI.WebControls[Windows.Forms].Charting
//
// Classes: LineAnnotation, VerticalLineAnnotation,
// HorizontalLineAnnotation
//
// Purpose: Line annotation class.
//
// Reviewed:
//
//===================================================================
#region Used namespace
using System;
using System.Collections;
using System.Collections.Specialized;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Data;
using System.Drawing;
using System.Drawing.Design;
using System.Drawing.Text;
using System.Drawing.Drawing2D;
#if Microsoft_CONTROL
using System.Windows.Forms.DataVisualization.Charting;
using System.Windows.Forms.DataVisualization.Charting.Data;
using System.Windows.Forms.DataVisualization.Charting.ChartTypes;
using System.Windows.Forms.DataVisualization.Charting.Utilities;
using System.Windows.Forms.DataVisualization.Charting.Borders3D;
#else
using System.Web;
using System.Web.UI;
using System.Web.UI.DataVisualization.Charting;
using System.Web.UI.DataVisualization.Charting.Data;
using System.Web.UI.DataVisualization.Charting.Utilities;
#endif
#endregion
#if Microsoft_CONTROL
namespace System.Windows.Forms.DataVisualization.Charting
#else
namespace System.Web.UI.DataVisualization.Charting
#endif
{
/// <summary>
/// <b>LineAnnotation</b> is a class that represents a line annotation.
/// </summary>
[
SRDescription("DescriptionAttributeLineAnnotation_LineAnnotation"),
]
#if ASPPERM_35
[AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
[AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
#endif
public class LineAnnotation : Annotation
{
#region Fields
// Indicates that an infinitive line should be drawn through 2 specified points.
private bool _isInfinitive = false;
// Line start/end caps
private LineAnchorCapStyle _startCap = LineAnchorCapStyle.None;
private LineAnchorCapStyle _endCap = LineAnchorCapStyle.None;
#endregion
#region Construction and Initialization
/// <summary>
/// Default public constructor.
/// </summary>
public LineAnnotation()
: base()
{
this.anchorAlignment = ContentAlignment.TopLeft;
}
#endregion
#region Properties
#region Line Visual Attributes
/// <summary>
/// Gets or sets a flag that indicates if an infinitive line should be drawn.
/// </summary>
/// <value>
/// <b>True</b> if a line should be drawn infinitively through 2 points provided, <b>false</b> otherwise.
/// </value>
[
SRCategory("CategoryAttributeAppearance"),
DefaultValue(false),
SRDescription("DescriptionAttributeDrawInfinitive"),
]
virtual public bool IsInfinitive
{
get
{
return _isInfinitive;
}
set
{
_isInfinitive = value;
Invalidate();
}
}
/// <summary>
/// Gets or sets a cap style used at the start of an annotation line.
/// <seealso cref="EndCap"/>
/// </summary>
/// <value>
/// A <see cref="LineAnchorCapStyle"/> value, used for a cap style used at the start of an annotation line.
/// </value>
[
SRCategory("CategoryAttributeAppearance"),
DefaultValue(LineAnchorCapStyle.None),
SRDescription("DescriptionAttributeStartCap3"),
]
virtual public LineAnchorCapStyle StartCap
{
get
{
return _startCap;
}
set
{
_startCap = value;
Invalidate();
}
}
/// <summary>
/// Gets or sets a cap style used at the end of an annotation line.
/// <seealso cref="StartCap"/>
/// </summary>
/// <value>
/// A <see cref="LineAnchorCapStyle"/> value, used for a cap style used at the end of an annotation line.
/// </value>
[
SRCategory("CategoryAttributeAppearance"),
DefaultValue(LineAnchorCapStyle.None),
SRDescription("DescriptionAttributeStartCap3"),
]
virtual public LineAnchorCapStyle EndCap
{
get
{
return _endCap;
}
set
{
_endCap = value;
Invalidate();
}
}
#endregion
#region Non Applicable Annotation Appearance Attributes (set as Non-Browsable)
/// <summary>
/// Not applicable to this annotation type.
/// </summary>
/// <value>
/// A <see cref="ContentAlignment"/> value.
/// </value>
[
SRCategory("CategoryAttributeAppearance"),
Browsable(false),
DefaultValue(typeof(ContentAlignment), "MiddleCenter"),
]
override public ContentAlignment Alignment
{
get
{
return base.Alignment;
}
set
{
base.Alignment = value;
}
}
/// <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>
[Browsable(false)]
[EditorBrowsable(EditorBrowsableState.Never)]
public override TextStyle TextStyle
{
get
{
return base.TextStyle;
}
set
{
base.TextStyle = value;
}
}
/// <summary>
/// Not applicable to this annotation type.
/// <seealso cref="Font"/>
/// </summary>
/// <value>
/// A <see cref="Color"/> value.
/// </value>
[
SRCategory("CategoryAttributeAppearance"),
Browsable(false),
DefaultValue(typeof(Color), "Black"),
SRDescription("DescriptionAttributeForeColor"),
TypeConverter(typeof(ColorConverter)),
Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base)
]
override public Color ForeColor
{
get
{
return base.ForeColor;
}
set
{
base.ForeColor = value;
}
}
/// <summary>
/// Not applicable to this annotation type.
/// <seealso cref="ForeColor"/>
/// </summary>
/// <value>
/// A <see cref="Font"/> object.
/// </value>
[
SRCategory("CategoryAttributeAppearance"),
Browsable(false),
DefaultValue(typeof(Font), "Microsoft Sans Serif, 8pt"),
]
override public Font Font
{
get
{
return base.Font;
}
set
{
base.Font = value;
}
}
/// <summary>
/// Not applicable to this annotation type.
/// </summary>
[
SRCategory("CategoryAttributeAppearance"),
Browsable(false),
DefaultValue(typeof(Color), ""),
NotifyParentPropertyAttribute(true),
TypeConverter(typeof(ColorConverter)),
Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base)
]
override public Color BackColor
{
get
{
return base.BackColor;
}
set
{
base.BackColor = value;
}
}
/// <summary>
/// Not applicable to this annotation type.
/// </summary>
/// <value>
/// A <see cref="ChartHatchStyle"/> value.
/// </value>
[
SRCategory("CategoryAttributeAppearance"),
Browsable(false),
DefaultValue(ChartHatchStyle.None),
NotifyParentPropertyAttribute(true),
Editor(Editors.HatchStyleEditor.Editor, Editors.HatchStyleEditor.Base)
]
override public ChartHatchStyle BackHatchStyle
{
get
{
return base.BackHatchStyle;
}
set
{
base.BackHatchStyle = value;
}
}
/// <summary>
/// Not applicable to this annotation type.
/// </summary>
[
SRCategory("CategoryAttributeAppearance"),
Browsable(false),
DefaultValue(GradientStyle.None),
NotifyParentPropertyAttribute(true),
Editor(Editors.GradientEditor.Editor, Editors.GradientEditor.Base)
]
override public GradientStyle BackGradientStyle
{
get
{
return base.BackGradientStyle;
}
set
{
base.BackGradientStyle = value;
}
}
/// <summary>
/// Not applicable to this annotation type.
/// </summary>
[
SRCategory("CategoryAttributeAppearance"),
Browsable(false),
DefaultValue(typeof(Color), ""),
NotifyParentPropertyAttribute(true),
TypeConverter(typeof(ColorConverter)),
Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base)
]
override public Color BackSecondaryColor
{
get
{
return base.BackSecondaryColor;
}
set
{
base.BackSecondaryColor = value;
}
}
#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="Annotation.Width"/>
/// <seealso cref="Annotation.Height"/>
/// </summary>
/// <value>
/// <b>True</b> if an annotation's <see cref="Annotation.Width"/> and <see cref="Annotation.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="Annotation.AxisX"/> or <see cref="Annotation.AxisY"/> properties.
/// </para>
/// </remarks>
[
SRCategory("CategoryAttributePosition"),
DefaultValue(true),
SRDescription("DescriptionAttributeSizeAlwaysRelative3"),
]
override public bool IsSizeAlwaysRelative
{
get
{
return base.IsSizeAlwaysRelative;
}
set
{
base.IsSizeAlwaysRelative = value;
}
}
#endregion // Position
#region Anchor
/// <summary>
/// Gets or sets an annotation position's alignment to the anchor point.
/// <seealso cref="Annotation.AnchorX"/>
/// <seealso cref="Annotation.AnchorY"/>
/// <seealso cref="Annotation.AnchorDataPoint"/>
/// <seealso cref="Annotation.AnchorOffsetX"/>
/// <seealso cref="Annotation.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="Annotation.AnchorDataPoint"/>, or the <see cref="Annotation.AnchorX"/>
/// and <see cref="Annotation.AnchorY"/> properties. Its <see cref="Annotation.X"/> and <see cref="Annotation.Y"/>
/// properties must be set to <b>Double.NaN</b>.
/// </remarks>
[
SRCategory("CategoryAttributeAnchor"),
Browsable(false),
EditorBrowsableAttribute(EditorBrowsableState.Never),
DefaultValue(typeof(ContentAlignment), "TopLeft"),
SRDescription("DescriptionAttributeAnchorAlignment"),
]
override public ContentAlignment AnchorAlignment
{
get
{
return base.AnchorAlignment;
}
set
{
base.AnchorAlignment = value;
}
}
#endregion // Anchoring
#region Other
/// <summary>
/// Gets or sets an annotation's type name.
/// </summary>
/// <remarks>
/// This property is used to get the name of each annotation type
/// (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("DescriptionAttributeAnnotationType"),
]
public override string AnnotationType
{
get
{
return "Line";
}
}
/// <summary>
/// Gets or sets an annotation's selection points style.
/// </summary>
/// <value>
/// A <see cref="SelectionPointsStyle"/> value that represents the 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"),
]
override internal SelectionPointsStyle SelectionPointsStyle
{
get
{
return SelectionPointsStyle.TwoPoints;
}
}
#endregion
#endregion
#region Methods
/// <summary>
/// Adjusts the two coordinates of the line.
/// </summary>
/// <param name="point1">First line coordinate.</param>
/// <param name="point2">Second line coordinate.</param>
/// <param name="selectionRect">Selection rectangle.</param>
virtual internal void AdjustLineCoordinates(ref PointF point1, ref PointF point2, ref RectangleF selectionRect)
{
// Adjust line points to draw infinitive line
if(IsInfinitive)
{
if(Math.Round(point1.X , 3) == Math.Round(point2.X, 3))
{
point1.Y = (point1.Y < point2.Y) ? 0f : 100f;
point2.Y = (point1.Y < point2.Y) ? 100f : 0f;
}
else if(Math.Round(point1.Y , 3) == Math.Round(point2.Y, 3))
{
point1.X = (point1.X < point2.X) ? 0f : 100f;
point2.X = (point1.X < point2.X) ? 100f : 0f;
}
else
{
// Calculate intersection point of the line with two bounaries Y = 0 and Y = 100
PointF intersectionPoint1 = PointF.Empty;
intersectionPoint1.Y = 0f;
intersectionPoint1.X = (0f - point1.Y) *
(point2.X - point1.X) /
(point2.Y - point1.Y) +
point1.X;
PointF intersectionPoint2 = PointF.Empty;
intersectionPoint2.Y = 100f;
intersectionPoint2.X = (100f - point1.Y) *
(point2.X - point1.X) /
(point2.Y - point1.Y) +
point1.X;
// Select point closect to the intersection
point1 = (point1.Y < point2.Y) ? intersectionPoint1 : intersectionPoint2;
point2 = (point1.Y < point2.Y) ? intersectionPoint2 : intersectionPoint1;
}
}
}
/// <summary>
/// Paints an annotation object on the specified graphics.
/// </summary>
/// <param name="graphics">
/// A <see cref="ChartGraphics"/> object, used to paint an annotation object.
/// </param>
/// <param name="chart">
/// Reference to the <see cref="Chart"/> owner control.
/// </param>
override internal void Paint(Chart chart, ChartGraphics graphics)
{
// Get annotation position in relative coordinates
PointF firstPoint = PointF.Empty;
PointF anchorPoint = PointF.Empty;
SizeF size = SizeF.Empty;
GetRelativePosition(out firstPoint, out size, out anchorPoint);
PointF secondPoint = new PointF(firstPoint.X + size.Width, firstPoint.Y + size.Height);
// Create selection rectangle
RectangleF selectionRect = new RectangleF(firstPoint, new SizeF(secondPoint.X - firstPoint.X, secondPoint.Y - firstPoint.Y));
// Adjust coordinates
AdjustLineCoordinates(ref firstPoint, ref secondPoint, ref selectionRect);
// Check if text position is valid
if( float.IsNaN(firstPoint.X) ||
float.IsNaN(firstPoint.Y) ||
float.IsNaN(secondPoint.X) ||
float.IsNaN(secondPoint.Y) )
{
return;
}
// Set line caps
bool capChanged = false;
LineCap oldStartCap = LineCap.Flat;
LineCap oldEndCap = LineCap.Flat;
if(this._startCap != LineAnchorCapStyle.None ||
this._endCap != LineAnchorCapStyle.None)
{
capChanged = true;
oldStartCap = graphics.Pen.StartCap;
oldEndCap = graphics.Pen.EndCap;
// Apply anchor cap settings
if(this._startCap == LineAnchorCapStyle.Arrow)
{
// Adjust arrow size for small line width
if(this.LineWidth < 4)
{
int adjustment = 3 - this.LineWidth;
graphics.Pen.StartCap = LineCap.Custom;
graphics.Pen.CustomStartCap = new AdjustableArrowCap(
this.LineWidth + adjustment,
this.LineWidth + adjustment,
true);
}
else
{
graphics.Pen.StartCap = LineCap.ArrowAnchor;
}
}
else if(this._startCap == LineAnchorCapStyle.Diamond)
{
graphics.Pen.StartCap = LineCap.DiamondAnchor;
}
else if(this._startCap == LineAnchorCapStyle.Round)
{
graphics.Pen.StartCap = LineCap.RoundAnchor;
}
else if(this._startCap == LineAnchorCapStyle.Square)
{
graphics.Pen.StartCap = LineCap.SquareAnchor;
}
if(this._endCap == LineAnchorCapStyle.Arrow)
{
// Adjust arrow size for small line width
if(this.LineWidth < 4)
{
int adjustment = 3 - this.LineWidth;
graphics.Pen.EndCap = LineCap.Custom;
graphics.Pen.CustomEndCap = new AdjustableArrowCap(
this.LineWidth + adjustment,
this.LineWidth + adjustment,
true);
}
else
{
graphics.Pen.EndCap = LineCap.ArrowAnchor;
}
}
else if(this._endCap == LineAnchorCapStyle.Diamond)
{
graphics.Pen.EndCap = LineCap.DiamondAnchor;
}
else if(this._endCap == LineAnchorCapStyle.Round)
{
graphics.Pen.EndCap = LineCap.RoundAnchor;
}
else if(this._endCap == LineAnchorCapStyle.Square)
{
graphics.Pen.EndCap = LineCap.SquareAnchor;
}
}
if(this.Common.ProcessModePaint)
{
// Draw line
graphics.DrawLineRel(
this.LineColor,
this.LineWidth,
this.LineDashStyle,
firstPoint,
secondPoint,
this.ShadowColor,
this.ShadowOffset);
}
if(this.Common.ProcessModeRegions)
{
// Create line graphics path
using (GraphicsPath path = new GraphicsPath())
{
path.AddLine(
graphics.GetAbsolutePoint(firstPoint),
graphics.GetAbsolutePoint(secondPoint));
using (Pen pen = (Pen)graphics.Pen.Clone())
{
// Increase pen size by 2 pixels
pen.DashStyle = DashStyle.Solid;
pen.Width += 2;
try
{
path.Widen(pen);
}
catch (OutOfMemoryException)
{
// GraphicsPath.Widen incorrectly throws OutOfMemoryException
// catching here and reacting by not widening
}
catch (ArgumentException)
{
}
}
// Add hot region
this.Common.HotRegionsList.AddHotRegion(
graphics,
path,
false,
ReplaceKeywords(this.ToolTip),
#if Microsoft_CONTROL
String.Empty,
String.Empty,
String.Empty,
#else // Microsoft_CONTROL
ReplaceKeywords(this.Url),
ReplaceKeywords(this.MapAreaAttributes),
ReplaceKeywords(this.PostBackValue),
#endif // Microsoft_CONTROL
this,
ChartElementType.Annotation);
}
}
// Restore line caps
if(capChanged)
{
graphics.Pen.StartCap = oldStartCap;
graphics.Pen.EndCap = oldEndCap;
}
// Paint selection handles
PaintSelectionHandles(graphics, selectionRect, null);
}
#endregion
}
/// <summary>
/// <b>VerticalLineAnnotation</b> is a class that represents a vertical line annotation.
/// </summary>
[
SRDescription("DescriptionAttributeVerticalLineAnnotation_VerticalLineAnnotation"),
]
#if ASPPERM_35
[AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
[AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
#endif
public class VerticalLineAnnotation : LineAnnotation
{
#region Construction and Initialization
/// <summary>
/// Default public constructor.
/// </summary>
public VerticalLineAnnotation()
: base()
{
}
#endregion
#region Properties
/// <summary>
/// Gets or sets an annotation's type name.
/// </summary>
/// <remarks>
/// This property is used to get the name of each annotation type
/// (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("DescriptionAttributeAnnotationType"),
]
public override string AnnotationType
{
get
{
return "VerticalLine";
}
}
#endregion
#region Methods
/// <summary>
/// Adjusts the two coordinates of the line.
/// </summary>
/// <param name="point1">First line coordinate.</param>
/// <param name="point2">Second line coordinate.</param>
/// <param name="selectionRect">Selection rectangle.</param>
override internal void AdjustLineCoordinates(ref PointF point1, ref PointF point2, ref RectangleF selectionRect)
{
// Make line vertical
point2.X = point1.X;
selectionRect.Width = 0f;
// Call base class
base.AdjustLineCoordinates(ref point1, ref point2, ref selectionRect);
}
#region Content Size
/// <summary>
/// Gets text annotation content size based on the text and font.
/// </summary>
/// <returns>Annotation content position.</returns>
override internal RectangleF GetContentPosition()
{
return new RectangleF(float.NaN, float.NaN, 0f, float.NaN);
}
#endregion // Content Size
#endregion
}
/// <summary>
/// <b>HorizontalLineAnnotation</b> is a class that represents a horizontal line annotation.
/// </summary>
[
SRDescription("DescriptionAttributeHorizontalLineAnnotation_HorizontalLineAnnotation"),
]
#if ASPPERM_35
[AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
[AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
#endif
public class HorizontalLineAnnotation : LineAnnotation
{
#region Construction and Initialization
/// <summary>
/// Default public constructor.
/// </summary>
public HorizontalLineAnnotation()
: base()
{
}
#endregion
#region Properties
/// <summary>
/// Gets or sets an annotation's type name.
/// </summary>
/// <remarks>
/// This property is used to get the name of each annotation type
/// (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("DescriptionAttributeAnnotationType"),
]
public override string AnnotationType
{
get
{
return "HorizontalLine";
}
}
#endregion
#region Methods
/// <summary>
/// Adjusts the two coordinates of the line.
/// </summary>
/// <param name="point1">First line coordinate.</param>
/// <param name="point2">Second line coordinate.</param>
/// <param name="selectionRect">Selection rectangle.</param>
override internal void AdjustLineCoordinates(ref PointF point1, ref PointF point2, ref RectangleF selectionRect)
{
// Make line horizontal
point2.Y = point1.Y;
selectionRect.Height = 0f;
// Call base class
base.AdjustLineCoordinates(ref point1, ref point2, ref selectionRect);
}
#region Content Size
/// <summary>
/// Gets text annotation content size based on the text and font.
/// </summary>
/// <returns>Annotation content position.</returns>
override internal RectangleF GetContentPosition()
{
return new RectangleF(float.NaN, float.NaN, float.NaN, 0f);
}
#endregion // Content Size
#endregion
}
}