コード例 #1
0
        public void Draw(Graphics g, RectangleF drawingRectangle)
        {
            if (NoOfBins <= 0)
            {
                return;
            }
            int[]  bins        = CreateBins();
            double maxBarValue = 0;

            g.SmoothingMode     = SmoothingMode.AntiAlias;
            g.TextRenderingHint = TextRenderingHint.AntiAlias;

            // get max bar height
            for (int i = 0; i < NoOfBins; i++)
            {
                maxBarValue = Math.Max(maxBarValue, bins[i]);
            }
            if (maxBarValue == 0)
            {
                return;
            }
            // allow some extra space at top
            double             spaceFactor       = 1.1;
            double             maxPercentage     = Math.Min(1, spaceFactor * maxBarValue / histogramData.Count);
            DoubleScaleCreator yAxisScaleCreator = new DoubleScaleCreator(0, maxPercentage, 5, true);

            maxPercentage = yAxisScaleCreator.ScaleEndValue;

            // calculate max x axis label size
            SizeF maxXAxisLabelSize = SizeF.Empty;

            for (int i = 0; i < xAxisScaleCreator.NoOfMarkers; i++)
            {
                double value     = xAxisScaleCreator.MarkerValue(i);
                string label     = xAxisNumericConverter.ToString(value);
                SizeF  labelSize = g.MeasureString(label, font);
                maxXAxisLabelSize.Width  = Math.Max(maxXAxisLabelSize.Width, labelSize.Width);
                maxXAxisLabelSize.Height = Math.Max(maxXAxisLabelSize.Height, labelSize.Height);
            }

            // calculate max y axis label size
            SizeF maxYAxisLabelSize = SizeF.Empty;

            for (int i = 0; i < yAxisScaleCreator.NoOfMarkers; i++)
            {
                double value     = yAxisScaleCreator.MarkerValue(i);
                string label     = String.Format("{0:P0}", value);
                SizeF  labelSize = g.MeasureString(label, font);
                maxYAxisLabelSize.Width  = Math.Max(maxYAxisLabelSize.Width, labelSize.Width);
                maxYAxisLabelSize.Height = Math.Max(maxYAxisLabelSize.Height, labelSize.Height);
            }

            // calculate the graph rectangle
            SizeF      xAxisCaptionSize   = g.MeasureString(xAxisCaption, font);
            SizeF      yAxisCaptionSize   = g.MeasureString(yAxisCaption, font);
            float      leftMargin         = Math.Max(yAxisCaptionSize.Height + maxYAxisLabelSize.Width, maxXAxisLabelSize.Width / 2);
            RectangleF histogramRectangle = new RectangleF(
                (int)(drawingRectangle.Left + leftMargin),
                (int)(drawingRectangle.Top + maxYAxisLabelSize.Height / 2),
                Math.Max(1, (int)(drawingRectangle.Width - leftMargin - maxXAxisLabelSize.Width / 2 - 1)),
                Math.Max(1, (int)(drawingRectangle.Height - maxYAxisLabelSize.Height / 2 - maxXAxisLabelSize.Height - xAxisCaptionSize.Height - 1)));
            float barWidth = histogramRectangle.Width / (float)((endValue - startValue) / binWidth);


            // clear graphics
            g.Clear(BackColor);

            // draw the histogram background
            Brush b = new SolidBrush(histogramBackColor);

            g.FillRectangle(b, histogramRectangle);
            b.Dispose();

            // draw the axis labels
            // x axis
            Brush fontBrush = new SolidBrush(fontColor);

            for (int i = 0; i < xAxisScaleCreator.NoOfMarkers; i++)
            {
                double value     = xAxisScaleCreator.MarkerValue(i);
                int    x         = (int)histogramRectangle.Left + (int)((float)(value - startValue) / (float)(endValue - startValue) * histogramRectangle.Width);
                string label     = xAxisNumericConverter.ToString(value);
                SizeF  labelSize = g.MeasureString(label, font);
                g.DrawString(label, font, fontBrush, new PointF(x - labelSize.Width / 2, histogramRectangle.Bottom));
                g.DrawLine(gridPen, new Point(x, (int)histogramRectangle.Top), new Point(x, (int)histogramRectangle.Bottom));
            }
            // y axis
            for (int i = 0; i < yAxisScaleCreator.NoOfMarkers; i++)
            {
                double value     = yAxisScaleCreator.MarkerValue(i);
                int    y         = (int)histogramRectangle.Bottom - (int)((float)(value / maxPercentage) * histogramRectangle.Height);
                string label     = String.Format("{0:P0}", value);
                SizeF  labelSize = g.MeasureString(label, font);
                g.DrawString(label, font, fontBrush, new PointF(histogramRectangle.Left - labelSize.Width, y - maxYAxisLabelSize.Height / 2));
                g.DrawLine(gridPen, new Point((int)histogramRectangle.Left, y), new Point((int)histogramRectangle.Right, y));
            }



            // draw the axis captions
            // x axis
            PointF xAxisCaptionLocation = new PointF(
                histogramRectangle.Left + (histogramRectangle.Width - xAxisCaptionSize.Width) / 2,
                histogramRectangle.Bottom + xAxisCaptionSize.Height);

            g.DrawString(xAxisCaption, Font, fontBrush, xAxisCaptionLocation);
            // y axis, rotated 90 degrees
            PointF yAxisCaptionLocation = new PointF(
                histogramRectangle.Left - 3 * yAxisCaptionSize.Height,
                histogramRectangle.Bottom - (histogramRectangle.Height - yAxisCaptionSize.Width) / 2);

            g.ResetTransform();
            g.TranslateTransform(-yAxisCaptionLocation.X, -yAxisCaptionLocation.Y, MatrixOrder.Append);
            g.RotateTransform(-90F, MatrixOrder.Append);
            g.TranslateTransform(yAxisCaptionLocation.X, yAxisCaptionLocation.Y, MatrixOrder.Append);
            g.DrawString(yAxisCaption, Font, fontBrush, yAxisCaptionLocation);
            g.ResetTransform();


            // draw the bars
            g.SetClip(histogramRectangle);
            for (int i = 0; i < NoOfBins; i++)
            {
                float      barHeight    = bins[i] / (float)histogramData.Count / (float)maxPercentage * histogramRectangle.Height;
                RectangleF barRectangle = new RectangleF(
                    histogramRectangle.Left + i * barWidth,
                    histogramRectangle.Top + histogramRectangle.Height - barHeight,
                    barWidth,
                    barHeight
                    );
                Color barColor = colorRange.GetColor(startValue + (i + 0.5) * binWidth);
                b = new SolidBrush(barColor);
                g.FillRectangle(b, barRectangle);
                b.Dispose();
                if (barBorderPen != null)
                {
                    g.DrawRectangle(barBorderPen, barRectangle.X, barRectangle.Y, barRectangle.Width, barRectangle.Height);
                }
            }
            g.ResetClip();

            // draw the histogram border
            g.DrawRectangle(borderPen, histogramRectangle.X, histogramRectangle.Y, histogramRectangle.Width, histogramRectangle.Height);

            fontBrush.Dispose();
        }
コード例 #2
0
        public void Draw(Graphics g, RectangleF drawingRectangle)
        {
            if (yAxisNumericConverter == null)
            {
                return;
            }
            if (yAxisScaleCreator == null)
            {
                return;
            }

            Brush fontBrush = new SolidBrush(fontColor);

            g.SmoothingMode     = SmoothingMode.AntiAlias;
            g.TextRenderingHint = TextRenderingHint.AntiAlias;

            // calculate caption sizes
            SizeF xAxisCaptionSize = g.MeasureString(xAxisCaption, font);
            SizeF yAxisCaptionSize = g.MeasureString(yAxisCaption, font);

            // calculate max x axis label size
            switch (xAxisAttribute)
            {
            case DomainAttribute.TimeOfDay:
                xAxisNumericConverter = new TimeConverter(TimeConverter.TimeConverterType.TimeOfDay);
                XAxisScaleCreator     = new TimeScaleCreator(xAxisMinValue, xAxisMaxValue, 15, false);
                break;

            case DomainAttribute.ElapsedTime:
                xAxisNumericConverter = new TimeConverter(TimeConverter.TimeConverterType.ElapsedTime);
                XAxisScaleCreator     = new TimeScaleCreator(xAxisMinValue, xAxisMaxValue, 15, false);
                break;

            case DomainAttribute.Distance:
                xAxisNumericConverter = new NumericConverter();
                XAxisScaleCreator     = new DoubleScaleCreator(xAxisMinValue, xAxisMaxValue, 15, false);
                break;
            }

            SizeF maxXAxisLabelSize = SizeF.Empty;

            for (int i = 0; i < xAxisScaleCreator.NoOfMarkers; i++)
            {
                double value     = xAxisScaleCreator.MarkerValue(i);
                string label     = xAxisNumericConverter.ToString(value);
                SizeF  labelSize = g.MeasureString(label, font);
                maxXAxisLabelSize.Width  = Math.Max(maxXAxisLabelSize.Width, labelSize.Width);
                maxXAxisLabelSize.Height = Math.Max(maxXAxisLabelSize.Height, labelSize.Height);
            }

            // calculate max y axis label size
            SizeF maxYAxisLabelSize = SizeF.Empty;

            for (int i = 0; i < yAxisScaleCreator.NoOfMarkers; i++)
            {
                double value     = yAxisScaleCreator.MarkerValue(i);
                string label     = yAxisNumericConverter.ToString(value);
                SizeF  labelSize = g.MeasureString(label, font);
                maxYAxisLabelSize.Width  = Math.Max(maxYAxisLabelSize.Width, labelSize.Width);
                maxYAxisLabelSize.Height = Math.Max(maxYAxisLabelSize.Height, labelSize.Height);
            }

            // calculate graph drawing rectangle
            float leftMargin = Math.Max(1.5F * yAxisCaptionSize.Height + maxYAxisLabelSize.Width, maxXAxisLabelSize.Width / 2);
            int   width      = (int)(drawingRectangle.Width - leftMargin - maxXAxisLabelSize.Width / 2 - 1);
            int   height     = (int)(drawingRectangle.Height - maxYAxisLabelSize.Height / 2 - maxXAxisLabelSize.Height - xAxisCaptionSize.Height - 1);

            graphDrawingRectangle = new Rectangle(
                (int)(drawingRectangle.Left + leftMargin),
                (int)(drawingRectangle.Top + maxYAxisLabelSize.Height / 2),
                Math.Max(width, 1),
                Math.Max(height, 1));

            // draw graph background
            g.FillRectangle(lineGraphBackgroundBrush, GraphDrawingRectangle);

            // draw the axis labels
            // x axis
            for (int i = 0; i < xAxisScaleCreator.NoOfMarkers; i++)
            {
                double value     = xAxisScaleCreator.MarkerValue(i);
                int    x         = (int)Math.Round(ValueToX(value));
                string label     = xAxisNumericConverter.ToString(value);
                SizeF  labelSize = g.MeasureString(label, font);
                g.DrawString(label, font, fontBrush, new PointF(x - labelSize.Width / 2, GraphDrawingRectangle.Bottom));
                g.DrawLine(gridPen, new Point(x, GraphDrawingRectangle.Top), new Point(x, GraphDrawingRectangle.Bottom));
            }
            // y axis
            for (int i = 0; i < yAxisScaleCreator.NoOfMarkers; i++)
            {
                double value     = yAxisScaleCreator.MarkerValue(i);
                int    y         = (int)Math.Round(ValueToY(value));
                string label     = yAxisNumericConverter.ToString(value);
                SizeF  labelSize = g.MeasureString(label, font);
                g.DrawString(label, font, fontBrush, new PointF(GraphDrawingRectangle.Left - labelSize.Width, y - maxYAxisLabelSize.Height / 2));
                g.DrawLine(gridPen, new Point(GraphDrawingRectangle.Left, y), new Point(GraphDrawingRectangle.Right, y));
            }

            // draw the axis captions
            // x axis
            PointF xAxisCaptionLocation = new PointF(
                GraphDrawingRectangle.Left + (GraphDrawingRectangle.Width - xAxisCaptionSize.Width) / 2,
                GraphDrawingRectangle.Bottom + xAxisCaptionSize.Height);

            g.DrawString(xAxisCaption, font, fontBrush, xAxisCaptionLocation);
            // y axis, rotated 90 degrees
            PointF yAxisCaptionLocation = new PointF(
                GraphDrawingRectangle.Left - 3 * yAxisCaptionSize.Height,
                GraphDrawingRectangle.Bottom - (GraphDrawingRectangle.Height - yAxisCaptionSize.Width) / 2);

            g.ResetTransform();
            g.TranslateTransform(-yAxisCaptionLocation.X, -yAxisCaptionLocation.Y, MatrixOrder.Append);
            g.RotateTransform(-90F, MatrixOrder.Append);
            g.TranslateTransform(yAxisCaptionLocation.X, yAxisCaptionLocation.Y, MatrixOrder.Append);
            g.DrawString(yAxisCaption, font, fontBrush, yAxisCaptionLocation);
            g.ResetTransform();

            // create the line points
            var polygonList = new List <List <PointF> >();

            if (pointsList != null)
            {
                foreach (var points in pointsList)
                {
                    GraphicsPath path    = new GraphicsPath();
                    var          polygon = new List <PointF> {
                        new PointF(ValueToX(points[0].X), GraphDrawingRectangle.Bottom)
                    };
                    foreach (LineGraphPoint p in points)
                    {
                        polygon.Add(new PointF(ValueToX(p.X), ValueToY(p.Y)));
                    }
                    polygon.Add(new PointF(ValueToX(points[points.Count - 1].X), GraphDrawingRectangle.Bottom));
                    path.AddPolygon(polygon.ToArray());
                    polygonList.Add(polygon);
                    g.SetClip(path);

                    RouteLineSettings rls = session.Settings.RouteLineSettingsCollection[yAxisAttribute];

                    // draw the gradient filling
                    Bitmap   templateBitmap     = new Bitmap(32, GraphDrawingRectangle.Height);
                    Graphics templateGraphics   = Graphics.FromImage(templateBitmap);
                    double   colorRangeInterval = rls.ColorRange.EndValue - rls.ColorRange.StartValue;
                    if (colorRangeInterval == 0)
                    {
                        colorRangeInterval = 0.00001;
                    }
                    rls.ColorRange.Gradient.Draw(
                        templateGraphics,
                        new Rectangle(0, 0, templateBitmap.Width, templateBitmap.Height),
                        (yAxisMinValue - rls.ColorRange.StartValue) / colorRangeInterval,
                        1 + (yAxisMaxValue - rls.ColorRange.EndValue) / colorRangeInterval,
                        Gradient.Direction.ReverseVertical);
                    templateGraphics.Dispose();
                    for (int i = 0; i < GraphDrawingRectangle.Width; i += templateBitmap.Width)
                    {
                        g.DrawImage(templateBitmap, GraphDrawingRectangle.Left + i, GraphDrawingRectangle.Top);
                    }
                }
            }

            g.SetClip(GraphDrawingRectangle);

            // draw lap lines
            foreach (Lap lap in session.Laps)
            {
                double xValue = 0;
                switch (xAxisAttribute)
                {
                case DomainAttribute.TimeOfDay:
                    xValue = (double)lap.Time.ToLocalTime().Ticks / TimeSpan.TicksPerSecond;
                    break;

                case DomainAttribute.ElapsedTime:
                    xValue =
                        session.Route.GetAttributeFromParameterizedLocation(
                            WaypointAttribute.ElapsedTime,
                            session.Route.GetParameterizedLocationFromTime(lap.Time)).Value;
                    break;

                case DomainAttribute.Distance:
                    xValue =
                        session.Route.GetAttributeFromParameterizedLocation(
                            WaypointAttribute.Distance,
                            session.Route.GetParameterizedLocationFromTime(lap.Time)).Value;
                    break;
                }

                int x = (int)Math.Round(ValueToX(xValue));
                g.DrawLine(lapPen, x, graphDrawingRectangle.Top, x, graphDrawingRectangle.Bottom);
            }

            // draw the line above the gradient area
            foreach (var polygon in polygonList)
            {
                g.DrawLines(linePen, polygon.ToArray());
            }
            g.ResetClip();
            g.DrawRectangle(borderPen, GraphDrawingRectangle);

            // dispose drawing objects
            fontBrush.Dispose();
        }