SciChart Android 2D Charts API > 2D Chart Types > The Custom RenderableSeries API
The Custom RenderableSeries API

Creating your Own Series

If the built-in chart types in SciChart are not enough, you can create your own RenderableSeries! CustomRenderableSeries should extend BaseRenderableSeries if you want to provide some custom data or one of predefined base classes if you want to display data from one of default DataSeries implementations.

Base class for CustomRenderableSeries When to use
XyRenderableSeriesBase If you want to use XyDataSeries as data source for custom RenderableSeries
XyyRenderableSeriesBase If you want to use XyyDataSeries as data source for custom RenderableSeries
HlRenderableSeriesBase If you want to use HlDataSeries as data source for custom RenderableSeries
OhlcRenderableSeriesBase If you want to use OhlcDataSeries as data source for custom RenderableSeries
XyzRenderableSeriesBase If you want to use XyzDataSeries as data source for custom RenderableSeries
BaseRenderableSeries If default DataSeries implementations aren't suitable for data which should be dispayed and you want to create custom DataSeries type

For example let's try to create a series which draws PointMarker at specified (x, y) coordinates:

class CustomRenderableSeries extends XyRenderableSeriesBase {
    /**
     * Creates a new instance of {@link XyRenderableSeriesBase} class
     */
    public CustomRenderableSeries() {
        // In default constructor we use:
        // - XyRenderPassData which will store points to draw ( If you need to store some additional data for drawing you can extend it and add additional fields )
        // - PointMarkerHitProvider which performs hit checks on points rendered by series. In our case we just check if point marker is hit
        // - NearestXyPointProvider allows to locate nearest (x, y) point to specified point on screen
        this(new XyRenderPassData(), new PointMarkerHitProvider(), new NearestXyPointProvider());
    }
    /**
     * Creates a new instance of {@link XyRenderableSeriesBase} class
     *
     * @param currentRenderPassData The render pass data instance
     * @param hitProvider           The hit provider instance
     * @param nearestPointProvider  The nearest point provider instance
     */
    protected CustomRenderableSeries(XyRenderPassData currentRenderPassData, IHitProvider hitProvider, INearestPointProvider nearestPointProvider) {
        super(currentRenderPassData, hitProvider, nearestPointProvider);
    }
    /**
     * Draws the series using the {@link IRenderContext2D}, the {@link IAssetManager2D} and the {@link ISeriesRenderPassData} passed in
     *
     * @param renderContext  The render context. This is a graphics object which has methods to draw lines, quads and polygons to the screen
     * @param assetManager   The asset manager. This is manager for graphic assets which has method for creation pens, brushes and textures
     * @param renderPassData The render pass data which contain a resampled point series, the index range of point on the screen
     *                       and the current coordinate calculator of XAxis and YAxis to convert data-point to screen points
     */
    @Override
    protected void internalDraw(IRenderContext2D renderContext, IAssetManager2D assetManager, ISeriesRenderPassData renderPassData) {
        // here we cast render pass data to type of render pass data which we created in constructor
        final XyRenderPassData renderPassDataToDraw = (XyRenderPassData) renderPassData;

        // here we need to draw something using specified renderContext!
        // use helper method to draw data as point markers
        drawPointMarkers(renderContext, assetManager, renderPassDataToDraw.xCoords, renderPassDataToDraw.yCoords);
    }
}
                
class CustomRenderableSeries : XyRenderableSeriesBase
    {
        public CustomRenderableSeries() : this(new XyRenderPassData(), new PointMarkerHitProvider(), new NearestXyPointProvider())
        {
            // In default constructor we use:
            // - XyRenderPassData which will store points to draw ( If you need to store some additional data for drawing you can extend it and add additional fields )
            // - PointMarkerHitProvider which performs hit checks on points rendered by series. In our case we just check if point marker is hit
            // - NearestXyPointProvider allows to locate nearest (x, y) point to specified point on screen
        }
        protected CustomRenderableSeries(XyRenderPassData currentRenderPassData, IHitProvider hitProvider, INearestPointProvider nearestPointProvider) : base(currentRenderPassData, hitProvider, nearestPointProvider)
        {
        }
        protected override void InternalDraw(IRenderContext2D renderContext, IAssetManager2D assetManager, ISeriesRenderPassData renderPassData)
        {
            // here we cast render pass data to type of render pass data which we created in constructor
            XyRenderPassData renderPassDataToDraw = (XyRenderPassData)renderPassData;
            // here we need to draw something using specified renderContext!
            // use helper method to draw data as point markers
            DrawPointMarkers(renderContext, assetManager, renderPassDataToDraw.XCoords, renderPassDataToDraw.YCoords);
        }
    }

IRenderContext2D and IAssetManager2D – the Immediate Mode Graphics

The IRenderContext2D and IAssetManager2D passed into the internalDraw() method are parts of the graphics context for this render pass. Use this to draw to the screen.

Note: For a full walk-through of the RenderContext API, see the section on Immediate Mode RenderContext API.

ISeriesRenderPassData – the current Data to Draw

The data to draw is contained in the ISeriesRenderPassData passed in to the internalDraw() method. Using the ISeriesRenderPassData you can access the data values and coordinates to draw, the PointRange (the indices of the data to draw, inclusive), the XCoordinateCalculator and YCoordinateCalculator (which transforms data to pixel coordinates).

Depending on DataSeries type you can have a different ISeriesRenderPassData type and different ways to access the data to draw.

SeriesRenderPassData type DataSeries type
XyRenderPassData If you want to use XyDataSeries as data source for custom RenderableSeries
XyyRenderPassData If you want to use XyyDataSeries as data source for custom RenderableSeries
XyzRenderPassData If you want to use XyzDataSeries as data source for custom RenderableSeries
OhlcRenderPassData If you want to use OhlcDataSeries as data source for custom RenderableSeries

HlRenderPassData

If you want to use HlDataSeries as data source for custom RenderableSeries
UniformHeatmapRenderPassData If you want to use UniformHeatmapDataSeries as data source for custom RenderableSeries

The types above could be extended to add some additional information which is required for rendering ( e.g. ColumnRenderPassData extends XyRenderPassData and adds fields for caching of column width in pixels and coordinate of zero line ).

Example: SplineRoundedColumnRenderableSeries

We have a full worked example, which shows how to create a rounded column series with this powerful API.