React Custom Texture

Creates a Custom Texture example with multiple renderableSeries, all allowing for customTextureOptions images.

Fullscreen

Edit

 Edit

Docs

drawExample.ts

index.tsx

theme.ts

Copy to clipboard
Minimise
Fullscreen
1import {
2    NumberRange,
3    SciChartSurface,
4    NumericAxis,
5    ZoomPanModifier,
6    ZoomExtentsModifier,
7    MouseWheelZoomModifier,
8    FastTriangleRenderableSeries,
9    ETriangleSeriesDrawMode,
10    XyxyDataSeries,
11    ICustomTextureOptions,
12    FastRectangleRenderableSeries,
13    EColumnMode,
14    EColumnYMode,
15    createImageAsync,
16    FastBandRenderableSeries,
17    XyyDataSeries,
18    ELineDrawMode,
19    SplineMountainRenderableSeries,
20    XyDataSeries,
21} from "scichart";
22
23import { appTheme } from "../../../theme";
24
25import scichartImg from "./scichart.jpg";
26import mountain from "./mountain.jpg";
27import cloud from "./cloud.jpg";
28import buildings from "./buildings.jpg";
29import moon from "./moon.jpg";
30
31let textureRepeat = false;
32
33export class ImageTextureOptions implements ICustomTextureOptions {
34    isPerPrimitive?: boolean = false;
35    options: { image: HTMLImageElement; textureWidth?: number; textureHeight?: number; repeat?: boolean };
36    textureHeight: number = 800;
37    textureWidth: number = 600;
38    repeat = false;
39
40    public constructor(options: {
41        image: HTMLImageElement;
42        textureWidth?: number;
43        textureHeight?: number;
44        repeat?: boolean;
45    }) {
46        this.options = options;
47        this.textureHeight = options.textureHeight;
48        this.textureWidth = options.textureWidth;
49        this.repeat = options.repeat;
50    }
51
52    public createTexture(context: CanvasRenderingContext2D) {
53        context.drawImage(this.options.image, 0, 0);
54    }
55}
56
57export const drawExample = async (rootElement: string | HTMLDivElement) => {
58    // Create a SciChartSurface
59    const { sciChartSurface, wasmContext } = await SciChartSurface.create(rootElement, {
60        theme: appTheme.SciChartJsTheme,
61    });
62
63    const growBy = new NumberRange(0.01, 0.01);
64
65    sciChartSurface.xAxes.add(new NumericAxis(wasmContext, { growBy }));
66    sciChartSurface.yAxes.add(new NumericAxis(wasmContext, { growBy }));
67
68    const scichartBitmap = await createImageAsync(scichartImg);
69    const mountainBitmap = await createImageAsync(mountain);
70    const cloudBitmap = await createImageAsync(cloud);
71    const buildingsBitmap = await createImageAsync(buildings);
72    const moonBitmap = await createImageAsync(moon);
73
74    // triangles
75    const polygonSeries = new FastTriangleRenderableSeries(wasmContext, {
76        isDigitalLine: false,
77        fill: "cornflowerblue",
78        drawMode: ETriangleSeriesDrawMode.Strip,
79        polygonVertices: 6, // Sets the number of vertices per polygon. Applies only for drawMode ETriangleSeriesDrawMode.Polygon
80        customTextureOptions: new ImageTextureOptions({
81            image: scichartBitmap,
82            textureWidth: 600,
83            textureHeight: 324,
84            repeat: textureRepeat,
85        }),
86        opacity: 0.5,
87    });
88
89    const dataSeries = new XyxyDataSeries(wasmContext);
90
91    let myData: number[][] = [];
92
93    function generateRectangle(minX: number, maxX: number, minY: number, maxY: number) {
94        const midX = (minX + maxX) / 2;
95        const midY = (minY + maxY) / 2;
96
97        [
98            [midX, midY, 0.5, 0.5], // Center point
99            [minX, minY, 0, 1], // Bottom-left
100            [maxX, minY, 1, 1], // Bottom-right
101            [maxX, maxY, 1, 0], // Top-right
102            [minX, maxY, 0, 0], // Top-left
103            [minX, minY, 0, 1], // Bottom-left (duplicate)
104        ].forEach((d) => {
105            myData.push([d[0], d[1], d[2], d[3]]);
106            dataSeries.append(d[0], d[1], d[2], d[3]);
107        });
108    }
109
110    console.log(myData);
111
112    generateRectangle(500, 950, 150, 400);
113
114    polygonSeries.dataSeries = dataSeries;
115
116    // rectangless
117
118    const xValues = [0, 110, 220, 330];
119    const yValues = [20, 0, 20, 0];
120    const x1Values = [100, 210, 320, 430];
121    const y1Values = [320, 300, 320, 300];
122
123    const rectangleSeries = new FastRectangleRenderableSeries(wasmContext, {
124        dataSeries: new XyxyDataSeries(wasmContext, {
125            xValues,
126            yValues,
127            x1Values,
128            y1Values,
129        }),
130        columnXMode: EColumnMode.StartEnd, // x, x1
131        columnYMode: EColumnYMode.TopBottom, // y, y1
132        stroke: "black",
133        strokeThickness: 2,
134        customTextureOptions: new ImageTextureOptions({
135            image: buildingsBitmap,
136            textureWidth: 640,
137            textureHeight: 480,
138            repeat: textureRepeat,
139        }),
140        opacity: 1,
141    });
142
143    // band
144    const dataSeriesB = new XyyDataSeries(wasmContext);
145    const POINTSB = 1000;
146    const STEPB = (3 * Math.PI) / POINTSB;
147    for (let i = 0; i <= 1000; i++) {
148        const k = 1 - i / 2000;
149        let y = Math.sin(i * STEPB) * k * 0.7;
150        const y1 = Math.cos(i * STEPB) * k;
151        if (i >= 200 && i <= 300) {
152            y = NaN;
153        }
154        dataSeriesB.append(i, y * 100 + 500, y1 * 100 + 500);
155    }
156    const bandSeries = new FastBandRenderableSeries(wasmContext, {
157        dataSeries: dataSeriesB,
158        strokeThickness: 2,
159        drawNaNAs: ELineDrawMode.PolyLine,
160        customTextureOptions: new ImageTextureOptions({
161            image: cloudBitmap,
162            textureWidth: 640,
163            textureHeight: 480,
164            repeat: textureRepeat,
165        }),
166    });
167
168    // mountain
169
170    const mountainSeries = new SplineMountainRenderableSeries(wasmContext, {
171        stroke: "black",
172        strokeThickness: 2,
173        zeroLineY: 0.0,
174        fill: "rgba(176, 196, 222, 0.7)",
175        interpolationPoints: 5,
176        customTextureOptions: new ImageTextureOptions({
177            image: mountainBitmap,
178            textureWidth: 400,
179            textureHeight: 300,
180            repeat: textureRepeat,
181        }),
182        // pointMarker: new EllipsePointMarker(wasmContext),
183    });
184
185    const dataSeriesM = new XyDataSeries(wasmContext);
186    const POINTS = 10;
187    const STEP = (3 * Math.PI) / POINTS;
188    for (let i = 0; i <= POINTS; i++) {
189        const y = Math.abs(Math.sin(i * STEP)) * 100;
190        dataSeriesM.append(i * 100, y);
191    }
192    mountainSeries.dataSeries = dataSeriesM;
193
194    // triangle
195
196    const sXValues = [100, 100, 300, 300, 300, 100];
197    const sYValues = [500, 350, 350, 370, 520, 520];
198
199    const triangkeSeries = new FastTriangleRenderableSeries(wasmContext, {
200        dataSeries: new XyDataSeries(wasmContext, {
201            xValues: sXValues,
202            yValues: sYValues,
203        }),
204        drawMode: ETriangleSeriesDrawMode.List,
205        customTextureOptions: new ImageTextureOptions({
206            image: moonBitmap,
207            textureWidth: 800,
208            textureHeight: 600,
209            repeat: textureRepeat,
210        }),
211    });
212
213    sciChartSurface.renderableSeries.add(polygonSeries, triangkeSeries, rectangleSeries, bandSeries, mountainSeries);
214
215    sciChartSurface.chartModifiers.add(new ZoomPanModifier());
216    sciChartSurface.chartModifiers.add(new ZoomExtentsModifier());
217    sciChartSurface.chartModifiers.add(new MouseWheelZoomModifier());
218
219    return { sciChartSurface, wasmContext };
220};
221

Custom Texture Example - React

Overview

This React example demonstrates texture mapping in SciChart.js using the SciChartReact component. It applies custom image textures to multiple series types while maintaining React's component lifecycle.

Technical Implementation

The implementation uses React's component pattern with an initChart prop that initializes the chart surface. Custom textures are defined through ImageTextureOptions and applied to series like FastTriangleRenderableSeries.

Features and Capabilities

The example showcases texture mapping with different coordinate systems (XY and XYXY) and demonstrates texture control properties like textureWidth and textureHeight. It combines multiple textured series with interactive modifiers for a rich visualization experience.

Integration and Best Practices

The SciChartReact component handles WASM context lifecycle automatically. Developers can extend this pattern by adding React state management for dynamic texture updates while following React integration guidelines.

SciChart Ltd, 16 Beaufort Court, Admirals Way, Docklands, London, E14 9XL.