SciChart Android 2D Charts API > 2D Chart Types > Renderable Series APIs > PaletteProvider API
PaletteProvider API

What is a PaletteProvider?

PaletteProvider is an API that allows to change series color on a point-to-point basis:

 

Using PaletteProviders

To enable series coloring with PaletteProvider, you need to create a class which implements either IStrokePaletteProvider, or IFillPaletteProvider, or IPointMarkerPaletteProvider, or all of them. A choice depends on a RenderableSeries type which PaletteProvider is planned for. If it has to paint some area in a color that differs from that of rest of a series, implement IFillPaletteProvider. For painting parts of the series' outline, choose IStrokePaletteProvider. To change the fill of some PointMarkers, use IPointMarkerPaletteProvider.

Every PaletteProvider interface declares the only method which returns an array with colors for every data points. For the convenience, there is also the PaletteProviderBase class, which provides some basic implementation. The update() method is called every time a RenderableSeries requires a redraw, so it is supposed that the colors array should be updated there correspondingly.

The following code snippet demonstrates how to create a custom PaletteProvider for a Scatter Series:

private static final class HorizontalThresholdPaletteProvider extends PaletteProviderBase<XyScatterRenderableSeries> implements IPointMarkerPaletteProvider{
    IAnnotation upperLimit, lowerLimit;
    int upperColor = ColorUtil.Red, mediumColor = ColorUtil.Purple, lowerColor = ColorUtil.Green;
    IntegerValues colors = new IntegerValues();
    protected HorizontalThresholdPaletteProvider(IAnnotation upperLimit, IAnnotation lowerLimit) {
        super(XyScatterRenderableSeries.class);
        this.upperLimit = upperLimit;
        this.lowerLimit = lowerLimit;
    }
    @Override
    public void update() {
        final XyScatterRenderableSeries scaterSeries = this.renderableSeries;
        final XyRenderPassData currentRenderPassData = (XyRenderPassData) scaterSeries.getCurrentRenderPassData();
        final DoubleValues yValues = currentRenderPassData.yValues;
        final int size = currentRenderPassData.pointsCount();
        colors.setSize(size);
        final double y1 = (Double)upperLimit.getY1();
        final double y2 = (Double)lowerLimit.getY1();
        final double min = Math.min(y1, y2);
        final double max = Math.max(y1, y2);
        final int[] colorsArray = colors.getItemsArray();
        final double[] valuesArray = yValues.getItemsArray();
        for (int i = 0; i < size; i++) {
            final double value = valuesArray[i];
            if (value >= max)
                colorsArray[i] = upperColor;
            else if(value > min && value < max)
                colorsArray[i] = mediumColor;
            else
                colorsArray[i] = lowerColor;
        }
    }
    @Override
    public IntegerValues getPointMarkerColors() {
        return colors;
    }
}

Once a PaletteProvider class is ready, its instances can be used to set up the PaletteProvider for a RenderableSeries via the setPaletteProvider() method:

final EllipsePointMarker pointMarker = sciChartBuilder.newPointMarker(new EllipsePointMarker())
        .withSize(15, 15)
        .build();
HorizontalLineAnnotation upperLimit = sciChartBuilder.newHorizontalLineAnnotation().withIsEditable(true).withStroke(2, ColorUtil.Red).withY1(0.7d).build();
HorizontalLineAnnotation lowerLimit = sciChartBuilder.newHorizontalLineAnnotation().withIsEditable(true).withStroke(2, ColorUtil.Purple).withY1(0.2d).build();
final IRenderableSeries scatters = sciChartBuilder.newScatterSeries()
        .withDataSeries(dataSeries)
        .withPointMarker(pointMarker)
        .withPaletteProvider(new HorizontalThresholdPaletteProvider(upperLimit, lowerLimit))
        .build();
Collections.addAll(surface.getAnnotations(), upperLimit, lowerLimit);
Collections.addAll(surface.getRenderableSeries(), scatters);

The code above results in a chart with a Scatter Series which change colors of its PointMarkers depending on the threshold levels provided by two HorizontalLineAnnotations:

More examples of PaletteProvider usage can be found in the SciChart Android Examples Suite.

Using PaletteProviders with Heatmaps

There is a special PaletteProvider interface called IUniformHeatmapPaletteProvider designed for usage with Heatmaps. The only distinction from the other interfaces is the shouldSetColors() method, which determines whether an IUniformHeatmapPaletteProvider implementation provides colors for every data point or it just updates colors passed in by a FastUniformHeatmapRenderableSeries object.

The following code snippet demonstrates how to create a custom IUniformHeatmapPaletteProvider:

public class CustomUniformHeatMapProvider extends PaletteProviderBase<FastUniformHeatmapRenderableSeries> implements IUniformHeatmapPaletteProvider {
    private double thresholdValue;
    public CustomUniformHeatMapProvider() {
        super(FastUniformHeatmapRenderableSeries.class);
    }
    public void setThresholdValue(double thresholdValue) {
        this.thresholdValue = thresholdValue;
        if(renderableSeries != null)
            renderableSeries.invalidateElement();
    }
    @Override
    public boolean shouldSetColors() {
        return false;
    }
    @Override
    public void update() {
        final FastUniformHeatmapRenderableSeries renderableSeries = this.renderableSeries;
        final UniformHeatmapRenderPassData currentRenderPassData = (UniformHeatmapRenderPassData) renderableSeries.getCurrentRenderPassData();
        final DoubleValues zValues = currentRenderPassData.zValues;
        final IntegerValues zColors = currentRenderPassData.zColors;
        final int size = zValues.size();
        zColors.setSize(size);
        // working with array is much faster than calling set() many times
        final double[] zValuesArray = zValues.getItemsArray();
        final int[] zColorsArray = zColors.getItemsArray();
        for (int zIndex = 0; zIndex < size; zIndex++) {
            final double value = zValuesArray[zIndex];
            zColorsArray[zIndex] = value < thresholdValue ? Color.BLACK : Color.WHITE;
        }
    }
}

The code above defines the IUniformHeatmapPaletteProvider called CustomUniformHeatMapProvider. Since its shouldSetColors() method returns False, CustomUniformHeatMapProvider has to provide a color for every data point. In this sample the color is picked based on the threshold value. The array with colors is created in the update() method and the current RenderPassData instance is updated to pass it to a FastUniformHeatmapRenderableSeries object for rendering:

The complete code sample can be found in the SciChart Android Example Suite.

See Also