//------------------------------------------------------------- // // Copyright � Microsoft Corporation. All Rights Reserved. // //------------------------------------------------------------- // @owner=alexgor, deliant //================================================================= // File: EmbedBorder.cs // // Namespace: System.Web.UI.WebControls[Windows.Forms].Charting.Borders3D // // Classes: EmbedBorder, FrameTitle1Border, FrameTitle2Border, // FrameTitle3Border, FrameTitle4Border, FrameTitle5Border, // FrameTitle6Border, FrameTitle7Border, FrameTitle8Border, // FrameThin2Border, FrameThin3Border, FrameThin4Border, // FrameThin5Border, FrameThin6Border, FrameThin1Border, // RaisedBorder, SunkenBorder // // Purpose: Classes that implement different 3D border styles. // // Reviewed: AG - August 7, 2002 // //=================================================================== #region Used namespaces using System; using System.Resources; using System.Reflection; using System.Collections; using System.Drawing; using System.Drawing.Drawing2D; using System.ComponentModel.Design; #if WINFORMS_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.UI.DataVisualization.Charting; using System.Web.UI.DataVisualization.Charting.Data; using System.Web.UI.DataVisualization.Charting.Utilities; #endif #endregion #if WINFORMS_CONTROL namespace System.Windows.Forms.DataVisualization.Charting.Borders3D #else namespace System.Web.UI.DataVisualization.Charting.Borders3D #endif { /// /// Implements frame border. /// internal class FrameTitle1Border : FrameThin1Border { #region Border properties and methods /// /// Default constructor /// public FrameTitle1Border() { sizeLeftTop = new SizeF(sizeLeftTop.Width, defaultRadiusSize*2f); } /// /// Chart type name /// public override string Name { get{ return "FrameTitle1";}} public override float Resolution { set { base.Resolution = value; sizeLeftTop = new SizeF(sizeLeftTop.Width, defaultRadiusSize * 2f); } } /// /// Returns the position of the rectangular area in the border where /// title should be displayed. Returns empty rect if title can't be shown in the border. /// /// Title position in border. public override RectangleF GetTitlePositionInBorder() { return new RectangleF( defaultRadiusSize * 0.25f, defaultRadiusSize * 0.25f, defaultRadiusSize * 0.25f, defaultRadiusSize * 1.6f); } #endregion } /// /// Implements frame border. /// internal class FrameTitle2Border : FrameThin2Border { #region Border properties and methods /// /// Default constructor /// public FrameTitle2Border() { sizeLeftTop = new SizeF(sizeLeftTop.Width, defaultRadiusSize*2f); } /// /// Chart type name /// public override string Name { get{ return "FrameTitle2";}} public override float Resolution { set { base.Resolution = value; sizeLeftTop = new SizeF(sizeLeftTop.Width, defaultRadiusSize * 2f); } } /// /// Returns the position of the rectangular area in the border where /// title should be displayed. Returns empty rect if title can't be shown in the border. /// /// Title position in border. public override RectangleF GetTitlePositionInBorder() { return new RectangleF( defaultRadiusSize * 0.25f, defaultRadiusSize * 0.25f, defaultRadiusSize * 0.25f, defaultRadiusSize * 1.6f); } #endregion } /// /// Implements frame border. /// internal class FrameTitle3Border : FrameThin3Border { #region Border properties and methods /// /// Default constructor /// public FrameTitle3Border() { sizeLeftTop = new SizeF(sizeLeftTop.Width, defaultRadiusSize*2f); } /// /// Chart type name /// public override string Name { get{ return "FrameTitle3";}} public override float Resolution { set { base.Resolution = value; sizeLeftTop = new SizeF(sizeLeftTop.Width, defaultRadiusSize * 2f); } } /// /// Returns the position of the rectangular area in the border where /// title should be displayed. Returns empty rect if title can't be shown in the border. /// /// Title position in border. public override RectangleF GetTitlePositionInBorder() { return new RectangleF( defaultRadiusSize * 0.25f, defaultRadiusSize * 0.25f, defaultRadiusSize * 0.25f, defaultRadiusSize * 1.6f); } #endregion } /// /// Implements frame border. /// internal class FrameTitle4Border : FrameThin4Border { #region Border properties and methods /// /// Default constructor /// public FrameTitle4Border() { sizeLeftTop = new SizeF(sizeLeftTop.Width, defaultRadiusSize*2f); } /// /// Chart type name /// public override string Name { get{ return "FrameTitle4";}} public override float Resolution { set { base.Resolution = value; sizeLeftTop = new SizeF(sizeLeftTop.Width, defaultRadiusSize * 2f); } } /// /// Returns the position of the rectangular area in the border where /// title should be displayed. Returns empty rect if title can't be shown in the border. /// /// Title position in border. public override RectangleF GetTitlePositionInBorder() { return new RectangleF( defaultRadiusSize * 0.25f, defaultRadiusSize * 0.25f, defaultRadiusSize * 0.25f, defaultRadiusSize * 1.6f); } #endregion } /// /// Implements frame border. /// internal class FrameTitle5Border : FrameThin5Border { #region Border properties and methods /// /// Default constructor /// public FrameTitle5Border() { sizeLeftTop = new SizeF(sizeLeftTop.Width, defaultRadiusSize*2f); this.drawScrews = true; } /// /// Chart type name /// public override string Name { get{ return "FrameTitle5";}} public override float Resolution { set { base.Resolution = value; sizeLeftTop = new SizeF(sizeLeftTop.Width, defaultRadiusSize * 2f); } } /// /// Returns the position of the rectangular area in the border where /// title should be displayed. Returns empty rect if title can't be shown in the border. /// /// Title position in border. public override RectangleF GetTitlePositionInBorder() { return new RectangleF( defaultRadiusSize * 0.25f, defaultRadiusSize * 0.25f, defaultRadiusSize * 0.25f, defaultRadiusSize * 1.6f); } #endregion } /// /// Implements frame border. /// internal class FrameTitle6Border : FrameThin6Border { #region Border properties and methods /// /// Default constructor /// public FrameTitle6Border() { sizeLeftTop = new SizeF(sizeLeftTop.Width, defaultRadiusSize*2f); } /// /// Chart type name /// public override string Name { get{ return "FrameTitle6";}} public override float Resolution { set { base.Resolution = value; sizeLeftTop = new SizeF(sizeLeftTop.Width, defaultRadiusSize * 2f); } } /// /// Returns the position of the rectangular area in the border where /// title should be displayed. Returns empty rect if title can't be shown in the border. /// /// Title position in border. public override RectangleF GetTitlePositionInBorder() { return new RectangleF( defaultRadiusSize * 0.25f, defaultRadiusSize * 0.25f, defaultRadiusSize * 0.25f, defaultRadiusSize * 1.6f); } #endregion } /// /// Implements frame border. /// internal class FrameTitle7Border : FrameTitle1Border { #region Border properties and methods /// /// Default constructor /// public FrameTitle7Border() { this.sizeRightBottom = new SizeF(0, sizeRightBottom.Height); float[] corners = {15f, 1f, 1f, 1f, 1f, 15f, 15f, 15f}; innerCorners = corners; } /// /// Chart type name /// public override string Name { get{ return "FrameTitle7";}} public override float Resolution { set { base.Resolution = value; this.sizeRightBottom = new SizeF(0, sizeRightBottom.Height); float largeRadius = 15f * resolution / 96.0f; float smallRadius = 1 * resolution / 96.0f; float[] corners = { largeRadius, smallRadius, smallRadius, smallRadius, smallRadius, largeRadius, largeRadius, largeRadius }; innerCorners = corners; } } #endregion } /// /// Implements frame border. /// internal class FrameTitle8Border : FrameTitle1Border { #region Border properties and methods /// /// Default constructor /// public FrameTitle8Border() { this.sizeLeftTop = new SizeF(0, sizeLeftTop.Height); this.sizeRightBottom = new SizeF(0, sizeRightBottom.Height); float[] corners = {1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f}; innerCorners = corners; } /// /// Chart type name /// public override string Name { get{ return "FrameTitle8";}} public override float Resolution { set { base.Resolution = value; this.sizeLeftTop = new SizeF(0, sizeLeftTop.Height); this.sizeRightBottom = new SizeF(0, sizeRightBottom.Height); float radius = 1 * resolution / 96.0f; float[] corners = { radius, radius, radius, radius, radius, radius, radius, radius }; innerCorners = corners; } } #endregion } /// /// Implements frame border. /// internal class FrameThin2Border : FrameThin1Border { #region Border properties and methods /// /// Default constructor /// public FrameThin2Border() { float[] corners = {15f, 15f, 15f, 1f, 1f, 1f, 1f, 15f}; cornerRadius = corners; innerCorners = corners; } /// /// Chart type name /// public override string Name { get{ return "FrameThin2";}} public override float Resolution { set { base.Resolution = value; float largeRadius = 15f * resolution / 96.0f; float smallRadius = 1 * resolution / 96.0f; float[] corners = { largeRadius, largeRadius, largeRadius, smallRadius, smallRadius, smallRadius, smallRadius, largeRadius }; cornerRadius = corners; innerCorners = corners; } } #endregion } /// /// Implements frame border. /// internal class FrameThin3Border : FrameThin1Border { #region Border properties and methods /// /// Default constructor /// public FrameThin3Border() { float[] corners = {1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f}; cornerRadius = corners; innerCorners = corners; } /// /// Chart type name /// public override string Name { get{ return "FrameThin3";}} public override float Resolution { set { base.Resolution = value; float radius = resolution / 96.0f; float[] corners = { radius, radius, radius, radius, radius, radius, radius, radius }; cornerRadius = corners; innerCorners = corners; } } #endregion } /// /// Implements frame border. /// internal class FrameThin4Border : FrameThin1Border { #region Border properties and methods /// /// Default constructor /// public FrameThin4Border() { float[] corners = {1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f}; cornerRadius = corners; } /// /// Chart type name /// public override string Name { get{ return "FrameThin4";}} public override float Resolution { set { base.Resolution = value; float radius = 1f * resolution / 96.0f; cornerRadius = new float[] { radius, radius, radius, radius, radius, radius, radius, radius }; } } #endregion } /// /// Implements frame border. /// internal class FrameThin5Border : FrameThin1Border { #region Border properties and methods /// /// Default constructor /// public FrameThin5Border() { drawScrews = true; } /// /// Chart type name /// public override string Name { get{ return "FrameThin5";}} #endregion } /// /// Implements frame border. /// internal class FrameThin6Border : FrameThin1Border { #region Border properties and methods /// /// Default constructor /// public FrameThin6Border() { float[] corners = {1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f}; innerCorners = corners; } /// /// Chart type name /// public override string Name { get{ return "FrameThin6";}} public override float Resolution { set { base.Resolution = value; float radius = resolution / 96.0f; float[] corners = { radius, radius, radius, radius, radius, radius, radius, radius }; innerCorners = corners; } } #endregion } /// /// Implements frame border. /// internal class FrameThin1Border : RaisedBorder { #region Border properties and methods /// /// Inner corners radius array /// internal float[] innerCorners = { 15f, 15f, 15f, 15f, 15f, 15f, 15f, 15f }; /// /// Default constructor /// public FrameThin1Border() { sizeLeftTop = new SizeF(defaultRadiusSize * .8f, defaultRadiusSize * .8f); sizeRightBottom = new SizeF(defaultRadiusSize * .8f, defaultRadiusSize * .8f); } /// /// Chart type name /// public override string Name { get{ return "FrameThin1";}} public override float Resolution { set { base.Resolution = value; float radius = 15.0f * resolution / 96.0f; innerCorners = new float[] { radius, radius, radius, radius, radius, radius, radius, radius }; sizeLeftTop = new SizeF(defaultRadiusSize * .8f, defaultRadiusSize * .8f); sizeRightBottom = new SizeF(defaultRadiusSize * .8f, defaultRadiusSize * .8f); } } /// /// Draws 3D border. /// /// Graphics to draw the border on. /// Border skin object. /// Rectangle of the border. /// Color of rectangle /// Hatch style /// Back Image /// Image mode /// Image transparent color. /// Image alignment /// Gradient type /// Gradient End Color /// Border Color /// Border Width /// Border Style public override void DrawBorder( ChartGraphics graph, BorderSkin borderSkin, RectangleF rect, Color backColor, ChartHatchStyle backHatchStyle, string backImage, ChartImageWrapMode backImageWrapMode, Color backImageTransparentColor, ChartImageAlignmentStyle backImageAlign, GradientStyle backGradientStyle, Color backSecondaryColor, Color borderColor, int borderWidth, ChartDashStyle borderDashStyle) { drawBottomShadow = true; sunken = false; outsideShadowRate = .9f; drawOutsideTopLeftShadow = false; bool oldScrewsFlag = this.drawScrews; this.drawScrews = false; base.DrawBorder( graph, borderSkin, rect, borderSkin.BackColor, borderSkin.BackHatchStyle, borderSkin.BackImage, borderSkin.BackImageWrapMode, borderSkin.BackImageTransparentColor, borderSkin.BackImageAlignment, borderSkin.BackGradientStyle, borderSkin.BackSecondaryColor, borderSkin.BorderColor, borderSkin.BorderWidth, borderSkin.BorderDashStyle); this.drawScrews = oldScrewsFlag; rect.X += sizeLeftTop.Width; rect.Y += sizeLeftTop.Height; rect.Width -= sizeRightBottom.Width + sizeLeftTop.Width; rect.Height -= sizeRightBottom.Height + sizeLeftTop.Height; if(rect.Width > 0 && rect.Height > 0 ) { float[] oldCorners = new float[8]; oldCorners = (float[])cornerRadius.Clone(); cornerRadius = innerCorners; drawBottomShadow = false; sunken = true; drawOutsideTopLeftShadow = true; outsideShadowRate = 1.4f; Color oldPageColor = borderSkin.PageColor; borderSkin.PageColor = Color.Transparent; base.DrawBorder( graph, borderSkin, rect, backColor, backHatchStyle, backImage, backImageWrapMode, backImageTransparentColor, backImageAlign, backGradientStyle, backSecondaryColor, borderColor, borderWidth, borderDashStyle ); borderSkin.PageColor = oldPageColor; cornerRadius = oldCorners; } } #endregion } /// /// Implements raised border. /// internal class RaisedBorder : SunkenBorder { #region Border properties and methods /// /// Public constructor /// public RaisedBorder() { sunken = false; } /// /// Chart type name /// public override string Name { get{ return "Raised";}} #endregion } /// /// Implements embed 3D border. /// internal class SunkenBorder : IBorderType { #region Border properties and methods /// /// Radius for rounded rectangle /// internal float defaultRadiusSize = 15f; /// /// Outside shadow rate /// internal float outsideShadowRate = .9f; /// /// Indicates that sunken shadows should be drawn /// internal bool sunken = true; /// /// Indicates that bottom shadow should be drawn /// internal bool drawBottomShadow = true; /// /// Indicates that top left outside dark shadow must be drawn /// internal bool drawOutsideTopLeftShadow = false; /// /// Array of corner radius /// internal float[] cornerRadius = { 15f, 15f, 15f, 15f, 15f, 15f, 15f, 15f }; /// /// Border top/left size /// internal SizeF sizeLeftTop = SizeF.Empty; /// /// Border right/bottom size /// internal SizeF sizeRightBottom = SizeF.Empty; /// /// Indicates that ----s should be drawn in the corners of the frame /// internal bool drawScrews = false; internal float resolution = 96f; /// /// Public constructor /// public SunkenBorder() { } /// /// Chart type name /// public virtual string Name { get{ return "Sunken";}} public virtual float Resolution { set { resolution = value; defaultRadiusSize = 15 * resolution / 96; //X = defaultRadiusSize; //Y = defaultRadiusSize; cornerRadius = new float[] { defaultRadiusSize, defaultRadiusSize, defaultRadiusSize, defaultRadiusSize, defaultRadiusSize, defaultRadiusSize, defaultRadiusSize, defaultRadiusSize }; } } /// /// Returns the position of the rectangular area in the border where /// title should be displayed. Returns empty rect if title can't be shown in the border. /// /// Title position in border. public virtual RectangleF GetTitlePositionInBorder() { return RectangleF.Empty; } /// /// Adjust areas rectangle coordinate to fit the 3D border /// /// Graphics to draw the border on. /// Position to adjust. public virtual void AdjustAreasPosition(ChartGraphics graph, ref RectangleF areasRect) { SizeF relSizeLeftTop = new SizeF(sizeLeftTop); SizeF relSizeRightBottom = new SizeF(sizeRightBottom); relSizeLeftTop.Width += defaultRadiusSize * 0.7f; relSizeLeftTop.Height += defaultRadiusSize * 0.85f; relSizeRightBottom.Width += defaultRadiusSize * 0.7f; relSizeRightBottom.Height += defaultRadiusSize * 0.7f; relSizeLeftTop = graph.GetRelativeSize(relSizeLeftTop); relSizeRightBottom = graph.GetRelativeSize(relSizeRightBottom); if(relSizeLeftTop.Width > 30f) relSizeLeftTop.Width = 0; if(relSizeLeftTop.Height > 30f) relSizeLeftTop.Height = 0; if(relSizeRightBottom.Width > 30f) relSizeRightBottom.Width = 0; if(relSizeRightBottom.Height > 30f) relSizeRightBottom.Height = 0; areasRect.X += relSizeLeftTop.Width; areasRect.Width -= (float)Math.Min(areasRect.Width, relSizeLeftTop.Width + relSizeRightBottom.Width); areasRect.Y += relSizeLeftTop.Height; areasRect.Height -= (float)Math.Min(areasRect.Height, relSizeLeftTop.Height + relSizeRightBottom.Height); if(areasRect.Right > 100f) { if(areasRect.Width > 100f - areasRect.Right) areasRect.Width -= 100f - areasRect.Right; else areasRect.X -= 100f - areasRect.Right; } if(areasRect.Bottom > 100f) { if(areasRect.Height > 100f - areasRect.Bottom) areasRect.Height -= 100f - areasRect.Bottom; else areasRect.Y -= 100f - areasRect.Bottom; } } /// /// Draws 3D border /// /// Graphics to draw the border on. /// Border skin object. /// Rectangle of the border. /// Color of rectangle /// Hatch style /// Back Image /// Image mode /// Image transparent color. /// Image alignment /// Gradient type /// Gradient End Color /// Border Color /// Border Width /// Border Style public virtual void DrawBorder( ChartGraphics graph, BorderSkin borderSkin, RectangleF rect, Color backColor, ChartHatchStyle backHatchStyle, string backImage, ChartImageWrapMode backImageWrapMode, Color backImageTransparentColor, ChartImageAlignmentStyle backImageAlign, GradientStyle backGradientStyle, Color backSecondaryColor, Color borderColor, int borderWidth, ChartDashStyle borderDashStyle) { RectangleF absolute = graph.Round( rect ); RectangleF shadowRect = absolute; // Calculate shadow colors (0.2 - 0.6) float colorDarkeningIndex = 0.3f + (0.4f * (borderSkin.PageColor.R + borderSkin.PageColor.G + borderSkin.PageColor.B) / 765f); Color shadowColor = Color.FromArgb( (int)(backColor.R*colorDarkeningIndex), (int)(backColor.G*colorDarkeningIndex), (int)(backColor.B*colorDarkeningIndex)); colorDarkeningIndex += 0.2f; Color shadowLightColor = Color.FromArgb( (int)(borderSkin.PageColor.R*colorDarkeningIndex), (int)(borderSkin.PageColor.G*colorDarkeningIndex), (int)(borderSkin.PageColor.B*colorDarkeningIndex)); if(borderSkin.PageColor == Color.Transparent) { shadowLightColor = Color.FromArgb(60, 0, 0, 0); } // Calculate rounded rect radius float radius = defaultRadiusSize; radius = (float)Math.Max(radius, 2f * resolution / 96.0f); radius = (float)Math.Min(radius, rect.Width/2f); radius = (float)Math.Min(radius, rect.Height/2f); radius = (float)Math.Ceiling(radius); // Fill page background color using (Brush brush = new SolidBrush(borderSkin.PageColor)) { graph.FillRectangle(brush, rect); } if(drawOutsideTopLeftShadow) { // Top/Left outside shadow shadowRect = absolute; shadowRect.X -= radius * 0.3f; shadowRect.Y -= radius * 0.3f; shadowRect.Width -= radius * .3f; shadowRect.Height -= radius * .3f; graph.DrawRoundedRectShadowAbs(shadowRect, cornerRadius, radius, Color.FromArgb(128, Color.Black), borderSkin.PageColor, outsideShadowRate); } // Bottom/Right outside shadow shadowRect = absolute; shadowRect.X += radius * 0.3f; shadowRect.Y += radius * 0.3f; shadowRect.Width -= radius * .3f; shadowRect.Height -= radius * .3f; graph.DrawRoundedRectShadowAbs(shadowRect, cornerRadius, radius, shadowLightColor, borderSkin.PageColor, outsideShadowRate); // Background shadowRect = absolute; shadowRect.Width -= radius * .3f; shadowRect.Height -= radius * .3f; GraphicsPath path = graph.CreateRoundedRectPath(shadowRect, cornerRadius); graph.DrawPathAbs( path, backColor, backHatchStyle, backImage, backImageWrapMode, backImageTransparentColor, backImageAlign, backGradientStyle, backSecondaryColor, borderColor, borderWidth, borderDashStyle, PenAlignment.Inset ); // Dispose Graphic path if( path != null ) path.Dispose(); // Draw ----s imitation in the corners of the farame if(drawScrews) { // Left/Top ---- RectangleF screwRect = RectangleF.Empty; float offset = radius * 0.4f; screwRect.X = shadowRect.X + offset; screwRect.Y = shadowRect.Y + offset; screwRect.Width = radius * 0.55f; screwRect.Height = screwRect.Width; DrawScrew(graph, screwRect); // Right/Top ---- screwRect.X = shadowRect.Right - offset - screwRect.Width; DrawScrew(graph, screwRect); // Right/Bottom ---- screwRect.X = shadowRect.Right - offset - screwRect.Width; screwRect.Y = shadowRect.Bottom - offset - screwRect.Height; DrawScrew(graph, screwRect); // Left/Bottom ---- screwRect.X = shadowRect.X + offset; screwRect.Y = shadowRect.Bottom - offset - screwRect.Height; DrawScrew(graph, screwRect); } // Bottom/Right inner shadow Region innerShadowRegion = null; if(drawBottomShadow) { shadowRect = absolute; shadowRect.Width -= radius * .3f; shadowRect.Height -= radius * .3f; innerShadowRegion = new Region( graph.CreateRoundedRectPath( new RectangleF( shadowRect.X - radius, shadowRect.Y - radius, shadowRect.Width + 0.5f*radius, shadowRect.Height + 0.5f*radius), cornerRadius)); innerShadowRegion.Complement(graph.CreateRoundedRectPath(shadowRect, cornerRadius)); graph.Clip = innerShadowRegion; shadowRect.X -= 0.5f*radius; shadowRect.Width += 0.5f*radius; shadowRect.Y -= 0.5f*radius; shadowRect.Height += 0.5f*radius; graph.DrawRoundedRectShadowAbs( shadowRect, cornerRadius, radius, Color.Transparent, Color.FromArgb(175, (sunken) ? Color.White : shadowColor), 1.0f); graph.Clip = new Region(); } // Top/Left inner shadow shadowRect = absolute; shadowRect.Width -= radius * .3f; shadowRect.Height -= radius * .3f; innerShadowRegion = new Region( graph.CreateRoundedRectPath( new RectangleF( shadowRect.X + radius*.5f, shadowRect.Y + radius*.5f, shadowRect.Width - .2f*radius, shadowRect.Height - .2f*radius), cornerRadius)); RectangleF shadowWithOffset = shadowRect; shadowWithOffset.Width += radius; shadowWithOffset.Height += radius; innerShadowRegion.Complement(graph.CreateRoundedRectPath(shadowWithOffset, cornerRadius)); innerShadowRegion.Intersect(graph.CreateRoundedRectPath(shadowRect, cornerRadius)); graph.Clip = innerShadowRegion; graph.DrawRoundedRectShadowAbs( shadowWithOffset, cornerRadius, radius, Color.Transparent, Color.FromArgb(175, (sunken) ? shadowColor : Color.White), 1.0f); graph.Clip = new Region(); } /// /// Helper function, which draws a ---- on the frame /// /// Chart graphics to use. /// ---- position. private void DrawScrew(ChartGraphics graph, RectangleF rect) { // Draw ---- Pen screwPen = new Pen(Color.FromArgb(128,255,255,255), 1); graph.DrawEllipse(screwPen, rect.X, rect.Y, rect.Width, rect.Height); graph.DrawLine(screwPen, rect.X + 2 * resolution / 96.0f, rect.Y + rect.Height - 2 * resolution / 96.0f, rect.Right - 2 * resolution / 96.0f, rect.Y + 2 * resolution / 96.0f); screwPen = new Pen(Color.FromArgb(128, Color.Black), 1); graph.DrawEllipse(screwPen, rect.X + 1 * resolution / 96.0f, rect.Y + 1 * resolution / 96.0f, rect.Width, rect.Height); graph.DrawLine(screwPen, rect.X + 3 * resolution / 96.0f, rect.Y + rect.Height - 1 * resolution / 96.0f, rect.Right - 1 * resolution / 96.0f, rect.Y + 3 * resolution / 96.0f); } #endregion } }