SciChart.js JavaScript 2D Charts API > PaletteProvider API > Per-point Colouring of Mountain Segments
Per-point Colouring of Mountain Segments

Colouring Mountain Series Segments with PaletteProvider

If you wanted to colour segments of a mountain (area) chart differently based on a rule, use the PaletteProvider API in SciChart.js.

First, declare a custom PaletteProvider:

In order to override stroke and fill for Y-value bigger than 0.5, we will create a PaletteProvider.

import {
    DefaultPaletteProvider,
    EFillPaletteMode,
    EStrokePaletteMode
} from 'scichart/Charting/Model/IPaletteProvider';
import { parseColorToUIntArgb } from 'scichart/utils/parseColor';
import { uintArgbColorMultiplyOpacity } from 'scichart/utils/colorUtil';

export class MountainPaletteProvider extends DefaultPaletteProvider {
    constructor() {
        super();
        this.fillPaletteMode = EFillPaletteMode.SOLID;
        this.strokePaletteMode = EStrokePaletteMode.SOLID;
        this.limeStroke = parseColorToUIntArgb('lime');
        this.yellowFill = parseColorToUIntArgb('yellow');
    }
    overrideFillArgb(xValue, yValue, index, opacity, metadata) {
        if (yValue >= 0.5) {
            return opacity !== undefined ? uintArgbColorMultiplyOpacity(this.yellowFill, opacity) : this.yellowFill;
        }
        return undefined;
    }
    overrideStrokeArgb(xValue, yValue, index, opacity, metadata) {
        if (yValue >= 0.5) {
            return opacity !== undefined ? uintArgbColorMultiplyOpacity(this.limeStroke, opacity) : this.limeStroke;
        }
    return undefined;
    }
}               
import {
    EFillPaletteMode,
    EStrokePaletteMode,
    IFillPaletteProvider,
    IPointMarkerPaletteProvider,
    IStrokePaletteProvider,
    TPointMarkerArgb
} from 'scichart/Charting/Model/IPaletteProvider';
import { parseColorToUIntArgb } from 'scichart/utils/parseColor';
import { IRenderableSeries } from 'scichart/Charting/Visuals/RenderableSeries/IRenderableSeries';
import { IPointMetadata } from 'scichart/Charting/Model/IPointMetadata';
import { uintArgbColorMultiplyOpacity } from 'scichart/utils/colorUtil';

export class MountainPaletteProvider implements IStrokePaletteProvider, IFillPaletteProvider {
    public readonly fillPaletteMode = EFillPaletteMode.SOLID;
    public readonly strokePaletteMode = EStrokePaletteMode.SOLID;
    private readonly limeStroke = parseColorToUIntArgb('lime');
    private readonly yellowFill = parseColorToUIntArgb('yellow');
    public onAttached(parentSeries: IRenderableSeries): void {}
    public onDetached(): void {}
    public overrideFillArgb(
        xValue: number,
        yValue: number,
        index: number,
        opacity?: number,
        metadata?: IPointMetadata
    ): number {
        if (yValue >= 0.5) {
            return opacity !== undefined ? uintArgbColorMultiplyOpacity(this.yellowFill, opacity) : this.yellowFill;
        }
        return undefined;
    }
    public overrideStrokeArgb(
        xValue: number,
        yValue: number,
        index: number,
        opacity?: number,
        metadata?: IPointMetadata
    ): number {
        if (yValue >= 0.5) {
            return opacity !== undefined ? uintArgbColorMultiplyOpacity(this.limeStroke, opacity) : this.limeStroke;
        }
        return undefined;
    }
}               

Next, apply it to a Mountain series:

// Usage
const mountainSeries = new FastMountainRenderableSeries(wasmContext, {
        dataSeries,
        stroke: '#4682b4',
        strokeThickness: 10,
        zeroLineY: 0.0,
        fill: 'rgba(176, 196, 222, 1)',
        opacity: 1,
        paletteProvider: new MountainPaletteProvider()
    });

 

The result is as follows. Y values greater than 0.5 have a different fill and stroke.

Note: SciChart won't bisect the line at a threshold value but only changes colour between line segments in the data you already have. If you want to have a perfect transistion from one colour to another at a specific Y-value, you will need to include data-points

Colouring Mountain Series Point-Markers with PaletteProvider

It is also possible to override colors for mountain series point markers by implementing IPointMarkerPaletteProvider. If we add a point marker and use this palette provider it will produce the chart with overridden point markers for Y-values bigger than 0.5.

class MountainPointMarkerPaletteProvider extends DefaultPaletteProvider {
    constructor() {
        super();
        this.fillPaletteMode = EFillPaletteMode.SOLID;
        this.strokePaletteMode = EStrokePaletteMode.SOLID;
        this.redStroke = parseColorToUIntArgb('red');
        this.blueFill = parseColorToUIntArgb('blue');
    }
    overridePointMarkerArgb(xValue, yValue, index, opacity, metadata) {
        if (yValue >= 0.5) {
            // The opacity is already applied in the texture
            // And this opacity is the renderable series opacity, therefore we do not use it here
            const stroke = this.redStroke;
            const fill = this.blueFill;
            return { stroke, fill };
        }
        return undefined;
    }
}

// Usage
const mountainSeries = new FastMountainRenderableSeries(wasmContext, {
        dataSeries,
        stroke: '#4682b4',
        strokeThickness: 10,
        zeroLineY: 0.0,
        fill: 'rgba(176, 196, 222, 1)',
        pointMarker: new EllipsePointMarker(wasmContext, {
            width: 18,
            height: 18,
            strokeThickness: 5,
            fill: '#ff0000',
            stroke: '#000000',
            opacity: 1
        }),
        opacity: 1,
        paletteProvider: new MountainPointMarkerPaletteProvider()
    });
// PaletteProvider definition
export class MountainPointMarkerPaletteProvider implements IPointMarkerPaletteProvider {
    public readonly fillPaletteMode = EFillPaletteMode.SOLID;
    public readonly strokePaletteMode = EStrokePaletteMode.SOLID;
    private readonly redStroke = parseColorToUIntArgb('red');
    private readonly blueFill = parseColorToUIntArgb('blue');
    public onAttached(parentSeries: IRenderableSeries): void {}
    public onDetached(): void {}
    public overridePointMarkerArgb(
        xValue: number,
        yValue: number,
        index: number,
        opacity?: number,
        metadata?: IPointMetadata
    ): TPointMarkerArgb {
        if (yValue >= 0.5) {
            // The opacity is already applied in the texture
            // And this opacity is the renderable series opacity, therefore we do not use it here
            const stroke = this.redStroke;
            const fill = this.blueFill;
            return { stroke, fill };
        }
        return undefined;
    }
}

// Usage
const mountainSeries = new FastMountainRenderableSeries(wasmContext, {
        dataSeries,
        stroke: '#4682b4',
        strokeThickness: 10,
        zeroLineY: 0.0,
        fill: 'rgba(176, 196, 222, 1)',
        pointMarker: new EllipsePointMarker(wasmContext, {
            width: 18,
            height: 18,
            strokeThickness: 5,
            fill: '#ff0000',
            stroke: '#000000',
            opacity: 1
        }),
        opacity: 1,
        paletteProvider: new MountainPointMarkerPaletteProvider()
    });

This results in the following:

It is also possible to have stroke or fill gradient. To enable this, set fillPaletteMode and strokePaletteMode properties

class MountainPaletteProvider extends DefaultPaletteProvider {
    constructor(stroke, rule) {
        super();
        // Can be set to Solid or Gradient transition
        this.strokePaletteMode = EStrokePaletteMode.GRADIENT;
        this.fillPaletteMode = fillPaletteMode = EFillPaletteMode.GRADIENT;
        // ..
    }
    // ..
}
export class MountainPaletteProvider implements IStrokePaletteProvider, IFillPaletteProvider {
     // Can be set to Solid or Gradient transition
     public readonly fillPaletteMode = EFillPaletteMode.GRADIENT;
     public readonly strokePaletteMode = EStrokePaletteMode.GRADIENT;
 ...
 }
See Also