A choice depends on a RenderableSeries type, which PaletteProvider is designed for.
Every PaletteProvider protocol declares the only property, which returns an array with colors for every data points.
The -[ISCIPaletteProvider update] method is called every time a RenderableSeries requires a redraw, so it expects that the colors array should be updated there correspondingly.
For the convenience, there is also the SCIPaletteProviderBase class, which provides some basic implementation, so it’s recommended to inherit from it while implementing custom PaletteProviders.
Create Custom PaletteProvider
The following code snippet demonstrates how to create a custom PaletteProvider which conforms to all - Fill, Stroke, PointMarker - palette providers and potentially can be shared between multiple series.
import SciChart.Protected.SCIPaletteProviderBase
class SharedPaletteProvider: SCIPaletteProviderBase<SCIXyRenderableSeriesBase>, ISCIStrokePaletteProvider, ISCIFillPaletteProvider, ISCIPointMarkerPaletteProvider {
let strokeColors = SCIUnsignedIntegerValues()
let fillColors = SCIUnsignedIntegerValues()
var pointMarkerColors: SCIUnsignedIntegerValues! { return fillColors }
let lowerLimit: ISCIAnnotation
let upperLimit: ISCIAnnotation
init(lowerLimit: ISCIAnnotation, upperLimit: ISCIAnnotation) {
self.lowerLimit = lowerLimit
self.upperLimit = upperLimit
super.init(renderableSeriesType: SCIXyRenderableSeriesBase.self)
}
override func update() {
let y1: Double = lowerLimit.getY1()
let y2: Double = upperLimit.getY1()
let minimum = min(y1, y2)
let maximum = max(y1, y2)
let renderPassData = renderableSeries.currentRenderPassData as! SCIXyRenderPassData
let count = renderPassData.pointsCount
strokeColors.count = count
fillColors.count = count
let yValues = renderPassData.yValues!
for i in 0 ..< count {
let value = yValues.getValueAt(i)
if (value > maximum) {
strokeColors.set(0xffff0000, at: i)
fillColors.set(0x99ff0000, at: i)
} else if (value < minimum) {
strokeColors.set(0xff00ff00, at: i)
fillColors.set(0x9900ff00, at: i)
} else {
strokeColors.set(0xffffff00, at: i)
fillColors.set(0x99ffff00, at: i)
}
}
}
}
class SharedPaletteProvider : SCIPaletteProviderBase<SCIXyRenderableSeriesBase>, IISCIStrokePaletteProvider, IISCIFillPaletteProvider, IISCIPointMarkerPaletteProvider
{
public SCIUnsignedIntegerValues StrokeColors { get; } = new SCIUnsignedIntegerValues();
public SCIUnsignedIntegerValues FillColors { get; } = new SCIUnsignedIntegerValues();
public SCIUnsignedIntegerValues PointMarkerColors { get { return FillColors; } }
private SCIAnnotationBase lowerLimit;
private SCIAnnotationBase upperLimit;
public SharedPaletteProvider(SCIAnnotationBase lowerLimit, SCIAnnotationBase upperLimit)
{
this.lowerLimit = lowerLimit;
this.upperLimit = upperLimit;
}
public override void Update()
{
var y1 = (double)lowerLimit.Y1Value;
var y2 = (double)upperLimit.Y1Value;
var minimum = Math.Min(y1, y2);
var maximum = Math.Max(y1, y2);
var renderPassData = (SCIXyRenderPassData)RenderableSeries.CurrentRenderPassData;
var count = renderPassData.PointsCount;
StrokeColors.Count = count;
FillColors.Count = count;
var yValues = renderPassData.YValues;
for (var i = 0; i < count; i++)
{
var value = yValues.GetValueAt(i);
if (value > maximum)
{
StrokeColors.Set(0xffff0000, i);
FillColors.Set(0x99ff0000, i);
}
else if (value < minimum)
{
StrokeColors.Set(0xff00ff00, i);
FillColors.Set(0x9900ff00, i);
}
else
{
StrokeColors.Set(0xffffff00, i);
FillColors.Set(0x99ffff00, i);
}
}
}
}
Once a PaletteProvider class is ready, its instances can be used to set it for a RenderableSeries via the ISCIRenderableSeries.paletteProvider property: