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; } } }