/// <summary> /// Render the <see cref="Line"/>'s as vertical sticks (from a <see cref="StickItem" />) to /// the specified <see cref="Graphics"/> device. /// </summary> /// <param name="g"> /// A graphic device object to be drawn into. This is normally e.Graphics from the /// PaintEventArgs argument to the Paint() method. /// </param> /// <param name="pane"> /// A reference to the <see cref="ZedGraph.GraphPane"/> object that is the parent or /// owner of this object. /// </param> /// <param name="curve">A <see cref="CurveItem"/> representing this /// curve.</param> /// <param name="scaleFactor"> /// The scaling factor to be used for rendering objects. This is calculated and /// passed down by the parent <see cref="GraphPane"/> object using the /// <see cref="PaneBase.CalcScaleFactor"/> method, and is used to proportionally adjust /// font sizes, etc. according to the actual size of the graph. /// </param> public void DrawSticks(Graphics g, GraphPane pane, CurveItem curve, float scaleFactor) { Axis yAxis = curve.IsY2Axis ? (Axis)pane.Y2Axis : (Axis)pane.YAxis; float basePix = yAxis.Transform(0.0); Pen pen = new Pen(this.color, pane.ScaledPenWidth(width, scaleFactor)); pen.DashStyle = this.Style; for (int i = 0; i < curve.Points.Count; i++) { PointPair pt = curve.Points[i]; if (pt.X != PointPair.Missing && pt.Y != PointPair.Missing && !System.Double.IsNaN(pt.X) && !System.Double.IsNaN(pt.Y) && !System.Double.IsInfinity(pt.X) && !System.Double.IsInfinity(pt.Y) && (!pane.XAxis.IsLog || pt.X > 0.0) && (!yAxis.IsLog || pt.Y > 0.0)) { float pixY = yAxis.Transform(curve.IsOverrideOrdinal, i, pt.Y); float pixX = pane.XAxis.Transform(curve.IsOverrideOrdinal, i, pt.X); g.DrawLine(pen, pixX, pixY, pixX, basePix); } } }
/// <summary> /// Draw the this <see cref="CurveItem"/> to the specified <see cref="Graphics"/> /// device using the specified smoothing property (<see cref="ZedGraph.Line.SmoothTension"/>). /// The routine draws the line segments and the area fill (if any, see <see cref="FillType"/>; /// the symbols are drawn by the <see cref="Symbol.Draw"/> method. This method /// is normally only called by the Draw method of the /// <see cref="CurveItem"/> object. Note that the <see cref="StepType"/> property /// is ignored for smooth lines (e.g., when <see cref="ZedGraph.Line.IsSmooth"/> is true). /// </summary> /// <param name="g"> /// A graphic device object to be drawn into. This is normally e.Graphics from the /// PaintEventArgs argument to the Paint() method. /// </param> /// <param name="scaleFactor"> /// The scaling factor to be used for rendering objects. This is calculated and /// passed down by the parent <see cref="GraphPane"/> object using the /// <see cref="PaneBase.CalcScaleFactor"/> method, and is used to proportionally adjust /// font sizes, etc. according to the actual size of the graph. /// </param> /// <param name="pane"> /// A reference to the <see cref="GraphPane"/> object that is the parent or /// owner of this object. /// </param> /// <param name="curve">A <see cref="LineItem"/> representing this /// curve.</param> /// <param name="isY2Axis">A value indicating to which Y axis this curve is assigned. /// true for the "Y2" axis, false for the "Y" axis.</param> public void DrawSmoothFilledCurve(Graphics g, GraphPane pane, LineItem curve, bool isY2Axis, float scaleFactor) { PointF[] arrPoints; int count; PointPairList points = curve.Points; if (this.IsVisible && !this.Color.IsEmpty && points != null && BuildPointsArray(pane, curve, isY2Axis, out arrPoints, out count) && count > 2) { Pen pen = new Pen(this.Color, pane.ScaledPenWidth(width, scaleFactor)); pen.DashStyle = this.Style; float tension = this.isSmooth ? this.smoothTension : 0f; // Fill the curve if needed if (this.Fill.IsVisible) { GraphicsPath path = new GraphicsPath(FillMode.Winding); path.AddCurve(arrPoints, 0, count - 2, tension); double yMin = pane.YAxis.Min < 0 ? 0.0 : pane.YAxis.Min; //double yMin = pane.YAxis.Min; CloseCurve(pane, curve, arrPoints, isY2Axis, count, yMin, path); Brush brush = this.fill.MakeBrush(path.GetBounds()); g.FillPath(brush, path); brush.Dispose(); } // Stroke the curve g.DrawCurve(pen, arrPoints, 0, count - 2, tension); } }
/// <summary> /// Render this object to the specified <see cref="Graphics"/> device. /// </summary> /// <remarks> /// This method is normally only called by the Draw method /// of the parent <see cref="GraphItemList"/> collection object. /// </remarks> /// <param name="g"> /// A graphic device object to be drawn into. This is normally e.Graphics from the /// PaintEventArgs argument to the Paint() method. /// </param> /// <param name="pane"> /// A reference to the <see cref="GraphPane"/> object that is the parent or /// owner of this object. /// </param> /// <param name="scaleFactor"> /// The scaling factor to be used for rendering objects. This is calculated and /// passed down by the parent <see cref="GraphPane"/> object using the /// <see cref="GraphPane.CalcScaleFactor"/> method, and is used to proportionally adjust /// font sizes, etc. according to the actual size of the graph. /// </param> override public void Draw(Graphics g, GraphPane pane, double scaleFactor) { // Convert the arrow coordinates from the user coordinate system // to the screen coordinate system PointF pix1 = this.Location.TransformTopLeft(pane); PointF pix2 = this.Location.TransformBottomRight(pane); if (pix1.X > -10000 && pix1.X < 100000 && pix1.Y > -100000 && pix1.Y < 100000 && pix2.X > -10000 && pix2.X < 100000 && pix2.Y > -100000 && pix2.Y < 100000) { // get a scaled size for the arrowhead float scaledSize = (float)(this.size * scaleFactor); // calculate the length and the angle of the arrow "vector" double dy = pix2.Y - pix1.Y; double dx = pix2.X - pix1.X; float angle = (float)Math.Atan2(dy, dx) * 180.0F / (float)Math.PI; float length = (float)Math.Sqrt(dx * dx + dy * dy); // Save the old transform matrix Matrix transform = g.Transform; // Move the coordinate system so it is located at the starting point // of this arrow g.TranslateTransform(pix1.X, pix1.Y); // Rotate the coordinate system according to the angle of this arrow // about the starting point g.RotateTransform(angle); // get a pen according to this arrow properties Pen pen = new Pen(this.color, pane.ScaledPenWidth(penWidth, scaleFactor)); // Draw the line segment for this arrow g.DrawLine(pen, 0, 0, length - scaledSize * 0.75F, 0); // Only show the arrowhead if required if (this.isArrowHead) { SolidBrush brush = new SolidBrush(this.color); // Create a polygon representing the arrowhead based on the scaled // size PointF[] polyPt = new PointF[4]; float hsize = scaledSize / 3.0F; polyPt[0].X = length; polyPt[0].Y = 0; polyPt[1].X = length - scaledSize; polyPt[1].Y = hsize; polyPt[2].X = length - scaledSize; polyPt[2].Y = -hsize; polyPt[3] = polyPt[0]; // render the arrowhead g.FillPolygon(brush, polyPt); } // Restore the transform matrix back to its original state g.Transform = transform; } }
/// <summary> /// Render a single <see cref="Line"/> segment to the specified /// <see cref="Graphics"/> device. /// </summary> /// <param name="g"> /// A graphic device object to be drawn into. This is normally e.Graphics from the /// PaintEventArgs argument to the Paint() method. /// </param> /// <param name="pane"> /// A reference to the <see cref="ZedGraph.GraphPane"/> object that is the parent or /// owner of this object. /// </param> /// <param name="scaleFactor"> /// The scaling factor to be used for rendering objects. This is calculated and /// passed down by the parent <see cref="GraphPane"/> object using the /// <see cref="PaneBase.CalcScaleFactor"/> method, and is used to proportionally adjust /// font sizes, etc. according to the actual size of the graph. /// </param> /// <param name="x1">The x position of the starting point that defines the /// line segment in screen pixel units</param> /// <param name="y1">The y position of the starting point that defines the /// line segment in screen pixel units</param> /// <param name="x2">The x position of the ending point that defines the /// line segment in screen pixel units</param> /// <param name="y2">The y position of the ending point that defines the /// line segment in screen pixel units</param> public void DrawSegment(Graphics g, GraphPane pane, float x1, float y1, float x2, float y2, float scaleFactor) { if (this.isVisible && !this.Color.IsEmpty) { Pen pen = new Pen(this.color, pane.ScaledPenWidth(width, scaleFactor)); pen.DashStyle = this.Style; g.DrawLine(pen, x1, y1, x2, y2); } }
internal Pen GetPen(GraphPane pane, float scaleFactor) { var pen = new Pen(_color, pane.ScaledPenWidth(_penWidth, scaleFactor)); if (_dashOff <= 1e-10 || _dashOn <= 1e-10) { return(pen); } pen.DashStyle = DashStyle.Custom; pen.DashPattern = new [] { _dashOn, _dashOff }; return(pen); }
/// <summary> /// Render the label for this <see cref="GasGaugeNeedle"/>. /// </summary> /// <param name="g"> /// A graphic device object to be drawn into. This is normally e.Graphics from the /// PaintEventArgs argument to the Paint() method. /// </param> /// <param name="pane"> /// A graphic device object to be drawn into. This is normally e.Graphics from the /// PaintEventArgs argument to the Paint() method. /// </param> /// <param name="rect">Bounding rectangle for this <see cref="GasGaugeNeedle"/>.</param> /// <param name="scaleFactor"> /// The scaling factor to be used for rendering objects. This is calculated and /// passed down by the parent <see cref="ZedGraph.GraphPane"/> object using the /// <see cref="PaneBase.CalcScaleFactor"/> method, and is used to proportionally adjust /// font sizes, etc. according to the actual size of the graph. /// </param> public override void DrawLegendKey(Graphics g, GraphPane pane, RectangleF rect, float scaleFactor) { if (!_isVisible) { return; } float yMid = rect.Top + rect.Height / 2.0F; Pen pen = new Pen(NeedleColor, pane.ScaledPenWidth(NeedleWidth / 2, scaleFactor)); pen.StartCap = LineCap.Round; pen.EndCap = LineCap.ArrowAnchor; pen.DashStyle = DashStyle.Solid; g.DrawLine(pen, rect.Left, yMid, rect.Right, yMid); }
internal Pen GetPen(GraphPane pane, float scaleFactor) { Pen pen = new Pen(_color, pane.ScaledPenWidth(_penWidth, scaleFactor)); if (_dashOff > 1e-10 && _dashOn > 1e-10) { pen.DashStyle = DashStyle.Custom; float[] pattern = new float[2]; pattern[0] = _dashOn; pattern[1] = _dashOff; pen.DashPattern = pattern; } return(pen); }
/// <summary> /// Draw the this <see cref="CurveItem"/> to the specified <see cref="Graphics"/> /// device using the specified smoothing property (<see cref="ZedGraph.Line.SmoothTension"/>). /// The routine draws the line segments and the area fill (if any, see <see cref="FillType"/>; /// the symbols are drawn by the <see cref="Symbol.Draw"/> method. This method /// is normally only called by the Draw method of the /// <see cref="CurveItem"/> object. Note that the <see cref="StepType"/> property /// is ignored for smooth lines (e.g., when <see cref="ZedGraph.Line.IsSmooth"/> is true). /// </summary> /// <param name="g"> /// A graphic device object to be drawn into. This is normally e.Graphics from the /// PaintEventArgs argument to the Paint() method. /// </param> /// <param name="scaleFactor"> /// The scaling factor to be used for rendering objects. This is calculated and /// passed down by the parent <see cref="GraphPane"/> object using the /// <see cref="PaneBase.CalcScaleFactor"/> method, and is used to proportionally adjust /// font sizes, etc. according to the actual size of the graph. /// </param> /// <param name="pane"> /// A reference to the <see cref="GraphPane"/> object that is the parent or /// owner of this object. /// </param> /// <param name="curve">A <see cref="LineItem"/> representing this /// curve.</param> public void DrawSmoothFilledCurve(Graphics g, GraphPane pane, CurveItem curve, float scaleFactor) { PointF[] arrPoints; int count; PointPairList points = curve.Points; if (this.IsVisible && !this.Color.IsEmpty && points != null && BuildPointsArray(pane, curve, out arrPoints, out count) && count > 2) { Pen pen = new Pen(this.Color, pane.ScaledPenWidth(width, scaleFactor)); pen.DashStyle = this.Style; float tension = this.isSmooth ? this.smoothTension : 0f; // Fill the curve if needed if (this.Fill.IsVisible) { Axis yAxis = curve.IsY2Axis ? (Axis)pane.Y2Axis : (Axis)pane.YAxis; GraphicsPath path = new GraphicsPath(FillMode.Winding); path.AddCurve(arrPoints, 0, count - 2, tension); double yMin = yAxis.Min < 0 ? 0.0 : yAxis.Min; CloseCurve(pane, curve, arrPoints, count, yMin, path); RectangleF rect = path.GetBounds(); Brush brush = this.fill.MakeBrush(rect); g.FillPath(brush, path); brush.Dispose(); // restore the zero line if needed (since the fill tends to cover it up) yAxis.FixZeroLine(g, pane, scaleFactor, rect.Left, rect.Right); } // Stroke the curve g.DrawCurve(pen, arrPoints, 0, count - 2, tension); pen.Dispose(); } }
internal void Draw(Graphics g, GraphPane pane, float scaleFactor, float shiftPos, bool drawGrid) { float rightPix, topPix; if (_ownerAxis is XAxis) { rightPix = pane.Chart._rect.Width; topPix = -pane.Chart._rect.Height; } else { rightPix = pane.Chart._rect.Height; topPix = -pane.Chart._rect.Width; } // sanity check if (_min >= _max) { return; } MajorGrid majorGrid = _ownerAxis._majorGrid; MajorTic majorTic = _ownerAxis._majorTic; MinorTic tic = _ownerAxis._minorTic; MinorGrid grid = _ownerAxis._minorGrid; if (!drawGrid) { Pen pen = new Pen(_ownerAxis.Color, pane.ScaledPenWidth(majorTic._penWidth, scaleFactor)); // redraw the axis border if (_ownerAxis.IsAxisSegmentVisible) { g.DrawLine(pen, 0.0F, shiftPos, rightPix, shiftPos); } // Draw a zero-value line if needed if (majorGrid._isZeroLine && _min < 0.0 && _max > 0.0) { float zeroPix = LocalTransform(0.0); g.DrawLine(pen, zeroPix, 0.0F, zeroPix, topPix); } _ownerAxis.DrawTitle(g, pane, 0, scaleFactor); } // draw the time scales that fit best bool[] drawThese = DrawWhich((_maxLinTemp - _minLinTemp)); // Note: the Draw*Labels routines draw tics or grids too if (drawThese[(int)DateUnit.Hour]) { DrawHourMinuteLabels(g, pane, tic, grid, drawGrid, topPix, rightPix, shiftPos, scaleFactor); shiftPos += _fontSpec.GetHeight(scaleFactor) * 1.1F; tic = majorTic; grid = majorGrid; } if (drawThese[(int)DateUnit.Day]) { DrawDayLabels(g, pane, tic, grid, drawGrid, topPix, rightPix, shiftPos, scaleFactor, !drawThese[(int)DateUnit.Month]); shiftPos += _fontSpec.GetHeight(scaleFactor) * 1.1F; tic = majorTic; grid = majorGrid; } if (drawThese[(int)DateUnit.Month]) { DrawMonthLabels(g, pane, tic, grid, drawGrid, topPix, rightPix, shiftPos, scaleFactor, !drawThese[(int)DateUnit.Year]); shiftPos += _fontSpec.GetHeight(scaleFactor) * 1.1F; } if (drawThese[(int)DateUnit.Year]) { DrawYearLabels(g, pane, majorTic, majorGrid, drawGrid, topPix, rightPix, shiftPos, scaleFactor); shiftPos += _fontSpec.GetHeight(scaleFactor) * 1.1F; } }
internal Pen GetPen( GraphPane pane, float scaleFactor ) { return new Pen( _color, pane.ScaledPenWidth( _penWidth, scaleFactor ) ); }
/// <summary> /// Render the label for this <see cref="GasGaugeNeedle"/>. /// </summary> /// <param name="g"> /// A graphic device object to be drawn into. This is normally e.Graphics from the /// PaintEventArgs argument to the Paint() method. /// </param> /// <param name="pane"> /// A graphic device object to be drawn into. This is normally e.Graphics from the /// PaintEventArgs argument to the Paint() method. /// </param> /// <param name="rect">Bounding rectangle for this <see cref="GasGaugeNeedle"/>.</param> /// <param name="scaleFactor"> /// The scaling factor to be used for rendering objects. This is calculated and /// passed down by the parent <see cref="ZedGraph.GraphPane"/> object using the /// <see cref="PaneBase.CalcScaleFactor"/> method, and is used to proportionally adjust /// font sizes, etc. according to the actual size of the graph. /// </param> public override void DrawLegendKey(Graphics g, GraphPane pane, RectangleF rect, float scaleFactor) { if (!_isVisible) return; float yMid = rect.Top + rect.Height/2.0F; Pen pen = new Pen(NeedleColor, pane.ScaledPenWidth(NeedleWidth/2, scaleFactor)); pen.StartCap = LineCap.Round; pen.EndCap = LineCap.ArrowAnchor; pen.DashStyle = DashStyle.Solid; g.DrawLine(pen, rect.Left, yMid, rect.Right, yMid); }
/// <summary> /// Draw the minor tic marks as required for this <see cref="Axis"/>. /// </summary> /// <param name="g"> /// A graphic device object to be drawn into. This is normally e.Graphics from the /// PaintEventArgs argument to the Paint() method. /// </param> /// <param name="pane"> /// A reference to the <see cref="ZedGraph.GraphPane"/> object that is the parent or /// owner of this object. /// </param> /// <param name="baseVal"> /// The scale value for the first major tic position. This is the reference point /// for all other tic marks. /// </param> /// <param name="shift">The number of pixels to shift this axis, based on the /// value of <see cref="Cross"/>. A positive value is into the ChartRect relative to /// the default axis position.</param> /// <param name="scaleFactor"> /// The scaling factor to be used for rendering objects. This is calculated and /// passed down by the parent <see cref="GraphPane"/> object using the /// <see cref="PaneBase.CalcScaleFactor"/> method, and is used to proportionally adjust /// font sizes, etc. according to the actual size of the graph. /// </param> /// <param name="topPix"> /// The pixel location of the far side of the ChartRect from this axis. /// This value is the ChartRect.Height for the XAxis, or the ChartRect.Width /// for the YAxis and Y2Axis. /// </param> public void DrawMinorTics( IGraphics g, GraphPane pane, double baseVal, float shift, float scaleFactor, float topPix ) { // minor tics in log scales have some problems for Viewer; see defect 14624 if (_scale.IsLog) return; if ( ( this.MinorTic.IsOutside || this.MinorTic.IsOpposite || this.MinorTic.IsInside || this.MinorTic._isCrossOutside || this.MinorTic._isCrossInside || _minorGrid._isVisible ) && _isVisible ) { double tMajor = _scale._majorStep * _scale.MajorUnitMultiplier, tMinor = _scale._minorStep * _scale.MinorUnitMultiplier; if ( _scale.IsLog || tMinor < tMajor ) { float minorScaledTic = this.MinorTic.ScaledTic( scaleFactor ); // Minor tics start at the minimum value and step all the way thru // the full scale. This means that if the minor step size is not // an even division of the major step size, the minor tics won't // line up with all of the scale labels and major tics. double first = _scale._minLinTemp, last = _scale._maxLinTemp; double dVal = first; float pixVal; int iTic = _scale.CalcMinorStart( baseVal ); int MajorTic = 0; double majorVal = _scale.CalcMajorTicValue( baseVal, MajorTic ); using ( Pen pen = new Pen( _minorTic._color, pane.ScaledPenWidth( MinorTic._penWidth, scaleFactor ) ) ) using ( Pen minorGridPen = _minorGrid.GetPen( pane, scaleFactor ) ) { // Draw the minor tic marks while ( dVal < last && iTic < 5000 ) { // Calculate the scale value for the current tic dVal = _scale.CalcMinorTicValue( baseVal, iTic ); // Maintain a value for the current major tic if ( dVal > majorVal ) majorVal = _scale.CalcMajorTicValue( baseVal, ++MajorTic ); // Make sure that the current value does not match up with a major tic if ( ( ( Math.Abs( dVal ) < 1e-20 && Math.Abs( dVal - majorVal ) > 1e-20 ) || ( Math.Abs( dVal ) > 1e-20 && Math.Abs( ( dVal - majorVal ) / dVal ) > 1e-10 ) ) && ( dVal >= first && dVal <= last ) ) { pixVal = _scale.LocalTransform( dVal ); _minorGrid.Draw( g, minorGridPen, pixVal, topPix ); _minorTic.Draw( g, pane, pen, pixVal, topPix, shift, minorScaledTic ); } iTic++; } } } } }
/// <summary> /// Draw the value labels, tic marks, and grid lines as /// required for this <see cref="Axis"/>. /// </summary> /// <param name="g"> /// A graphic device object to be drawn into. This is normally e.Graphics from the /// PaintEventArgs argument to the Paint() method. /// </param> /// <param name="pane"> /// A reference to the <see cref="GraphPane"/> object that is the parent or /// owner of this object. /// </param> /// <param name="baseVal"> /// The first major tic value for the axis /// </param> /// <param name="nTics"> /// The total number of major tics for the axis /// </param> /// <param name="topPix"> /// The pixel location of the far side of the axisRect from this axis. /// This value is the axisRect.Height for the XAxis, or the axisRect.Width /// for the YAxis and Y2Axis. /// </param> /// <param name="scaleFactor"> /// The scaling factor to be used for rendering objects. This is calculated and /// passed down by the parent <see cref="GraphPane"/> object using the /// <see cref="GraphPane.CalcScaleFactor"/> method, and is used to proportionally adjust /// font sizes, etc. according to the actual size of the graph. /// </param> public void DrawLabels( Graphics g, GraphPane pane, double baseVal, int nTics, float topPix, double scaleFactor ) { double dVal, dVal2; float pixVal, pixVal2; string tmpStr; float scaledTic = this.ScaledTic( scaleFactor ); double scaleMult = Math.Pow( (double) 10.0, this.scaleMag ); Pen pen = new Pen(this.color, pane.ScaledPenWidth(ticPenWidth, scaleFactor)); Pen dottedPen = new Pen(this.gridColor, pane.ScaledPenWidth(gridPenWidth, scaleFactor)); dottedPen.DashStyle = DashStyle.Custom; float[] pattern = new float[2]; pattern[0] = this.gridDashOn; pattern[1] = this.gridDashOff; dottedPen.DashPattern = pattern; // get the Y position of the center of the axis labels // (the axis itself is referenced at zero) float maxSpace = this.GetScaleMaxSpace( g, pane, scaleFactor ).Height; float textTop = (float) scaleFactor * ( ticSize * 1.5F ); float textCenter; double rangeTol = ( this.maxScale - this.minScale ) * 0.00001; // loop for each major tic for ( int i=0; i<nTics; i++ ) { dVal = CalcMajorTicValue( baseVal, i ); // If we're before the start of the scale, just go to the next tic if ( dVal < this.minScale ) continue; // if we've already past the end of the scale, then we're done if ( dVal > this.maxScale + rangeTol ) break; // convert the value to a pixel position pixVal = this.LocalTransform( dVal ); // see if the tic marks will be draw between the labels instead of at the labels // (this applies only to AxisType.Text if ( this.isTicsBetweenLabels && this.type == AxisType.Text ) { // We need one extra tic in order to draw the tics between labels // so provide an exception here if ( i == 0 ) { dVal2 = CalcMajorTicValue( baseVal, -0.5 ); if ( dVal2 >= this.minScale ) { pixVal2 = this.LocalTransform( dVal2 ); DrawATic( g, pen, pixVal2, topPix, scaledTic ); // draw the grid if ( this.isVisible && this.isShowGrid ) g.DrawLine( dottedPen, pixVal2, 0.0F, pixVal2, topPix ); } } dVal2 = CalcMajorTicValue( baseVal, (double) i + 0.5 ); if ( dVal2 > this.maxScale ) break; pixVal2 = this.LocalTransform( dVal2 ); } else pixVal2 = pixVal; DrawATic( g, pen, pixVal2, topPix, scaledTic ); // draw the grid if ( this.isVisible && this.isShowGrid ) g.DrawLine( dottedPen, pixVal2, 0.0F, pixVal2, topPix ); if ( this.isVisible ) { // draw the label MakeLabel( i, dVal, out tmpStr ); if ( pane.BarType == BarType.PercentStack ) //rpk { if( this is YAxis && pane.BarBase == BarBase.X ) tmpStr = tmpStr + "%" ; if( this is XAxis && pane.BarBase == BarBase.Y ) tmpStr = tmpStr + "%" ; } float height = ScaleFontSpec.BoundingBox( g, tmpStr, scaleFactor ).Height; if ( this.ScaleAlign == AlignP.Center ) textCenter = textTop + maxSpace / 2.0F; else if ( this.ScaleAlign == AlignP.Outside ) textCenter = textTop + maxSpace - height / 2.0F; else // inside textCenter = textTop + height / 2.0F; if ( this.IsLog && this.isUseTenPower ) this.ScaleFontSpec.DrawTenPower( g, pane, tmpStr, pixVal, textCenter, AlignH.Center, AlignV.Center, scaleFactor ); else this.ScaleFontSpec.Draw( g, pane, tmpStr, pixVal, textCenter, AlignH.Center, AlignV.Center, scaleFactor ); } } }
/// <summary> /// Draw the minor tic marks as required for this <see cref="Axis"/>. /// </summary> /// <param name="g"> /// A graphic device object to be drawn into. This is normally e.Graphics from the /// PaintEventArgs argument to the Paint() method. /// </param> /// <param name="pane"> /// A reference to the <see cref="ZedGraph.GraphPane"/> object that is the parent or /// owner of this object. /// </param> /// <param name="baseVal"> /// The scale value for the first major tic position. This is the reference point /// for all other tic marks. /// </param> /// <param name="scaleFactor"> /// The scaling factor to be used for rendering objects. This is calculated and /// passed down by the parent <see cref="GraphPane"/> object using the /// <see cref="GraphPane.CalcScaleFactor"/> method, and is used to proportionally adjust /// font sizes, etc. according to the actual size of the graph. /// </param> /// <param name="topPix"> /// The pixel location of the far side of the axisRect from this axis. /// This value is the axisRect.Height for the XAxis, or the axisRect.Width /// for the YAxis and Y2Axis. /// </param> public void DrawMinorTics( Graphics g, GraphPane pane, double baseVal, double scaleFactor, float topPix ) { if ( this.isMinorTic && this.isVisible ) { double tMajor = this.step * ( IsDate ? GetUnitMultiple( majorUnit ) : 1.0 ), tMinor = this.minorStep * ( IsDate ? GetUnitMultiple( minorUnit ) : 1.0 ); if ( this.IsLog || tMinor < tMajor ) { float minorScaledTic = this.ScaledMinorTic( scaleFactor ); // Minor tics start at the minimum value and step all the way thru // the full scale. This means that if the minor step size is not // an even division of the major step size, the minor tics won't // line up with all of the scale labels and major tics. double first = this.min, last = this.max; if ( this.IsLog ) { first = SafeLog( this.min ); last = SafeLog( this.max ); } double dVal = first; float pixVal; Pen pen = new Pen(this.color, pane.ScaledPenWidth(ticPenWidth, scaleFactor)); Pen minorGridPen = new Pen( this.minorGridColor, pane.ScaledPenWidth(minorGridPenWidth, scaleFactor)); minorGridPen.DashStyle = DashStyle.Custom; float[] pattern = new float[2]; pattern[0] = this.minorGridDashOn; pattern[1] = this.minorGridDashOff; minorGridPen.DashPattern = pattern; int iTic = CalcMinorStart( baseVal ); int majorTic = 0; double majorVal = CalcMajorTicValue( baseVal, majorTic ); // Draw the minor tic marks while ( dVal < last && iTic < 5000 ) { // Calculate the scale value for the current tic dVal = CalcMinorTicValue( baseVal, iTic ); // Maintain a value for the current major tic if ( dVal > majorVal ) majorVal = CalcMajorTicValue( baseVal, ++majorTic ); // Make sure that the current value does not match up with a major tic if ( ( Math.Abs(dVal) < 1e-20 && Math.Abs( dVal - majorVal ) > 1e-20 ) || ( Math.Abs(dVal) > 1e-20 && Math.Abs( (dVal - majorVal) / dVal ) > 1e-10 ) && ( dVal >= first && dVal <= last ) ) { pixVal = this.LocalTransform( dVal ); // draw the minor grid if ( this.isShowMinorGrid ) g.DrawLine( minorGridPen, pixVal, 0.0F, pixVal, topPix ); // draw the outside tic if ( this.isMinorTic ) g.DrawLine( pen, pixVal, 0.0F, pixVal, 0.0F + minorScaledTic ); // draw the inside tic if ( this.isMinorInsideTic ) g.DrawLine( pen, pixVal, 0.0F, pixVal, 0.0F - minorScaledTic ); // draw the opposite tic if ( this.isMinorOppositeTic ) g.DrawLine( pen, pixVal, topPix, pixVal, topPix + minorScaledTic ); } iTic++; } } } }
/// <summary> /// Draw the this <see cref="CurveItem"/> to the specified <see cref="Graphics"/> /// device using the specified smoothing property (<see cref="ZedGraph.Line.SmoothTension"/>). /// The routine draws the line segments and the area fill (if any, see <see cref="FillType"/>; /// the symbols are drawn by the <see cref="Symbol.Draw"/> method. This method /// is normally only called by the Draw method of the /// <see cref="CurveItem"/> object. Note that the <see cref="StepType"/> property /// is ignored for smooth lines (e.g., when <see cref="ZedGraph.Line.IsSmooth"/> is true). /// </summary> /// <param name="g"> /// A graphic device object to be drawn into. This is normally e.Graphics from the /// PaintEventArgs argument to the Paint() method. /// </param> /// <param name="scaleFactor"> /// The scaling factor to be used for rendering objects. This is calculated and /// passed down by the parent <see cref="GraphPane"/> object using the /// <see cref="GraphPane.CalcScaleFactor"/> method, and is used to proportionally adjust /// font sizes, etc. according to the actual size of the graph. /// </param> /// <param name="pane"> /// A reference to the <see cref="GraphPane"/> object that is the parent or /// owner of this object. /// </param> /// <param name="points">A <see cref="PointPairList"/> of point values representing this /// curve.</param> /// <param name="isY2Axis">A value indicating to which Y axis this curve is assigned. /// true for the "Y2" axis, false for the "Y" axis.</param> public void DrawSmoothFilledCurve( Graphics g, GraphPane pane, PointPairList points, bool isY2Axis, double scaleFactor) { PointF[] arrPoints; int count; if ( this.IsVisible && !this.Color.IsEmpty && points != null && BuildPointsArray( pane, points, isY2Axis, out arrPoints, out count ) && count > 2 ) { Pen pen = new Pen(this.Color, pane.ScaledPenWidth(width, scaleFactor)); pen.DashStyle = this.Style; float tension = this.isSmooth ? this.smoothTension : 0f; // Fill the curve if needed if ( this.Fill.IsVisible ) { GraphicsPath path = new GraphicsPath( FillMode.Winding ); path.AddCurve( arrPoints, 0, count-2, tension ); double yMin = pane.YAxis.Min < 0 ? 0.0 : pane.YAxis.Min; //double yMin = pane.YAxis.Min; CloseCurve( pane, arrPoints, isY2Axis, count, yMin, path ); Brush brush = this.fill.MakeBrush( path.GetBounds() ); g.FillPath( brush, path ); brush.Dispose(); } // Stroke the curve g.DrawCurve( pen, arrPoints, 0, count-2, tension ); } }
/// <summary> /// Draw the this <see cref="CurveItem"/> to the specified <see cref="Graphics"/> /// device. The format (stair-step or line) of the curve is /// defined by the <see cref="StepType"/> property. The routine /// only draws the line segments; the symbols are drawn by the /// <see cref="Symbol.Draw"/> method. This method /// is normally only called by the Draw method of the /// <see cref="CurveItem"/> object /// </summary> /// <param name="g"> /// A graphic device object to be drawn into. This is normally e.Graphics from the /// PaintEventArgs argument to the Paint() method. /// </param> /// <param name="scaleFactor"> /// The scaling factor to be used for rendering objects. This is calculated and /// passed down by the parent <see cref="GraphPane"/> object using the /// <see cref="GraphPane.CalcScaleFactor"/> method, and is used to proportionally adjust /// font sizes, etc. according to the actual size of the graph. /// </param> /// <param name="pane"> /// A reference to the <see cref="GraphPane"/> object that is the parent or /// owner of this object. /// </param> /// <param name="points">A <see cref="PointPairList"/> of point values representing this /// curve.</param> /// <param name="isY2Axis">A value indicating to which Y axis this curve is assigned. /// true for the "Y2" axis, false for the "Y" axis.</param> public void DrawCurve( Graphics g, GraphPane pane, PointPairList points, bool isY2Axis, double scaleFactor) { float tmpX, tmpY, lastX = 0, lastY = 0; double curX, curY; bool broke = true; Pen pen = new Pen(this.color, pane.ScaledPenWidth(width, scaleFactor)); pen.DashStyle = this.Style; if ( points != null && !this.color.IsEmpty && this.IsVisible ) { // Loop over each point in the curve for ( int i=0; i<points.Count; i++ ) { curX = points[i].X; curY = points[i].Y; // Any value set to double max is invalid and should be skipped // This is used for calculated values that are out of range, divide // by zero, etc. // Also, any value <= zero on a log scale is invalid if ( curX == PointPair.Missing || curY == PointPair.Missing || System.Double.IsNaN( curX ) || System.Double.IsNaN( curY ) || System.Double.IsInfinity( curX ) || System.Double.IsInfinity( curY ) || ( pane.XAxis.IsLog && curX <= 0.0 ) || ( isY2Axis && pane.Y2Axis.IsLog && curY <= 0.0 ) || ( !isY2Axis && pane.YAxis.IsLog && curY <= 0.0 ) ) { broke = true; } else { // Transform the current point from user scale units to // screen coordinates tmpX = pane.XAxis.Transform( curX ); if ( isY2Axis ) tmpY = pane.Y2Axis.Transform( curY ); else tmpY = pane.YAxis.Transform( curY ); // off-scale values "break" the line if ( tmpX < -100000 || tmpX > 100000 || tmpY < -100000 || tmpY > 100000 ) broke = true; else { // If the last two points are valid, draw a line segment if ( !broke || ( pane.IsIgnoreMissing && lastX != 0 ) ) { if ( this.StepType == StepType.ForwardStep ) { g.DrawLine( pen, lastX, lastY, tmpX, lastY ); g.DrawLine( pen, tmpX, lastY, tmpX, tmpY ); } else if ( this.StepType == StepType.RearwardStep ) { g.DrawLine( pen, lastX, lastY, lastX, tmpY ); g.DrawLine( pen, lastX, tmpY, tmpX, tmpY ); } else // non-step g.DrawLine( pen, lastX, lastY, tmpX, tmpY ); } // Save some values for the next point broke = false; lastX = tmpX; lastY = tmpY; } } } } }
internal Pen GetPen(GraphPane pane, float scaleFactor) { var pen = new Pen(_color, pane.ScaledPenWidth(_width, scaleFactor)); pen.DashStyle = _style; if (_style == DashStyle.Custom) { if (_dashOff > 1e-10 && _dashOn > 1e-10) { pen.DashStyle = DashStyle.Custom; var pattern = new float[2]; pattern[0] = _dashOn; pattern[1] = _dashOff; pen.DashPattern = pattern; } else pen.DashStyle = DashStyle.Solid; } return pen; }
/// <summary> /// Draw the scale, including the tic marks, value labels, and grid lines as /// required for this <see cref="Axis"/>. /// </summary> /// <param name="g"> /// A graphic device object to be drawn into. This is normally e.Graphics from the /// PaintEventArgs argument to the Paint() method. /// </param> /// <param name="pane"> /// A reference to the <see cref="GraphPane"/> object that is the parent or /// owner of this object. /// </param> /// <param name="scaleFactor"> /// The scaling factor to be used for rendering objects. This is calculated and /// passed down by the parent <see cref="GraphPane"/> object using the /// <see cref="GraphPane.CalcScaleFactor"/> method, and is used to proportionally adjust /// font sizes, etc. according to the actual size of the graph. /// </param> public void DrawScale( Graphics g, GraphPane pane, double scaleFactor ) { float rightPix, topPix; if ( this is XAxis ) { rightPix = pane.AxisRect.Width; topPix = -pane.AxisRect.Height; } else { rightPix = pane.AxisRect.Height; topPix = -pane.AxisRect.Width; } // sanity check if ( this.min >= this.max ) return; // if the step size is outrageous, then quit // (step size not used for log scales) if ( !this.IsLog ) { if ( this.step <= 0 || this.minorStep <= 0 ) return; double tMajor = ( this.max - this.min ) / this.step, tMinor = ( this.max - this.min ) / this.minorStep; if ( IsDate ) { tMajor /= GetUnitMultiple( majorUnit ); tMinor /= GetUnitMultiple( minorUnit ); } if ( tMajor > 1000 || ( ( this.isMinorTic || this.isMinorInsideTic || this.isMinorOppositeTic ) && tMinor > 5000 ) ) return; } // calculate the total number of major tics required int nTics = CalcNumTics(); // get the first major tic value double baseVal = CalcBaseTic(); if ( this.IsVisible ) { Pen pen = new Pen(this.color, pane.ScaledPenWidth(ticPenWidth, scaleFactor)); // redraw the axis border g.DrawLine( pen, 0.0F, 0.0F, rightPix, 0.0F ); // Draw a zero-value line if needed if ( this.isZeroLine && this.min < 0.0 && this.max > 0.0 ) { float zeroPix = LocalTransform( 0.0 ); g.DrawLine( pen, zeroPix, 0.0F, zeroPix, topPix ); } // draw the major tics and labels DrawLabels( g, pane, baseVal, nTics, topPix, scaleFactor ); DrawMinorTics( g, pane, baseVal, scaleFactor, topPix ); } }
/// <summary> /// Draw the scale, including the tic marks, value labels, and grid lines as /// required for this <see cref="Axis"/>. /// </summary> /// <param name="g"> /// A graphic device object to be drawn into. This is normally e.Graphics from the /// PaintEventArgs argument to the Paint() method. /// </param> /// <param name="pane"> /// A reference to the <see cref="GraphPane"/> object that is the parent or /// owner of this object. /// </param> /// <param name="scaleFactor"> /// The scaling factor to be used for rendering objects. This is calculated and /// passed down by the parent <see cref="GraphPane"/> object using the /// <see cref="PaneBase.CalcScaleFactor"/> method, and is used to proportionally adjust /// font sizes, etc. according to the actual size of the graph. /// </param> /// <param name="shiftPos"> /// The number of pixels to shift to account for non-primary axis position (e.g., /// the second, third, fourth, etc. <see cref="YAxis" /> or <see cref="Y2Axis" />. /// </param> internal void Draw( Graphics g, GraphPane pane, float scaleFactor, float shiftPos ) { MajorGrid majorGrid = _ownerAxis._majorGrid; MajorTic majorTic = _ownerAxis._majorTic; MinorTic minorTic = _ownerAxis._minorTic; float rightPix, topPix; GetTopRightPix( pane, out topPix, out rightPix ); // calculate the total number of major tics required int nTics = CalcNumTics(); // get the first major tic value double baseVal = CalcBaseTic(); using ( Pen pen = new Pen( _ownerAxis.Color, pane.ScaledPenWidth( majorTic._penWidth, scaleFactor ) ) ) { // redraw the axis border if ( _ownerAxis.IsAxisSegmentVisible ) g.DrawLine( pen, 0.0F, shiftPos, rightPix, shiftPos ); // Draw a zero-value line if needed if ( majorGrid._isZeroLine && _min < 0.0 && _max > 0.0 ) { float zeroPix = LocalTransform( 0.0 ); g.DrawLine( pen, zeroPix, 0.0F, zeroPix, topPix ); } } // draw the major tics and labels DrawLabels( g, pane, baseVal, nTics, topPix, shiftPos, scaleFactor ); // _ownerAxis.DrawMinorTics( g, pane, baseVal, shiftPos, scaleFactor, topPix ); _ownerAxis.DrawTitle( g, pane, shiftPos, scaleFactor ); }
/// <summary> /// Draw the this <see cref="CurveItem"/> to the specified <see cref="Graphics"/> /// device. The format (stair-step or line) of the curve is /// defined by the <see cref="StepType"/> property. The routine /// only draws the line segments; the symbols are drawn by the /// <see cref="Symbol.Draw"/> method. This method /// is normally only called by the Draw method of the /// <see cref="CurveItem"/> object /// </summary> /// <param name="g"> /// A graphic device object to be drawn into. This is normally e.Graphics from the /// PaintEventArgs argument to the Paint() method. /// </param> /// <param name="scaleFactor"> /// The scaling factor to be used for rendering objects. This is calculated and /// passed down by the parent <see cref="GraphPane"/> object using the /// <see cref="PaneBase.CalcScaleFactor"/> method, and is used to proportionally adjust /// font sizes, etc. according to the actual size of the graph. /// </param> /// <param name="pane"> /// A reference to the <see cref="GraphPane"/> object that is the parent or /// owner of this object. /// </param> /// <param name="curve">A <see cref="LineItem"/> representing this /// curve.</param> public void DrawCurve(Graphics g, GraphPane pane, CurveItem curve, float scaleFactor) { float tmpX, tmpY, lastX = 0, lastY = 0; double curX, curY, lowVal; bool broke = true; PointPairList points = curve.Points; ValueHandler valueHandler = new ValueHandler(pane, false); Axis yAxis = curve.IsY2Axis ? (Axis)pane.Y2Axis : (Axis)pane.YAxis; Pen pen = new Pen(this.color, pane.ScaledPenWidth(width, scaleFactor)); pen.DashStyle = this.Style; if (points != null && !this.color.IsEmpty && this.IsVisible) { // Loop over each point in the curve for (int i = 0; i < points.Count; i++) { if (pane.LineType == LineType.Stack) { if (!valueHandler.GetValues(curve, i, out curX, out lowVal, out curY)) { curX = PointPair.Missing; curY = PointPair.Missing; } } else { curX = points[i].X; curY = points[i].Y; } // Any value set to double max is invalid and should be skipped // This is used for calculated values that are out of range, divide // by zero, etc. // Also, any value <= zero on a log scale is invalid if (curX == PointPair.Missing || curY == PointPair.Missing || System.Double.IsNaN(curX) || System.Double.IsNaN(curY) || System.Double.IsInfinity(curX) || System.Double.IsInfinity(curY) || (pane.XAxis.IsLog && curX <= 0.0) || (yAxis.IsLog && curY <= 0.0)) { broke = true; } else { // Transform the current point from user scale units to // screen coordinates tmpX = pane.XAxis.Transform(curve.IsOverrideOrdinal, i, curX); tmpY = yAxis.Transform(curve.IsOverrideOrdinal, i, curY); // off-scale values "break" the line if (tmpX < -1000000 || tmpX > 1000000 || tmpY < -1000000 || tmpY > 1000000) { broke = true; } else { // If the last two points are valid, draw a line segment if (!broke || (pane.IsIgnoreMissing && lastX != 0)) { if (this.StepType == StepType.ForwardStep) { g.DrawLine(pen, lastX, lastY, tmpX, lastY); g.DrawLine(pen, tmpX, lastY, tmpX, tmpY); } else if (this.StepType == StepType.RearwardStep) { g.DrawLine(pen, lastX, lastY, lastX, tmpY); g.DrawLine(pen, lastX, tmpY, tmpX, tmpY); } else // non-step { g.DrawLine(pen, lastX, lastY, tmpX, tmpY); } } // Save some values for the next point broke = false; lastX = tmpX; lastY = tmpY; } } } } }
/// <summary> /// Render a single <see cref="Line"/> segment to the specified /// <see cref="Graphics"/> device. /// </summary> /// <param name="g"> /// A graphic device object to be drawn into. This is normally e.Graphics from the /// PaintEventArgs argument to the Paint() method. /// </param> /// <param name="pane"> /// A reference to the <see cref="ZedGraph.GraphPane"/> object that is the parent or /// owner of this object. /// </param> /// <param name="scaleFactor"> /// The scaling factor to be used for rendering objects. This is calculated and /// passed down by the parent <see cref="GraphPane"/> object using the /// <see cref="GraphPane.CalcScaleFactor"/> method, and is used to proportionally adjust /// font sizes, etc. according to the actual size of the graph. /// </param> /// <param name="x1">The x position of the starting point that defines the /// line segment in screen pixel units</param> /// <param name="y1">The y position of the starting point that defines the /// line segment in screen pixel units</param> /// <param name="x2">The x position of the ending point that defines the /// line segment in screen pixel units</param> /// <param name="y2">The y position of the ending point that defines the /// line segment in screen pixel units</param> public void DrawSegment(Graphics g, GraphPane pane, float x1, float y1, float x2, float y2, double scaleFactor) { if ( this.isVisible && !this.Color.IsEmpty ) { Pen pen = new Pen(this.color, pane.ScaledPenWidth(width, scaleFactor)); pen.DashStyle = this.Style; g.DrawLine( pen, x1, y1, x2, y2 ); } }
/// <summary> /// Create a new <see cref="Pen"/> object from the properties of this /// <see cref="Border"/> object. /// </summary> /// <param name="pane"> /// A reference to the <see cref="ZedGraph.GraphPane"/> object that is the parent or /// owner of this object. /// </param> /// <param name="scaleFactor"> /// The scaling factor for the features of the graph based on the <see cref="GraphPane.BaseDimension"/>. This /// scaling factor is calculated by the <see cref="GraphPane.CalcScaleFactor"/> method. The scale factor /// represents a linear multiple to be applied to font sizes, symbol sizes, etc. /// </param> /// <returns>A <see cref="Pen"/> object with the proper color and pen width.</returns> public Pen MakePen(GraphPane pane, double scaleFactor) { return(new Pen(color, pane.ScaledPenWidth(penWidth, scaleFactor))); }
internal Pen GetPen(GraphPane pane, float scaleFactor) { return(new Pen(_color, pane.ScaledPenWidth(_penWidth, scaleFactor))); }
/// <summary> /// Draw the scale, including the tic marks, value labels, and grid lines as /// required for this <see cref="Axis"/>. /// </summary> /// <param name="g"> /// A graphic device object to be drawn into. This is normally e.Graphics from the /// PaintEventArgs argument to the Paint() method. /// </param> /// <param name="pane"> /// A reference to the <see cref="GraphPane"/> object that is the parent or /// owner of this object. /// </param> /// <param name="scaleFactor"> /// The scaling factor to be used for rendering objects. This is calculated and /// passed down by the parent <see cref="GraphPane"/> object using the /// <see cref="PaneBase.CalcScaleFactor"/> method, and is used to proportionally adjust /// font sizes, etc. according to the actual size of the graph. /// </param> /// <param name="shiftPos"> /// The number of pixels to shift to account for non-primary axis position (e.g., /// the second, third, fourth, etc. <see cref="YAxis" /> or <see cref="Y2Axis" />. /// </param> internal void Draw(Graphics g, GraphPane pane, float scaleFactor, float shiftPos) { MajorGrid majorGrid = _ownerAxis._majorGrid; MajorTic majorTic = _ownerAxis._majorTic; MinorTic minorTic = _ownerAxis._minorTic; float rightPix, topPix; if (_ownerAxis is XAxis) { rightPix = pane.Chart._rect.Width; topPix = -pane.Chart._rect.Height; } else { rightPix = pane.Chart._rect.Height; topPix = -pane.Chart._rect.Width; } // sanity check if (_min >= _max) return; // if the step size is outrageous, then quit // (step size not used for log scales) if (!IsLog) { if (_majorStep <= 0 || _minorStep <= 0) return; double tMajor = (_max - _min)/(_majorStep*MajorUnitMultiplier); double tMinor = (_max - _min)/(_minorStep*MinorUnitMultiplier); if (tMajor > 1000 || ((minorTic.IsOutside || minorTic.IsInside || minorTic.IsOpposite) && tMinor > 5000)) return; } // calculate the total number of major tics required int nTics = CalcNumTics(); // get the first major tic value double baseVal = CalcBaseTic(); using (var pen = new Pen(_ownerAxis.Color, pane.ScaledPenWidth(majorTic._penWidth, scaleFactor))) { // redraw the axis border if (_ownerAxis.IsAxisSegmentVisible) g.DrawLine(pen, 0.0F, shiftPos, rightPix, shiftPos); // Draw a zero-value line if needed if (majorGrid._isZeroLine && _min < 0.0 && _max > 0.0) { float zeroPix = LocalTransform(0.0); g.DrawLine(pen, zeroPix, 0.0F, zeroPix, topPix); } } // draw the major tics and labels DrawLabels(g, pane, baseVal, nTics, topPix, shiftPos, scaleFactor); _ownerAxis.DrawMinorTics(g, pane, baseVal, shiftPos, scaleFactor, topPix); _ownerAxis.DrawTitle(g, pane, shiftPos, scaleFactor); }
internal void FixZeroLine( IGraphics g, GraphPane pane, float scaleFactor, float left, float right ) { // restore the zero line if needed (since the fill tends to cover it up) if ( _isVisible && _majorGrid._isZeroLine && _scale._min < 0.0 && _scale._max > 0.0 ) { float zeroPix = _scale.Transform( 0.0 ); using ( Pen zeroPen = new Pen( _color, pane.ScaledPenWidth( _majorGrid._penWidth, scaleFactor ) ) ) { g.DrawLine( zeroPen, left, zeroPix, right, zeroPix ); //zeroPen.Dispose(); } } }
/// <summary> /// Create a new <see cref="Pen"/> object from the properties of this /// <see cref="Border"/> object. /// </summary> /// <param name="pane"> /// A reference to the <see cref="ZedGraph.GraphPane"/> object that is the parent or /// owner of this object. /// </param> /// <param name="scaleFactor"> /// The scaling factor for the features of the graph based on the <see cref="GraphPane.BaseDimension"/>. This /// scaling factor is calculated by the <see cref="GraphPane.CalcScaleFactor"/> method. The scale factor /// represents a linear multiple to be applied to font sizes, symbol sizes, etc. /// </param> /// <returns>A <see cref="Pen"/> object with the proper color and pen width.</returns> public Pen MakePen( GraphPane pane, double scaleFactor ) { return new Pen( color, pane.ScaledPenWidth( penWidth, scaleFactor ) ); }
internal Pen GetPen( GraphPane pane, float scaleFactor ) { Pen pen = new Pen( _color, pane.ScaledPenWidth( _penWidth, scaleFactor ) ); if ( _dashOff > 1e-10 && _dashOn > 1e-10 ) { pen.DashStyle = DashStyle.Custom; float[] pattern = new float[2]; pattern[0] = _dashOn; pattern[1] = _dashOff; pen.DashPattern = pattern; } return pen; }
/// <summary> /// Render this object to the specified <see cref="Graphics"/> device. /// </summary> /// <remarks> /// This method is normally only called by the Draw method /// of the parent <see cref="GraphItemList"/> collection object. /// </remarks> /// <param name="g"> /// A graphic device object to be drawn into. This is normally e.Graphics from the /// PaintEventArgs argument to the Paint() method. /// </param> /// <param name="pane"> /// A reference to the <see cref="GraphPane"/> object that is the parent or /// owner of this object. /// </param> /// <param name="scaleFactor"> /// The scaling factor to be used for rendering objects. This is calculated and /// passed down by the parent <see cref="GraphPane"/> object using the /// <see cref="GraphPane.CalcScaleFactor"/> method, and is used to proportionally adjust /// font sizes, etc. according to the actual size of the graph. /// </param> public override void Draw( Graphics g, GraphPane pane, double scaleFactor ) { // Convert the arrow coordinates from the user coordinate system // to the screen coordinate system PointF pix1 = this.Location.TransformTopLeft( pane ); PointF pix2 = this.Location.TransformBottomRight( pane ); if ( pix1.X > -10000 && pix1.X < 100000 && pix1.Y > -100000 && pix1.Y < 100000 && pix2.X > -10000 && pix2.X < 100000 && pix2.Y > -100000 && pix2.Y < 100000 ) { // get a scaled size for the arrowhead float scaledSize = (float) ( this.size * scaleFactor ); // calculate the length and the angle of the arrow "vector" double dy = pix2.Y - pix1.Y; double dx = pix2.X - pix1.X; float angle = (float) Math.Atan2( dy, dx ) * 180.0F / (float) Math.PI; float length = (float) Math.Sqrt( dx*dx + dy*dy ); // Save the old transform matrix Matrix transform = g.Transform; // Move the coordinate system so it is located at the starting point // of this arrow g.TranslateTransform( pix1.X, pix1.Y ); // Rotate the coordinate system according to the angle of this arrow // about the starting point g.RotateTransform( angle ); // get a pen according to this arrow properties Pen pen = new Pen( this.color, pane.ScaledPenWidth( penWidth,scaleFactor) ); // Draw the line segment for this arrow g.DrawLine( pen, 0, 0, length-scaledSize*0.75F, 0 ); // Only show the arrowhead if required if ( this.isArrowHead ) { SolidBrush brush = new SolidBrush( this.color ); // Create a polygon representing the arrowhead based on the scaled // size PointF[] polyPt = new PointF[4]; float hsize = scaledSize / 3.0F; polyPt[0].X = length; polyPt[0].Y = 0; polyPt[1].X = length-scaledSize; polyPt[1].Y = hsize; polyPt[2].X = length-scaledSize; polyPt[2].Y = -hsize; polyPt[3] = polyPt[0]; // render the arrowhead g.FillPolygon( brush, polyPt ); } // Restore the transform matrix back to its original state g.Transform = transform; } }