JavaScript Chart with Smith Chart

Demonstrates how to create a JavaScript Smith Chart using SciChart.js, High Performance JavaScript Charts

MARKERSClick chart to place a marker

Fullscreen

Edit

 Edit

Docs

drawExample.ts

index.html

vanilla.ts

theme.ts

smithChartAdmittance.ts

smithChartAxes.ts

smithChartChain.ts

smithChartMarkers.ts

smithChartVswr.ts

useSmithChart.ts

Copy to clipboard
Minimise
Fullscreen
1import {
2    SciChartSurface,
3    EAxisAlignment,
4    NumberRange,
5    ZoomExtentsModifier,
6    MouseWheelZoomModifier,
7    PinchZoomModifier,
8    ZoomPanModifier,
9    EExecuteOn,
10} from "scichart";
11import { appTheme } from "../../../theme";
12import { SmithChartResistanceAxis, SmithChartReactanceAxis } from "./smithChartAxes";
13import { SmithChartAdmittanceResistanceAxis, SmithChartAdmittanceReactanceAxis } from "./smithChartAdmittance";
14import { SmithMarkersAdapter } from "./smithChartMarkers";
15import { SmithVswrAdapter } from "./smithChartVswr";
16import { SmithChainAdapter } from "./smithChartChain";
17import { SmithState, SmithAction } from "./useSmithChart";
18
19export const drawExample = async (rootElement: string | HTMLDivElement) => {
20    const { sciChartSurface, wasmContext } = await SciChartSurface.create(rootElement, {
21        theme: appTheme.SciChartJsTheme,
22    });
23
24    const gridColor = "#aaaaaa";
25    const axisRange = 1.2;
26    sciChartSurface.xAxes.add(
27        new SmithChartResistanceAxis(wasmContext, {
28            visibleRange: new NumberRange(-axisRange, axisRange),
29            axisAlignment: EAxisAlignment.Bottom,
30            labelPrecision: 2,
31            majorGridLineStyle: { color: gridColor, strokeThickness: 2 },
32            minorGridLineStyle: { color: gridColor + "77", strokeThickness: 1 },
33            rimLineStyle: { color: appTheme.MutedBlue },
34            rimTickLineStyle: { color: appTheme.MutedBlue },
35            rimLabelStyle: { color: appTheme.MutedBlue },
36        })
37    );
38
39    sciChartSurface.yAxes.add(
40        new SmithChartReactanceAxis(wasmContext, {
41            visibleRange: new NumberRange(-axisRange, axisRange),
42            axisAlignment: EAxisAlignment.Left,
43            labelPrecision: 2,
44            majorGridLineStyle: { color: gridColor, strokeThickness: 2 },
45            minorGridLineStyle: { color: gridColor + "77", strokeThickness: 1 },
46        })
47    );
48
49    const yAdmittanceColor = "#44AAFF";
50    const admittanceResistanceAxis = new SmithChartAdmittanceResistanceAxis(wasmContext, {
51        visibleRange: new NumberRange(-axisRange, axisRange),
52        axisAlignment: EAxisAlignment.Bottom,
53        isVisible: false,
54        majorGridLineStyle: { color: yAdmittanceColor, strokeThickness: 2 },
55        minorGridLineStyle: { color: yAdmittanceColor + "77", strokeThickness: 1 },
56    });
57    const admittanceReactanceAxis = new SmithChartAdmittanceReactanceAxis(wasmContext, {
58        visibleRange: new NumberRange(-axisRange, axisRange),
59        axisAlignment: EAxisAlignment.Left,
60        isVisible: false,
61        majorGridLineStyle: { color: yAdmittanceColor, strokeThickness: 2 },
62        minorGridLineStyle: { color: yAdmittanceColor + "77", strokeThickness: 1 },
63    });
64    sciChartSurface.xAxes.add(admittanceResistanceAxis);
65    sciChartSurface.yAxes.add(admittanceReactanceAxis);
66
67    // vswrAdapter must be created first so SmithVswrModifier gets priority over SmithClickModifier
68    const vswrAdapter = new SmithVswrAdapter(sciChartSurface);
69    const markersAdapter = new SmithMarkersAdapter(sciChartSurface, wasmContext);
70    const chainAdapter = new SmithChainAdapter(sciChartSurface, wasmContext);
71
72    sciChartSurface.chartModifiers.add(
73        new MouseWheelZoomModifier(),
74        new ZoomExtentsModifier(),
75        new PinchZoomModifier(),
76        new ZoomPanModifier({ executeCondition: { button: EExecuteOn.MouseRightButton } })
77    );
78
79    const alphaHex = (v: number) =>
80        Math.round(Math.min(1, Math.max(0, v)) * 255)
81            .toString(16)
82            .padStart(2, "0");
83
84    const update = (state: SmithState) => {
85        markersAdapter.update(state);
86        vswrAdapter.update(state);
87        chainAdapter.update(state);
88
89        // Grid mode — show/hide impedance and admittance axes
90        const zGridActive = state.gridMode === "Z" || state.gridMode === "ZY";
91        const yGridActive = state.gridMode === "Y" || state.gridMode === "ZY";
92        // Z resistance axis stays visible in all modes so the rim always draws;
93        // its R-circles are made transparent when not in Z/ZY mode.
94        sciChartSurface.xAxes.get(0).isVisible = true;
95        sciChartSurface.yAxes.get(0).isVisible = zGridActive;
96        admittanceResistanceAxis.isVisible = yGridActive;
97        admittanceReactanceAxis.isVisible = yGridActive;
98
99        // Labels: Z labels in Z or ZY; Y labels only in Y-only mode
100        const zLabels = zGridActive;
101        const yLabels = state.gridMode === "Y";
102        (sciChartSurface.xAxes.get(0) as SmithChartResistanceAxis).drawGridLabels = zLabels;
103        admittanceResistanceAxis.drawLabels = yLabels;
104        admittanceReactanceAxis.drawLabels = yLabels;
105
106        // Grid opacity — Z circles hidden (transparent) in Y-only mode
107        const zMajor = zGridActive ? `${gridColor}${alphaHex(state.zOpacity)}` : "#00000000";
108        const zMinor = zGridActive ? `${gridColor}${alphaHex(state.zOpacity * 0.5)}` : "#00000000";
109        const yMajor = `${yAdmittanceColor}${alphaHex(state.yOpacity)}`;
110        const yMinor = `${yAdmittanceColor}${alphaHex(state.yOpacity * 0.5)}`;
111        sciChartSurface.xAxes.get(0).majorGridLineStyle = { color: zMajor, strokeThickness: 2 };
112        sciChartSurface.xAxes.get(0).minorGridLineStyle = { color: zMinor, strokeThickness: 1 };
113        sciChartSurface.yAxes.get(0).majorGridLineStyle = { color: zMajor, strokeThickness: 2 };
114        sciChartSurface.yAxes.get(0).minorGridLineStyle = { color: zMinor, strokeThickness: 1 };
115        admittanceResistanceAxis.majorGridLineStyle = { color: yMajor, strokeThickness: 2 };
116        admittanceResistanceAxis.minorGridLineStyle = { color: yMinor, strokeThickness: 1 };
117        admittanceReactanceAxis.majorGridLineStyle = { color: yMajor, strokeThickness: 2 };
118        admittanceReactanceAxis.minorGridLineStyle = { color: yMinor, strokeThickness: 1 };
119    };
120
121    const setDispatch = (dispatch: (a: SmithAction) => void) => {
122        markersAdapter.setDispatch(dispatch);
123        vswrAdapter.setDispatch(dispatch);
124        chainAdapter.setDispatch(dispatch);
125    };
126
127    return {
128        sciChartSurface,
129        wasmContext,
130        update,
131        setDispatch,
132        getChainTip: (s: SmithState) => chainAdapter.getChainTip(s),
133        addChainStep: chainAdapter.addStep.bind(chainAdapter),
134    };
135};
136

What is a Smith Chart?

RF and microwave engineers face a recurring problem: getting maximum power from a source into a load when both have complex, frequency-dependent impedances. A mismatch causes reflections that waste power, distort signals, and can damage amplifiers. Fixing it means choosing the right combination of inductors, capacitors, and transmission-line sections — but the interactions are non-linear and hard to reason about algebraically.

The Smith chart makes this tractable by turning the matching problem into a geometry problem. Every possible impedance maps to a point inside a circle, and adding each type of component moves that point along a predictable curve. Series inductors and capacitors arc along circles; shunt components arc along a different family; a length of transmission line rotates the point around the chart centre. The goal — a perfect impedance match — is the centre of the chart.

This demo lets you explore those mechanics interactively. Place a marker to read the full impedance, admittance, VSWR and return-loss figures at any point. Load one of the built-in examples to see a complete matching problem worked through step by step. Or build your own network in the Chain panel, adding components one at a time and watching the operating point move to its destination.

SciChart.js Implementation

This example is built entirely on SciChartSurface with custom NumericAxis subclasses — no specialised polar surface is required because the Γ plane is Cartesian.

Custom axes override drawGridLines and drawLabels to render the characteristic Smith chart curves using WebGL arc primitives via the SciChart WASM context:

  • SmithChartResistanceAxis (X-axis) draws constant-R circles and the outer rim ring, and hosts a custom SmithChartAxisRenderer that places R labels at each circle’s left tangent point.
  • SmithChartReactanceAxis (Y-axis) draws constant-X arcs clipped to the unit circle with X labels at each arc’s unit-circle intersection.
  • SmithChartAdmittanceResistanceAxis / SmithChartAdmittanceReactanceAxis mirror these for the Y-overlay, registered as secondary axes. Labels are shown only in Y-only mode to avoid clutter in ZY mode.

Grid density is dynamically computed by SmithGridCalculator, which selects major and minor tick values in s-space (s = 1/(v+1)) to give perceptually uniform coverage and automatically clips minor arcs near the (1, 0) singularity.

Three adapters add interactivity on top of the chart surface:

  • SmithMarkersAdapter — click-to-place markers with constrained drag modes (free, constant |Γ|, R, X, G or B curve), implemented as custom ChartModifierBase subclasses.
  • SmithVswrAdapter — draggable VSWR circle with optional fill shading rendered as an EllipsePointMarker annotation.
  • SmithChainAdapter — component chain that moves a starting point along the correct Smith chart curve for each component type, computing the new Γ analytically for series L/C/R, shunt L/C/R and transmission line sections.

Using the Demo

Chart navigation: mouse wheel to zoom, right-click drag to pan, double-click to zoom to extents.

Markers: click anywhere on the chart to place a numbered marker. The right-hand sidebar shows a full readout for each marker — Γ (complex), |Γ|, ∠Γ, normalised Z and Y, VSWR, return loss, mismatch loss, Q factor, WTG and WTL. Each marker can be dragged freely or constrained to a constant-R, X, |Γ|, G or B curve via the Drag selector in its accordion.

Examples menu (top-left overlay button) loads pre-built RF scenarios demonstrating typical Smith chart workflows such as L-network matching and stub tuning.

Chain panel builds a component matching network step by step: select a component type (Series L/C/R, Shunt L/C/R, Transmission Line), enter a value and click Add. Each step draws the arc from the current point to the next impedance. The VSWR circle can be resized by dragging its handle on the real axis; Shade fills the acceptable-match region.

Grid Config panel controls the chart appearance: the Z / Y / ZY toggle switches between the impedance grid (grey), admittance grid (blue) or both overlaid. Independent opacity sliders fade each grid. Advanced controls adjust grid density and the outer rim tick spacing.

javascript Chart Examples & Demos

See Also: Scientific & Medical Charts (11 Demos)

JavaScript Vital Signs ECG/EKG Medical Demo | SciChart.js

JavaScript Vital Signs ECG/EKG Medical Demo

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.

JavaScript Chart with Logarithmic Axis Example | SciChart

JavaScript Chart with Logarithmic Axis Example

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

LiDAR 3D Point Cloud of Geospatial Data | SciChart.js

LiDAR 3D Point Cloud of Geospatial Data

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

JavaScript Chart with Vertically Stacked Axes | SciChart

JavaScript Chart with Vertically Stacked Axes

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

Realtime Audio Spectrum Analyzer Chart | SciChart.js Demo

Realtime Audio Spectrum Analyzer Chart Example

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

Realtime Audio Analyzer Bars Demo | SciChart.js Demo

Realtime Audio Analyzer Bars Demo

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

Interactive Waterfall Chart | Javascript Charts | SciChart.js

Interactive Waterfall Spectral Chart

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

Interactive Phasor Diagram chart | Javascript Charts | SciChart.js

Phasor Diagram Chart Example

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

JavaScript Correlation Plot | Javascript Charts | SciChart.js

JavaScript Correlation Plot

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

NEW!
Semiconductors Dashboard | JavaScript Charts | SciChart.js

Semiconductors Dashboard

JavaScript **Semiconductors Dashboard** using SciChart.js, by leveraging the **FastRectangleRenderableSeries**, and its `customTextureOptions` property to have a custom tiling texture fill.

Wafer Analysis Chart | JavaScript Charts | SciChart.js

Wafer Analysis Chart

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

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