private void DrawSeries(Graphics g, List <UIDoughnutSeries> series) { if (series == null || series.Count == 0) { return; } for (int pieIndex = 0; pieIndex < series.Count; pieIndex++) { var pie = series[pieIndex]; for (int azIndex = 0; azIndex < pie.Data.Count; azIndex++) { Angle angle = Angles[pieIndex][azIndex]; Color color = ChartStyle.GetColor(azIndex); UIPieSeriesData data = pie.Data[azIndex]; if (data.StyleCustomMode) { color = data.Color; } if (ActiveAzIndex == azIndex) { g.FillFan(color, angle.Center, angle.Inner, angle.Outer + 5, angle.Start - 90, angle.Sweep); } else { g.FillFan(color, angle.Center, angle.Inner, angle.Outer, angle.Start - 90, angle.Sweep); } Angles[pieIndex][azIndex].TextSize = g.MeasureString(Angles[pieIndex][azIndex].Text, LegendFont); if (pie.Label.Show && ActiveAzIndex == azIndex) { if (pie.Label.Position == UIPieSeriesLabelPosition.Center) { SizeF sf = g.MeasureString(pie.Data[azIndex].Name, Font); g.DrawString(pie.Data[azIndex].Name, Font, color, angle.Center.X - sf.Width / 2.0f, angle.Center.Y - sf.Height / 2.0f); } } } } }
protected override void CalcData() { Bars.Clear(); NeedDraw = false; if (Option == null || Option.Series == null || Option.SeriesCount == 0) { return; } DrawOrigin = new Point(Option.Grid.Left, Height - Option.Grid.Bottom); DrawSize = new Size(Width - Option.Grid.Left - Option.Grid.Right, Height - Option.Grid.Top - Option.Grid.Bottom); if (DrawSize.Width <= 0 || DrawSize.Height <= 0) { return; } if (Option.XAxis.Data.Count == 0) { return; } NeedDraw = true; DrawBarWidth = DrawSize.Width * 1.0f / Option.XAxis.Data.Count; double min = double.MaxValue; double max = double.MinValue; foreach (var series in Option.Series) { if (series.Data.Count > 0) { min = Math.Min(min, series.Data.Min()); max = Math.Max(max, series.Data.Max()); } } if (min > 0 && max > 0 && !Option.YAxis.Scale) { min = 0; } if (min < 0 && max < 0 && !Option.YAxis.Scale) { max = 0; } if (!Option.YAxis.MaxAuto) { max = Option.YAxis.Max; } if (!Option.YAxis.MinAuto) { min = Option.YAxis.Min; } if ((max - min).IsZero() && min.IsZero()) { max = 100; min = 0; } else { if (max > 0) { min = 0; } else { max = 0; } } CalcDegreeScale(min, max, Option.YAxis.SplitNumber, out int start, out int end, out double interval, out int decimalCount); YAxisStart = start; YAxisEnd = end; YAxisInterval = interval; YAxisDecimalCount = decimalCount; float x1 = DrawBarWidth / (Option.SeriesCount * 2 + Option.SeriesCount + 1); float x2 = x1 * 2; for (int i = 0; i < Option.SeriesCount; i++) { float barX = DrawOrigin.X; var series = Option.Series[i]; Bars.TryAdd(i, new List <BarInfo>()); for (int j = 0; j < series.Data.Count; j++) { Color color = ChartStyle.GetColor(i); if (series.Colors.Count > 0 && j >= 0 && j < series.Colors.Count) { color = series.Colors[j]; } float xx = barX + x1 * (i + 1) + x2 * i + x1; float ww = Math.Min(x2, series.MaxWidth); xx -= ww / 2.0f; if (YAxisStart >= 0) { float h = Math.Abs((float)(DrawSize.Height * (series.Data[j] - start * interval) / ((end - start) * interval))); Bars[i].Add(new BarInfo() { Rect = new RectangleF(xx, DrawOrigin.Y - h, ww, h), Color = color }); } else if (YAxisEnd <= 0) { float h = Math.Abs((float)(DrawSize.Height * (end * interval - series.Data[j]) / ((end - start) * interval))); Bars[i].Add(new BarInfo() { Rect = new RectangleF(xx, Option.Grid.Top + 1, ww, h - 1), Color = color }); } else { float lowH = 0; float highH = 0; float DrawBarHeight = DrawSize.Height * 1.0f / (YAxisEnd - YAxisStart); float lowV = 0; float highV = 0; for (int k = YAxisStart; k <= YAxisEnd; k++) { if (k < 0) { lowH += DrawBarHeight; } if (k > 0) { highH += DrawBarHeight; } if (k < 0) { lowV += (float)YAxisInterval; } if (k > 0) { highV += (float)YAxisInterval; } } // lowH.ConsoleWriteLine(); // highH.ConsoleWriteLine(); if (series.Data[j] >= 0) { float h = Math.Abs((float)(highH * series.Data[j] / highV)); Bars[i].Add(new BarInfo() { Rect = new RectangleF(xx, DrawOrigin.Y - lowH - h, ww, h), Color = color }); } else { float h = Math.Abs((float)(lowH * series.Data[j] / lowV)); Bars[i].Add(new BarInfo() { Rect = new RectangleF(xx, DrawOrigin.Y - lowH + 1, ww, h - 1), Color = color }); } } barX += DrawBarWidth; } } if (Option.ToolTip != null) { for (int i = 0; i < Option.XAxis.Data.Count; i++) { string str = Option.XAxis.Data[i]; foreach (var series in Option.Series) { str += '\n'; str += series.Name + " : " + series.Data[i].ToString(Option.ToolTip.ValueFormat); } Bars[0][i].Tips = str; } } }
private void DrawSeries(Graphics g) { if (YScale == null) { return; } bmp?.Dispose(); bmp = new Bitmap(Width, Height); //using (Graphics graphics = bmp.Graphics()) //{ // graphics.FillRectangle(FillColor, 0, 0, Width, Height); //} // //using (Graphics graphics = bmpGreater.Graphics()) //{ // graphics.FillRectangle(FillColor, 0, 0, Width, Height); //} // //using (Graphics graphics = bmpLess.Graphics()) //{ // graphics.FillRectangle(FillColor, 0, 0, Width, Height); //} int idx = 0; float wTop = Option.Grid.Top; float wBottom = Height - Option.Grid.Bottom; float wLeft = Option.Grid.Left; float wRight = Width - Option.Grid.Right; if ((Option.GreaterWarningArea == null && Option.LessWarningArea == null) || Option.HaveY2) { foreach (var series in Option.Series.Values) { Color color = series.Color; if (!series.CustomColor) { color = ChartStyle.GetColor(idx); } using (Graphics graphics = bmp.Graphics()) { DrawSeries(graphics, color, series); } idx++; } } else { bmpGreater?.Dispose(); bmpGreater = new Bitmap(Width, Height); bmpLess?.Dispose(); bmpLess = new Bitmap(Width, Height); foreach (var series in Option.Series.Values) { Color color = series.Color; if (!series.CustomColor) { color = ChartStyle.GetColor(idx); } using (Graphics graphics = bmp.Graphics()) { DrawSeries(graphics, color, series); } if (Option.GreaterWarningArea != null) { using Graphics graphics = bmpGreater.Graphics(); DrawSeries(graphics, Option.GreaterWarningArea.Color, series); } if (Option.LessWarningArea != null) { using Graphics graphics = bmpLess.Graphics(); DrawSeries(graphics, Option.LessWarningArea.Color, series); } idx++; } if (Option.GreaterWarningArea != null) { wTop = YScale.CalcYPixel(Option.GreaterWarningArea.Value, DrawOrigin.Y, DrawSize.Height); if (wTop < Option.Grid.Top) { wTop = Option.Grid.Top; } else { if (wTop > Height - Option.Grid.Bottom) { wTop = Height - Option.Grid.Bottom; } g.DrawImage(bmpGreater, new Rectangle((int)wLeft, Option.Grid.Top, (int)(wRight - wLeft), (int)(wTop - Option.Grid.Top)), new Rectangle((int)wLeft, Option.Grid.Top, (int)(wRight - wLeft), (int)(wTop - Option.Grid.Top)), GraphicsUnit.Pixel); } } if (Option.LessWarningArea != null) { wBottom = YScale.CalcYPixel(Option.LessWarningArea.Value, DrawOrigin.Y, DrawSize.Height); if (wBottom > Height - Option.Grid.Bottom) { wBottom = Height - Option.Grid.Bottom; } else { if (wBottom < Option.Grid.Top) { wBottom = Option.Grid.Top; } g.DrawImage(bmpLess, new Rectangle((int)wLeft, (int)wBottom, (int)(wRight - wLeft), (int)(Height - Option.Grid.Bottom - wBottom)), new Rectangle((int)wLeft, (int)wBottom, (int)(wRight - wLeft), (int)(Height - Option.Grid.Bottom - wBottom)), GraphicsUnit.Pixel); } } } g.DrawImage(bmp, new Rectangle((int)wLeft, (int)wTop, (int)(wRight - wLeft), (int)(wBottom - wTop)), new Rectangle((int)wLeft, (int)wTop, (int)(wRight - wLeft), (int)(wBottom - wTop)), GraphicsUnit.Pixel); }
private void DrawSeries(Graphics g) { if (YScale == null) { return; } int idx = 0; if (Option.GreaterWarningArea == null && Option.LessWarningArea == null) { foreach (var series in Option.Series.Values) { Color color = series.Color; if (!series.CustomColor) { color = ChartStyle.GetColor(idx); } DrawSeries(g, color, series); idx++; } } else { Bitmap bmp = new Bitmap(Width, Height); Bitmap bmpGreater = new Bitmap(Width, Height); Bitmap bmpLess = new Bitmap(Width, Height); float wTop = 0; float wBottom = Height; foreach (var series in Option.Series.Values) { Color color = series.Color; if (!series.CustomColor) { color = ChartStyle.GetColor(idx); } using (Graphics graphics = bmp.Graphics()) { DrawSeries(graphics, color, series); } if (Option.GreaterWarningArea != null) { using (Graphics graphics = bmpGreater.Graphics()) { DrawSeries(graphics, Option.GreaterWarningArea.Color, series); } } if (Option.LessWarningArea != null) { using (Graphics graphics = bmpLess.Graphics()) { DrawSeries(graphics, Option.LessWarningArea.Color, series); } } idx++; } if (Option.GreaterWarningArea != null) { wTop = YScale.CalcYPixel(Option.GreaterWarningArea.Value, DrawOrigin.Y, DrawSize.Height); g.DrawImage(bmpGreater, new Rectangle(0, 0, Width, (int)wTop), new Rectangle(0, 0, Width, (int)wTop), GraphicsUnit.Pixel); } if (Option.LessWarningArea != null) { wBottom = YScale.CalcYPixel(Option.LessWarningArea.Value, DrawOrigin.Y, DrawSize.Height); g.DrawImage(bmpLess, new Rectangle(0, (int)wBottom, Width, Height - (int)wBottom), new Rectangle(0, (int)wBottom, Width, Height - (int)wBottom), GraphicsUnit.Pixel); } g.DrawImage(bmp, new Rectangle(0, (int)wTop, Width, (int)wBottom - (int)wTop), new Rectangle(0, (int)wTop, Width, (int)wBottom - (int)wTop), GraphicsUnit.Pixel); bmpGreater.Dispose(); bmpLess.Dispose(); bmp.Dispose(); } idx = 0; foreach (var series in Option.Series.Values) { Color color = series.Color; if (!series.CustomColor) { color = ChartStyle.GetColor(idx); } if (series.Symbol != UILinePointSymbol.None) { using (Brush br = new SolidBrush(ChartStyle.BackColor)) using (Pen pn = new Pen(color, series.SymbolLineWidth)) { foreach (var p in series.Points) { switch (series.Symbol) { case UILinePointSymbol.Square: g.FillRectangle(br, p.X - series.SymbolSize, p.Y - series.SymbolSize, series.SymbolSize * 2, series.SymbolSize * 2); g.DrawRectangle(pn, p.X - series.SymbolSize, p.Y - series.SymbolSize, series.SymbolSize * 2, series.SymbolSize * 2); break; case UILinePointSymbol.Diamond: { PointF pt1 = new PointF(p.X - series.SymbolSize, p.Y); PointF pt2 = new PointF(p.X, p.Y - series.SymbolSize); PointF pt3 = new PointF(p.X + series.SymbolSize, p.Y); PointF pt4 = new PointF(p.X, p.Y + series.SymbolSize); PointF[] pts = { pt1, pt2, pt3, pt4, pt1 }; g.SetHighQuality(); GraphicsPath path = pts.Path(); g.FillPath(br, path); g.DrawPath(pn, path); path.Dispose(); } break; case UILinePointSymbol.Triangle: { PointF pt1 = new PointF(p.X, p.Y - series.SymbolSize); PointF pt2 = new PointF(p.X - series.SymbolSize * 0.866f, p.Y + series.SymbolSize * 0.5f); PointF pt3 = new PointF(p.X + series.SymbolSize * 0.866f, p.Y + series.SymbolSize * 0.5f); PointF[] pts = { pt1, pt2, pt3, pt1 }; g.SetHighQuality(); GraphicsPath path = pts.Path(); g.FillPath(br, path); g.DrawPath(pn, path); path.Dispose(); } break; case UILinePointSymbol.Circle: g.SetHighQuality(); g.FillEllipse(br, p.X - series.SymbolSize, p.Y - series.SymbolSize, series.SymbolSize * 2, series.SymbolSize * 2); g.DrawEllipse(pn, p.X - series.SymbolSize, p.Y - series.SymbolSize, series.SymbolSize * 2, series.SymbolSize * 2); break; case UILinePointSymbol.Plus: g.DrawLine(pn, p.X - series.SymbolSize, p.Y, p.X + series.SymbolSize, p.Y); g.DrawLine(pn, p.X, p.Y - series.SymbolSize, p.X, p.Y + series.SymbolSize); break; case UILinePointSymbol.Star: g.SetHighQuality(); g.DrawLine(pn, p.X, p.Y - series.SymbolSize, p.X, p.Y + series.SymbolSize); g.DrawLine(pn, p.X - series.SymbolSize * 0.866f, p.Y + series.SymbolSize * 0.5f, p.X + series.SymbolSize * 0.866f, p.Y - series.SymbolSize * 0.5f); g.DrawLine(pn, p.X - series.SymbolSize * 0.866f, p.Y - series.SymbolSize * 0.5f, p.X + series.SymbolSize * 0.866f, p.Y + series.SymbolSize * 0.5f); break; } } } g.SetDefaultQuality(); } idx++; } }
private void DrawSeries(Graphics g, List <UIPieSeries> series) { if (series == null || series.Count == 0) { return; } if (AllIsZero) { if (series.Count > 0) { RectangleF rect = GetSeriesRect(series[0]); g.DrawEllipse(Color.Red, rect); } return; } for (int pieIndex = 0; pieIndex < series.Count; pieIndex++) { var pie = series[pieIndex]; RectangleF rect = GetSeriesRect(pie); for (int azIndex = 0; azIndex < pie.Data.Count; azIndex++) { Color color = ChartStyle.GetColor(azIndex); UIPieSeriesData data = pie.Data[azIndex]; if (data.StyleCustomMode) { color = data.Color; } RectangleF rectx = new RectangleF(rect.X - 10, rect.Y - 10, rect.Width + 20, rect.Width + 20); g.FillPie(color, (ActivePieIndex == pieIndex && ActiveAzIndex == azIndex) ? rectx : rect, Angles[pieIndex][azIndex].Start - 90, Angles[pieIndex][azIndex].Sweep); Angles[pieIndex][azIndex].TextSize = g.MeasureString(Angles[pieIndex][azIndex].Text, LegendFont); if (pie.Label.Show) { double az = Angles[pieIndex][azIndex].Start + Angles[pieIndex][azIndex].Sweep / 2; double x = Math.Abs(Math.Sin(az * Math.PI / 180)); double y = Math.Abs(Math.Cos(az * Math.PI / 180)); string name = Option.Legend != null ? Option.Legend.Data[azIndex] + " : " : ""; if (pie.Data[azIndex].Value > 0) { string text = name + pie.Data[azIndex].Value.ToString("F0"); SizeF sf = g.MeasureString(text, SubFont); PointF pf; int added = 9; if (az >= 0 && az < 90) { pf = new PointF((float)(DrawCenter(pie).X + RadiusSize(pie) * x + added), (float)(DrawCenter(pie).Y - RadiusSize(pie) * y - sf.Height - added)); } else if (az >= 90 && az < 180) { pf = new PointF((float)(DrawCenter(pie).X + RadiusSize(pie) * x + added), (float)(DrawCenter(pie).Y + RadiusSize(pie) * y + added)); } else if (az >= 180 && az < 270) { pf = new PointF((float)(DrawCenter(pie).X - RadiusSize(pie) * x - added) - sf.Width, (float)(DrawCenter(pie).Y + RadiusSize(pie) * y + added)); } else { pf = new PointF((float)(DrawCenter(pie).X - RadiusSize(pie) * x - added) - sf.Width, (float)(DrawCenter(pie).Y - RadiusSize(pie) * y) - sf.Height - added); } if (pie.Data[azIndex].Value > 0) { g.DrawString(text, SubFont, color, pf.X, pf.Y); } } } } } }
protected override void CalcData() { Bars.Clear(); NeedDraw = false; if (Option == null || Option.Series == null || Option.SeriesCount == 0) { return; } if (DrawSize.Width <= 0 || DrawSize.Height <= 0) { return; } if (Option.Series.Count == 0) { return; } NeedDraw = true; DrawBarWidth = DrawSize.Width * 1.0f / Option.Series.Count; double min = double.MaxValue; double max = double.MinValue; foreach (var series in Option.Series) { min = Math.Min(min, series.Data.Min()); max = Math.Max(max, series.Data.Max()); } if (min > 0 && max > 0 && !Option.YAxis.Scale) { min = 0; } if (min < 0 && max < 0 && !Option.YAxis.Scale) { max = 0; } if (!Option.YAxis.MaxAuto) { max = Option.YAxis.Max; } if (!Option.YAxis.MinAuto) { min = Option.YAxis.Min; } if ((max - min).IsZero()) { if (min.IsZero()) { max = 100; min = 0; } else if (max > 0) { max = max * 2; min = 0; } else { max = 0; min = min * 2; } } CalcDegreeScale(min, max, Option.YAxis.SplitNumber, out int start, out int end, out double interval, out int decimalCount); YAxisStart = start; YAxisEnd = end; YAxisInterval = interval; YAxisDecimalCount = decimalCount; float barX = DrawOrigin.X; if (Option.AutoSizeBars) { //每个柱子等宽 float x1 = DrawSize.Width * 1.0f / DataCount / 4; float x2 = x1 * 2; if (Option.AutoSizeBarsCompact) { //紧凑 for (int i = 0; i < Option.SeriesCount; i++) { var series = Option.Series[i]; Bars.TryAdd(i, new List <BarInfo>()); float sx = barX + x1 * ((series.Data.Count * 4 - (series.Data.Count * 2 + (series.Data.Count - 1) * Option.AutoSizeBarsCompactValue)) / 2.0f) + x1; for (int j = 0; j < series.Data.Count; j++) { Color color = ChartStyle.GetColor(i); if (series.Colors.Count > 0 && j >= 0 && j < series.Colors.Count) { color = series.Colors[j]; } float ww = Math.Min(x2, series.MaxWidth); float xx = sx - ww / 2.0f; if (YAxisStart >= 0) { float h = Math.Abs((float)(DrawSize.Height * (series.Data[j] - start * interval) / ((end - start) * interval))); Bars[i].Add(new BarInfo() { Rect = new RectangleF(xx, DrawOrigin.Y - h, ww, h), Color = color }); } else if (YAxisEnd <= 0) { float h = Math.Abs((float)(DrawSize.Height * (end * interval - series.Data[j]) / ((end - start) * interval))); Bars[i].Add(new BarInfo() { Rect = new RectangleF(xx, Option.Grid.Top + 1, ww, h - 1), Color = color }); } else { float lowH = 0; float highH = 0; float DrawBarHeight = DrawSize.Height * 1.0f / (YAxisEnd - YAxisStart); float lowV = 0; float highV = 0; for (int k = YAxisStart; k <= YAxisEnd; k++) { if (k < 0) { lowH += DrawBarHeight; } if (k > 0) { highH += DrawBarHeight; } if (k < 0) { lowV += (float)YAxisInterval; } if (k > 0) { highV += (float)YAxisInterval; } } if (series.Data[j] >= 0) { float h = Math.Abs((float)(highH * series.Data[j] / highV)); Bars[i].Add(new BarInfo() { Rect = new RectangleF(xx, DrawOrigin.Y - lowH - h, ww, h), Color = color }); } else { float h = Math.Abs((float)(lowH * series.Data[j] / lowV)); Bars[i].Add(new BarInfo() { Rect = new RectangleF(xx, DrawOrigin.Y - lowH + 1, ww, h - 1), Color = color }); } } sx += x2 + x1 * Option.AutoSizeBarsCompactValue; } barX += x2 * 2 * series.Data.Count; } } else { //宽松 for (int i = 0; i < Option.SeriesCount; i++) { var series = Option.Series[i]; Bars.TryAdd(i, new List <BarInfo>()); for (int j = 0; j < series.Data.Count; j++) { Color color = ChartStyle.GetColor(i); if (series.Colors.Count > 0 && j >= 0 && j < series.Colors.Count) { color = series.Colors[j]; } float xx = barX + DrawSize.Width * 1.0f / DataCount / 2; float ww = Math.Min(x2, series.MaxWidth); xx -= ww / 2.0f; if (YAxisStart >= 0) { float h = Math.Abs((float)(DrawSize.Height * (series.Data[j] - start * interval) / ((end - start) * interval))); Bars[i].Add(new BarInfo() { Rect = new RectangleF(xx, DrawOrigin.Y - h, ww, h), Color = color }); } else if (YAxisEnd <= 0) { float h = Math.Abs((float)(DrawSize.Height * (end * interval - series.Data[j]) / ((end - start) * interval))); Bars[i].Add(new BarInfo() { Rect = new RectangleF(xx, Option.Grid.Top + 1, ww, h - 1), Color = color }); } else { float lowH = 0; float highH = 0; float DrawBarHeight = DrawSize.Height * 1.0f / (YAxisEnd - YAxisStart); float lowV = 0; float highV = 0; for (int k = YAxisStart; k <= YAxisEnd; k++) { if (k < 0) { lowH += DrawBarHeight; } if (k > 0) { highH += DrawBarHeight; } if (k < 0) { lowV += (float)YAxisInterval; } if (k > 0) { highV += (float)YAxisInterval; } } if (series.Data[j] >= 0) { float h = Math.Abs((float)(highH * series.Data[j] / highV)); Bars[i].Add(new BarInfo() { Rect = new RectangleF(xx, DrawOrigin.Y - lowH - h, ww, h), Color = color }); } else { float h = Math.Abs((float)(lowH * series.Data[j] / lowV)); Bars[i].Add(new BarInfo() { Rect = new RectangleF(xx, DrawOrigin.Y - lowH + 1, ww, h - 1), Color = color }); } } barX += DrawSize.Width * 1.0f / DataCount; } } } } else { //每个序列等宽 if (Option.AutoSizeBarsCompact) { //紧凑 float CompactWidth = DrawBarWidth / 4.0f * Option.AutoSizeBarsCompactValue; for (int i = 0; i < Option.SeriesCount; i++) { var series = Option.Series[i]; float x1 = DrawBarWidth / series.Data.Count / 4.0f; float x2 = x1 * 2; float ww = Math.Min(x2, series.MaxWidth); float sx = barX + (DrawBarWidth - ww * series.Data.Count - (series.Data.Count - 1) * CompactWidth) / 2.0f; Bars.TryAdd(i, new List <BarInfo>()); for (int j = 0; j < series.Data.Count; j++) { Color color = ChartStyle.GetColor(i); if (series.Colors.Count > 0 && j >= 0 && j < series.Colors.Count) { color = series.Colors[j]; } float xx = sx; if (YAxisStart >= 0) { float h = Math.Abs((float)(DrawSize.Height * (series.Data[j] - start * interval) / ((end - start) * interval))); Bars[i].Add(new BarInfo() { Rect = new RectangleF(xx, DrawOrigin.Y - h, ww, h), Color = color }); } else if (YAxisEnd <= 0) { float h = Math.Abs((float)(DrawSize.Height * (end * interval - series.Data[j]) / ((end - start) * interval))); Bars[i].Add(new BarInfo() { Rect = new RectangleF(xx, Option.Grid.Top + 1, ww, h - 1), Color = color }); } else { float lowH = 0; float highH = 0; float DrawBarHeight = DrawSize.Height * 1.0f / (YAxisEnd - YAxisStart); float lowV = 0; float highV = 0; for (int k = YAxisStart; k <= YAxisEnd; k++) { if (k < 0) { lowH += DrawBarHeight; } if (k > 0) { highH += DrawBarHeight; } if (k < 0) { lowV += (float)YAxisInterval; } if (k > 0) { highV += (float)YAxisInterval; } } if (series.Data[j] >= 0) { float h = Math.Abs((float)(highH * series.Data[j] / highV)); Bars[i].Add(new BarInfo() { Rect = new RectangleF(xx, DrawOrigin.Y - lowH - h, ww, h), Color = color }); } else { float h = Math.Abs((float)(lowH * series.Data[j] / lowV)); Bars[i].Add(new BarInfo() { Rect = new RectangleF(xx, DrawOrigin.Y - lowH + 1, ww, h - 1), Color = color }); } } sx += ww + CompactWidth; } barX += DrawBarWidth; } } else { //宽松 for (int i = 0; i < Option.SeriesCount; i++) { var series = Option.Series[i]; float x1; if (Option.FixedSeriesCount > 0) { x1 = DrawBarWidth / (Option.FixedSeriesCount * 2 + Option.FixedSeriesCount + 1); } else { x1 = DrawBarWidth / (series.Data.Count * 2 + series.Data.Count + 1); } float x2 = x1 * 2; Bars.TryAdd(i, new List <BarInfo>()); for (int j = 0; j < series.Data.Count; j++) { Color color = ChartStyle.GetColor(i); if (series.Colors.Count > 0 && j >= 0 && j < series.Colors.Count) { color = series.Colors[j]; } float xx; if (Option.FixedSeriesCount > 0) { xx = barX + DrawBarWidth / (series.Data.Count * 2 + series.Data.Count + 1) * ((j + 1) * 3 - 1); } else { xx = barX + x1 * ((j + 1) * 3 - 1); } float ww = Math.Min(x2, series.MaxWidth); xx -= ww / 2.0f; if (YAxisStart >= 0) { float h = Math.Abs((float)(DrawSize.Height * (series.Data[j] - start * interval) / ((end - start) * interval))); Bars[i].Add(new BarInfo() { Rect = new RectangleF(xx, DrawOrigin.Y - h, ww, h), Color = color }); } else if (YAxisEnd <= 0) { float h = Math.Abs((float)(DrawSize.Height * (end * interval - series.Data[j]) / ((end - start) * interval))); Bars[i].Add(new BarInfo() { Rect = new RectangleF(xx, Option.Grid.Top + 1, ww, h - 1), Color = color }); } else { float lowH = 0; float highH = 0; float DrawBarHeight = DrawSize.Height * 1.0f / (YAxisEnd - YAxisStart); float lowV = 0; float highV = 0; for (int k = YAxisStart; k <= YAxisEnd; k++) { if (k < 0) { lowH += DrawBarHeight; } if (k > 0) { highH += DrawBarHeight; } if (k < 0) { lowV += (float)YAxisInterval; } if (k > 0) { highV += (float)YAxisInterval; } } if (series.Data[j] >= 0) { float h = Math.Abs((float)(highH * series.Data[j] / highV)); Bars[i].Add(new BarInfo() { Rect = new RectangleF(xx, DrawOrigin.Y - lowH - h, ww, h), Color = color }); } else { float h = Math.Abs((float)(lowH * series.Data[j] / lowV)); Bars[i].Add(new BarInfo() { Rect = new RectangleF(xx, DrawOrigin.Y - lowH + 1, ww, h - 1), Color = color }); } } } barX += DrawBarWidth; } } } if (Option.ToolTip != null) { for (int i = 0; i < Option.Series.Count; i++) { var series = Option.Series[i]; string str = Option.Series[i].Name; for (int j = 0; j < series.Data.Count; j++) { str += '\n'; if (series.BarName.Count > 0 && j < series.BarName.Count) { str += series.BarName[j] + " : "; } str += series.Data[j].ToString(Option.ToolTip.ValueFormat); } Bars[i][0].Tips = str; } } }
protected override void CalcData() { Bars.Clear(); NeedDraw = false; if (Option == null || Option.Series == null || Option.SeriesCount == 0) { return; } if (DrawSize.Width <= 0 || DrawSize.Height <= 0) { return; } if (Option.XAxis.Data.Count == 0) { return; } NeedDraw = true; DrawBarWidth = DrawSize.Width * 1.0f / Option.XAxis.Data.Count; double min = double.MaxValue; double max = double.MinValue; foreach (var series in Option.Series) { if (series.Data.Count > 0) { min = Math.Min(min, series.Data.Min()); max = Math.Max(max, series.Data.Max()); } } if (min > 0 && max > 0 && !Option.YAxis.Scale) { min = 0; } if (min < 0 && max < 0 && !Option.YAxis.Scale) { max = 0; } if (!Option.YAxis.MaxAuto) { max = Option.YAxis.Max; } if (!Option.YAxis.MinAuto) { min = Option.YAxis.Min; } if (Option.YAxis.MaxAuto && Option.YAxis.MinAuto) { if (min > 0) { min = 0; } if (max < 0) { max = 0; } if (min.IsZero() && !max.IsZero()) { max = max * 1.2; } if (max.IsZero() && !min.IsZero()) { min = min * 1.2; } if (!max.IsZero() && !min.IsZero()) { max = max * 1.2; min = min * 1.2; } } if ((max - min).IsZero()) { if (min.IsZero()) { max = 100; min = 0; } else if (max > 0) { max = max * 2; min = 0; } else { max = 0; min = min * 2; } } YScale.Max = max; YScale.Min = min; YScale.AxisChange(); YAxisStart = YScale.Min; YAxisEnd = YScale.Max; YAxisInterval = YScale.Step; double[] YLabels = YScale.CalcLabels(); float[] labels = YScale.CalcYPixels(YLabels, DrawOrigin.Y, DrawSize.Height); YAxisDecimalCount = YScale.Format.Replace("F", "").ToInt(); float x1 = DrawBarWidth / (Option.SeriesCount * 2 + Option.SeriesCount + 1); float x2 = x1 * 2; for (int i = 0; i < Option.SeriesCount; i++) { float barX = DrawOrigin.X; var series = Option.Series[i]; Bars.TryAdd(i, new List <BarInfo>()); for (int j = 0; j < series.Data.Count; j++) { Color color = ChartStyle.GetColor(i); if (series.Colors.Count > 0 && j >= 0 && j < series.Colors.Count) { color = series.Colors[j]; } float xx = barX + x1 * (i + 1) + x2 * i + x1; float ww = Math.Min(x2, series.MaxWidth); xx -= ww / 2.0f; float YZeroPos = YScale.CalcYPixel(0, DrawOrigin.Y, DrawSize.Height); float VPos = YScale.CalcYPixel(series.Data[j], DrawOrigin.Y, DrawSize.Height); if (VPos <= YZeroPos) { Bars[i].Add(new BarInfo() { Rect = new RectangleF(xx, VPos, ww, (YZeroPos - VPos)), Value = series.Data[j], Color = color, Top = true }); } else { Bars[i].Add(new BarInfo() { Rect = new RectangleF(xx, YZeroPos, ww, (VPos - YZeroPos)), Value = series.Data[j], Color = color, Top = false }); } barX += DrawBarWidth; } } if (Option.ToolTip != null) { for (int i = 0; i < Option.XAxis.Data.Count; i++) { string str = Option.XAxis.Data[i]; foreach (var series in Option.Series) { str += '\n'; str += series.Name + " : " + series.Data[i].ToString(Option.ToolTip.ValueFormat); } Bars[0][i].Tips = str; } } }
private void DrawSeries(Graphics g) { if (YScale == null) { return; } using (Graphics graphics = bmp.Graphics()) { graphics.FillRectangle(FillColor, 0, 0, Width, Height); } using (Graphics graphics = bmpGreater.Graphics()) { graphics.FillRectangle(FillColor, 0, 0, Width, Height); } using (Graphics graphics = bmpLess.Graphics()) { graphics.FillRectangle(FillColor, 0, 0, Width, Height); } int idx = 0; float wTop = Option.Grid.Top; float wBottom = Height - Option.Grid.Bottom; float wLeft = Option.Grid.Left; float wRight = Width - Option.Grid.Right; if (Option.GreaterWarningArea == null && Option.LessWarningArea == null) { foreach (var series in Option.Series.Values) { Color color = series.Color; if (!series.CustomColor) { color = ChartStyle.GetColor(idx); } using (Graphics graphics = bmp.Graphics()) { DrawSeries(graphics, color, series); } idx++; } } else { foreach (var series in Option.Series.Values) { Color color = series.Color; if (!series.CustomColor) { color = ChartStyle.GetColor(idx); } using (Graphics graphics = bmp.Graphics()) { DrawSeries(graphics, color, series); } if (Option.GreaterWarningArea != null) { using (Graphics graphics = bmpGreater.Graphics()) { DrawSeries(graphics, Option.GreaterWarningArea.Color, series); } } if (Option.LessWarningArea != null) { using (Graphics graphics = bmpLess.Graphics()) { DrawSeries(graphics, Option.LessWarningArea.Color, series); } } idx++; } if (Option.GreaterWarningArea != null) { wTop = YScale.CalcYPixel(Option.GreaterWarningArea.Value, DrawOrigin.Y, DrawSize.Height); if (wTop < Option.Grid.Top) { wTop = Option.Grid.Top; } else { if (wTop > Height - Option.Grid.Bottom) { wTop = Height - Option.Grid.Bottom; } g.DrawImage(bmpGreater, new Rectangle((int)wLeft, Option.Grid.Top, (int)(wRight - wLeft), (int)(wTop - Option.Grid.Top)), new Rectangle((int)wLeft, Option.Grid.Top, (int)(wRight - wLeft), (int)(wTop - Option.Grid.Top)), GraphicsUnit.Pixel); } } if (Option.LessWarningArea != null) { wBottom = YScale.CalcYPixel(Option.LessWarningArea.Value, DrawOrigin.Y, DrawSize.Height); if (wBottom > Height - Option.Grid.Bottom) { wBottom = Height - Option.Grid.Bottom; } else { if (wBottom < Option.Grid.Top) { wBottom = Option.Grid.Top; } g.DrawImage(bmpLess, new Rectangle((int)wLeft, (int)wBottom, (int)(wRight - wLeft), (int)(Height - Option.Grid.Bottom - wBottom)), new Rectangle((int)wLeft, (int)wBottom, (int)(wRight - wLeft), (int)(Height - Option.Grid.Bottom - wBottom)), GraphicsUnit.Pixel); } } } g.DrawImage(bmp, new Rectangle((int)wLeft, (int)wTop, (int)(wRight - wLeft), (int)(wBottom - wTop)), new Rectangle((int)wLeft, (int)wTop, (int)(wRight - wLeft), (int)(wBottom - wTop)), GraphicsUnit.Pixel); idx = 0; foreach (var series in Option.Series.Values) { Color color = series.Color; if (!series.CustomColor) { color = ChartStyle.GetColor(idx); } if (series.Symbol != UILinePointSymbol.None) { using (Brush br = new SolidBrush(FillColor)) using (Pen pn = new Pen(color, series.SymbolLineWidth)) { foreach (var p in series.Points) { if (p.X <= Option.Grid.Left || p.X >= Width - Option.Grid.Right) { continue; } if (p.Y <= Option.Grid.Top || p.Y >= Height - Option.Grid.Bottom) { continue; } switch (series.Symbol) { case UILinePointSymbol.Square: g.FillRectangle(br, p.X - series.SymbolSize, p.Y - series.SymbolSize, series.SymbolSize * 2, series.SymbolSize * 2); g.DrawRectangle(pn, p.X - series.SymbolSize, p.Y - series.SymbolSize, series.SymbolSize * 2, series.SymbolSize * 2); break; case UILinePointSymbol.Diamond: { PointF pt1 = new PointF(p.X - series.SymbolSize, p.Y); PointF pt2 = new PointF(p.X, p.Y - series.SymbolSize); PointF pt3 = new PointF(p.X + series.SymbolSize, p.Y); PointF pt4 = new PointF(p.X, p.Y + series.SymbolSize); PointF[] pts = { pt1, pt2, pt3, pt4, pt1 }; g.SetHighQuality(); GraphicsPath path = pts.Path(); g.FillPath(br, path); g.DrawPath(pn, path); path.Dispose(); } break; case UILinePointSymbol.Triangle: { PointF pt1 = new PointF(p.X, p.Y - series.SymbolSize); PointF pt2 = new PointF(p.X - series.SymbolSize * 0.866f, p.Y + series.SymbolSize * 0.5f); PointF pt3 = new PointF(p.X + series.SymbolSize * 0.866f, p.Y + series.SymbolSize * 0.5f); PointF[] pts = { pt1, pt2, pt3, pt1 }; g.SetHighQuality(); GraphicsPath path = pts.Path(); g.FillPath(br, path); g.DrawPath(pn, path); path.Dispose(); } break; case UILinePointSymbol.Circle: g.SetHighQuality(); g.FillEllipse(br, p.X - series.SymbolSize, p.Y - series.SymbolSize, series.SymbolSize * 2, series.SymbolSize * 2); g.DrawEllipse(pn, p.X - series.SymbolSize, p.Y - series.SymbolSize, series.SymbolSize * 2, series.SymbolSize * 2); break; case UILinePointSymbol.Plus: g.DrawLine(pn, p.X - series.SymbolSize, p.Y, p.X + series.SymbolSize, p.Y); g.DrawLine(pn, p.X, p.Y - series.SymbolSize, p.X, p.Y + series.SymbolSize); break; case UILinePointSymbol.Star: g.SetHighQuality(); g.DrawLine(pn, p.X, p.Y - series.SymbolSize, p.X, p.Y + series.SymbolSize); g.DrawLine(pn, p.X - series.SymbolSize * 0.866f, p.Y + series.SymbolSize * 0.5f, p.X + series.SymbolSize * 0.866f, p.Y - series.SymbolSize * 0.5f); g.DrawLine(pn, p.X - series.SymbolSize * 0.866f, p.Y - series.SymbolSize * 0.5f, p.X + series.SymbolSize * 0.866f, p.Y + series.SymbolSize * 0.5f); break; } } } g.SetDefaultQuality(); } idx++; } }