private void DrawMultipleDoughnut(IChartTransformer transformer) { if (IsSegmentVisible) { var segmentStartAngle = ActualStartAngle; var segmentEndAngle = ActualEndAngle; var center = parentSeries.Center; double actualRadius = parentSeries.InternalDoughnutSize * Math.Min(transformer.Viewport.Width, transformer.Viewport.Height) / 2; double remainingWidth = actualRadius - (actualRadius * Series.ActualArea.InternalDoughnutHoleSize); double equalParts = (remainingWidth / doughnutSegmentsCount) * parentSeries.InternalDoughnutCoefficient; double radius = actualRadius - (equalParts * (doughnutSegmentsCount - (DoughnutSegmentIndex + 1))); parentSeries.Radius = actualRadius - equalParts; double innerRadius = radius - equalParts; double outerRadius = radius - equalParts * parentSeries.SegmentSpacing; innerRadius = ChartMath.MaxZero(innerRadius); if (parentSeries.Segments.IndexOf(this) == 0) { parentSeries.InnerRadius = innerRadius; } this.pathGeometry = GetDoughnutGeometry(center, outerRadius, innerRadius, segmentStartAngle, segmentEndAngle, false); this.segmentPath.Data = pathGeometry; //Rendering the back segments. var seriesStartAngle = parentSeries.DegreeToRadianConverter(parentSeries.StartAngle); var seriesEndAngle = parentSeries.DegreeToRadianConverter(parentSeries.EndAngle); var totalArcLength = Math.PI * 2; var arcLength = seriesEndAngle - seriesStartAngle; if (Math.Abs(Math.Round(arcLength, 2)) > totalArcLength) { arcLength = arcLength % totalArcLength; } seriesEndAngle = arcLength + seriesStartAngle; this.circularPathGeometry = GetDoughnutGeometry(center, outerRadius, innerRadius, seriesStartAngle, seriesEndAngle, true); this.CircularDoughnutPath.Data = circularPathGeometry; } else { this.pathGeometry = null; this.segmentPath.Data = null; this.circularPathGeometry = null; this.CircularDoughnutPath.Data = null; } }
/// <summary> /// Creates the point. /// </summary> protected override void CreatePoints() { if (Area.RootPanelDesiredSize != null) { this.actualWidth = Area.RootPanelDesiredSize.Value.Width; this.actualHeight = Area.RootPanelDesiredSize.Value.Height; } var doughnutIndex = GetPieSeriesIndex(); var doughnutCount = GetCircularSeriesCount(); double actualRadius = InternalCircleCoefficient * Math.Min(actualWidth, actualHeight) / 2; double remainingWidth = actualRadius - (actualRadius * Area.InternalDoughnutHoleSize); double equalParts = remainingWidth / doughnutCount; this.Radius = actualRadius - (equalParts * (doughnutCount - (doughnutIndex + 1))); this.InnerRadius = this.Radius - (equalParts * this.InternlDoughnutCoefficient); this.InnerRadius = ChartMath.MaxZero(this.InnerRadius); base.CreatePoints(); }
private void DrawSingleDoughnut(IChartTransformer transformer) { var segmentStartAngle = ActualStartAngle; var segmentEndAngle = ActualEndAngle; Point center; if (doughnutSeriesCount > 1) { center = new Point(0.5 * transformer.Viewport.Width, 0.5 * transformer.Viewport.Height); } else { center = parentSeries.Center; } CalculateGapRatioAngle(ref segmentEndAngle, ref segmentStartAngle); double actualRadius = parentSeries.InternalDoughnutSize * Math.Min(transformer.Viewport.Width, transformer.Viewport.Height) / 2; double remainingWidth = actualRadius - (actualRadius * Series.ActualArea.InternalDoughnutHoleSize); double equalParts = remainingWidth / doughnutSeriesCount; double radius = parentSeries.Radius = actualRadius - (equalParts * (doughnutSeriesCount - (doughnutSeriesIndex + 1))); double innerRadius = radius - (equalParts * parentSeries.InternalDoughnutCoefficient); innerRadius = ChartMath.MaxZero(innerRadius); if (parentSeries.Segments.IndexOf(this) == 0) { parentSeries.InnerRadius = innerRadius; } this.pathGeometry = GetDoughnutGeometry(center, radius, innerRadius, segmentStartAngle, segmentEndAngle, false); this.segmentPath.Data = pathGeometry; this.circularPathGeometry = null; this.CircularDoughnutPath.Data = null; }
/// <summary> /// Updates the segments based on its data point value. This method is not /// intended to be called explicitly outside the Chart but it can be overriden by /// any derived class. /// </summary> /// <param name="transformer">Reresents the view port of chart control.(refer <see cref="IChartTransformer"/>)</param> public override void Update(IChartTransformer transformer) { double radius = Radius; double actualRadius = Math.Min(transformer.Viewport.Width, transformer.Viewport.Height) / 2; if (Series is PieSeries) { var hostSeries = Series as PieSeries; double pieSeriesCount = hostSeries.GetPieSeriesCount(); double equalParts = actualRadius / pieSeriesCount; double innerRadius = equalParts * pieIndex; Point center; if (pieSeriesCount == 1) { center = hostSeries.Center; } else { center = ChartLayoutUtils.GetCenter(transformer.Viewport); } if (hostSeries != null && hostSeries.LabelPosition == CircularSeriesLabelPosition.Inside) { if (pieIndex > 0) { double difference = (radius - innerRadius) / 2; radius = radius - difference; } else { radius = radius / 2; } } this.X = center.X + radius * Math.Cos(Angle); this.Y = center.Y + radius * Math.Sin(Angle); } else if (Series is DoughnutSeries) { var hostSeries = Series as DoughnutSeries; actualRadius *= hostSeries.InternalDoughnutSize; Point center; double remainingWidth = 0d, equalParts = 0d, innerRadius = 0d; var adornmentAngle = Angle; if (hostSeries.IsStackedDoughnut) { var adornmentIndex = Series.Adornments.IndexOf(this); var doughnutSegment = hostSeries.Segments[adornmentIndex] as DoughnutSegment; int doughnutSegmentsCount = hostSeries.Segments.Count; center = hostSeries.Center; remainingWidth = actualRadius - (actualRadius * Series.ActualArea.InternalDoughnutHoleSize); equalParts = (remainingWidth / doughnutSegmentsCount) * hostSeries.InternalDoughnutCoefficient; radius = actualRadius - (equalParts * (doughnutSegmentsCount - (doughnutSegment.DoughnutSegmentIndex + 1))); InnerDoughnutRadius = innerRadius = radius - equalParts; radius = radius - equalParts * hostSeries.SegmentSpacing; Radius = radius; innerRadius = ChartMath.MaxZero(innerRadius); double difference = (radius - innerRadius) / 2; radius = radius - difference; adornmentAngle = hostSeries.LabelPosition == CircularSeriesLabelPosition.Outside ? doughnutSegment.StartAngle : hostSeries.LabelPosition == CircularSeriesLabelPosition.OutsideExtended ? doughnutSegment.EndAngle : Angle; } else { int doughnutSeriesCount = hostSeries.GetDoughnutSeriesCount(); center = doughnutSeriesCount == 1 ? hostSeries.Center : ChartLayoutUtils.GetCenter(transformer.Viewport); remainingWidth = actualRadius - (actualRadius * Series.ActualArea.InternalDoughnutHoleSize); equalParts = remainingWidth / doughnutSeriesCount; InnerDoughnutRadius = innerRadius = radius - (equalParts * hostSeries.InternalDoughnutCoefficient); innerRadius = ChartMath.MaxZero(innerRadius); if (hostSeries != null && hostSeries.LabelPosition == CircularSeriesLabelPosition.Inside) { double difference = (radius - innerRadius) / 2; radius = radius - difference; } } this.X = center.X + radius * Math.Cos(adornmentAngle); this.Y = center.Y + radius * Math.Sin(adornmentAngle); } }
/// <summary> /// Updates the segments based on its data point value. This method is not /// intended to be called explicitly outside the Chart but it can be overriden by /// any derived class. /// </summary> /// <param name="transformer">Represents the view port of chart control.(refer <see cref="IChartTransformer"/>)</param> public override void Update(IChartTransformer transformer) { double radius = Radius; double actualRadius = Math.Min(transformer.Viewport.Width, transformer.Viewport.Height) / 2; if (Series is DoughnutSeries3D) { var hostSeries = Series as DoughnutSeries3D; double doughnutSeriesCount = hostSeries.GetCircularSeriesCount(); actualRadius *= hostSeries.InternalCircleCoefficient; Point center = hostSeries.Center; if (doughnutSeriesCount > 1) { center = new Point(transformer.Viewport.Width / 2, transformer.Viewport.Height / 2); } double remainingWidth = actualRadius - (actualRadius * Series.ActualArea.InternalDoughnutHoleSize); double equalParts = remainingWidth / doughnutSeriesCount; double innerRadius = radius - (equalParts * hostSeries.InternlDoughnutCoefficient); innerRadius = ChartMath.MaxZero(innerRadius); if (hostSeries.ExplodeIndex == hostSeries.Segments.Count - 1 || hostSeries.ExplodeAll) { var rect = new Rect(0, 0, transformer.Viewport.Width, transformer.Viewport.Height); center = hostSeries.GetActualCenter(new Point(rect.X + rect.Width / 2, rect.Y + rect.Height / 2), Radius); } if (hostSeries != null && hostSeries.LabelPosition == CircularSeriesLabelPosition.Inside) { double difference = (radius - innerRadius) / 2; radius -= difference; } this.X = center.X + radius * Math.Cos(Angle); this.Y = center.Y + radius * Math.Sin(Angle); } else if (Series is PieSeries3D) { var hostSeries = Series as PieSeries3D; Point center = hostSeries.Center; double pieSeriesCount = hostSeries.GetCircularSeriesCount(); double equalParts = actualRadius / pieSeriesCount; double innerRadius = equalParts * pieIndex; if (hostSeries.ExplodeIndex == hostSeries.Segments.Count - 1 || hostSeries.ExplodeAll) { var rect = new Rect(0, 0, transformer.Viewport.Width, transformer.Viewport.Height); center = hostSeries.GetActualCenter(new Point(rect.X + rect.Width / 2, rect.Y + rect.Height / 2), Radius); } if (hostSeries != null && hostSeries.LabelPosition == CircularSeriesLabelPosition.Inside) { if (pieIndex == 0) { radius = radius / 2; } else { double difference = (radius - innerRadius) / 2; radius -= difference; } } this.X = center.X + radius * Math.Cos(Angle); this.Y = center.Y + radius * Math.Sin(Angle); } this.ActualStartDepth = this.StartDepth; }