windowsforms-117078-controls-and-libraries-chart-control-examples-end-user-interaction-how-to-implement-a-custom-funnel-animation.md
To implement a custom bar animation, design a class inheriting the FunnelAnimationBase class and override the FunnelAnimationBase.ApplyState method which determines the transformations applied to an individual funnel point.
using DevExpress.XtraCharts;
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
namespace AnimationExample {
class FanFunnelAnimation : FunnelAnimationBase {
const float AnimationStartAngle = 270;
const float MaxSweepAngle = 180;
const float HalfMaxSweepAngle = 90;
public override void ApplyState(
SceneModifier modifier,
RectangleF diagramBounds,
FunnelSeriesPointLayoutParameters funnelParameters,
float progress
) {
RectangleF funnelBounds = funnelParameters.Bounds;
float fanCenterX = funnelBounds.Left + funnelBounds.Width / 2;
float fanCenterY = funnelBounds.Bottom;
float fanRadius = (float)Math.Sqrt(
(funnelBounds.Left - fanCenterX) * (funnelBounds.Left - fanCenterX)
+ (funnelBounds.Height) * (funnelBounds.Height)
);
float startAngle = AnimationStartAngle - HalfMaxSweepAngle * progress;
float sweepAngle = MaxSweepAngle * progress;
float endAngle = startAngle + sweepAngle;
float fanLeftBoundEndX =
fanCenterX + (float)Math.Cos(startAngle / 180 * Math.PI) * fanRadius;
float fanLeftBoundEndY =
fanCenterY + (float)Math.Sin(startAngle / 180 * Math.PI) * fanRadius;
float fanRightBoundEndX =
fanCenterX + (float)Math.Cos(endAngle / 180 * Math.PI) * fanRadius;
float fanRightBoundEndY =
fanCenterY + (float)Math.Sin(endAngle / 180 * Math.PI) * fanRadius;
RectangleF fanBounds = new RectangleF(
fanCenterX - fanRadius,
fanCenterY - fanRadius,
2 * fanRadius,
2 * fanRadius
);
GraphicsPath path = new GraphicsPath();
path.AddLine(fanCenterX, fanCenterY, fanLeftBoundEndX, fanLeftBoundEndY);
path.AddArc(fanBounds, startAngle, sweepAngle);
path.AddLine(fanRightBoundEndX, fanRightBoundEndY, fanCenterX, fanCenterY);
modifier.Clip(path);
}
protected override ChartElement CreateObjectForClone() {
return new FanFunnelAnimation();
}
}
}
protected override void OnLoad(EventArgs e) {
base.OnLoad(e);
view.Animation = new FanFunnelAnimation {
BeginTime = new TimeSpan(0, 0, 0),
Duration = new TimeSpan(0, 0, 0, 1, 500),
PointDelay = new TimeSpan(0, 0, 0, 0, 500),
PointOrder = PointAnimationOrder.Straight,
EasingFunction = new LinearEasingFunction {
EasingMode = EasingMode.Out
}
};
chartControl.AnimationStartMode = ChartAnimationMode.OnLoad;
}
private void OnAnimateClick(object sender, EventArgs e) {
chartControl.Animate();
}
Imports DevExpress.XtraCharts
Imports System
Imports System.Drawing
Imports System.Drawing.Drawing2D
Namespace AnimationExample
Friend Class FanFunnelAnimation
Inherits FunnelAnimationBase
Private Const AnimationStartAngle As Single = 270
Private Const MaxSweepAngle As Single = 180
Private Const HalfMaxSweepAngle As Single = 90
Public Overrides Sub ApplyState(ByVal modifier As SceneModifier, ByVal diagramBounds As RectangleF, ByVal funnelParameters As FunnelSeriesPointLayoutParameters, ByVal progress As Single)
Dim funnelBounds As RectangleF = funnelParameters.Bounds
Dim fanCenterX As Single = funnelBounds.Left + funnelBounds.Width / 2
Dim fanCenterY As Single = funnelBounds.Bottom
Dim fanRadius As Single = CSng(Math.Sqrt((funnelBounds.Left - fanCenterX) * (funnelBounds.Left - fanCenterX) + (funnelBounds.Height) * (funnelBounds.Height)))
Dim startAngle As Single = AnimationStartAngle - HalfMaxSweepAngle * progress
Dim sweepAngle As Single = MaxSweepAngle * progress
Dim endAngle As Single = startAngle + sweepAngle
Dim fanLeftBoundEndX As Single = fanCenterX + CSng(Math.Cos(startAngle / 180 * Math.PI)) * fanRadius
Dim fanLeftBoundEndY As Single = fanCenterY + CSng(Math.Sin(startAngle / 180 * Math.PI)) * fanRadius
Dim fanRightBoundEndX As Single = fanCenterX + CSng(Math.Cos(endAngle / 180 * Math.PI)) * fanRadius
Dim fanRightBoundEndY As Single = fanCenterY + CSng(Math.Sin(endAngle / 180 * Math.PI)) * fanRadius
Dim fanBounds As New RectangleF(fanCenterX - fanRadius, fanCenterY - fanRadius, 2 * fanRadius, 2 * fanRadius)
Dim path As New GraphicsPath()
path.AddLine(fanCenterX, fanCenterY, fanLeftBoundEndX, fanLeftBoundEndY)
path.AddArc(fanBounds, startAngle, sweepAngle)
path.AddLine(fanRightBoundEndX, fanRightBoundEndY, fanCenterX, fanCenterY)
modifier.Clip(path)
End Sub
Protected Overrides Function CreateObjectForClone() As ChartElement
Return New FanFunnelAnimation()
End Function
End Class
End Namespace
Protected Overrides Sub OnLoad(ByVal e As EventArgs)
MyBase.OnLoad(e)
view.Animation = New FanFunnelAnimation With { _
.BeginTime = New TimeSpan(0, 0, 0), .Duration = New TimeSpan(0, 0, 0, 1, 500), .PointDelay = New TimeSpan(0, 0, 0, 0, 500), .PointOrder = PointAnimationOrder.Straight, .EasingFunction = New LinearEasingFunction With {.EasingMode = EasingMode.Out} _
}
chartControl.AnimationStartMode = ChartAnimationMode.OnLoad
End Sub
Private Sub OnAnimateClick(ByVal sender As Object, ByVal e As EventArgs) Handles btnAnumate.Click
chartControl.Animate()
End Sub