Android & Xamarin.Android Charting Documentation - SciChart Android Charts SDK v2.x
PointMarker API

This article detail how to configure a RenderableSeries to render markers for every data point.

What is a PointMarker?

The PointMarkers feature allows to annotate the data points of a certain series with markers, e.g. Ellipse, Square, Triangle or a custom shape marker. Some series types, such as XyScatterRenderableSeries or FastImpulseRenderableSeries, require a PointMarker assigned to them lest they will not render at all.

PointMarker Types

The list of the PointMarker types available out of the box can be found below:

The following screenshot demonstrates how all these appear on a chart with multiple Line Series:

It is possible to change how point markers appears by extending any of the above classes. The SpritePointMarker allows to render Drawables as point markers. For more details, refer to the Custom PointMarkers section down the page.

PointMarker Styling

All the PointMarker types implement the IPointMarker interface. It provides the following styling options:

setSize()getWidth()getHeight()

Allows to specify the size of a PointMarker. PointMarkers will not appear if this value isn't set. The units are DIP (Device Independent Pixels).

setFillStyle()getFillStyle()

Specifies a fill brush of the BrushStyle type. It contains information about the fill Color and the desired type of visual output. Please see the PenStyle, BrushStyle and FontStyle article to find out more.

setStrokeStyle()getStrokeStyle()

Specifies a stroke pen of the PenStyle type. It contains information about the Color, Stroke Thickness, etc. Please see the PenStyle, BrushStyle and FontStyle article to find out more.

Using PointMarkers

Code for creation and assigning a PointMarker to a RenderableSeries is essentially the same regardless of a PointMarker type. After an instance of it has been created, it can be configured and then applied to the RenderableSeries via the setPointMarker() method:

Copy Code
// Create a Triangle PointMarker instance
IPointMarker pointMarker = new TrianglePointMarker();
pointMarker.setSize(40,40);
// Create a PenStyle for Stroke
PenStyle strokeStyle = new SolidPenStyle(ColorUtil.Green, true, 2, null);
pointMarker.setStrokeStyle(strokeStyle);
// Create a BrushStyle for Fill
BrushStyle fillStyle = new SolidBrushStyle(ColorUtil.Red);
pointMarker.setFillStyle(fillStyle);
// Apply the PointMarker to a LineSeries
IRenderableSeries lineSeries = new FastLineRenderableSeries();
lineSeries.setPointMarker(pointMarker);
// Set Stroke Thickness and Color to the LineSeries
lineSeries.setStrokeStyle(new SolidPenStyle(ColorUtil.Blue, true, 4f, null));

The code will produce the following chart (assuming that the data has been added to the LineSeries):

 

 Custom PointMarkers

There are two ways of creating custom PointMarkers in SciChart. The first one involves using our RenderContext2D API for drawing, and the second allows to use Android drawing capabilities.

Extend DrawablePointMarkers

This technique requires extending the DrawablePointMarker class and overridding the internalDraw() method. It is called for every data point in a series. In the implementation, a PointMarker can be drawn calling methods from IRenderContext2D. The code below demonstrates how custom EllipsePointMarker can be created using this approach:

Copy Code
private final class EllipsePointMarker extends DrawablePointMarker {
    @Override
    protected void internalDraw(IRenderContext2D renderContext, float x, float y, IPen2D strokePen, IBrush2D fillBrush) {
        renderContext.drawEllipse(x, y, getWidth(), getHeight(), strokePen, fillBrush);
    }
}

However, the RenderContext2D API has its own limitations. It isn't suitable for drawing complex custom shapes. Besides, calling drawing methods for every data point is redundant and actually overkill. So the second technique, described in the following paragraph,  is better suited for most cases.

Implement ISpritePointMarkerDrawer

This approach is rather different. It allows to draw a shape on Android Canvas with Android Paint objects. Then, a sprite is created out of the Canvas, which is rendered for every data point in a series. This requires implementing the onDraw() method of the ISpritePointMarkerDrawer interface and passing in an instance of it to the SpritePointMarker's constructor, as follows:

Copy Code
// Implement the ISpritePointMarkerDrawer interface
private class CustomPointMarkerDrawer implements SpritePointMarker.ISpritePointMarkerDrawer {
    private final Drawable drawable;
    private CustomPointMarkerDrawer(Context context, @DrawableRes int drawableId) {
        this.drawable = context.getResources().getDrawable(drawableId);
    }
    @Override
    public void onDraw(Canvas canvas, Paint stroke, Paint fill) {
        drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
        // Render the drawable on a Canvas
        drawable.draw(canvas);
    }
}

Then a new instance of CustomPointMarkerDrawer is created and passed in the SpritePointMarker's constructor:

Copy Code
// Create a SpritePointMarker out of a CustomPointMarkerDrawer
IPointMarker spritePointMarker = new SpritePointMarker(new CustomPointMarkerDrawer(getActivity(), R.drawable.my_point_marker_image));

// Apply the PointMarker to a LineSeries
 IRenderableSeries lineSeries = new FastLineRenderableSeries();
 lineSeries.setPointMarker(pointMarker);
// Set Stroke Thickness and Color to the LineSeries
 lineSeries.setStrokeStyle(new SolidPenStyle(ColorUtil.Blue, true, 4f, null));

In the code above, an Android Drawable object is passed in to be used as the PointMarker for a series:

 

The complete code sample can be found in the Use Point Markers example from the SciChart Android Examples Suite.

PointMarkerBuilder Helper

To simplify PointMarker creation, SciChart provides a bunch of helper Builder Classes. Their usage can be benefitial in many ways. For instance, there is no need to create PenStyle and BrushStyle instances explicitly for PointMarker styling:

Copy Code
// Create an Ellipse PointMarker, with given Fill and Stroke colors
final EllipsePointMarker pointMarker = sciChartBuilder.newPointMarker(new EllipsePointMarker())
        .withSize(15, 15)
        .withStroke(ColorUtil.argb(255, 176, 196, 222), 2)
        .withFill(ColorUtil.argb(255, 70, 130, 180))
        .build();
// Create a Scatter RenderableSeries and apply the PointMarker
final IRenderableSeries rs1 = sciChartBuilder.newScatterSeries()
        .withPointMarker(pointMarker)
        .build();

 

See Also

2D Chart Types

Styling and Theming