Animations API
In SciChart you can use Animations API to animate RenderableSeries. The Animations API is based on our Transformation API, which allows to define different IRenderPassDataTransformation to your ISeriesRenderPassData during the render pass.
We provide helper AnimationsHelper class, which provides set of methods to create animations for IRenderableSeries.
Let's see a simple example of using sweep
animation on our Line Series:
// declare FastLineRenderableSeries to animate
final FastLineRenderableSeries rSeries = new FastLineRenderableSeries();
// Animate Line Series with Sweep Transformation
AnimationsHelper.createAnimator(
rSeries,
new SweepXyTransformation<>(XyRenderPassData.class),
3000,
350,
new DecelerateInterpolator(),
new FloatEvaluator(),
0f, 1f
).start();
Under the hood AnimationsHelper methods creates Android Animator to animate specified series. After creation of animator you can combine them using AnimatorSet to animate several series at the same time or to create more complex animations.
There are several default implementations of Tranformation API which allow to animate different series:
Animation Types
There are several animation types provided out of the box in SciChart:
// declare FastLineRenderableSeries to animate
final FastLineRenderableSeries rSeries = new FastLineRenderableSeries();
// Animate Line Series with Sweep Transformation
AnimationsHelper.createAnimator(
rSeries,
new SweepXyTransformation<>(XyRenderPassData.class),
3000,
350,
new DecelerateInterpolator(),
new FloatEvaluator(),
0f, 1f
).start();
Fade-In Animation
AnimationsHelper.createOpacityAnimator(
rSeries,
2000,
350,
new DecelerateInterpolator(),
new FloatEvaluator(),
0f, 1f
).start();
Note
The Fade-In animation is implemented utilizing the opacity property under the hood.
Note
Examples which uses Fade-In animation can be found in the SciChart Android Examples Suite as well as on GitHub:
Scale Animation
AnimationsHelper.createAnimator(
rSeries,
new ScaleXyTransformation<>(XyRenderPassData.class, 0),
3000,
350,
new ElasticOutInterpolator(),
new FloatEvaluator(),
0f, 1f
).start();
Note
The Scale animation is implemented utilizing the Scale Transformation under the hood.
Note
Examples which uses Scale animation can be found in the SciChart Android Examples Suite as well as on GitHub:
Sweep Animation
AnimationsHelper.createAnimator(
rSeries,
new SweepXyTransformation(XyRenderPassData.class),
3000,
350,
new DecelerateInterpolator(),
new FloatEvaluator(),
0f, 1f
).start();
Note
The Sweep animation is implemented utilizing the Sweep Transformation under the hood and available only for continuous series (e.g. Line, Mountain, Band etc...), where it's possible to interpolate points to have smooth animation.
Note
Examples which uses Sweep animation can be found in the SciChart Android Examples Suite as well as on GitHub:
Wave Animation
AnimationsHelper.createAnimator(
rSeries,
new WaveXyTransformation(XyRenderPassData.class, 0, 0.5f),
3000,
350,
new DecelerateInterpolator(),
new FloatEvaluator(),
0f,
1f
).start();
Note
The Wave animation is implemented utilizing the Wave Transformation under the hood.
Note
Examples which uses Wave animation can be found in the SciChart Android Examples Suite as well as on GitHub:
Translate-X Animation
AnimationsHelper.createAnimator(
rSeries,
new TranslateXTransformation(XyRenderPassData.class, -500),
3000,
350,
new DecelerateInterpolator(),
new FloatEvaluator(),
0f,
1f
).start();
Note
The Translate-X animation is implemented utilizing the Translate Transformation under the hood.
Translate-Y Animation
AnimationsHelper.createAnimator(
rSeries,
new TranslateXyTransformation<>(XyRenderPassData.class, -500),
3000,
350,
new DecelerateInterpolator(),
new FloatEvaluator(),
0f,
1f
).start();
Note
The Translate-Y animation is implemented utilizing the Translate Transformation under the hood.
Transformation API
The Animations API is based on Tranformation API which allows to define different tranformations for IRenderableSeries which we apply during animation. When we start Animator created by Builders API or using AnimationsHelper directly it animates Progress of tranformation from 0 ( begining of animation ) to 1 ( end of animation ).
There are several transformations provided out of the box which allow to animate different types of series:
Scale Transformation
Scale transformation is represented by the ScaleTransformationBase<T> and its implementors:
Transformation Type | Applicable to: |
---|---|
ScaleXyTransformation<T> | XyRenderPassData and inheritors. |
ScaleXyyTransformation<T> | XyyRenderPassData and inheritors. |
ScaleXyzTransformation<T> | XyzRenderPassData and inheritors. |
ScaleHlTransformation<T> | HlRenderPassData and inheritors. |
ScaleOhlcTransformation<T> | OhlcRenderPassData and inheritors. |
ScaleStackedXyTransformation<T> | StackedSeriesRenderPassData and inheritors. |
Note
The Scale Animation is implemented based on this transformation.
Sweep Transformation
Sweep transformation is represented by the SweepXyTransformation<T> and SweepXyyTransformation<T> which allows to transform XyRenderPassData and XyyRenderPassData respectively.
Note
The Sweep Animation is implemented base on this transformation.
Wave Transformation
Wave transformation is represented by the WaveTransformationBase<T> and its implementors:
Transformation Type | Applicable to: |
---|---|
WaveXyTransformation<T> | XyRenderPassData and inheritors. |
WaveXyyTransformation<T> | XyyRenderPassData and inheritors. |
WaveHlTransformation<T> | HlRenderPassData and inheritors. |
WaveOhlcTransformation<T> | OhlcRenderPassData and inheritors. |
WaveStackedXyTransformation<T> | StackedSeriesRenderPassData and inheritors. |
Note
The Wave Animation is implemented based on this transformation.
Translate Transformation
Wave transformation is represented by the TranslateXTransformation<T> as well as TranslateXyTransformationBase<T> and its implementors:
Transformation Type | Applicable to: |
---|---|
TranslateXTransformation<T> | XSeriesRenderPassData and inheritors. |
TranslateXyTransformation<T> | XyRenderPassData and inheritors. |
TranslateXyyTransformation<T> | XyyRenderPassData and inheritors. |
TranslateHlTransformation<T> | HlRenderPassData and inheritors. |
TranslateOhlcTransformation<T> | OhlcRenderPassData and inheritors. |
TranslateStackedXyTransformation<T> | StackedSeriesRenderPassData and inheritors. |
Note
Translate-X and Translate-Y animations are implemented based on this transformation.
Composite Transformation
You might want to combine effects of several transformations at the same time without rewriting those into complex transformation. The CompositeTransformation is in SciChart to do just that. It allows to aggregate effects into one transformation (e.g. wave and translate-x)
Let's try to use Wave and Translate-X at the same time, to animate Candlestick Series based on the Candlestick Chart example which can be found in the SciChart Android Examples Suite as well as on GitHub:
// declare Candlestick Series to animate
final FastCandlestickRenderableSeries rSeries = new FastCandlestickRenderableSeries();
// Create transformations and make a Composite one out of them
final WaveOhlcTransformation wave = new WaveOhlcTransformation(OhlcRenderPassData.class, 0, 0.5f);
final TranslateXTransformation translateX = new TranslateXTransformation(OhlcRenderPassData.class, -300);
final CompositeTransformation composite = new CompositeTransformation(wave, translateX);
// Animate Candlestick Series with Composite Transformation
AnimationsHelper.createAnimator(
rSeries,
composite,
3000,
350,
new DecelerateInterpolator(),
new FloatEvaluator(),
0f,
1f
).start();
which results in the following:
Custom Animation
To create custom animation we need to create a class which implements IRenderPassDataTransformation protocol. Inside we need to add code which modifies the render pass data of the RenderableSeries which we need to animate. For example, we'll try to animate line series and create expand effect which moves points from some predefined origin point.
First we need to create a transformation for our XyRenderPassData:
class CustomXyTransformation extends BaseRenderPassDataTransformation<XyRenderPassData> {
private final FloatValues originalXCoordinates = new FloatValues();
private final FloatValues originalYCoordinates = new FloatValues();
private final double centerX;
private final double centerY;
private float zeroXCoord, zeroYCoord;
public CustomXyTransformation(double centerX, double centerY) {
super(XyRenderPassData.class);
this.centerX = centerX;
this.centerY = centerY;
}
@Override
protected void saveOriginalData() {
final int count = renderPassData.pointsCount();
// clear buffers
originalXCoordinates.clear();
originalYCoordinates.clear();
// save initial xCoords and yCoords
originalXCoordinates.add(renderPassData.xCoords.getItemsArray(), 0, count);
originalYCoordinates.add(renderPassData.yCoords.getItemsArray(), 0, count);
zeroXCoord = renderPassData.getXCoordinateCalculator().getCoordinate(centerX);
zeroYCoord = renderPassData.getYCoordinateCalculator().getCoordinate(centerY);
}
@Override
protected void applyTransformation() {
// transform current render pass data
transformValues(renderPassData.xCoords, originalXCoordinates, zeroXCoord);
transformValues(renderPassData.yCoords, originalYCoordinates, zeroYCoord);
}
private void transformValues(FloatValues valuesToTransform, FloatValues originalCoordinates, float zeroCoord) {
final float transformationValue = 1 - getCurrentTransformationValue();
// calculate new values to display based on original value
final float[] itemsArray = valuesToTransform.getItemsArray();
final float[] originalValues = originalCoordinates.getItemsArray();
for (int i = 0, size = renderPassData.pointsCount(); i < size; i++) {
final float originalValue = originalValues[i];
itemsArray[i] = originalValue - (originalValue - zeroCoord) * transformationValue;
}
}
@Override
protected void discardTransformation() {
// clear coordinate buffers
renderPassData.xCoords.clear();
renderPassData.yCoords.clear();
// save initial xCoords and yCoords
renderPassData.xCoords.add(originalXCoordinates.getItemsArray(), 0, originalXCoordinates.size());
renderPassData.yCoords.add(originalYCoordinates.getItemsArray(), 0, originalYCoordinates.size());
}
@Override
protected void onInternalRenderPassDataChanged() { }
}
Then we use this custom transformation to animate series using AnimationsHelper APIs:
AnimationsHelper.createAnimator(
rSeries,
new CustomXyTransformation(150, 300),
3000,
350,
new DecelerateInterpolator(),
new FloatEvaluator(),
0f,
1f
).start();
The result is the following: