/// <summary> /// Create pie chart parts. /// </summary> /// <param name="segments">Pie chart segments.</param> private void SpawnPieParts(List <PieSegment> segments) { Random.InitState(colourSeed); foreach (PieSegment segment in segments) { // Generate random colours for each segment if random colours is enabled if (isColourRandom) { segment.Color = Color.HSVToRGB(Random.value, 0.6f, .8f); } // Spawn pie chart parts PieChartPart part = Instantiate(partPrefab, transform); part.gameObject.name = segment.Name; part.Name = segment.Name; part.Value = segment.Value; part.Total = totalValue; part.Color = segment.Color; part.Thickness = segment.Thickness; part.Radius = segment.Radius; // Hide empty segments if (segment.Value == 0) { part.gameObject.GetComponent <Renderer>().enabled = false; } Debug.Assert(part.Thickness != 0.0f, $"[{name}] Segment thickness for {part.Name} is 0!"); Debug.Assert(part.Radius != 0.0f, $"[{name}] Segment radius for {part.Name} is 0!"); // Add to instantiated object list pieParts.Add(part); // Spawn label objects TextMeshPro label = Instantiate(labelPrefab, transform); label.text = segment.Value.ToString("P0"); // Add to instantiated object list labels.Add(label); } // Animate pie chart if enabled if (isAnimated) { animEnumerator = AnimatePieChart(); StartCoroutine(animEnumerator); } else { UpdatePie(); } }
/// <summary> /// Updates pie chart values and rotations. /// </summary> /// <param name="t">The ratio to the maximum angle in which the chart will be expanded to. [0..1]</param> private void UpdatePie(float t = 1.0f) { float angle = 0.0f, prevAngle = 0.0f; // Update each segment for (int i = 0; i < pieParts.Count; i++) { // Interpolate pie chart radius pieParts[i].Value = t * segments[i].Value; pieParts[i].UpdateMesh(); pieParts[i].transform.localRotation = Quaternion.Euler(0.0f, angle, 0.0f); // Next part of the pie will follow at the end of the previous pie part angle += pieParts[i].Value / totalValue * 360.0f; // Hide label if its value is 0 if (segments[i].Value == 0) { labels[i].gameObject.SetActive(false); } else { // Show object if it has non-zero value labels[i].gameObject.SetActive(true); // Position labels float midPointAngle = (angle + prevAngle) / 2; labels[i].transform.localPosition = new Vector3( Mathf.Sin(PieChartPart.ToRad(midPointAngle)) * pieParts[i].Radius * labelRadiusRatio, pieParts[i].Thickness, Mathf.Cos(PieChartPart.ToRad(midPointAngle)) * pieParts[i].Radius * labelRadiusRatio) + labelOffset; // Update label text labels[i].text = pieParts[i].Value.ToString("P0"); } // Update prevAngle prevAngle = angle; } }