using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Drawing.Drawing2D; using DevComponents.DotNetBar.Charts.Style; namespace DevComponents.DotNetBar.Charts { #region ChartMajorGridLines #region ChartMajorGridLinesX /// /// Represents a chart's MajorGridLines for the X-Axis. /// public class ChartMajorGridLinesX : ChartMajorGridLines { public ChartMajorGridLinesX() : base(AxisOrientation.X) { } #region RenderOverride protected override void RenderOverride(ChartRenderInfo renderInfo) { if (Visible == true) { TickmarkTick[] ticks = TickmarkLayout.Ticks; if (ticks != null) { Graphics g = renderInfo.Graphics; ChartAxis axis = Parent as ChartAxis; ChartXy chartXy = axis.Parent as ChartXy; PieGridLineVisualStyle gstyle = EffectiveStyle; Rectangle scContentBounds = GetScrollBounds(chartXy.ContentBounds); if (gstyle.LinePattern != LinePattern.None && gstyle.LinePattern != LinePattern.NotSet && gstyle.LineWidth > 0) { using (Pen pen = new Pen(gstyle.LineColor, Dpi.Width(gstyle.LineWidth))) { pen.DashStyle = (DashStyle)gstyle.LinePattern; Point pt = chartXy.GetLocalAdjustedPoint(Point.Empty); foreach (TickmarkTick tmi in ticks) { Point pt1 = tmi.TickPoint; pt1.X += pt.X; pt1.Y = scContentBounds.Y; Point pt2 = pt1; pt2.Y = scContentBounds.Bottom; g.DrawLine(pen, pt1, pt2); } } } } } } #endregion #region Copy/CopyTo /// /// Create a copy of the MajorGridLine. /// /// public override ChartVisualElement Copy() { ChartMajorGridLinesX copy = new ChartMajorGridLinesX(); CopyTo(copy); return (copy); } /// /// Copies the MajorGridLine to the given "copy". /// /// public override void CopyTo(ChartVisualElement copy) { ChartMajorGridLinesX c = copy as ChartMajorGridLinesX; if (c != null) base.CopyTo(c); } #endregion } #endregion #region ChartMajorGridLinesY /// /// Represents a chart's MajorGridLines for the Y-Axis. /// public class ChartMajorGridLinesY : ChartMajorGridLines { public ChartMajorGridLinesY() : base(AxisOrientation.Y) { } #region RenderOverride protected override void RenderOverride(ChartRenderInfo renderInfo) { if (Visible == true) { TickmarkTick[] ticks = TickmarkLayout.Ticks; if (ticks != null) { Graphics g = renderInfo.Graphics; ChartAxis axis = Parent as ChartAxis; ChartXy chartXy = axis.Parent as ChartXy; PieGridLineVisualStyle gstyle = EffectiveStyle; Rectangle scContentBounds = GetScrollBounds(chartXy.ContentBounds); if (gstyle.LinePattern != LinePattern.None && gstyle.LinePattern != LinePattern.NotSet && gstyle.LineWidth > 0) { using (Pen pen = new Pen(gstyle.LineColor, Dpi.Height(gstyle.LineWidth))) { pen.DashStyle = (DashStyle)gstyle.LinePattern; Point pt = chartXy.GetLocalAdjustedPoint(Point.Empty); foreach (TickmarkTick tmi in ticks) { Point pt1 = tmi.TickPoint; pt1.X = scContentBounds.X; pt1.Y += pt.Y; Point pt2 = pt1; pt2.X = scContentBounds.Right; g.DrawLine(pen, pt1, pt2); } } } } } } #endregion #region Copy/CopyTo /// /// Create a copy of the MajorGridLine. /// /// public override ChartVisualElement Copy() { ChartMajorGridLinesY copy = new ChartMajorGridLinesY(); CopyTo(copy); return (copy); } /// /// Copies the MajorGridLine to the given "copy". /// /// public override void CopyTo(ChartVisualElement copy) { ChartMajorGridLinesY c = copy as ChartMajorGridLinesY; if (c != null) base.CopyTo(c); } #endregion } #endregion #region ChartMajorGridLines /// /// Represents a chart's MajorGridLines. /// public class ChartMajorGridLines : ChartGridLines { public ChartMajorGridLines(AxisOrientation orientation) : base(orientation) { } } #endregion #endregion #region ChartMinorGridLines #region ChartMinorGridLinesX public class ChartMinorGridLinesX : ChartMinorGridLines { public ChartMinorGridLinesX() : base(AxisOrientation.X) { } #region RenderOverride protected override void RenderOverride(ChartRenderInfo renderInfo) { if (Visible == true) { TickmarkTick[] ticks = TickmarkLayout.Ticks; if (ticks != null && ticks.Length > 1) { Graphics g = renderInfo.Graphics; ChartAxis axis = Parent as ChartAxis; ChartXy chartXy = axis.Parent as ChartXy; PieGridLineVisualStyle gstyle = EffectiveStyle; Rectangle scContentBounds = GetScrollBounds(chartXy.ContentBounds); if (gstyle.LinePattern != LinePattern.None && gstyle.LinePattern != LinePattern.NotSet && gstyle.LineWidth > 0) { using (Pen pen = new Pen(gstyle.LineColor, Dpi.Width(gstyle.LineWidth))) { pen.DashStyle = (DashStyle)gstyle.LinePattern; int minorTickCount = axis.MinorTickmarks.TickmarkCount; Point pt = chartXy.GetLocalAdjustedPoint(Point.Empty); for (int i = 0; i < ticks.Length - 1; i++) { TickmarkTick tick = ticks[i]; Point pt1 = tick.TickPoint; pt1.Y = scContentBounds.Y; Point pt2 = pt1; pt2.Y = scContentBounds.Bottom; double dx = (double)(ticks[i + 1].TickPoint.X - tick.TickPoint.X) / (minorTickCount + 1); double ddx = dx; for (int j = 0; j < minorTickCount; j++) { pt1.X = pt.X + (int)(tick.TickPoint.X + ddx); pt2.X = pt1.X; ddx += dx; g.DrawLine(pen, pt1, pt2); } } } } } } } #endregion #region Copy/CopyTo /// /// Create a copy of the MinorGridLine. /// /// public override ChartVisualElement Copy() { ChartMinorGridLinesX copy = new ChartMinorGridLinesX(); CopyTo(copy); return (copy); } /// /// Copies the MinorGridLine to the given "copy". /// /// public override void CopyTo(ChartVisualElement copy) { ChartMinorGridLinesX c = copy as ChartMinorGridLinesX; if (c != null) base.CopyTo(c); } #endregion } #endregion #region ChartMinorGridLinesY public class ChartMinorGridLinesY : ChartMinorGridLines { public ChartMinorGridLinesY() : base(AxisOrientation.Y) { } #region RenderOverride protected override void RenderOverride(ChartRenderInfo renderInfo) { if (Visible == true) { TickmarkTick[] ticks = TickmarkLayout.Ticks; if (ticks != null) { Graphics g = renderInfo.Graphics; ChartAxis axis = Parent as ChartAxis; ChartXy chartXy = axis.Parent as ChartXy; PieGridLineVisualStyle gstyle = EffectiveStyle; Rectangle scContentBounds = GetScrollBounds(chartXy.ContentBounds); if (gstyle.LinePattern != LinePattern.None && gstyle.LinePattern != LinePattern.NotSet && gstyle.LineWidth > 0) { using (Pen pen = new Pen(gstyle.LineColor, Dpi.Height(gstyle.LineWidth))) { pen.DashStyle = (DashStyle)gstyle.LinePattern; int minorTickCount = axis.MinorTickmarks.TickmarkCount; Point pt = chartXy.GetLocalAdjustedPoint(Point.Empty); for (int i = 0; i < ticks.Length - 1; i++) { TickmarkTick tick = ticks[i]; Point pt1 = tick.TickPoint; pt1.X = scContentBounds.X; Point pt2 = pt1; pt2.X = scContentBounds.Right; double dy = (double)(ticks[i + 1].TickPoint.Y - tick.TickPoint.Y) / (minorTickCount + 1); double ddy = dy; for (int j = 0; j < axis.MinorTickmarks.TickmarkCount; j++) { pt1.Y = pt.Y + (int)(tick.TickPoint.Y + ddy); pt2.Y = pt1.Y; ddy += dy; g.DrawLine(pen, pt1, pt2); } } } } } } } #endregion #region Copy/CopyTo /// /// Create a copy of the MinorGridLine. /// /// public override ChartVisualElement Copy() { ChartMinorGridLinesY copy = new ChartMinorGridLinesY(); CopyTo(copy); return (copy); } /// /// Copies the MinorGridLine to the given "copy". /// /// public override void CopyTo(ChartVisualElement copy) { ChartMinorGridLinesY c = copy as ChartMinorGridLinesY; if (c != null) base.CopyTo(c); } #endregion } #endregion #region ChartMinorGridLines public class ChartMinorGridLines : ChartGridLines { public ChartMinorGridLines(AxisOrientation orientation) : base(orientation) { } } #endregion #endregion #region ChartGridLines [TypeConverter(typeof(BlankExpandableObjectConverter))] public abstract class ChartGridLines : ChartVisualElement { #region Private variables private States _States; private AxisOrientation _AxisOrientation; private TickmarkLayout _TickmarkLayout; private PieGridLineVisualStyle _GridLinesVisualStyle; private EffectiveStyle _EffectiveStyle; #endregion public ChartGridLines(AxisOrientation orientation) { _AxisOrientation = orientation; InitDefaultStates(); _EffectiveStyle = new EffectiveStyle(this); } #region InitDefaultStates private void InitDefaultStates() { } #endregion #region Public properties #region DisplayOnTop /// /// Gets or sets whether grid lines are displayed on top of chart data. /// [DefaultValue(false), Category("Appearance")] [Description("Indicates whether grid lines are displayed on top of chart data.")] public bool DisplayOnTop { get { return (TestState(States.DisplayOnTop)); } set { if (value != DisplayOnTop) { SetState(States.DisplayOnTop, value); OnPropertyChangedEx("DisplayOnTop", VisualChangeType.Render); } } } #endregion #region EffectiveStyles /// /// Gets a reference to the GridLine's Effective (cached, composite) style. /// [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public PieGridLineVisualStyle EffectiveStyle { get { return (_EffectiveStyle.Style); } } #endregion #region GridLinesVisualStyle /// /// Gets or sets the visual style for the GridLines. /// [Category("Style")] [Description("Indicates the visual style for the GridLines.")] [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] public PieGridLineVisualStyle GridLinesVisualStyle { get { if (_GridLinesVisualStyle == null) { _GridLinesVisualStyle = new PieGridLineVisualStyle(); StyleVisualChangeHandler(null, _GridLinesVisualStyle); } return (_GridLinesVisualStyle); } set { if (_GridLinesVisualStyle != value) { PieGridLineVisualStyle oldValue = _GridLinesVisualStyle; _GridLinesVisualStyle = value; OnVisualStyleChanged("GridLinesVisualStyle", oldValue, value); if (oldValue != null) oldValue.Dispose(); } } } #endregion #endregion #region Internal properties #region TickmarkLayout internal TickmarkLayout TickmarkLayout { get { return (_TickmarkLayout); } set { _TickmarkLayout = value; } } #endregion #endregion #region MeasureOverride protected override void MeasureOverride(ChartLayoutInfo layoutInfo) { } #endregion #region ArrangeOverride protected override void ArrangeOverride(ChartLayoutInfo layoutInfo) { BoundsRelative = layoutInfo.LayoutBounds; } #endregion #region RenderOverride protected override void RenderOverride(ChartRenderInfo renderInfo) { } #endregion #region Render internal override void Render(ChartRenderInfo renderInfo) { if (Displayed == true) { Rectangle bounds = BoundsRelative; if (renderInfo.ClipRectangle.IntersectsWith(bounds)) RenderOverride(renderInfo); } } #endregion #region Style handling #region ApplyStyles public override void ApplyStyles(BaseVisualStyle style) { PieGridLineVisualStyle sstyle = style as PieGridLineVisualStyle; if (sstyle != null) { ApplyParentStyles(sstyle, Parent as ChartContainer); sstyle.ApplyStyle(GridLinesVisualStyle); if (sstyle.LineColor.IsEmpty == true) { if (this is ChartMajorGridLines) sstyle.LineColor = Color.DimGray; else sstyle.LineColor = Color.LightGray; } if (sstyle.LinePattern == LinePattern.NotSet) sstyle.LinePattern = LinePattern.Solid; if (sstyle.LineWidth < 0) sstyle.LineWidth = 1; } } #region ApplyParentStyles private void ApplyParentStyles(PieGridLineVisualStyle pstyle, ChartContainer item) { if (item != null) { ApplyParentStyles(pstyle, item.Parent as ChartContainer); if (item is ChartPanel) { pstyle.ApplyStyle(((ChartPanel)item).DefaultVisualStyles.GridLineVisualStyle); } } else { pstyle.ApplyStyle(ChartControl.BaseVisualStyles.GridLineVisualStyle); pstyle.ApplyStyle(ChartControl.DefaultVisualStyles.GridLineVisualStyle); } } #endregion #endregion #region ClearEffectiveStyles protected override void ClearEffectiveStyles() { base.ClearEffectiveStyles(); if (_EffectiveStyle.InvalidateStyle() == true) InvalidateLayout(); } #endregion #endregion #region Copy/CopyTo /// /// Copies the chart element to the given "copy". /// /// public override void CopyTo(ChartVisualElement copy) { ChartGridLines c = copy as ChartGridLines; if (c != null) { base.CopyTo(c); c.DisplayOnTop = DisplayOnTop; c.GridLinesVisualStyle = (_GridLinesVisualStyle != null) ? GridLinesVisualStyle.Copy() : null; } } #endregion #region GetSerialData internal override SerialElementCollection GetSerialData(string serialName) { SerialElementCollection sec = new SerialElementCollection(); if (serialName != null) { if (serialName.Equals("") == true) serialName = "ChartGridLines"; sec.AddStartElement(serialName); } sec.AddValue("DisplayOnTop", DisplayOnTop, false); if (_GridLinesVisualStyle != null && _GridLinesVisualStyle.IsEmpty == false) sec.AddElement(_GridLinesVisualStyle.GetSerialData("GridLinesVisualStyle")); sec.AddElement(base.GetSerialData(null)); if (serialName != null) sec.AddEndElement(serialName); return (sec); } #endregion #region PutSerialData #region ProcessValue internal override void ProcessValue(SerialElement se) { switch (se.Name) { case "DisplayOnTop": DisplayOnTop = bool.Parse(se.StringValue); break; default: base.ProcessValue(se); break; } } #endregion #region ProcessCollection internal override void ProcessCollection(SerialElement se) { SerialElementCollection sec = se.Sec; switch (se.Name) { case "GridLinesVisualStyle": sec.PutSerialData(GridLinesVisualStyle); break; default: base.ProcessCollection(se); break; } } #endregion #endregion #region States [Flags] private enum States : uint { DisplayOnTop = (1U << 0), } #region TestState private bool TestState(States state) { return ((_States & state) == state); } #endregion #region SetState private void SetState(States state, bool value) { if (value == true) _States |= state; else _States &= ~state; } #endregion #endregion #region IDisposable public override void Dispose() { GridLinesVisualStyle = null; base.Dispose(); } #endregion } #endregion }