Esempio n. 1
0
        public void Draw(FastChart owner, PaintEventArgs e, Point o, Point tip, int width)
        {
            var lineCl = LineColor.HasValue ? LineColor.Value : Color.Black;

            var start = !AlwaysShowNil ? MinValue : new Cortege2 <double, DateTime>(0, DateTime.MinValue);
            var step  = CalculateStep(start, o, tip);

            if (step.a == 0 && step.b == TimeSpan.Zero)
            {
                // нет делений
                return;
            }

            var lblFmt = DeriveFormatFromStep(step);

            var cur = start;

            // сместить текущую отметку на ближ. целое значение шага
            if (!IsDateTime)
            {
                cur.a = ((int)(cur.a / step.a)) * step.a;
            }

            var drawFormat = new StringFormat(VerticalText ?
                                              StringFormatFlags.DirectionVertical : StringFormatFlags.NoWrap);
            var lenPx = Direction == FastAxisDirection.X
                ? Math.Abs(tip.X - o.X) : Math.Abs(tip.Y - o.Y);

            using (var brush = new SolidBrush(lineCl))
            {
                using (var pen = new Pen(lineCl))
                {
                    e.Graphics.DrawLine(pen, o.X, o.Y, tip.X, tip.Y);
                    using (var penGridMain = new Pen(ColorMainGrid.HasValue ? ColorMainGrid.Value : Color.DarkGray))
                    {
                        while (true)
                        {
                            // след. значение
                            if (!IsDateTime)
                            {
                                if (step.a == 0)
                                {
                                    break;
                                }
                                cur.a += step.a;
                            }
                            else
                            {
                                if (step.b == TimeSpan.Zero)
                                {
                                    break;
                                }
                                cur.b += step.b;
                            }
                            // вышли за пределы шкалы?
                            if (!IsDateTime)
                            {
                                if (cur.a > MaxValue.a)
                                {
                                    break;
                                }
                            }
                            if (IsDateTime)
                            {
                                if (cur.b > MaxValue.b)
                                {
                                    break;
                                }
                            }

                            // текст подписи
                            var labelTxt = !IsDateTime
                                               ? cur.a.ToString(lblFmt)
                                               : cur.b.ToString(lblFmt);

                            // размеры, занимаемые подписью
                            var txtSzOrig = e.Graphics.MeasureString(labelTxt, owner.Font);
                            var txtSz     = VerticalText
                                            ? new SizeF(txtSzOrig.Height, txtSzOrig.Width)
                                            : txtSzOrig;
                            // координата
                            var ptDist = !IsDateTime
                                             ? (cur.a - start.a) / (MaxValue.a - start.a)
                                             : (cur.b - start.b).TotalMilliseconds /
                                         (MaxValue.b - start.b).TotalMilliseconds;
                            ptDist *= lenPx;
                            var ptDot = Direction == FastAxisDirection.X
                                            ? new Point(o.X + (int)ptDist, o.Y)
                                            : new Point(o.X, o.Y - (int)ptDist);
                            var ptLeftUp = Direction == FastAxisDirection.X
                                               ? new PointF(ptDot.X - txtSz.Width / 2, ptDot.Y + 3)
                                               : new PointF(ptDot.X - txtSz.Width - 3, ptDot.Y - txtSz.Height / 2);
                            // нарисовать текст
                            e.Graphics.DrawString(labelTxt, owner.Font, brush,
                                                  ptLeftUp.X, ptLeftUp.Y, drawFormat);
                            // нарисовать засечку
                            try
                            {
                                if (Direction == FastAxisDirection.X)
                                {
                                    e.Graphics.DrawLine(pen, ptDot.X, ptDot.Y - 2, ptDot.X, ptDot.Y + 2);
                                }
                                else
                                {
                                    e.Graphics.DrawLine(pen, ptDot.X - 2, ptDot.Y, ptDot.X + 2, ptDot.Y);
                                }
                            }
                            catch (Exception ex)
                            {
                                owner.lastError = ex.ToString();
                                return;
                            }

                            // нарисовать сетку
                            if (DrawMainGrid)
                            {
                                if (Direction == FastAxisDirection.X)
                                {
                                    e.Graphics.DrawLine(penGridMain, ptDot.X, ptDot.Y + 2, ptDot.X, ptDot.Y - width);
                                }
                                else
                                {
                                    e.Graphics.DrawLine(penGridMain, ptDot.X + 2, ptDot.Y, ptDot.X + width, ptDot.Y);
                                }
                            }
                        }// while

                        // нарисовать рамку
                        if (DrawMainGrid)
                        {
                            if (Direction == FastAxisDirection.X)
                            {
                                e.Graphics.DrawLine(penGridMain, o.X, o.Y - width, tip.X, o.Y - width);
                            }
                            else
                            {
                                e.Graphics.DrawLine(penGridMain, o.X + width, o.Y, o.X + width, tip.Y);
                            }
                        }
                    } // main grid pen
                }     // brush
            }
        }
        private void RenderChart(StringBuilder sb, string title, int width, int height,
                                 List <List <FastSeriesPoint> > series, List <string> seriesNames)
        {
            var seriesColors = new [] { Color.DarkBlue, Color.DarkOliveGreen, Color.Firebrick };

            var needYearsInFormat = stat.listEquity[stat.listEquity.Count - 1].time.Year != stat.listEquity[0].time.Year;
            var formatString      = needYearsInFormat ? "dd.MM.yyyy" : "dd MMM";

            var chart = new FastChart.Chart.FastChart
            {
                ShowLegend      = series.Count > 1,
                LegendPlacement = FastChart.Chart.FastChart.ChartLegendPlacement.Справа,
                BorderStyle     = BorderStyle.None,
                DrawMargin      = false
            };

            var axisX = new FastAxis(FastAxisDirection.X, true)
            {
                ColorMainGrid = Color.FromArgb(205, 205, 205),
                ColorSubGrid  = Color.FromArgb(220, 220, 220),
                DrawMainGrid  = true,
                DrawSubGrid   = true,
                LabelFormat   = formatString
            };

            // границы оси Y
            var min = double.MaxValue;
            var max = double.MinValue;

            foreach (var ser in series)
            {
                foreach (var pt in ser)
                {
                    if (min > pt.y)
                    {
                        min = pt.y;
                    }
                    if (max < pt.y)
                    {
                        max = pt.y;
                    }
                }
            }
            min = GetLowerBound(min);

            var axisY = new FastAxis(FastAxisDirection.Y, false)
            {
                ColorMainGrid = Color.FromArgb(205, 205, 205),
                ColorSubGrid  = Color.FromArgb(220, 220, 220),
                DrawMainGrid  = true,
                DrawSubGrid   = true,
                AutoScale100  = false,
                MinValue      = new FastChart.Chart.Cortege2 <double, DateTime>(min, default(DateTime)),
                MaxValue      = new FastChart.Chart.Cortege2 <double, DateTime>(max * 1.05, default(DateTime))
            };


            chart.Axes.Add(axisX);
            chart.Axes.Add(axisY);

            // добавить серии и точки
            for (var i = 0; i < series.Count; i++)
            {
                var ser = new FastSeries(seriesNames[i], FastSeriesType.Линия, axisX, axisY, false)
                {
                    PenLine = new Pen(seriesColors[i], 2f), AntiAlias = true
                };
                ser.points.AddRange(series[i]);
                chart.series.Add(ser);
            }

            chart.Width  = width;
            chart.Height = height;

            // рендерить чарт в картинку
            var img = new Bitmap(width, height);

            chart.DrawToBitmap(img, new Rectangle(0, 0, width - 1, height - 1));

            // включить картинку в HTML
            var str    = BaseWebServer.MakeEmbeddedPictureString(img);
            var imgStr = string.Format(
                "<img src=\"{0}\" alt=\"Доходность по счету\" style=\"cursor:pointer\" /> ", str);

            sb.AppendLine("<br/>");
            sb.AppendLine(imgStr);
            sb.AppendLine(string.Format("    <p style=\"font-weight:bold\">{0}</p>", title));
        }
Esempio n. 3
0
        public void Draw(FastChart owner, PaintEventArgs e, Point o, Point tip, int width)
        {
            var lineCl = LineColor.HasValue ? LineColor.Value : Color.Black;

            var start = !AlwaysShowNil ? MinValue : new Cortege2<double, DateTime>(0, DateTime.MinValue);
            var step = CalculateStep(start, o, tip);
            if (step.a == 0 && step.b == TimeSpan.Zero)
                // нет делений
                return;

            var lblFmt = DeriveFormatFromStep(step);

            var cur = start;
            // сместить текущую отметку на ближ. целое значение шага
            if (!IsDateTime)
            {
                cur.a = ((int)(cur.a / step.a)) * step.a;
            }

            var drawFormat = new StringFormat(VerticalText ?
                StringFormatFlags.DirectionVertical : StringFormatFlags.NoWrap);
            var lenPx = Direction == FastAxisDirection.X
                ? Math.Abs(tip.X - o.X) : Math.Abs(tip.Y - o.Y);

            using (var brush = new SolidBrush(lineCl))
            {
                using (var pen = new Pen(lineCl))
                {
                    e.Graphics.DrawLine(pen, o.X, o.Y, tip.X, tip.Y);
                    using (var penGridMain = new Pen(ColorMainGrid.HasValue ? ColorMainGrid.Value : Color.DarkGray))
                    {
                        while (true)
                        {
                            // след. значение
                            if (!IsDateTime)
                            {
                                if (step.a == 0) break;
                                cur.a += step.a;
                            }
                            else
                            {
                                if (step.b == TimeSpan.Zero) break;
                                cur.b += step.b;
                            }
                            // вышли за пределы шкалы?
                            if (!IsDateTime) if (cur.a > MaxValue.a) break;
                            if (IsDateTime) if (cur.b > MaxValue.b) break;

                            // текст подписи
                            var labelTxt = !IsDateTime
                                               ? cur.a.ToString(lblFmt)
                                               : cur.b.ToString(lblFmt);
                            // размеры, занимаемые подписью
                            var txtSzOrig = e.Graphics.MeasureString(labelTxt, owner.Font);
                            var txtSz = VerticalText
                                            ? new SizeF(txtSzOrig.Height, txtSzOrig.Width)
                                            : txtSzOrig;
                            // координата
                            var ptDist = !IsDateTime
                                             ? (cur.a - start.a)/(MaxValue.a - start.a)
                                             : (cur.b - start.b).TotalMilliseconds/
                                               (MaxValue.b - start.b).TotalMilliseconds;
                            ptDist *= lenPx;
                            var ptDot = Direction == FastAxisDirection.X
                                            ? new Point(o.X + (int) ptDist, o.Y)
                                            : new Point(o.X, o.Y - (int) ptDist);
                            var ptLeftUp = Direction == FastAxisDirection.X
                                               ? new PointF(ptDot.X - txtSz.Width/2, ptDot.Y + 3)
                                               : new PointF(ptDot.X - txtSz.Width - 3, ptDot.Y - txtSz.Height/2);
                            // нарисовать текст
                            e.Graphics.DrawString(labelTxt, owner.Font, brush,
                                                  ptLeftUp.X, ptLeftUp.Y, drawFormat);
                            // нарисовать засечку
                            try
                            {
                                if (Direction == FastAxisDirection.X)
                                    e.Graphics.DrawLine(pen, ptDot.X, ptDot.Y - 2, ptDot.X, ptDot.Y + 2);
                                else
                                    e.Graphics.DrawLine(pen, ptDot.X - 2, ptDot.Y, ptDot.X + 2, ptDot.Y);
                            }
                            catch (Exception ex)
                            {
                                owner.lastError = ex.ToString();
                                return;
                            }

                            // нарисовать сетку
                            if (DrawMainGrid)
                            {
                                if (Direction == FastAxisDirection.X)
                                    e.Graphics.DrawLine(penGridMain, ptDot.X, ptDot.Y + 2, ptDot.X, ptDot.Y - width);
                                else
                                    e.Graphics.DrawLine(penGridMain, ptDot.X + 2, ptDot.Y, ptDot.X + width, ptDot.Y);
                            }
                        }// while

                        // нарисовать рамку
                        if (DrawMainGrid)
                        {
                            if (Direction == FastAxisDirection.X)
                                e.Graphics.DrawLine(penGridMain, o.X, o.Y - width, tip.X, o.Y - width);
                            else
                                e.Graphics.DrawLine(penGridMain, o.X + width, o.Y, o.X + width, tip.Y);
                        }

                    }// main grid pen
                }// brush
            }
        }
        /// <summary>
        /// вернуть полный путь к файлу с картинкой доходности
        /// </summary>
        private string MakeProfitChart(string tempFolder, Size chartSize)
        {
            var chart = new FastChart.Chart.FastChart
            {
                ShowLegend      = true,
                LegendPlacement = FastChart.Chart.FastChart.ChartLegendPlacement.Справа,
                BorderStyle     = BorderStyle.None,
                DrawMargin      = false
            };
            var axisX = new FastAxis(FastAxisDirection.X, true)
            {
                ColorMainGrid = Color.FromArgb(205, 205, 205),
                ColorSubGrid  = Color.FromArgb(220, 220, 220),
                DrawMainGrid  = true,
                DrawSubGrid   = true,
                Step          = new FastChart.Chart.Cortege2 <double, TimeSpan>(0,
                                                                                new TimeSpan(356, 0, 0, 0)),
                LabelFormat = "yyyy"
            };
            var maxProfit = (double)profitDic.Max(p => p.equity);
            var axisY     = new FastAxis(FastAxisDirection.Y, false)
            {
                ColorMainGrid = Color.FromArgb(205, 205, 205),
                ColorSubGrid  = Color.FromArgb(220, 220, 220),
                DrawMainGrid  = true,
                DrawSubGrid   = true,
                AutoScale100  = false,
                MinValue      = new FastChart.Chart.Cortege2 <double, DateTime>(0, default(DateTime)),
                MaxValue      = new FastChart.Chart.Cortege2 <double, DateTime>(maxProfit * 1.1,
                                                                                default(DateTime))
            };

            if (maxProfit > 1000)
            {
                var stepSize = maxProfit < 2000 ? 200 : maxProfit < 4000 ? 500 : 1000;
                axisY.Step = new FastChart.Chart.Cortege2 <double, TimeSpan>(stepSize, default(TimeSpan));
            }

            chart.Axes.Add(axisX);
            chart.Axes.Add(axisY);
            var seriesFund = new FastSeries("УК", FastSeriesType.Линия, axisX, axisY, false)
            {
                PenLine = new Pen(Color.FromArgb(80, 5, 5), 2f), AntiAlias = true
            };

            seriesFund.points.AddRange(profitDic.Select(p => new FastSeriesPoint(p.time, p.equity)).ToList());
            chart.series.Add(seriesFund);
            // серии бенчмарков
            var seriesBmA = new FastSeries(benchmarkA, FastSeriesType.Линия, axisX, axisY, false)
            {
                PenLine = new Pen(Color.FromArgb(5, 80, 5), 2f), AntiAlias = true
            };
            var seriesBmB = new FastSeries(benchmarkB, FastSeriesType.Линия, axisX, axisY, false)
            {
                PenLine = new Pen(Color.FromArgb(5, 5, 80), 2f), AntiAlias = true
            };

            seriesBmA.points.AddRange(MakeBenchmarkProfit1000Points(vamiBenchmarkA));
            seriesBmB.points.AddRange(MakeBenchmarkProfit1000Points(vamiBenchmarkB));
            chart.series.Add(seriesBmA);
            chart.series.Add(seriesBmB);

            chart.Width  = chartSize.Width;
            chart.Height = chartSize.Height;

            var img = new Bitmap(chartSize.Width, chartSize.Height);

            chart.DrawToBitmap(img, new Rectangle(0, 0, chartSize.Width, chartSize.Height));
            var path = string.Format("{0}\\chartProfit1000_{1}.png", tempFolder, DateTime.Now.Millisecond);

            img.Save(path, ImageFormat.Png);
            return(path);
        }
        private void RenderChart(StringBuilder sb, string title, int width, int height, 
            List<List<FastSeriesPoint>> series, List<string> seriesNames)
        {
            var seriesColors = new [] {Color.DarkBlue, Color.DarkOliveGreen, Color.Firebrick};

            var needYearsInFormat = stat.listEquity[stat.listEquity.Count - 1].time.Year != stat.listEquity[0].time.Year;
            var formatString = needYearsInFormat ? "dd.MM.yyyy" : "dd MMM";

            var chart = new FastChart.Chart.FastChart
            {
                ShowLegend = series.Count > 1,
                LegendPlacement = FastChart.Chart.FastChart.ChartLegendPlacement.Справа,
                BorderStyle = BorderStyle.None,
                DrawMargin = false
            };

            var axisX = new FastAxis(FastAxisDirection.X, true)
            {
                ColorMainGrid = Color.FromArgb(205, 205, 205),
                ColorSubGrid = Color.FromArgb(220, 220, 220),
                DrawMainGrid = true,
                DrawSubGrid = true,
                LabelFormat = formatString
            };

            // границы оси Y
            var min = double.MaxValue;
            var max = double.MinValue;
            foreach (var ser in series)
            {
                foreach (var pt in ser)
                {
                    if (min > pt.y) min = pt.y;
                    if (max < pt.y) max = pt.y;
                }
            }
            min = GetLowerBound(min);

            var axisY = new FastAxis(FastAxisDirection.Y, false)
            {
                ColorMainGrid = Color.FromArgb(205, 205, 205),
                ColorSubGrid = Color.FromArgb(220, 220, 220),
                DrawMainGrid = true,
                DrawSubGrid = true,
                AutoScale100 = false,
                MinValue = new FastChart.Chart.Cortege2<double, DateTime>(min, default(DateTime)),
                MaxValue = new FastChart.Chart.Cortege2<double, DateTime>(max * 1.05, default(DateTime))
            };

            chart.Axes.Add(axisX);
            chart.Axes.Add(axisY);

            // добавить серии и точки
            for (var i = 0; i < series.Count; i++)
            {
                var ser = new FastSeries(seriesNames[i], FastSeriesType.Линия, axisX, axisY, false)
                              {
                                  PenLine = new Pen(seriesColors[i], 2f), AntiAlias = true
                              };
                ser.points.AddRange(series[i]);
                chart.series.Add(ser);
            }

            chart.Width = width;
            chart.Height = height;

            // рендерить чарт в картинку
            var img = new Bitmap(width, height);
            chart.DrawToBitmap(img, new Rectangle(0, 0, width - 1, height - 1));

            // включить картинку в HTML
            var str = BaseWebServer.MakeEmbeddedPictureString(img);
            var imgStr = string.Format(
                "<img src=\"{0}\" alt=\"Доходность по счету\" style=\"cursor:pointer\" /> ", str);

            sb.AppendLine("<br/>");
            sb.AppendLine(imgStr);
            sb.AppendLine(string.Format("    <p style=\"font-weight:bold\">{0}</p>", title));
        }
Esempio n. 6
0
 public void ApplyToChart(FastChart chart)
 {
     chart.Padding = Padding;
     chart.DrawMargin = DrawMargin;
     if (PenMargin != null) chart.penMargin = PenMargin;
     if (BrushArea != null) chart.brushArea = BrushArea;
     chart.UseGradient = UseGradient;
     chart.ClGradStart = ClGradStart;
     chart.ClGradEnd = ClGradEnd;
     chart.GradAngle = GradAngle;
     if (ChartFont != null) chart.Font = ChartFont;
     if (ColorAxes.Length > 0)
     {
         var clIndex = 0;
         foreach (var ax in chart.Axes.FindAll(a => a.Direction == FastAxisDirection.X))
         {
             if (ax.LineColor.HasValue) continue;
             ax.LineColor = ColorAxes[clIndex++];
             if (clIndex >= ColorAxes.Length) clIndex = 0;
         }
         clIndex = 0;
         foreach (var ax in chart.Axes.FindAll(a => a.Direction == FastAxisDirection.Y))
         {
             if (ax.LineColor.HasValue) continue;
             ax.LineColor = ColorAxes[clIndex++];
             if (clIndex >= ColorAxes.Length) clIndex = 0;
         }
     }
     if (ColorAxesGrids.Length > 0)
     {
         var clIndex = 0;
         foreach (var ax in chart.Axes.FindAll(a => a.Direction == FastAxisDirection.X))
         {
             if (ax.ColorMainGrid.HasValue) continue;
             ax.ColorMainGrid = ColorAxesGrids[clIndex++];
             if (clIndex >= ColorAxesGrids.Length) clIndex = 0;
         }
         clIndex = 0;
         foreach (var ax in chart.Axes.FindAll(a => a.Direction == FastAxisDirection.Y))
         {
             if (ax.ColorMainGrid.HasValue) continue;
             ax.ColorMainGrid = ColorAxesGrids[clIndex++];
             if (clIndex >= ColorAxesGrids.Length) clIndex = 0;
         }
     }
 }
Esempio n. 7
0
 public void ApplyToChart(FastChart chart)
 {
     chart.Padding    = Padding;
     chart.DrawMargin = DrawMargin;
     if (PenMargin != null)
     {
         chart.penMargin = PenMargin;
     }
     if (BrushArea != null)
     {
         chart.brushArea = BrushArea;
     }
     chart.UseGradient = UseGradient;
     chart.ClGradStart = ClGradStart;
     chart.ClGradEnd   = ClGradEnd;
     chart.GradAngle   = GradAngle;
     if (ChartFont != null)
     {
         chart.Font = ChartFont;
     }
     if (ColorAxes.Length > 0)
     {
         var clIndex = 0;
         foreach (var ax in chart.Axes.FindAll(a => a.Direction == FastAxisDirection.X))
         {
             if (ax.LineColor.HasValue)
             {
                 continue;
             }
             ax.LineColor = ColorAxes[clIndex++];
             if (clIndex >= ColorAxes.Length)
             {
                 clIndex = 0;
             }
         }
         clIndex = 0;
         foreach (var ax in chart.Axes.FindAll(a => a.Direction == FastAxisDirection.Y))
         {
             if (ax.LineColor.HasValue)
             {
                 continue;
             }
             ax.LineColor = ColorAxes[clIndex++];
             if (clIndex >= ColorAxes.Length)
             {
                 clIndex = 0;
             }
         }
     }
     if (ColorAxesGrids.Length > 0)
     {
         var clIndex = 0;
         foreach (var ax in chart.Axes.FindAll(a => a.Direction == FastAxisDirection.X))
         {
             if (ax.ColorMainGrid.HasValue)
             {
                 continue;
             }
             ax.ColorMainGrid = ColorAxesGrids[clIndex++];
             if (clIndex >= ColorAxesGrids.Length)
             {
                 clIndex = 0;
             }
         }
         clIndex = 0;
         foreach (var ax in chart.Axes.FindAll(a => a.Direction == FastAxisDirection.Y))
         {
             if (ax.ColorMainGrid.HasValue)
             {
                 continue;
             }
             ax.ColorMainGrid = ColorAxesGrids[clIndex++];
             if (clIndex >= ColorAxesGrids.Length)
             {
                 clIndex = 0;
             }
         }
     }
 }
Esempio n. 8
0
        /// <returns>размер, отъедаемый легендой от графика</returns>
        public Size DrawLegend(PaintEventArgs e, FastChart owner)
        {
            if (!ShowLegend || owner.series.Count == 0)
            {
                return(new Size(0, 0));
            }
            const int legRecHeight     = 40;
            var       legendHeight     = owner.series.Count * legRecHeight;
            var       legendHeightFull = LegendInnerPadding * 2 + legendHeight;

            if (Width < (LengthMinWidth + 120 + LegendPadding * 2) ||
                Height < (legendHeightFull + 100 + LegendPadding * 2))
            {
                return(new Size(0, 0));
            }

            var rect =
                LegendPlacement == ChartLegendPlacement.Вверху
                    ? new Rectangle(Math.Max(Width / 5, LegendPadding), LegendPadding,
                                    Math.Min(Width * 4 / 5, LegendPadding), legendHeightFull)
                    : new Rectangle(Width - lengthMinWidth - LegendPadding, LegendPadding,
                                    lengthMinWidth, legendHeightFull);

            // нарисовать тень
            if (DrawShadow)
            {
                rect.Offset(4, 4);
                e.Graphics.FillRectangle(legendShadowBrush, rect);
                rect.Offset(-4, -4);
            }
            // закрасить
            e.Graphics.FillRectangle(legendBrush, rect);
            // рамка
            if (DrawLegendMargin)
            {
                e.Graphics.DrawRectangle(penLegend, rect);
            }

            // текст
            var textY = rect.Top + LegendInnerPadding;
            var textX = rect.Left + LegendInnerPadding;

            using (var brushText = new SolidBrush(LegendMarginColor))
            {
                foreach (var sr in owner.series)
                {
                    var txtSz = e.Graphics.MeasureString(sr.Name, owner.Font);
                    // точка
                    using (var brushDot = new SolidBrush(sr.PenLine != null
                        ? sr.PenLine.Color : Color.DarkGray))
                    {
                        e.Graphics.FillRectangle(brushDot, textX, textY + legRecHeight / 2 - 4,
                                                 4, 4);
                    }
                    // текст
                    e.Graphics.DrawString(sr.Name, owner.Font, brushText, textX + 7,
                                          textY + legRecHeight / 2 - txtSz.Height / 2);

                    textY += legRecHeight;
                }
            }

            return(new Size(lengthMinWidth + LegendPadding * 2,
                            legendHeightFull + LegendPadding * 2));
        }
        /// <summary>
        /// вернуть полный путь к файлу с картинкой доходности
        /// </summary>
        private string MakeProfitChart(string tempFolder, Size chartSize)
        {
            var chart = new FastChart.Chart.FastChart
                            {
                                ShowLegend = true,
                                LegendPlacement = FastChart.Chart.FastChart.ChartLegendPlacement.Справа,
                                BorderStyle = BorderStyle.None,
                                DrawMargin = false
                            };
            var axisX = new FastAxis(FastAxisDirection.X, true)
                            {
                                ColorMainGrid = Color.FromArgb(205, 205, 205),
                                ColorSubGrid = Color.FromArgb(220, 220, 220),
                                DrawMainGrid = true,
                                DrawSubGrid = true,
                                Step = new FastChart.Chart.Cortege2<double, TimeSpan>(0,
                                                                                      new TimeSpan(356, 0, 0, 0)),
                                LabelFormat = "yyyy"
                            };
            var maxProfit = (double) profitDic.Max(p => p.equity);
            var axisY = new FastAxis(FastAxisDirection.Y, false)
                            {
                                ColorMainGrid = Color.FromArgb(205, 205, 205),
                                ColorSubGrid = Color.FromArgb(220, 220, 220),
                                DrawMainGrid = true,
                                DrawSubGrid = true,
                                AutoScale100 = false,
                                MinValue = new FastChart.Chart.Cortege2<double, DateTime>(0, default(DateTime)),
                                MaxValue = new FastChart.Chart.Cortege2<double, DateTime>(maxProfit * 1.1,
                                    default(DateTime))
                            };
            if (maxProfit > 1000)
            {
                var stepSize = maxProfit < 2000 ? 200 : maxProfit < 4000 ? 500 : 1000;
                axisY.Step = new FastChart.Chart.Cortege2<double, TimeSpan>(stepSize, default(TimeSpan));
            }

            chart.Axes.Add(axisX);
            chart.Axes.Add(axisY);
            var seriesFund = new FastSeries("УК", FastSeriesType.Линия, axisX, axisY, false)
                             {PenLine = new Pen(Color.FromArgb(80, 5, 5), 2f), AntiAlias = true };
            seriesFund.points.AddRange(profitDic.Select(p => new FastSeriesPoint(p.time, p.equity)).ToList());
            chart.series.Add(seriesFund);
            // серии бенчмарков
            var seriesBmA = new FastSeries(benchmarkA, FastSeriesType.Линия, axisX, axisY, false) { PenLine = new Pen(Color.FromArgb(5, 80, 5), 2f), AntiAlias = true };
            var seriesBmB = new FastSeries(benchmarkB, FastSeriesType.Линия, axisX, axisY, false) { PenLine = new Pen(Color.FromArgb(5, 5, 80), 2f), AntiAlias = true };
            seriesBmA.points.AddRange(MakeBenchmarkProfit1000Points(vamiBenchmarkA));
            seriesBmB.points.AddRange(MakeBenchmarkProfit1000Points(vamiBenchmarkB));
            chart.series.Add(seriesBmA);
            chart.series.Add(seriesBmB);

            chart.Width = chartSize.Width;
            chart.Height = chartSize.Height;

            var img = new Bitmap(chartSize.Width, chartSize.Height);
            chart.DrawToBitmap(img, new Rectangle(0, 0, chartSize.Width, chartSize.Height));
            var path = string.Format("{0}\\chartProfit1000_{1}.png", tempFolder, DateTime.Now.Millisecond);
            img.Save(path, ImageFormat.Png);
            return path;
        }