protected override void CreateEmptyOption() { if (emptyOption != null) { return; } emptyOption = new UIOption(); emptyOption.Title = new UITitle(); emptyOption.Title.Text = "SunnyUI"; emptyOption.Title.SubText = "PieChart"; var series = new UISeries(); series.Name = "饼状图"; series.Type = UISeriesType.Pie; series.Center = new UICenter(50, 55); series.Radius = 70; for (int i = 0; i < 5; i++) { series.AddData("Data" + i, (i + 1) * 20); } emptyOption.Series.Add(series); }
protected override void CalcData(UIOption option) { Angles.Clear(); UIDoughnutOption o = (UIDoughnutOption)option; if (o == null || o.Series == null || o.Series.Count == 0) { return; } for (int pieIndex = 0; pieIndex < o.Series.Count; pieIndex++) { var pie = o.Series[pieIndex]; Angles.TryAdd(pieIndex, new ConcurrentDictionary <int, Angle>()); double all = 0; foreach (var data in pie.Data) { all += data.Value; } if (all.IsZero()) { return; } float start = 0; for (int i = 0; i < pie.Data.Count; i++) { float angle = (float)(pie.Data[i].Value * 360.0f / all); float percent = (float)(pie.Data[i].Value * 100.0f / all); string text = ""; if (o.ToolTip != null) { try { UITemplate template = new UITemplate(o.ToolTip.Formatter); template.Set("a", pie.Name); template.Set("b", pie.Data[i].Name); template.Set("c", pie.Data[i].Value.ToString(o.ToolTip.ValueFormat)); template.Set("d", percent.ToString("F2")); text = template.Render(); } catch { text = pie.Data[i].Name + " : " + pie.Data[i].Value.ToString("F2") + "(" + percent.ToString("F2") + "%)"; if (pie.Name.IsValid()) { text = pie.Name + '\n' + text; } } } Angle pieAngle = new Angle(start, angle, text); GetSeriesRect(pie, ref pieAngle); Angles[pieIndex].AddOrUpdate(i, pieAngle); start += angle; } } }
protected override void DrawSeries(Graphics g, UIOption o, List <UISeries> series) { if (series == null || series.Count == 0) { 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.SeriesColor[azIndex % ChartStyle.ColorCount]; 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].Size = g.MeasureString(Angles[pieIndex][azIndex].Text, legendFont); } } }
protected override void OnMouseMove(MouseEventArgs e) { base.OnMouseMove(e); UIOption option = Option ?? EmptyOption; if (option.SeriesCount == 0) { SetPieAndAzIndex(-1, -1); return; } for (int pieIndex = 0; pieIndex < option.SeriesCount; pieIndex++) { RectangleF rect = GetSeriesRect(option.Series[pieIndex]); if (!e.Location.InRect(rect)) { continue; } PointF pf = new PointF(rect.Left + rect.Width / 2.0f, rect.Top + rect.Height / 2.0f); if (MathEx.CalcDistance(e.Location, pf) * 2 > rect.Width) { continue; } double az = MathEx.CalcAngle(e.Location, pf); for (int azIndex = 0; azIndex < option.Series[pieIndex].Data.Count; azIndex++) { if (az >= Angles[pieIndex][azIndex].Start && az <= Angles[pieIndex][azIndex].Start + Angles[pieIndex][azIndex].Sweep) { SetPieAndAzIndex(pieIndex, azIndex); if (tip.Text != Angles[pieIndex][azIndex].Text) { tip.Text = Angles[pieIndex][azIndex].Text; tip.Size = new Size((int)Angles[pieIndex][azIndex].Size.Width + 4, (int)Angles[pieIndex][azIndex].Size.Height + 4); } if (az >= 0 && az < 90) { tip.Top = e.Location.Y + 20; tip.Left = e.Location.X - tip.Width; } else if (az >= 90 && az < 180) { tip.Left = e.Location.X - tip.Width; tip.Top = e.Location.Y - tip.Height - 2; } else if (az >= 180 && az < 270) { tip.Left = e.Location.X; tip.Top = e.Location.Y - tip.Height - 2; } else if (az >= 270 && az < 360) { tip.Left = e.Location.X + 15; tip.Top = e.Location.Y + 20; } if (!tip.Visible) { tip.Visible = Angles[pieIndex][azIndex].Text.IsValid(); } return; } } } SetPieAndAzIndex(-1, -1); tip.Visible = false; }
protected override void CalcData(UIOption option) { Bars.Clear(); NeedDraw = false; UIBarOption o = (UIBarOption)option; if (o == null || o.Series == null || o.SeriesCount == 0) { return; } DrawOrigin = new Point(BarOption.Grid.Left, Height - BarOption.Grid.Bottom); DrawSize = new Size(Width - BarOption.Grid.Left - BarOption.Grid.Right, Height - BarOption.Grid.Top - BarOption.Grid.Bottom); if (DrawSize.Width <= 0 || DrawSize.Height <= 0) { return; } if (o.XAxis.Data.Count == 0) { return; } NeedDraw = true; DrawBarWidth = DrawSize.Width * 1.0f / o.XAxis.Data.Count; double min = double.MaxValue; double max = double.MinValue; foreach (var series in o.Series) { min = Math.Min(min, series.Data.Min()); max = Math.Max(max, series.Data.Max()); } if (min > 0 && max > 0 && !o.YAxis.Scale) { min = 0; } if (min < 0 && max < 0 && !o.YAxis.Scale) { max = 0; } if (!o.YAxis.MaxAuto) { max = o.YAxis.Max; } if (!o.YAxis.MinAuto) { min = o.YAxis.Min; } if ((max - min).IsZero()) { max = 100; min = 0; } UIChartHelper.CalcDegreeScale(min, max, o.YAxis.SplitNumber, out int start, out int end, out double interval); YAxisStart = start; YAxisEnd = end; YAxisInterval = interval; float x1 = DrawBarWidth / ((o.SeriesCount * 2) + o.SeriesCount + 1); float x2 = x1 * 2; for (int i = 0; i < o.SeriesCount; i++) { float barX = DrawOrigin.X; var series = o.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]; } 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( barX + x1 * (i + 1) + x2 * i, DrawOrigin.Y - h, x2, 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( barX + x1 * (i + 1) + x2 * i, BarOption.Grid.Top + 1, x2, 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( barX + x1 * (i + 1) + x2 * i, DrawOrigin.Y - lowH - h, x2, h), Color = color }); } else { float h = Math.Abs((float)(lowH * series.Data[j] / lowV)); Bars[i].Add(new BarInfo() { Rect = new RectangleF( barX + x1 * (i + 1) + x2 * i, DrawOrigin.Y - lowH + 1, x2, h - 1), Color = color }); } } barX += DrawBarWidth; } } if (BarOption.ToolTip != null) { for (int i = 0; i < BarOption.XAxis.Data.Count; i++) { string str = BarOption.XAxis.Data[i]; foreach (var series in BarOption.Series) { str += '\n'; str += series.Name + " : " + series.Data[i].ToString(BarOption.ToolTip.ValueFormat); } Bars[0][i].Tips = str; } } }