internal void Paint(ChartGraphics chartGraph, bool drawAnnotationOnly) { ChartPicture chartPicture = this.Chart.chartPicture; // Restore previous background using double buffered bitmap if (!chartPicture.isSelectionMode && this.Count > 0 /*&& * !this.Chart.chartPicture.isPrinting*/) { chartPicture.backgroundRestored = true; Rectangle chartPosition = new Rectangle(0, 0, chartPicture.Width, chartPicture.Height); if (chartPicture.nonTopLevelChartBuffer == null || !drawAnnotationOnly) { // Dispose previous bitmap if (chartPicture.nonTopLevelChartBuffer != null) { chartPicture.nonTopLevelChartBuffer.Dispose(); chartPicture.nonTopLevelChartBuffer = null; } // Copy chart area plotting rectangle from the chart's dubble buffer image into area dubble buffer image if (this.Chart.paintBufferBitmap != null && this.Chart.paintBufferBitmap.Size.Width >= chartPosition.Size.Width && this.Chart.paintBufferBitmap.Size.Height >= chartPosition.Size.Height) { chartPicture.nonTopLevelChartBuffer = this.Chart.paintBufferBitmap.Clone( chartPosition, this.Chart.paintBufferBitmap.PixelFormat); } } else if (drawAnnotationOnly && chartPicture.nonTopLevelChartBuffer != null) { // Restore previous background this.Chart.paintBufferBitmapGraphics.DrawImageUnscaled( chartPicture.nonTopLevelChartBuffer, chartPosition); } } // Draw all annotation objects foreach (Annotation annotation in this) { // Reset calculated relative position annotation.ResetCurrentRelativePosition(); if (annotation.IsVisible()) { bool resetClip = false; // Check if anchor point assosiated with plot area is inside the scaleView if (annotation.IsAnchorVisible()) { // Set annotation object clipping if (annotation.ClipToChartArea.Length > 0 && annotation.ClipToChartArea != Constants.NotSetValue && Chart != null) { int areaIndex = Chart.ChartAreas.IndexOf(annotation.ClipToChartArea); if (areaIndex >= 0) { // Get chart area object ChartArea chartArea = Chart.ChartAreas[areaIndex]; chartGraph.SetClip(chartArea.PlotAreaPosition.ToRectangleF()); resetClip = true; } } // Start Svg Selection mode string url = String.Empty; chartGraph.StartHotRegion( annotation.ReplaceKeywords(url), annotation.ReplaceKeywords(annotation.ToolTip)); // Draw annotation object annotation.Paint(Chart, chartGraph); // End Svg Selection mode chartGraph.EndHotRegion( ); // Reset clipping region if (resetClip) { chartGraph.ResetClip(); } } } } }
/// <summary> /// Draw strip(s) or line(s). /// </summary> /// <param name="graph">Reference to the Chart Graphics object.</param> /// <param name="common">Common objects.</param> /// <param name="drawLinesOnly">Indicates if Lines or Stripes should be drawn.</param> internal void Paint( ChartGraphics graph, CommonElements common, bool drawLinesOnly) { // Strip lines are not supported in circular chart area if (this.Axis.ChartArea.chartAreaIsCurcular) { return; } // Get plot area position RectangleF plotAreaPosition = this.Axis.ChartArea.PlotAreaPosition.ToRectangleF(); // Detect if strip/line is horizontal or vertical bool horizontal = true; if (this.Axis.AxisPosition == AxisPosition.Bottom || this.Axis.AxisPosition == AxisPosition.Top) { horizontal = false; } // Get first series attached to this axis Series axisSeries = null; if (Axis.axisType == AxisName.X || Axis.axisType == AxisName.X2) { List <string> seriesArray = Axis.ChartArea.GetXAxesSeries((Axis.axisType == AxisName.X) ? AxisType.Primary : AxisType.Secondary, Axis.SubAxisName); if (seriesArray.Count > 0) { axisSeries = Axis.Common.DataManager.Series[seriesArray[0]]; if (axisSeries != null && !axisSeries.IsXValueIndexed) { axisSeries = null; } } } // Get starting position from axis // NOTE: Starting position was changed from "this.Axis.minimum" to // fix the minimum scaleView location to fix issue #5962 -- AG double currentPosition = this.Axis.ViewMinimum; // Adjust start position depending on the interval type if (!Axis.ChartArea.chartAreaIsCurcular || Axis.axisType == AxisName.Y || Axis.axisType == AxisName.Y2) { double intervalToUse = this.Interval; // NOTE: fix for issue #5962 // Always use original grid interval for isInterlaced strip lines. if (this.interlaced) { // Automaticly generated isInterlaced strips have interval twice as big as major grids intervalToUse /= 2.0; } currentPosition = ChartHelper.AlignIntervalStart(currentPosition, intervalToUse, this.IntervalType, axisSeries); } // Too many tick marks if (this.Interval != 0) { if ((Axis.ViewMaximum - Axis.ViewMinimum) / ChartHelper.GetIntervalSize(currentPosition, this._interval, this._intervalType, axisSeries, 0, DateTimeIntervalType.Number, false) > ChartHelper.MaxNumOfGridlines) { return; } } DateTimeIntervalType offsetType = (IntervalOffsetType == DateTimeIntervalType.Auto) ? IntervalType : IntervalOffsetType; if (this.Interval == 0) { currentPosition = this.IntervalOffset; } /****************************************************************** * Removed by AG. Causing issues with interalced strip lines. * /****************************************************************** * else if(axisSeries != null && axisSeries.IsXValueIndexed) * { * // Align first position for indexed series * currentPosition += this.Axis.AlignIndexedIntervalStart( * currentPosition, * this.Interval, * this.IntervalType, * axisSeries, * this.IntervalOffset, * offsetType, * false); * } */ else { if (this.IntervalOffset > 0) { currentPosition += ChartHelper.GetIntervalSize(currentPosition, this.IntervalOffset, offsetType, axisSeries, 0, DateTimeIntervalType.Number, false); } else if (this.IntervalOffset < 0) { currentPosition -= ChartHelper.GetIntervalSize(currentPosition, -this.IntervalOffset, offsetType, axisSeries, 0, DateTimeIntervalType.Number, false); } } // Draw several lines or strips if Interval property is set int counter = 0; do { // Check if we do not exceed max number of elements if (counter++ > ChartHelper.MaxNumOfGridlines) { break; } // Draw strip if (this.StripWidth > 0 && !drawLinesOnly) { double stripRightPosition = currentPosition + ChartHelper.GetIntervalSize(currentPosition, this.StripWidth, this.StripWidthType, axisSeries, this.IntervalOffset, offsetType, false); if (stripRightPosition > this.Axis.ViewMinimum && currentPosition < this.Axis.ViewMaximum) { // Calculate strip rectangle RectangleF rect = RectangleF.Empty; double pos1 = (float)this.Axis.GetLinearPosition(currentPosition); double pos2 = (float)this.Axis.GetLinearPosition(stripRightPosition); if (horizontal) { rect.X = plotAreaPosition.X; rect.Width = plotAreaPosition.Width; rect.Y = (float)Math.Min(pos1, pos2); rect.Height = (float)Math.Max(pos1, pos2) - rect.Y; // Check rectangle boundaries rect.Intersect(plotAreaPosition); } else { rect.Y = plotAreaPosition.Y; rect.Height = plotAreaPosition.Height; rect.X = (float)Math.Min(pos1, pos2); rect.Width = (float)Math.Max(pos1, pos2) - rect.X; // Check rectangle boundaries rect.Intersect(plotAreaPosition); } if (rect.Width > 0 && rect.Height > 0) { // Start Svg Selection mode graph.StartHotRegion("", this._toolTip); if (!this.Axis.ChartArea.Area3DStyle.Enable3D) { // Draw strip graph.FillRectangleRel(rect, this.BackColor, this.BackHatchStyle, this.BackImage, this.BackImageWrapMode, this.BackImageTransparentColor, this.BackImageAlignment, this.BackGradientStyle, this.BackSecondaryColor, this.BorderColor, this.BorderWidth, this.BorderDashStyle, Color.Empty, 0, PenAlignment.Inset); } else { Draw3DStrip(graph, rect, horizontal); } // End Svg Selection mode graph.EndHotRegion(); // Draw strip line title PaintTitle(graph, rect); if (common.ProcessModeRegions) { if (!this.Axis.ChartArea.Area3DStyle.Enable3D) { common.HotRegionsList.AddHotRegion(rect, this.ToolTip, string.Empty, string.Empty, string.Empty, this, ChartElementType.StripLines, null); } } } } } // Draw line else if (this.StripWidth == 0 && drawLinesOnly) { if (currentPosition > this.Axis.ViewMinimum && currentPosition < this.Axis.ViewMaximum) { // Calculate line position PointF point1 = PointF.Empty; PointF point2 = PointF.Empty; if (horizontal) { point1.X = plotAreaPosition.X; point1.Y = (float)this.Axis.GetLinearPosition(currentPosition); point2.X = plotAreaPosition.Right; point2.Y = point1.Y; } else { point1.X = (float)this.Axis.GetLinearPosition(currentPosition); point1.Y = plotAreaPosition.Y; point2.X = point1.X; point2.Y = plotAreaPosition.Bottom; } // Start Svg Selection mode graph.StartHotRegion("", this._toolTip); // Draw Line if (!this.Axis.ChartArea.Area3DStyle.Enable3D) { graph.DrawLineRel(this.BorderColor, this.BorderWidth, this.BorderDashStyle, point1, point2); } else { graph.Draw3DGridLine(this.Axis.ChartArea, _borderColor, _borderWidth, _borderDashStyle, point1, point2, horizontal, Axis.Common, this); } // End Svg Selection mode graph.EndHotRegion(); // Draw strip line title PaintTitle(graph, point1, point2); if (common.ProcessModeRegions) { SizeF relBorderWidth = new SizeF(this.BorderWidth + 1, this.BorderWidth + 1); relBorderWidth = graph.GetRelativeSize(relBorderWidth); RectangleF lineRect = RectangleF.Empty; if (horizontal) { lineRect.X = point1.X; lineRect.Y = point1.Y - relBorderWidth.Height / 2f; lineRect.Width = point2.X - point1.X; lineRect.Height = relBorderWidth.Height; } else { lineRect.X = point1.X - relBorderWidth.Width / 2f; lineRect.Y = point1.Y; lineRect.Width = relBorderWidth.Width; lineRect.Height = point2.Y - point1.Y; } common.HotRegionsList.AddHotRegion(lineRect, this.ToolTip, null, null, null, this, ChartElementType.StripLines, null); } } } // Go to the next line/strip if (this.Interval > 0) { currentPosition += ChartHelper.GetIntervalSize(currentPosition, this.Interval, this.IntervalType, axisSeries, this.IntervalOffset, offsetType, false); } } while(this.Interval > 0 && currentPosition <= this.Axis.ViewMaximum); }