Creates a React Semiconductors Dashboard using SciChart.js, by leveraging the FastRectangleRenderableSeries, and its customTextureOptions property to have a custom tiling texture fill.
index.tsx
RandomWalkGenerator.ts
theme.ts
columnChart.ts
lineChart.ts
paretoChart.ts
styles.css
waferData.ts
waferGrid.ts
1import { IPointMetadata } from "scichart";
2
3// Define quality categories as a union type for type safety
4export type WaferQuality = "Good" | "Marginal" | "Fail";
5
6// Constants for measurement parameters
7const MEASUREMENT_PARAMS = {
8 INPUT1: { mean: 1100, stdDev: 20 }, // temperature (°C)
9 INPUT2: { mean: 500, stdDev: 150 }, // flow rate (units)
10 MEASURE1: { mean: 100, stdDev: 5 }, // thickness (nm)
11 MEASURE2: { mean: 50, stdDev: 3 }, // width (nm)
12 MEASURE3: { mean: 10, stdDev: 1 }, // resistance (Ω/□)
13};
14
15// Time constants in milliseconds
16const MS_PER_DAY = 24 * 60 * 60 * 1000;
17
18export interface WaferLotData extends IPointMetadata {
19 isSelected: boolean;
20 Date: string; // Timestamp of the run/lot/batch (ISO format)
21 Batch: number; // Processing group (1-10)
22 Quality: WaferQuality; // Categorical: 'Good', 'Marginal', or 'Fail'
23 Input1: number; // Process input variable (e.g., furnace temperature setpoint)
24 Input2: number; // Another process input (e.g., gas flow rate)
25 Measure1: number; // Output measurement (e.g., film thickness in nm)
26 Measure2: number; // Output measurement (e.g., line width in nm)
27 Measure3: number; // Output measurement (e.g., sheet resistance in Ω/sq)
28}
29
30export interface WaferDayData {
31 Date: string; // Timestamp of the run/lot/batch (ISO format)
32 Mean1: number;
33 Mean2: number;
34 Batches: WaferLotData[];
35}
36
37/**
38 * Generates a value from an approximate normal distribution
39 * Uses Box-Muller transform for better statistical properties
40 * @param mean Mean value of the distribution
41 * @param stdDev Standard deviation of the distribution
42 * @returns Random value from the normal distribution
43 */
44function randomNormal(mean: number, stdDev: number): number {
45 // Box-Muller transform for better normal distribution approximation
46 const u1 = Math.random();
47 const u2 = Math.random();
48
49 // Guard against u1 being zero
50 if (u1 === 0) return randomNormal(mean, stdDev);
51
52 const z0 = Math.sqrt(-2.0 * Math.log(u1)) * Math.cos(2.0 * Math.PI * u2);
53 return mean + z0 * stdDev;
54}
55
56/**
57 * Determines wafer quality based on predefined distribution
58 * 70% Good, 20% Marginal, 10% Fail
59 * @returns Quality category as a string
60 */
61function getQuality(input: number): WaferQuality {
62 if (input > 500) return "Good";
63 if (input > 350) return "Marginal";
64 return "Fail";
65}
66
67/**
68 * Formats a number to a specified precision without string conversion overhead
69 * @param value Number to format
70 * @param precision Decimal places to keep
71 * @returns Formatted number
72 */
73function formatNumber(value: number, precision: number = 2): number {
74 const factor = Math.pow(10, precision);
75 return Math.round(value * factor) / factor;
76}
77
78/**
79 * Generates an array of mock wafer data entries based on the specified structure.
80 * Includes improved error handling, performance optimizations, and better type safety.
81 *
82 * @param numDays Number of data entries to generate
83 * @param startDate Optional starting date (defaults to current date)
84 * @returns Array of WaferLotData objects
85 * @throws Error if numEntries is invalid
86 */
87export function generateWaferLotData(
88 numDays: number,
89 numBatches: number = 15,
90 startDate: Date = new Date()
91): WaferDayData[] {
92 // Validate inputs
93 if (!Number.isInteger(numDays) || numDays <= 0) {
94 throw new Error("numEntries must be a positive integer");
95 }
96
97 if (!(startDate instanceof Date) || isNaN(startDate.getTime())) {
98 throw new Error("startDate must be a valid Date object");
99 }
100
101 const data: WaferDayData[] = [];
102 const startTime = startDate.getTime();
103
104 for (let i = 0; i < numDays; i++) {
105 // Generate date: increment by days for temporal trends
106 const date = new Date(startTime + i * MS_PER_DAY);
107 const isoDate = date.toISOString().split("T")[0]; // YYYY-MM-DD format
108 const Batches: WaferLotData[] = [];
109 let total1 = 0;
110 let total2 = 0;
111 for (let b = 1; b <= numBatches; b++) {
112 const input2 = Math.round(randomNormal(MEASUREMENT_PARAMS.INPUT2.mean, MEASUREMENT_PARAMS.INPUT2.stdDev));
113 // Generate measurements using our helper functions
114 const batch = {
115 isSelected: false,
116 Date: isoDate,
117 Batch: b,
118 Quality: getQuality(input2),
119 Input1: Math.round(randomNormal(MEASUREMENT_PARAMS.INPUT1.mean, MEASUREMENT_PARAMS.INPUT1.stdDev)),
120 Input2: input2,
121 Measure1: formatNumber(randomNormal(input2, MEASUREMENT_PARAMS.MEASURE1.stdDev)),
122 Measure2: formatNumber(randomNormal(input2, MEASUREMENT_PARAMS.MEASURE2.stdDev)),
123 Measure3: formatNumber(randomNormal(input2, MEASUREMENT_PARAMS.MEASURE3.stdDev)),
124 };
125 Batches.push(batch);
126 total1 += batch.Input1;
127 total2 += batch.Input2;
128 }
129 data.push({
130 Date: isoDate,
131 Mean1: total1 / numBatches,
132 Mean2: total2 / numBatches,
133 Batches,
134 } as WaferDayData);
135 }
136
137 return data;
138}
139
140// Simple seeded random generator (LCG)
141function seededRandom(seed: number) {
142 let value = seed % 2147483647;
143 return () => {
144 value = (value * 48271) % 2147483647;
145 return (value - 1) / 2147483646;
146 };
147}
148
149// Simple hashCode for string/number seed generation
150function hashCode(obj: any, subChartIndex: number) {
151 const str = typeof obj === "string" ? obj : JSON.stringify(obj);
152 let hash = 0;
153 for (let i = 0; i < str.length; i++) {
154 hash = (Math.imul(31, hash) + str.charCodeAt(i)) | 0;
155 }
156
157 let result = Math.abs(hash) + subChartIndex;
158
159 return result;
160}
161
162export const generateGridOfPoints = (selectedPoint: WaferLotData, subChartIndex = 0) => {
163 const waferSize = 41;
164 const seed = hashCode(selectedPoint, subChartIndex); // Make seed depend on selectedPoint
165 const random = seededRandom(seed);
166
167 const dataJSON = [];
168
169 for (let row = 0; row < waferSize; row++) {
170 for (let col = 0; col < waferSize; col++) {
171 const centerX = waferSize / 2;
172 const centerY = waferSize / 2;
173 const distance = Math.sqrt(Math.pow(col - centerX, 2) + Math.pow(row - centerY, 2));
174
175 if (distance <= waferSize / 2) {
176 let defectType = "OK";
177
178 // Calculate defect probability inversely related to Input2
179 // Lower Input2 values result in higher defect probability
180 // Normalize Input2 to a 0-1 range based on expected range (200-800)
181 const normalizedInput2 = Math.max(0, Math.min(1, (selectedPoint.Input2 - 200) / 600));
182
183 // Invert the relationship: lower Input2 -> higher defect probability
184 const defectProbabilityMultiplier = 1 - normalizedInput2;
185
186 // Use seeded random with inverse relationship to Input2
187 const randomValue = random();
188
189 // Adjust thresholds based on Input2 - lower Input2 increases defect likelihood
190 const baseThreshold = defectProbabilityMultiplier * 1.5; // Scale factor for defect probability
191
192 if (distance > waferSize / 5) {
193 if (randomValue < 0.04 * baseThreshold) defectType = "S48"; // red
194 else if (randomValue < 0.05 * baseThreshold) defectType = "S36"; // orange
195 } else if (distance < waferSize / 5) {
196 if (randomValue < 0.03 * baseThreshold) defectType = "S28"; // blue
197 }
198
199 dataJSON.push({
200 MAP_ROW: row,
201 MAP_COL: col,
202 DEFECT: defectType,
203 MR: (random() - 0.5) * 20,
204 HR: (random() - 0.5) * 10,
205 HDI: (random() - 0.5) * 5,
206 MR2: (random() - 0.5) * 30,
207 });
208 }
209 }
210 }
211
212 return dataJSON;
213};
214The Semiconductors Dashboard demonstrates a sophisticated semiconductor manufacturing quality control interface that enables users to analyze wafer production data across multiple dimensions and hierarchical levels.
Yield Trend Chart (Top Panel): Line chart showing quality trends over time with clickable data points.
Batch Analysis (Bottom Left): Switchable view between Column Chart and Pareto Chart for batch-level analysis.
Wafer Maps (Bottom Right): Grid of 12 sub-charts displaying detailed wafer defect maps.
Click any point on the yield trend line chart to drill down into batch data for that specific day.
Toggle between Column Chart and Pareto Chart views using header buttons to analyze batch data differently.
Select individual batches from either chart view to examine corresponding wafer defect patterns.
All charts are synchronized — selections automatically propagate across all dashboard views.
Point Selection: Navigate through hierarchical data levels (Day → Batch → Wafer).
Chart Switching: Seamless toggle between analytical views without losing context.
Synchronized Navigation: Selection state maintained across all chart components.
Responsive Tooltips: Custom SVG tooltips showing detailed batch quality summaries.
Zoom and Pan: Standard chart navigation controls where appropriate.
The dashboard is implemented as a React component (index.tsx) utilizing SciChart React for multi-chart coordination.
SciChartReact components manage chart instance creation and lifecycle automatically.
Each chart exposes initialization functions that accept callback handlers for inter-chart communication.
React refs maintain references to chart instances and their APIs for programmatic control.
Lifecycle handled by SciChart React ensures proper cleanup and memory management.
Data is generated semi-randomly in waferData.ts using a hierarchical structure.
WaferDayData: Contains daily summary metrics (Mean1, Mean2) and an array of WaferLotData batches.
WaferLotData:: Batch-level data with quality categorization (Good, Marginal, Fail), input variables (Input1, Input2), output measurements (Measure1, Measure2, Measure3), and selection state tracking.
lineChart.ts)Inputs: waferData array, onPointSelected callback
Returns: Chart surface, WebAssembly context
Callback: onPointSelected(point: WaferDayData, index: number)
FastLineRenderableSeries with point markers for trend visualization.
Custom metadata interface IWaferPointMetadata extends point data with selection state.
DataPointSelectionPaletteProvider for visual selection feedback.
Custom tooltip and DataLabelProvider showing Input1 values above points.
columnChart.ts)Inputs: waferData batch array, onBatchSelected callback
Returns: Chart surface, updateData method, selection modifier
Callback: onBatchSelected(point: WaferLotData, isColumnChart: boolean)
Update: updateData(batchData, fireSelectionChanged)
StackedColumnRenderableSeries displaying three measures as stacked components.
XyNDataSeries with arrayCount: 3 for multi-dimensional data.
DataPointSelectionPaletteProvider for visual selection feedback.
Dynamic column width calculation and coordinate mapping.
paretoChart.ts)Inputs: waferData batch array, onBatchSelected callback
Returns: Chart surface, updateData method, selection modifier
Callback: onBatchSelected(point: WaferLotData, isColumnChart: boolean)
Update: updateData(waferData, fireSelectionChanged)
CumulativePercentageFilter extends XyFilterBase for real-time cumulative percentage calculations.FastColumnRenderableSeries (primary) and FastLineRenderableSeries (cumulative).waferGrid.ts)Input: selectedPoint — single WaferLotData seed for wafer defect patterns.
Returns: Main chart surface, generateSubcharts method.
Update: generateSubcharts(selectedPoint) regenerates all 12 sub-charts.
SciChartSubSurface API for creating 12 independent sub-charts.
FastRectangleRenderableSeries for wafer die representation.
RectanglePaletteProvider implementing IFillPaletteProvider for defect-based coloring.
Seeded random generation in generateGridOfPoints for reproducible wafer patterns.
handlePointSelected provides selected day data.
updateData() methods receive new batch arrays and manage state.
-handleBatchSelected provides selected batch and chart type.
-generateSubcharts() regenerates all wafer sub-charts.
-Column and Pareto chart share selection information via shared metadata
-Manual synchronization ensures consistent state between both views.
freezeWhenOutOfView: true prevents unnecessary updates.
Chart toggling uses CSS display properties instead of unmounting.
Sub-chart regeneration only when required.
Automatic cleanup via SciChart disposal mechanisms.
Ref-based chart management prevents leaks.
Efficient data handling for large datasets.
Centralized theme system (appTheme) ensures consistent:
Color palettes for categories
Typography and spacing
Visual feedback for selections
Responsive layout behavior
The Semiconductors Dashboard showcases advanced SciChart.js capabilities — including multi-chart coordination, hierarchical data exploration, sub-chart architectures, and synchronized user interactions — making it ideal for industrial and scientific analytics.

In this example we are simulating four channels of data showing that SciChart.js can be used to draw real-time ECG/EKG charts and graphs to monitor heart reate, body temperature, blood pressure, pulse rate, SPO2 blood oxygen, volumetric flow and more.

Demonstrates Logarithmic Axis on a React Chart using SciChart.js. SciChart supports logarithmic axis with scientific or engineering notation and positive and negative values

Demonstrating the capability of SciChart.js to create JavaScript 3D Point Cloud charts and visualize LiDAR data from the UK Defra Survey.

Demonstrates Vertically Stacked Axes on a React Chart using SciChart.js, allowing data to overlap

See the frequency of recordings with the React audio spectrum analyzer example from SciChart. This real-time audio visualizer demo uses a Fourier Transform.

Demonstrating the capability of SciChart.js to create a JavaScript Audio Analyzer Bars and visualize the Fourier-Transform of an audio waveform in realtime.

Demonstrates how to create a Waterfall chart in SciChart.js, showing chromotragraphy data with interactive selection of points.

See the React Phasor Diagram example to combine a Cartesian surface with a Polar subsurface. Get seamless React integration with SciChart. View demo now.

Create React Correlation Plot with high performance SciChart.js. Easily render pre-defined point types. Supports custom shapes. Get your free trial now.

React **Wafer Analysis Chart** using SciChart.js, by leveraging the **FastRectangleRenderableSeries**, and crossfilter to enable live filtering.