コード例 #1
0
        public void Render(PlotDimensions dims, Bitmap bmp, bool lowQuality = false)
        {
            if (IsVisible == false || (string.IsNullOrWhiteSpace(Label) && ImageLabel == null))
            {
                return;
            }

            using var gfx      = GDI.Graphics(bmp, lowQuality);
            (float x, float y) = GetAxisCenter(dims);

            if (ImageLabel is null)
            {
                RenderTextLabel(gfx, x, y);
            }
            else
            {
                RenderImageLabel(gfx, x, y);
            }
        }
コード例 #2
0
ファイル: LollipopPlot.cs プロジェクト: Jmerk523/ScottPlot
        private void RenderBarHorizontal(PlotDimensions dims, Graphics gfx, double position, double value, double valueError, double yOffset)
        {
            // bar body
            float  centerPx  = dims.GetPixelY(position);
            double edge2     = position + BarWidth / 2;
            double value1    = Math.Min(ValueBase, value) + yOffset;
            double value2    = Math.Max(ValueBase, value) + yOffset;
            double valueSpan = value2 - value1;
            var    rect      = new RectangleF(
                x: dims.GetPixelX(value1),
                y: dims.GetPixelY(edge2),
                height: (float)(BarWidth * dims.PxPerUnitY),
                width: (float)(valueSpan * dims.PxPerUnitX));

            RenderBarFromRect(rect, value < 0, gfx);

            // errorbar
            double error1   = value > 0 ? value2 - Math.Abs(valueError) : value1 - Math.Abs(valueError);
            double error2   = value > 0 ? value2 + Math.Abs(valueError) : value1 + Math.Abs(valueError);
            float  capPx1   = dims.GetPixelY(position - ErrorCapSize * BarWidth / 2);
            float  capPx2   = dims.GetPixelY(position + ErrorCapSize * BarWidth / 2);
            float  errorPx2 = dims.GetPixelX(error2);
            float  errorPx1 = dims.GetPixelX(error1);

            if (ErrorLineWidth > 0 && valueError > 0)
            {
                using var errorPen = new Pen(ErrorColor, ErrorLineWidth);
                gfx.DrawLine(errorPen, errorPx1, centerPx, errorPx2, centerPx);
                gfx.DrawLine(errorPen, errorPx1, capPx2, errorPx1, capPx1);
                gfx.DrawLine(errorPen, errorPx2, capPx2, errorPx2, capPx1);
            }

            if (ShowValuesAboveBars)
            {
                using (var valueTextFont = GDI.Font(Font))
                    using (var valueTextBrush = GDI.Brush(Font.Color))
                        using (var sf = new StringFormat()
                        {
                            LineAlignment = StringAlignment.Center, Alignment = StringAlignment.Near
                        })
                            gfx.DrawString(ValueFormatter(value), valueTextFont, valueTextBrush, rect.X + rect.Width, centerPx, sf);
            }
        }
コード例 #3
0
        public Tick[] GetVisibleMinorTicks(PlotDimensions dims)
        {
            double high, low;

            if (Orientation == AxisOrientation.Vertical)
            {
                low  = dims.YMin - dims.UnitsPerPxY; // add an extra pixel to capture the edge tick
                high = dims.YMax + dims.UnitsPerPxY; // add an extra pixel to capture the edge tick
            }
            else
            {
                low  = dims.XMin - dims.UnitsPerPxX; // add an extra pixel to capture the edge tick
                high = dims.XMax + dims.UnitsPerPxX; // add an extra pixel to capture the edge tick
            }

            return(GetMinorTicks()
                   .Where(t => t.Position >= low && t.Position <= high)
                   .ToArray());
        }
コード例 #4
0
ファイル: Legend.cs プロジェクト: ajipsum/ScottPlot
        private (float x, float y) GetLocationPx(PlotDimensions dims, float width, float height)
        {
            float leftX   = dims.DataOffsetX + Padding;
            float rightX  = dims.DataOffsetX + dims.DataWidth - Padding - width;
            float centerX = dims.DataOffsetX + dims.DataWidth / 2 - width / 2;

            float topY    = dims.DataOffsetY + Padding;
            float bottomY = dims.DataOffsetY + dims.DataHeight - Padding - height;
            float centerY = dims.DataOffsetY + dims.DataHeight / 2 - height / 2;

            switch (Location)
            {
            case Alignment.UpperLeft:
                return(leftX, topY);

            case Alignment.UpperCenter:
                return(centerX, topY);

            case Alignment.UpperRight:
                return(rightX, topY);

            case Alignment.MiddleRight:
                return(rightX, centerY);

            case Alignment.LowerRight:
                return(rightX, bottomY);

            case Alignment.LowerCenter:
                return(centerX, bottomY);

            case Alignment.LowerLeft:
                return(leftX, bottomY);

            case Alignment.MiddleLeft:
                return(leftX, centerY);

            case Alignment.MiddleCenter:
                return(centerX, centerY);

            default:
                throw new NotImplementedException();
            }
        }
コード例 #5
0
        public new void Render(PlotDimensions dims, Bitmap bmp, bool lowQuality = false)
        {
            base.Render(dims, bmp, lowQuality);

            if (isHighlighted is null || isHighlighted.Length == 0)
            {
                return;
            }

            using (var gfx = GDI.Graphics(bmp, dims, lowQuality))
            {
                var highlightedIndexes = Enumerable.Range(0, isHighlighted.Length).Where(x => isHighlighted[x]);
                foreach (int i in highlightedIndexes)
                {
                    PointF pt = new PointF(dims.GetPixelX(xs[i]), dims.GetPixelY(ys[i]));
                    MarkerTools.DrawMarker(gfx, pt, highlightedShape, highlightedMarkerSize, highlightedColor);
                }
            }
        }
コード例 #6
0
ファイル: Image.cs プロジェクト: xiaobin620/ScottPlot
        public void Render(PlotDimensions dims, Bitmap bmp, bool lowQuality = false)
        {
            PointF defaultPoint      = new PointF(dims.GetPixelX(x), dims.GetPixelY(y));
            PointF textLocationPoint = (rotation == 0) ? TextLocation(defaultPoint) : defaultPoint;

            using (Graphics gfx = GDI.Graphics(bmp, dims, lowQuality))
                using (var framePen = new Pen(frameColor, frameSize * 2))
                {
                    gfx.TranslateTransform((int)textLocationPoint.X, (int)textLocationPoint.Y);
                    gfx.RotateTransform((float)rotation);

                    if (frameSize > 0)
                    {
                        gfx.DrawRectangle(framePen, new Rectangle(0, 0, image.Width - 1, image.Height - 1));
                    }

                    gfx.DrawImage(image, new PointF(0, 0));
                    gfx.ResetTransform();
                }
        }
コード例 #7
0
ファイル: TickCollection.cs プロジェクト: whble/ScottPlot
        public void Recalculate(PlotDimensions dims, Drawing.Font tickFont)
        {
            if (manualTickPositions is null)
            {
                // first pass uses forced density with manual label sizes to consistently approximate labels
                if (LabelFormat == TickLabelFormat.DateTime)
                {
                    RecalculatePositionsAutomaticDatetime(dims, 20, 24, (int)(10 * TickDensity));
                }
                else
                {
                    RecalculatePositionsAutomaticNumeric(dims, 15, 12, (int)(10 * TickDensity));
                }

                // second pass calculates density using measured labels produced by the first pass
                (LargestLabelWidth, LargestLabelHeight) = MaxLabelSize(tickFont);
                if (LabelFormat == TickLabelFormat.DateTime)
                {
                    RecalculatePositionsAutomaticDatetime(dims, LargestLabelWidth, LargestLabelHeight, null);
                }
                else
                {
                    RecalculatePositionsAutomaticNumeric(dims, LargestLabelWidth, LargestLabelHeight, null);
                }
            }
            else
            {
                double min = Orientation == AxisOrientation.Vertical ? dims.YMin : dims.XMin;
                double max = Orientation == AxisOrientation.Vertical ? dims.YMax : dims.XMax;

                var visibleIndexes = Enumerable.Range(0, manualTickPositions.Count())
                                     .Where(i => manualTickPositions[i] >= min)
                                     .Where(i => manualTickPositions[i] <= max);

                tickPositionsMajor = visibleIndexes.Select(x => manualTickPositions[x]).ToArray();
                tickPositionsMinor = null;
                tickLabels         = visibleIndexes.Select(x => manualTickLabels[x]).ToArray();
                CornerLabel        = null;
                (LargestLabelWidth, LargestLabelHeight) = MaxLabelSize(tickFont);
            }
        }
コード例 #8
0
 public void Render(PlotDimensions dims, Bitmap bmp, bool lowQuality = false)
 {
     using (var gfx = GDI.Graphics(bmp, dims, lowQuality))
         using (var pen = GDI.Pen(color, lineWidth, lineStyle, true))
         {
             if (IsHorizontal)
             {
                 float pixelX1 = dims.GetPixelX(dims.XMin);
                 float pixelX2 = dims.GetPixelX(dims.XMax);
                 float pixelY  = dims.GetPixelY(position);
                 gfx.DrawLine(pen, pixelX1, pixelY, pixelX2, pixelY);
             }
             else
             {
                 float pixelX  = dims.GetPixelX(position);
                 float pixelY1 = dims.GetPixelY(dims.YMin);
                 float pixelY2 = dims.GetPixelY(dims.YMax);
                 gfx.DrawLine(pen, pixelX, pixelY1, pixelX, pixelY2);
             }
         }
 }
コード例 #9
0
        public void Render(PlotDimensions dims, Bitmap bmp, bool lowQuality = false)
        {
            using (var gfx = GDI.Graphics(bmp, dims, lowQuality))
                using (var font = GDI.Font(FontName, FontSize, FontBold))
                    using (var fontBrush = new SolidBrush(FontColor))
                        using (var linePen = new Pen(LineColor, LineWidth))
                            using (var sfNorth = new StringFormat()
                            {
                                LineAlignment = StringAlignment.Near, Alignment = StringAlignment.Center
                            })
                                using (var sfWest = new StringFormat()
                                {
                                    LineAlignment = StringAlignment.Center, Alignment = StringAlignment.Near
                                })
                                {
                                    // determine where the corner of the scalebar will be
                                    float  widthPx     = (float)(Width * dims.PxPerUnitX);
                                    float  heightPx    = (float)(Height * dims.PxPerUnitY);
                                    PointF cornerPoint = new PointF(dims.GetPixelX(dims.XMax) - Padding, dims.GetPixelY(dims.YMin) - Padding);

                                    // move the corner point away from the edge to accommodate label size
                                    var xLabelSize = GDI.MeasureString(gfx, HorizontalLabel, font);
                                    var yLabelSize = GDI.MeasureString(gfx, VerticalLabel, font);
                                    cornerPoint.X -= yLabelSize.Width * 1.2f;
                                    cornerPoint.Y -= yLabelSize.Height;

                                    // determine all other points relative to the corner point
                                    PointF horizPoint    = new PointF(cornerPoint.X - widthPx, cornerPoint.Y);
                                    PointF vertPoint     = new PointF(cornerPoint.X, cornerPoint.Y - heightPx);
                                    PointF horizMidPoint = new PointF((cornerPoint.X + horizPoint.X) / 2, cornerPoint.Y);
                                    PointF vertMidPoint  = new PointF(cornerPoint.X, (cornerPoint.Y + vertPoint.Y) / 2);

                                    // draw the scalebar
                                    gfx.DrawLines(linePen, new PointF[] { horizPoint, cornerPoint, vertPoint });
                                    gfx.DrawString(HorizontalLabel, font, fontBrush, horizMidPoint.X, cornerPoint.Y, sfNorth);
                                    gfx.DrawString(VerticalLabel, font, fontBrush, cornerPoint.X, vertMidPoint.Y, sfWest);
                                }
        }
コード例 #10
0
ファイル: AxisTicks.cs プロジェクト: xianglongcheng/ScottPlot
        private void RenderGridLines(PlotDimensions dims, Graphics gfx, double[] positions,
                                     LineStyle gridLineStyle, Color gridLineColor, float gridLineWidth)
        {
            if (positions is null || positions.Length == 0 || gridLineStyle == LineStyle.None)
            {
                return;
            }

            if (IsVertical)
            {
                float x  = (Edge == Edge.Left) ? dims.DataOffsetX : dims.DataOffsetX + dims.DataWidth;
                float x2 = (Edge == Edge.Left) ? dims.DataOffsetX + dims.DataWidth : dims.DataOffsetX;
                var   ys = positions.Select(i => dims.GetPixelY(i));
                if (gridLineStyle != LineStyle.None)
                {
                    using (var pen = GDI.Pen(gridLineColor, gridLineWidth, gridLineStyle))
                        foreach (float y in ys)
                        {
                            gfx.DrawLine(pen, x, y, x2, y);
                        }
                }
            }

            if (IsHorizontal)
            {
                float y  = (Edge == Edge.Top) ? dims.DataOffsetY : dims.DataOffsetY + dims.DataHeight;
                float y2 = (Edge == Edge.Top) ? dims.DataOffsetY + dims.DataHeight : dims.DataOffsetY;
                var   xs = positions.Select(i => dims.GetPixelX(i));
                if (gridLineStyle != LineStyle.None)
                {
                    using (var pen = GDI.Pen(gridLineColor, gridLineWidth, gridLineStyle))
                        foreach (float x in xs)
                        {
                            gfx.DrawLine(pen, x, y, x, y2);
                        }
                }
            }
        }
コード例 #11
0
        public static void Scatter(PlotDimensions dims, Bitmap bmp, bool lowQuality, Population pop, Random rand,
                                   double popLeft, double popWidth, Color fillColor, Color edgeColor, byte alpha, Position position)
        {
            // adjust edges to accomodate special positions
            if (position == Position.Hide)
            {
                return;
            }
            if (position == Position.Left || position == Position.Right)
            {
                popWidth /= 2;
            }
            if (position == Position.Right)
            {
                popLeft += popWidth;
            }

            // contract edges slightly to encourage padding between elements
            double edgePaddingFrac = 0.2;

            popLeft  += popWidth * edgePaddingFrac;
            popWidth -= (popWidth * edgePaddingFrac) * 2;

            float radius = 5;

            using (Graphics gfx = GDI.Graphics(bmp, dims, lowQuality))
                using (Pen penEdge = GDI.Pen(Color.FromArgb(alpha, edgeColor)))
                    using (Brush brushFill = GDI.Brush(Color.FromArgb(alpha, fillColor)))
                    {
                        foreach (double value in pop.values)
                        {
                            double yPx = dims.GetPixelY(value);
                            double xPx = dims.GetPixelX(popLeft + rand.NextDouble() * popWidth);
                            gfx.FillEllipse(brushFill, (float)(xPx - radius), (float)(yPx - radius), radius * 2, radius * 2);
                            gfx.DrawEllipse(penEdge, (float)(xPx - radius), (float)(yPx - radius), radius * 2, radius * 2);
                        }
                    }
        }
コード例 #12
0
ファイル: Text.cs プロジェクト: xiaobin620/ScottPlot
        public void Render(PlotDimensions dims, Bitmap bmp, bool lowQuality = false)
        {
            if (string.IsNullOrWhiteSpace(text))
            {
                return; // no render needed
            }
            using (Graphics gfx = GDI.Graphics(bmp, dims, lowQuality))
                using (var font = GDI.Font(FontName, FontSize, FontBold))
                {
                    float      pixelX     = dims.GetPixelX(x);
                    float      pixelY     = dims.GetPixelY(y);
                    SizeF      stringSize = GDI.MeasureString(gfx, text, font);
                    RectangleF stringRect = new RectangleF(0, 0, stringSize.Width, stringSize.Height);

                    if (rotation == 0)
                    {
                        (pixelX, pixelY) = ApplyAlignmentOffset(pixelX, pixelY, stringSize.Width, stringSize.Height);
                    }

                    gfx.TranslateTransform(pixelX, pixelY);
                    gfx.RotateTransform((float)rotation);

                    if (frame)
                    {
                        using (var frameBrush = new SolidBrush(frameColor))
                        {
                            gfx.FillRectangle(frameBrush, stringRect);
                        }
                    }

                    using (var fontBrush = new SolidBrush(FontColor))
                    {
                        gfx.DrawString(text, font, fontBrush, new PointF(0, 0));
                    }

                    gfx.ResetTransform();
                }
        }
コード例 #13
0
ファイル: Heatmap.cs プロジェクト: whble/ScottPlot
 private void RenderAxis(PlotDimensions dims, Bitmap bmp, bool lowQuality)
 {
     using (Graphics gfx = GDI.Graphics(bmp, dims, lowQuality))
         using (Pen pen = GDI.Pen(Color.Black))
             using (Brush brush = GDI.Brush(Color.Black))
                 using (var axisFont = GDI.Font(null, 12))
                     using (StringFormat right_centre = new StringFormat()
                     {
                         Alignment = StringAlignment.Far, LineAlignment = StringAlignment.Center
                     })
                         using (StringFormat centre_top = new StringFormat()
                         {
                             Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Near
                         })
                         {
                             double offset   = -2;
                             double minScale = Math.Min(dims.PxPerUnitX, dims.PxPerUnitY);
                             gfx.DrawString($"{AxisOffsets[0]:f3}", axisFont, brush, dims.GetPixelX(0), dims.GetPixelY(offset), centre_top);
                             gfx.DrawString($"{AxisOffsets[0] + AxisMultipliers[0]:f3}", axisFont, brush, new PointF((float)((Width * minScale) + dims.GetPixelX(0)), dims.GetPixelY(offset)), centre_top);
                             gfx.DrawString($"{AxisOffsets[1]:f3}", axisFont, brush, dims.GetPixelX(offset), dims.GetPixelY(0), right_centre);
                             gfx.DrawString($"{AxisOffsets[1] + AxisMultipliers[1]:f3}", axisFont, brush, new PointF(dims.GetPixelX(offset), dims.GetPixelY(0) - (float)(Height * minScale)), right_centre);
                         }
 }
コード例 #14
0
ファイル: BarSeries.cs プロジェクト: bclehmann/ScottPlot
 private RectangleF GetPixelRect(PlotDimensions dims, Bar bar)
 {
     if (bar.IsVertical)
     {
         float left   = dims.GetPixelX(bar.Position - bar.Thickness / 2);
         float right  = dims.GetPixelX(bar.Position + bar.Thickness / 2);
         float bottom = dims.GetPixelY(bar.ValueBase);
         float top    = dims.GetPixelY(bar.Value);
         float width  = right - left;
         float height = bottom - top;
         return(new RectangleF(left, top, width, height));
     }
     else
     {
         float left   = dims.GetPixelX(bar.ValueBase);
         float right  = dims.GetPixelX(bar.Value);
         float top    = dims.GetPixelY(bar.Position + bar.Thickness / 2);
         float bottom = dims.GetPixelY(bar.Position - bar.Thickness / 2);
         float width  = right - left;
         float height = bottom - top;
         return(new RectangleF(left, top, width, height));
     }
 }
コード例 #15
0
        // TODO: the negative coordiante thing is silly. Use alignment fields to control this behavior.

        public void Render(PlotDimensions dims, Bitmap bmp, bool lowQuality = false)
        {
            if (!IsVisible)
            {
                return;
            }

            using var gfx             = GDI.Graphics(bmp, lowQuality);
            using var font            = GDI.Font(Font);
            using var fontBrush       = new SolidBrush(Font.Color);
            using var shadowBrush     = new SolidBrush(ShadowColor);
            using var backgroundBrush = new SolidBrush(BackgroundColor);
            using var borderPen       = new Pen(BorderColor, BorderWidth);

            SizeF size = GDI.MeasureString(gfx, Label, font);

            double x        = (X >= 0) ? X : dims.DataWidth + X - size.Width;
            double y        = (Y >= 0) ? Y : dims.DataHeight + Y - size.Height;
            PointF location = new PointF((float)x + dims.DataOffsetX, (float)y + dims.DataOffsetY);

            if (Background && Shadow)
            {
                gfx.FillRectangle(shadowBrush, location.X + 5, location.Y + 5, size.Width, size.Height);
            }

            if (Background)
            {
                gfx.FillRectangle(backgroundBrush, location.X, location.Y, size.Width, size.Height);
            }

            if (Border)
            {
                gfx.DrawRectangle(borderPen, location.X, location.Y, size.Width, size.Height);
            }

            gfx.DrawString(Label, font, fontBrush, location);
        }
コード例 #16
0
        public void Recalculate(PlotDimensions dims, Drawing.Font tickFont)
        {
            if (manualTickPositions is null)
            {
                // first pass uses forced density with manual label sizes to consistently approximate labels
                if (dateFormat)
                {
                    RecalculatePositionsAutomaticDatetime(dims, 20, 24, 10);
                }
                else
                {
                    RecalculatePositionsAutomaticNumeric(dims, 15, 12, 10);
                }

                // second pass calculates density using measured labels produced by the first pass
                (maxLabelWidth, maxLabelHeight) = MaxLabelSize(tickFont);
                if (dateFormat)
                {
                    RecalculatePositionsAutomaticDatetime(dims, maxLabelWidth, maxLabelHeight, null);
                }
                else
                {
                    RecalculatePositionsAutomaticNumeric(dims, maxLabelWidth, maxLabelHeight, null);
                }
            }
            else
            {
                tickPositionsMajor = manualTickPositions;
                double min = verticalAxis ? dims.YMin : dims.XMin;
                double max = verticalAxis ? dims.YMax : dims.XMax;
                tickPositionsMajor = manualTickPositions.Where(x => x >= min && x <= max).ToArray();
                tickPositionsMinor = null;
                tickLabels         = manualTickLabels;
                cornerLabel        = null;
                (maxLabelWidth, maxLabelHeight) = MaxLabelSize(tickFont);
            }
        }
コード例 #17
0
        public void Render(PlotDimensions dims, Bitmap bmp, bool lowQuality = false)
        {
            if (IsVisible == false)
            {
                return;
            }

            using (var gfx = GDI.Graphics(bmp, dims, lowQuality, false))
                using (var pen = GDI.Pen(Color, Width))
                {
                    float left   = dims.DataOffsetX;
                    float right  = dims.DataOffsetX + dims.DataWidth;
                    float top    = dims.DataOffsetY;
                    float bottom = dims.DataOffsetY + dims.DataHeight;

                    if (Edge == Edge.Bottom)
                    {
                        gfx.DrawLine(pen, left, bottom + PixelOffset, right, bottom + PixelOffset);
                    }
                    else if (Edge == Edge.Left)
                    {
                        gfx.DrawLine(pen, left - PixelOffset, bottom, left - PixelOffset, top);
                    }
                    else if (Edge == Edge.Right)
                    {
                        gfx.DrawLine(pen, right + PixelOffset, bottom, right + PixelOffset, top);
                    }
                    else if (Edge == Edge.Top)
                    {
                        gfx.DrawLine(pen, left, top - PixelOffset, right, top - PixelOffset);
                    }
                    else
                    {
                        throw new NotImplementedException();
                    }
                }
        }
コード例 #18
0
        /// <summary>
        /// Return the point and rotation representing the center of the base of this axis
        /// </summary>
        private (float x, float y) GetAxisCenter(PlotDimensions dims)
        {
            float x = Edge switch
            {
                Edge.Left => dims.DataOffsetX - PixelOffset - PixelSize,
                Edge.Right => dims.DataOffsetX + dims.DataWidth + PixelOffset + PixelSize,
                Edge.Bottom => dims.DataOffsetX + dims.DataWidth / 2,
                Edge.Top => dims.DataOffsetX + dims.DataWidth / 2,
                _ => throw new NotImplementedException()
            };

            float y = Edge switch
            {
                Edge.Left => dims.DataOffsetY + dims.DataHeight / 2,
                Edge.Right => dims.DataOffsetY + dims.DataHeight / 2,
                Edge.Bottom => dims.DataOffsetY + dims.DataHeight + PixelOffset + PixelSize,
                Edge.Top => dims.DataOffsetY - PixelOffset - PixelSize,
                _ => throw new NotImplementedException()
            };

            return(x, y);
        }
    }
}
コード例 #19
0
        public void Render(PlotDimensions dims, Bitmap bmp, bool lowQuality = false)
        {
            Random rand       = new Random(0);
            double groupWidth = .8;
            var    popWidth   = groupWidth / seriesCount;

            for (int seriesIndex = 0; seriesIndex < seriesCount; seriesIndex++)
            {
                for (int groupIndex = 0; groupIndex < groupCount; groupIndex++)
                {
                    var series     = popMultiSeries.multiSeries[seriesIndex];
                    var population = series.populations[groupIndex];
                    var groupLeft  = groupIndex - groupWidth / 2;
                    var popLeft    = groupLeft + popWidth * seriesIndex;

                    Position scatterPos, boxPos;
                    switch (displayItems)
                    {
                    case DisplayItems.BoxAndScatter:
                        boxPos     = Position.Left;
                        scatterPos = Position.Right;
                        break;

                    case DisplayItems.BoxOnly:
                        boxPos     = Position.Center;
                        scatterPos = Position.Hide;
                        break;

                    case DisplayItems.ScatterAndBox:
                        boxPos     = Position.Right;
                        scatterPos = Position.Left;
                        break;

                    case DisplayItems.ScatterOnly:
                        boxPos     = Position.Hide;
                        scatterPos = Position.Center;
                        break;

                    default:
                        throw new NotImplementedException();
                    }

                    Scatter(dims, bmp, lowQuality, population, rand, popLeft, popWidth, series.color, scatterOutlineColor, 128, scatterPos);

                    if (displayDistributionCurve)
                    {
                        Distribution(dims, bmp, lowQuality, population, rand, popLeft, popWidth, distributionCurveColor, scatterPos, distributionCurveLineStyle);
                    }

                    switch (boxStyle)
                    {
                    case BoxStyle.BarMeanStdErr:
                        Bar(dims, bmp, lowQuality, population, rand, popLeft, popWidth, series.color, boxPos, useStdErr: true);
                        break;

                    case BoxStyle.BarMeanStDev:
                        Bar(dims, bmp, lowQuality, population, rand, popLeft, popWidth, series.color, boxPos, useStdErr: false);
                        break;

                    case BoxStyle.BoxMeanStdevStderr:
                        Box(dims, bmp, lowQuality, population, rand, popLeft, popWidth, series.color, boxPos, BoxFormat.StdevStderrMean);
                        break;

                    case BoxStyle.BoxMedianQuartileOutlier:
                        Box(dims, bmp, lowQuality, population, rand, popLeft, popWidth, series.color, boxPos, BoxFormat.OutlierQuartileMedian);
                        break;

                    case BoxStyle.MeanAndStderr:
                        MeanAndError(dims, bmp, lowQuality, population, rand, popLeft, popWidth, series.color, boxPos, useStdErr: true);
                        break;

                    case BoxStyle.MeanAndStdev:
                        MeanAndError(dims, bmp, lowQuality, population, rand, popLeft, popWidth, series.color, boxPos, useStdErr: false);
                        break;

                    default:
                        throw new NotImplementedException();
                    }
                }
            }
        }
コード例 #20
0
 public new void Render(PlotDimensions dims, Bitmap bmp, bool lowQuality = false) => throw new NotImplementedException();
コード例 #21
0
ファイル: AxisTicks.cs プロジェクト: xiaobin620/ScottPlot
        private void RenderTickLabels(PlotDimensions dims, Graphics gfx)
        {
            if (TickCollection.tickLabels is null || TickCollection.tickLabels.Length == 0 || MajorLabelEnable == false)
            {
                return;
            }

            using (var font = GDI.Font(MajorLabelFont))
                using (var brush = GDI.Brush(Color))
                    using (var sf = GDI.StringFormat())
                    {
                        if (Edge == Edge.Bottom)
                        {
                            if (Rotation == 0)
                            {
                                sf.Alignment     = RulerMode ? StringAlignment.Near : StringAlignment.Center;
                                sf.LineAlignment = StringAlignment.Near;
                                for (int i = 0; i < TickCollection.tickPositionsMajor.Length; i++)
                                {
                                    gfx.DrawString(TickCollection.tickLabels[i], font, brush, format: sf,
                                                   x: dims.GetPixelX(TickCollection.tickPositionsMajor[i]),
                                                   y: dims.DataOffsetY + dims.DataHeight + PixelOffset + MajorTickLength);
                                }

                                sf.Alignment = StringAlignment.Far;
                                gfx.DrawString(TickCollection.cornerLabel, font, brush, format: sf,
                                               x: dims.DataOffsetX + dims.DataWidth,
                                               y: dims.DataOffsetY + dims.DataHeight + MajorTickLength + TickCollection.maxLabelHeight);
                            }
                            else
                            {
                                for (int i = 0; i < TickCollection.tickPositionsMajor.Length; i++)
                                {
                                    float x = dims.GetPixelX(TickCollection.tickPositionsMajor[i]);
                                    float y = dims.DataOffsetY + dims.DataHeight + MajorTickLength + 3;

                                    gfx.TranslateTransform(x, y);
                                    gfx.RotateTransform(-Rotation);
                                    sf.Alignment     = StringAlignment.Far;
                                    sf.LineAlignment = StringAlignment.Center;
                                    gfx.DrawString(TickCollection.tickLabels[i], font, brush, 0, 0, sf);
                                    gfx.ResetTransform();
                                }
                            }
                        }
                        else if (Edge == Edge.Top)
                        {
                            sf.Alignment     = RulerMode ? StringAlignment.Near : StringAlignment.Center;
                            sf.LineAlignment = StringAlignment.Far;
                            for (int i = 0; i < TickCollection.tickPositionsMajor.Length; i++)
                            {
                                gfx.DrawString(TickCollection.tickLabels[i], font, brush, format: sf,
                                               x: dims.GetPixelX(TickCollection.tickPositionsMajor[i]),
                                               y: dims.DataOffsetY - PixelOffset - MajorTickLength);
                            }
                        }
                        else if (Edge == Edge.Left)
                        {
                            sf.LineAlignment = RulerMode ? StringAlignment.Far : StringAlignment.Center;
                            sf.Alignment     = StringAlignment.Far;
                            for (int i = 0; i < TickCollection.tickPositionsMajor.Length; i++)
                            {
                                gfx.DrawString(TickCollection.tickLabels[i], font, brush, format: sf,
                                               x: dims.DataOffsetX - PixelOffset - MajorTickLength,
                                               y: dims.GetPixelY(TickCollection.tickPositionsMajor[i]));
                            }

                            sf.LineAlignment = StringAlignment.Far;
                            sf.Alignment     = StringAlignment.Near;
                            gfx.DrawString(TickCollection.cornerLabel, font, brush, dims.DataOffsetX, dims.DataOffsetY, sf);
                        }
                        else if (Edge == Edge.Right)
                        {
                            sf.LineAlignment = RulerMode ? StringAlignment.Far : StringAlignment.Center;
                            sf.Alignment     = StringAlignment.Near;
                            for (int i = 0; i < TickCollection.tickPositionsMajor.Length; i++)
                            {
                                gfx.DrawString(TickCollection.tickLabels[i], font, brush, format: sf,
                                               x: dims.DataOffsetX + PixelOffset + MajorTickLength + dims.DataWidth,
                                               y: dims.GetPixelY(TickCollection.tickPositionsMajor[i]));
                            }
                        }
                        else
                        {
                            throw new NotImplementedException();
                        }
                    }
        }
コード例 #22
0
ファイル: TickCollection.cs プロジェクト: whble/ScottPlot
        private void RecalculatePositionsAutomaticNumeric(PlotDimensions dims, float labelWidth, float labelHeight, int?forcedTickCount)
        {
            double low, high, tickSpacing;
            int    maxTickCount;

            if (Orientation == AxisOrientation.Vertical)
            {
                low          = dims.YMin - dims.UnitsPerPxY; // add an extra pixel to capture the edge tick
                high         = dims.YMax + dims.UnitsPerPxY; // add an extra pixel to capture the edge tick
                maxTickCount = (int)(dims.DataHeight / labelHeight * TickDensity);
                maxTickCount = forcedTickCount ?? maxTickCount;
                tickSpacing  = (manualSpacingY != 0) ? manualSpacingY : GetIdealTickSpacing(low, high, maxTickCount, radix);
                tickSpacing  = Math.Max(tickSpacing, MinimumTickSpacing);
            }
            else
            {
                low          = dims.XMin - dims.UnitsPerPxX; // add an extra pixel to capture the edge tick
                high         = dims.XMax + dims.UnitsPerPxX; // add an extra pixel to capture the edge tick
                maxTickCount = (int)(dims.DataWidth / labelWidth * TickDensity);
                maxTickCount = forcedTickCount ?? maxTickCount;
                tickSpacing  = (manualSpacingX != 0) ? manualSpacingX : GetIdealTickSpacing(low, high, maxTickCount, radix);
                tickSpacing  = Math.Max(tickSpacing, MinimumTickSpacing);
            }

            // now that tick spacing is known, populate the list of ticks and labels
            double firstTickOffset = low % tickSpacing;
            int    tickCount       = (int)((high - low) / tickSpacing) + 2;

            tickCount          = tickCount > 1000 ? 1000 : tickCount;
            tickCount          = tickCount < 1 ? 1 : tickCount;
            tickPositionsMajor = Enumerable.Range(0, tickCount)
                                 .Select(x => low - firstTickOffset + tickSpacing * x)
                                 .Where(x => low <= x && x <= high)
                                 .ToArray();

            if (LabelFormat == TickLabelFormat.DateTime)
            {
                tickLabels         = GetDateLabels(tickPositionsMajor, Culture);
                tickPositionsMinor = null;
            }
            else
            {
                (tickLabels, CornerLabel) = GetPrettyTickLabels(
                    tickPositionsMajor,
                    useMultiplierNotation,
                    useOffsetNotation,
                    useExponentialNotation,
                    invertSign: LabelUsingInvertedSign,
                    culture: Culture
                    );

                if (MinorTickDistribution == MinorTickDistribution.log)
                {
                    tickPositionsMinor = MinorFromMajorLog(tickPositionsMajor, low, high);
                }
                else
                {
                    tickPositionsMinor = MinorFromMajor(tickPositionsMajor, 5, low, high);
                }
            }
        }
コード例 #23
0
 public Tick[] GetVisibleTicks(PlotDimensions dims)
 {
     return(GetVisibleMajorTicks(dims).Concat(GetVisibleMinorTicks(dims)).ToArray());
 }
コード例 #24
0
        public static void RenderTickLabels(PlotDimensions dims, Graphics gfx, TickCollection tc, Drawing.Font tickFont, Edge edge, float rotation, bool rulerMode, float PixelOffset, float MajorTickLength, float MinorTickLength)
        {
            if (tc.tickLabels is null || tc.tickLabels.Length == 0)
            {
                return;
            }

            using var font  = GDI.Font(tickFont);
            using var brush = GDI.Brush(tickFont.Color);
            using var sf    = GDI.StringFormat();

            Tick[] visibleMajorTicks = tc.GetVisibleMajorTicks(dims);

            switch (edge)
            {
            case Edge.Bottom:
                for (int i = 0; i < visibleMajorTicks.Length; i++)
                {
                    float x = dims.GetPixelX(visibleMajorTicks[i].Position);
                    float y = dims.DataOffsetY + dims.DataHeight + MajorTickLength;

                    gfx.TranslateTransform(x, y);
                    gfx.RotateTransform(-rotation);
                    sf.Alignment = rotation == 0 ? StringAlignment.Center : StringAlignment.Far;
                    if (rulerMode)
                    {
                        sf.Alignment = StringAlignment.Near;
                    }
                    sf.LineAlignment = rotation == 0 ? StringAlignment.Near : StringAlignment.Center;
                    gfx.DrawString(visibleMajorTicks[i].Label, font, brush, 0, 0, sf);
                    GDI.ResetTransformPreservingScale(gfx, dims);
                }
                break;

            case Edge.Top:
                for (int i = 0; i < visibleMajorTicks.Length; i++)
                {
                    float x = dims.GetPixelX(visibleMajorTicks[i].Position);
                    float y = dims.DataOffsetY - MajorTickLength;

                    gfx.TranslateTransform(x, y);
                    gfx.RotateTransform(-rotation);
                    sf.Alignment = rotation == 0 ? StringAlignment.Center : StringAlignment.Near;
                    if (rulerMode)
                    {
                        sf.Alignment = StringAlignment.Near;
                    }
                    sf.LineAlignment = rotation == 0 ? StringAlignment.Far : StringAlignment.Center;
                    gfx.DrawString(visibleMajorTicks[i].Label, font, brush, 0, 0, sf);
                    GDI.ResetTransformPreservingScale(gfx, dims);
                }
                break;

            case Edge.Left:
                for (int i = 0; i < visibleMajorTicks.Length; i++)
                {
                    float x = dims.DataOffsetX - PixelOffset - MajorTickLength;
                    float y = dims.GetPixelY(visibleMajorTicks[i].Position);

                    gfx.TranslateTransform(x, y);
                    gfx.RotateTransform(-rotation);
                    sf.Alignment     = StringAlignment.Far;
                    sf.LineAlignment = rulerMode ? StringAlignment.Far : StringAlignment.Center;
                    if (rotation == 90)
                    {
                        sf.Alignment     = StringAlignment.Center;
                        sf.LineAlignment = StringAlignment.Far;
                    }
                    gfx.DrawString(visibleMajorTicks[i].Label, font, brush, 0, 0, sf);
                    GDI.ResetTransformPreservingScale(gfx, dims);
                }
                break;

            case Edge.Right:
                for (int i = 0; i < visibleMajorTicks.Length; i++)
                {
                    float x = dims.DataOffsetX + PixelOffset + MajorTickLength + dims.DataWidth;
                    float y = dims.GetPixelY(visibleMajorTicks[i].Position);

                    gfx.TranslateTransform(x, y);
                    gfx.RotateTransform(-rotation);
                    sf.Alignment     = StringAlignment.Near;
                    sf.LineAlignment = rulerMode ? StringAlignment.Far : StringAlignment.Center;
                    if (rotation == 90)
                    {
                        sf.Alignment     = StringAlignment.Center;
                        sf.LineAlignment = StringAlignment.Near;
                    }
                    gfx.DrawString(visibleMajorTicks[i].Label, font, brush, 0, 0, sf);
                    GDI.ResetTransformPreservingScale(gfx, dims);
                }
                break;

            default:
                throw new NotImplementedException($"unsupported edge type {edge}");
            }

            if (!string.IsNullOrWhiteSpace(tc.CornerLabel))
            {
                switch (edge)
                {
                case Edge.Bottom:
                    sf.Alignment     = StringAlignment.Far;
                    sf.LineAlignment = StringAlignment.Near;
                    gfx.DrawString(s: "\n" + tc.CornerLabel,
                                   x: dims.DataOffsetX + dims.DataWidth,
                                   y: dims.DataOffsetY + dims.DataHeight + MajorTickLength,
                                   font: font, brush: brush, format: sf);
                    break;

                case Edge.Left:
                    sf.Alignment     = StringAlignment.Near;
                    sf.LineAlignment = StringAlignment.Far;
                    gfx.DrawString(s: "\n" + tc.CornerLabel,
                                   x: dims.DataOffsetX,
                                   y: dims.DataOffsetY,
                                   font: font, brush: brush, format: sf);
                    break;

                case Edge.Top:
                    throw new NotImplementedException("multiplier and offset notation is not supported for right and top axes");

                case Edge.Right:
                    throw new NotImplementedException("multiplier and offset notation is not supported for right and top axes");

                default:
                    throw new NotImplementedException($"unsupported edge type {edge}");
                }
            }
        }
コード例 #25
0
 /// <summary>
 /// Render the gauge onto an existing Bitmap
 /// </summary>
 /// <param name="gfx">active graphics object</param>
 /// <param name="dims">plot dimensions (used to determine pixel scaling)</param>
 /// <param name="centerPixel">pixel location on the bitmap to center the gauge on</param>
 /// <param name="radius">distance from the center (pixel units) to render the gauge</param>
 public void Render(Graphics gfx, PlotDimensions dims, PointF centerPixel, float radius)
 {
     RenderBackground(gfx, centerPixel, radius);
     RenderGaugeForeground(gfx, centerPixel, radius);
     RenderGaugeLabels(gfx, dims, centerPixel, radius);
 }
コード例 #26
0
        public static void Bar(PlotDimensions dims, Bitmap bmp, bool lowQuality, Population pop, Random rand,
                               double popLeft, double popWidth, Color color, Position position, bool useStdErr = false)
        {
            // adjust edges to accomodate special positions
            if (position == Position.Hide)
            {
                return;
            }
            if (position == Position.Left || position == Position.Right)
            {
                popWidth /= 2;
            }
            if (position == Position.Right)
            {
                popLeft += popWidth;
            }

            // determine the center point and calculate bounds
            double centerX = popLeft + popWidth / 2;
            double xPx     = dims.GetPixelX(centerX);
            double yPxTop  = dims.GetPixelY(pop.mean);
            double yPxBase = dims.GetPixelY(0);

            double errorMaxPx, errorMinPx;

            if (useStdErr)
            {
                errorMaxPx = dims.GetPixelY(pop.mean + pop.stdErr);
                errorMinPx = dims.GetPixelY(pop.mean - pop.stdErr);
            }
            else
            {
                errorMaxPx = dims.GetPixelY(pop.mean + pop.stDev);
                errorMinPx = dims.GetPixelY(pop.mean - pop.stDev);
            }

            // make cap width a fraction of available space
            double capWidthFrac = .38;
            double capWidth     = popWidth * capWidthFrac;
            double capPx1       = dims.GetPixelX(centerX - capWidth / 2);
            double capPx2       = dims.GetPixelX(centerX + capWidth / 2);

            // contract edges slightly to encourage padding between elements
            double edgePaddingFrac = 0.2;

            popLeft  += popWidth * edgePaddingFrac;
            popWidth -= (popWidth * edgePaddingFrac) * 2;
            double leftPx  = dims.GetPixelX(popLeft);
            double rightPx = dims.GetPixelX(popLeft + popWidth);

            RectangleF rect = new RectangleF((float)leftPx, (float)yPxTop, (float)(rightPx - leftPx), (float)(yPxBase - yPxTop));

            using (Graphics gfx = GDI.Graphics(bmp, dims, lowQuality))
                using (Pen pen = GDI.Pen(Color.Black))
                    using (Brush brush = GDI.Brush(color))
                    {
                        gfx.FillRectangle(brush, rect.X, rect.Y, rect.Width, rect.Height);
                        gfx.DrawRectangle(pen, rect.X, rect.Y, rect.Width, rect.Height);
                        gfx.DrawLine(pen, (float)xPx, (float)errorMinPx, (float)xPx, (float)errorMaxPx);
                        gfx.DrawLine(pen, (float)capPx1, (float)errorMinPx, (float)capPx2, (float)errorMinPx);
                        gfx.DrawLine(pen, (float)capPx1, (float)errorMaxPx, (float)capPx2, (float)errorMaxPx);
                    }
        }
コード例 #27
0
        public static void Box(PlotDimensions dims, Bitmap bmp, bool lowQuality, Population pop, Random rand,
                               double popLeft, double popWidth, Color color, Position position, BoxFormat boxFormat,
                               HorizontalAlignment errorAlignment = HorizontalAlignment.Right)
        {
            // adjust edges to accomodate special positions
            if (position == Position.Hide)
            {
                return;
            }
            if (position == Position.Left || position == Position.Right)
            {
                popWidth /= 2;
            }
            if (position == Position.Right)
            {
                popLeft += popWidth;
            }

            double errorMaxPx, errorMinPx;
            double yPxTop, yPxBase;
            double yPx;

            if (boxFormat == BoxFormat.StdevStderrMean)
            {
                errorMaxPx = dims.GetPixelY(pop.mean + pop.stDev);
                errorMinPx = dims.GetPixelY(pop.mean - pop.stDev);
                yPxTop     = dims.GetPixelY(pop.mean + pop.stdErr);
                yPxBase    = dims.GetPixelY(pop.mean - pop.stdErr);
                yPx        = dims.GetPixelY(pop.mean);
            }
            else if (boxFormat == BoxFormat.OutlierQuartileMedian)
            {
                errorMaxPx = dims.GetPixelY(pop.maxNonOutlier);
                errorMinPx = dims.GetPixelY(pop.minNonOutlier);
                yPxTop     = dims.GetPixelY(pop.Q3);
                yPxBase    = dims.GetPixelY(pop.Q1);
                yPx        = dims.GetPixelY(pop.median);
            }
            else
            {
                throw new NotImplementedException();
            }

            // make cap width a fraction of available space
            double capWidthFrac = .38;
            double capWidth     = popWidth * capWidthFrac;

            // contract edges slightly to encourage padding between elements
            double edgePaddingFrac = 0.2;

            popLeft  += popWidth * edgePaddingFrac;
            popWidth -= (popWidth * edgePaddingFrac) * 2;
            double     leftPx  = dims.GetPixelX(popLeft);
            double     rightPx = dims.GetPixelX(popLeft + popWidth);
            RectangleF rect    = new RectangleF(
                x: (float)leftPx,
                y: (float)yPxTop,
                width: (float)(rightPx - leftPx),
                height: (float)(yPxBase - yPxTop));

            // determine location of errorbars and caps
            double capPx1, capPx2, errorPxX;

            switch (errorAlignment)
            {
            case HorizontalAlignment.Center:
                double centerX = popLeft + popWidth / 2;
                errorPxX = dims.GetPixelX(centerX);
                capPx1   = dims.GetPixelX(centerX - capWidth / 2);
                capPx2   = dims.GetPixelX(centerX + capWidth / 2);
                break;

            case HorizontalAlignment.Right:
                errorPxX = dims.GetPixelX(popLeft + popWidth);
                capPx1   = dims.GetPixelX(popLeft + popWidth - capWidth / 2);
                capPx2   = dims.GetPixelX(popLeft + popWidth);
                break;

            case HorizontalAlignment.Left:
                errorPxX = dims.GetPixelX(popLeft);
                capPx1   = dims.GetPixelX(popLeft);
                capPx2   = dims.GetPixelX(popLeft + capWidth / 2);
                break;

            default:
                throw new NotImplementedException();
            }

            using (Graphics gfx = GDI.Graphics(bmp, dims, lowQuality))
                using (Pen pen = GDI.Pen(Color.Black))
                    using (Brush brush = GDI.Brush(color))
                    {
                        // draw the box
                        gfx.FillRectangle(brush, rect.X, rect.Y, rect.Width, rect.Height);
                        gfx.DrawRectangle(pen, rect.X, rect.Y, rect.Width, rect.Height);

                        // draw the line in the center
                        gfx.DrawLine(pen, rect.X, (float)yPx, rect.X + rect.Width, (float)yPx);

                        // draw errorbars and caps
                        gfx.DrawLine(pen, (float)errorPxX, (float)errorMinPx, (float)errorPxX, rect.Y + rect.Height);
                        gfx.DrawLine(pen, (float)errorPxX, (float)errorMaxPx, (float)errorPxX, rect.Y);
                        gfx.DrawLine(pen, (float)capPx1, (float)errorMinPx, (float)capPx2, (float)errorMinPx);
                        gfx.DrawLine(pen, (float)capPx1, (float)errorMaxPx, (float)capPx2, (float)errorMaxPx);
                    }
        }
コード例 #28
0
        public static void RenderTickLabels(PlotDimensions dims, Graphics gfx, TickCollection tc, Drawing.Font tickFont, Edge edge, float rotation, bool rulerMode, float PixelOffset, float MajorTickLength, float MinorTickLength)
        {
            if (tc.tickLabels is null || tc.tickLabels.Length == 0)
            {
                return;
            }

            using (var font = GDI.Font(tickFont))
                using (var brush = GDI.Brush(tickFont.Color))
                    using (var sf = GDI.StringFormat())
                    {
                        // TODO: Refactor to improve rotated tick label rendering:
                        //  1) rotation should always be assumed
                        //  2) a separate function should translate/rotate/render/reset
                        //  3) all edges should support rotation
                        if (edge == Edge.Bottom)
                        {
                            if (rotation == 0)
                            {
                                sf.Alignment     = rulerMode ? StringAlignment.Near : StringAlignment.Center;
                                sf.LineAlignment = StringAlignment.Near;
                                for (int i = 0; i < tc.tickPositionsMajor.Length; i++)
                                {
                                    gfx.DrawString(tc.tickLabels[i], font, brush, format: sf,
                                                   x: dims.GetPixelX(tc.tickPositionsMajor[i]),
                                                   y: dims.DataOffsetY + dims.DataHeight + PixelOffset + MajorTickLength);
                                }

                                sf.Alignment = StringAlignment.Far;
                                gfx.DrawString(tc.cornerLabel, font, brush, format: sf,
                                               x: dims.DataOffsetX + dims.DataWidth,
                                               y: dims.DataOffsetY + dims.DataHeight + MajorTickLength + tc.maxLabelHeight);
                            }
                            else
                            {
                                for (int i = 0; i < tc.tickPositionsMajor.Length; i++)
                                {
                                    float x = dims.GetPixelX(tc.tickPositionsMajor[i]);
                                    float y = dims.DataOffsetY + dims.DataHeight + MajorTickLength + 3;

                                    gfx.TranslateTransform(x, y);
                                    gfx.RotateTransform(-rotation);
                                    sf.Alignment     = StringAlignment.Far;
                                    sf.LineAlignment = StringAlignment.Center;
                                    gfx.DrawString(tc.tickLabels[i], font, brush, 0, 0, sf);
                                    gfx.ResetTransform();
                                }
                            }
                        }
                        else if (edge == Edge.Top)
                        {
                            sf.Alignment     = rulerMode ? StringAlignment.Near : StringAlignment.Center;
                            sf.LineAlignment = StringAlignment.Far;
                            for (int i = 0; i < tc.tickPositionsMajor.Length; i++)
                            {
                                gfx.DrawString(tc.tickLabels[i], font, brush, format: sf,
                                               x: dims.GetPixelX(tc.tickPositionsMajor[i]),
                                               y: dims.DataOffsetY - PixelOffset - MajorTickLength);
                            }
                        }
                        else if (edge == Edge.Left)
                        {
                            if (rotation == 0)
                            {
                                sf.LineAlignment = rulerMode ? StringAlignment.Far : StringAlignment.Center;
                                sf.Alignment     = StringAlignment.Far;
                                for (int i = 0; i < tc.tickPositionsMajor.Length; i++)
                                {
                                    gfx.DrawString(tc.tickLabels[i], font, brush, format: sf,
                                                   x: dims.DataOffsetX - PixelOffset - MajorTickLength,
                                                   y: dims.GetPixelY(tc.tickPositionsMajor[i]));
                                }

                                sf.LineAlignment = StringAlignment.Far;
                                sf.Alignment     = StringAlignment.Near;
                                gfx.DrawString(tc.cornerLabel, font, brush, dims.DataOffsetX, dims.DataOffsetY, sf);
                            }
                            else
                            {
                                for (int i = 0; i < tc.tickPositionsMajor.Length; i++)
                                {
                                    float x = dims.DataOffsetX - PixelOffset - MajorTickLength;
                                    float y = dims.GetPixelY(tc.tickPositionsMajor[i]);

                                    gfx.TranslateTransform(x, y);
                                    gfx.RotateTransform(-rotation);
                                    sf.Alignment     = StringAlignment.Far;
                                    sf.LineAlignment = StringAlignment.Center;
                                    gfx.DrawString(tc.tickLabels[i], font, brush, 0, 0, sf);
                                    gfx.ResetTransform();
                                }
                            }
                        }
                        else if (edge == Edge.Right)
                        {
                            sf.LineAlignment = rulerMode ? StringAlignment.Far : StringAlignment.Center;
                            sf.Alignment     = StringAlignment.Near;
                            for (int i = 0; i < tc.tickPositionsMajor.Length; i++)
                            {
                                gfx.DrawString(tc.tickLabels[i], font, brush, format: sf,
                                               x: dims.DataOffsetX + PixelOffset + MajorTickLength + dims.DataWidth,
                                               y: dims.GetPixelY(tc.tickPositionsMajor[i]));
                            }
                        }
                        else
                        {
                            throw new NotImplementedException();
                        }
                    }
        }
コード例 #29
0
ファイル: ArrowStyle.cs プロジェクト: Jmerk523/ScottPlot
        /// <summary>
        /// Render an evenly-spaced 2D vector field.
        /// </summary>
        public void Render(PlotDimensions dims, Graphics gfx, double[] xs, double[] ys, Statistics.Vector2[,] vectors, Color[] colors)
        {
            (float tipScale, float headAngle) = GetTipDimensions(); // precalculate angles for fancy arrows

            using Pen pen = Drawing.GDI.Pen(Color.Black);
            if (!ScaledArrowheads)
            {
                pen.CustomEndCap = new System.Drawing.Drawing2D.AdjustableArrowCap(NonScaledArrowheadWidth, NonScaledArrowheadLength);
            }

            for (int i = 0; i < xs.Length; i++)
            {
                for (int j = 0; j < ys.Length; j++)
                {
                    Statistics.Vector2 v = vectors[i, j];
                    float tailX, tailY, endX, endY;

                    switch (Anchor)
                    {
                    case ArrowAnchor.Base:
                        tailX = dims.GetPixelX(xs[i]);
                        tailY = dims.GetPixelY(ys[j]);
                        endX  = dims.GetPixelX(xs[i] + v.X);
                        endY  = dims.GetPixelY(ys[j] + v.Y);
                        break;

                    case ArrowAnchor.Center:
                        tailX = dims.GetPixelX(xs[i] - v.X / 2);
                        tailY = dims.GetPixelY(ys[j] - v.Y / 2);
                        endX  = dims.GetPixelX(xs[i] + v.X / 2);
                        endY  = dims.GetPixelY(ys[j] + v.Y / 2);
                        break;

                    case ArrowAnchor.Tip:
                        tailX = dims.GetPixelX(xs[i] - v.X);
                        tailY = dims.GetPixelY(ys[j] - v.Y);
                        endX  = dims.GetPixelX(xs[i]);
                        endY  = dims.GetPixelY(ys[j]);
                        break;

                    default:
                        throw new NotImplementedException("unsupported anchor type");
                    }

                    pen.Color = colors[i * ys.Length + j];
                    if (ScaledArrowheads)
                    {
                        DrawFancyArrow(gfx, pen, tailX, tailY, endX, endY, headAngle, tipScale);
                    }
                    else
                    {
                        gfx.DrawLine(pen, tailX, tailY, endX, endY);
                    }

                    if (MarkerShape != MarkerShape.none && MarkerSize > 0)
                    {
                        PointF markerPoint = new PointF(dims.GetPixelX(xs[i]), dims.GetPixelY(ys[j]));
                        MarkerTools.DrawMarker(gfx, markerPoint, MarkerShape, MarkerSize, pen.Color);
                    }
                }
            }
        }
コード例 #30
0
        private void RenderCandles(PlotDimensions dims, Bitmap bmp, bool lowQuality)
        {
            double fractionalTickWidth = .7;

            using Graphics gfx     = GDI.Graphics(bmp, dims, lowQuality);
            using Pen pen          = new Pen(Color.Magenta);
            using SolidBrush brush = new SolidBrush(Color.Magenta);
            for (int i = 0; i < OHLCs.Count; i++)
            {
                var    ohlc             = OHLCs[i];
                bool   closedHigher     = ohlc.Close >= ohlc.Open;
                double highestOpenClose = Math.Max(ohlc.Open, ohlc.Close);
                double lowestOpenClose  = Math.Min(ohlc.Open, ohlc.Close);

                var   ohlcTime = Sequential ? i : ohlc.DateTime.ToOADate();
                var   ohlcSpan = Sequential ? 1 : ohlc.TimeSpan.TotalDays;
                float pixelX   = dims.GetPixelX(ohlcTime);

                float boxWidth = (float)(ohlcSpan * dims.PxPerUnitX / 2 * fractionalTickWidth);

                Color priceChangeColor = closedHigher ? ColorUp : ColorDown;
                pen.Color = WickColor ?? priceChangeColor;
                pen.Width = (boxWidth >= 2) ? 2 : 1;

                // draw the wick below the box
                PointF wickLowBot = new PointF(pixelX, dims.GetPixelY(ohlc.Low));
                PointF wickLowTop = new PointF(pixelX, dims.GetPixelY(lowestOpenClose));
                gfx.DrawLine(pen, wickLowBot, wickLowTop);

                // draw the wick above the box
                PointF wickHighBot = new PointF(pixelX, dims.GetPixelY(highestOpenClose));
                PointF wickHighTop = new PointF(pixelX, dims.GetPixelY(ohlc.High));
                gfx.DrawLine(pen, wickHighBot, wickHighTop);

                // draw the candle body
                PointF boxLowerLeft  = new PointF(pixelX, dims.GetPixelY(lowestOpenClose));
                PointF boxUpperRight = new PointF(pixelX, dims.GetPixelY(highestOpenClose));
                if (ohlc.Open == ohlc.Close)
                {
                    // draw OHLC (non-filled) candle
                    gfx.DrawLine(pen, boxLowerLeft.X - boxWidth, boxLowerLeft.Y, boxLowerLeft.X + boxWidth, boxLowerLeft.Y);
                }
                else
                {
                    // draw a filled candle
                    brush.Color = priceChangeColor;
                    gfx.FillRectangle(
                        brush: brush,
                        x: boxLowerLeft.X - boxWidth,
                        y: boxUpperRight.Y,
                        width: boxWidth * 2,
                        height: boxLowerLeft.Y - boxUpperRight.Y);

                    if (WickColor != null)
                    {
                        gfx.DrawRectangle(
                            pen: pen,
                            x: boxLowerLeft.X - boxWidth,
                            y: boxUpperRight.Y,
                            width: boxWidth * 2,
                            height: boxLowerLeft.Y - boxUpperRight.Y);
                    }
                }
            }
        }