Polar Charts
Polar charts display data in polar coordinates, where each point is defined by a radial distance (r) and an angular position (θ). This visualization is ideal for circular patterns, directional data, and cyclic phenomena.
Features
- Dual Angle Modes: Support for both degrees and radians
- Fill Options: Optional area fill from origin
- Path Closing: Connect last point to first for closed shapes
- Polar Grid: Customizable radial and angular grid lines
- Flexible Rendering: Line or filled area modes
- Auto Bounds: Automatic symmetric bounds calculation
Basic Usage
typescript
import { createChart } from 'scichart-engine';
const chart = createChart({
container: document.getElementById('chart'),
title: 'Polar Chart Example'
});
// Create polar data
const polarData = {
r: new Float32Array([1, 2, 3, 2.5, 1.5]),
theta: new Float32Array([0, 72, 144, 216, 288]) // degrees
};
chart.addSeries({
id: 'polar1',
type: 'polar',
name: 'Polar Series',
data: polarData,
style: {
color: '#00f2ff',
width: 2,
angleMode: 'degrees'
}
});Data Format
PolarData Interface
typescript
interface PolarData {
/** Radial values (distance from origin) */
r: Float32Array | Float64Array | number[];
/** Angular values (theta) */
theta: Float32Array | Float64Array | number[];
}Important: The r and theta arrays must have the same length.
Styling Options
PolarStyle Interface
typescript
interface PolarStyle {
// Basic styling
color?: string; // Line/fill color
width?: number; // Line width in pixels
opacity?: number; // Overall opacity (0-1)
// Angle configuration
angleMode?: 'degrees' | 'radians'; // Default: 'degrees'
// Fill options
fill?: boolean; // Fill area to origin (default: false)
fillColor?: string; // Fill color (default: same as line)
fillOpacity?: number; // Fill opacity (default: 0.3)
closePath?: boolean; // Connect last to first (default: false)
// Grid configuration
showRadialGrid?: boolean; // Show concentric circles (default: true)
showAngularGrid?: boolean; // Show radial spokes (default: true)
angularDivisions?: number; // Number of angular divisions (default: 12)
radialDivisions?: number; // Number of radial divisions (default: 5)
// Scatter points
pointSize?: number; // Point marker size
symbol?: ScatterSymbol; // Point marker shape
}Examples
Wind Rose Diagram
typescript
// Wind direction and speed data
const windData = {
theta: new Float32Array([0, 45, 90, 135, 180, 225, 270, 315]),
r: new Float32Array([5, 8, 12, 6, 4, 7, 15, 10])
};
chart.addSeries({
id: 'wind-rose',
type: 'polar',
name: 'Wind Distribution',
data: windData,
style: {
color: '#4ecdc4',
width: 2,
fill: true,
fillOpacity: 0.4,
closePath: true,
angularDivisions: 8 // 45° intervals
}
});Cyclic Voltammetry
typescript
// Generate CV data (current vs potential in polar form)
function generateCVData(cycles: number = 1) {
const points = 200 * cycles;
const r = new Float32Array(points);
const theta = new Float32Array(points);
for (let i = 0; i < points; i++) {
const t = (i / points) * cycles * 2 * Math.PI;
const potential = Math.sin(t);
const current = Math.exp(-Math.pow(t - Math.PI, 2)) * 0.5;
// Convert to polar
r[i] = Math.sqrt(potential * potential + current * current);
theta[i] = Math.atan2(current, potential) * 180 / Math.PI;
}
return { r, theta };
}
chart.addSeries({
id: 'cv',
type: 'polar',
name: 'Cyclic Voltammetry',
data: generateCVData(3),
style: {
color: '#ff6b6b',
width: 1.5,
angleMode: 'degrees'
}
});Radar Chart (Multi-Metric)
typescript
// Performance metrics
const metrics = {
theta: new Float32Array([0, 60, 120, 180, 240, 300]),
r: new Float32Array([85, 90, 75, 80, 95, 70])
};
chart.addSeries({
id: 'performance',
type: 'polar',
name: 'Performance Metrics',
data: metrics,
style: {
color: '#00f2ff',
width: 2,
fill: true,
fillColor: 'rgba(0, 242, 255, 0.2)',
closePath: true,
pointSize: 6,
symbol: 'circle',
angularDivisions: 6
}
});Spiral Pattern
typescript
// Archimedean spiral
function generateSpiral(turns: number = 3) {
const points = 200;
const r = new Float32Array(points);
const theta = new Float32Array(points);
for (let i = 0; i < points; i++) {
const angle = (i / points) * turns * 360;
theta[i] = angle;
r[i] = angle / 360; // Radius increases linearly with angle
}
return { r, theta };
}
chart.addSeries({
id: 'spiral',
type: 'polar',
data: generateSpiral(5),
style: {
color: '#9b59b6',
width: 2,
angleMode: 'degrees'
}
});Angle Modes
Degrees (Default)
typescript
{
angleMode: 'degrees',
theta: [0, 90, 180, 270] // Quarter circle
}- Range: 0° to 360°
- 0° is at 3 o'clock position
- Increases counter-clockwise
Radians
typescript
{
angleMode: 'radians',
theta: [0, Math.PI/2, Math.PI, 3*Math.PI/2]
}- Range: 0 to 2π
- 0 is at 3 o'clock position
- Increases counter-clockwise
Grid Customization
Angular Divisions
Controls the number of radial spokes from the origin:
typescript
{
angularDivisions: 12 // 30° intervals (360/12)
}Common values:
4- Cardinal directions (N, E, S, W)8- 45° intervals12- 30° intervals (default)16- 22.5° intervals
Radial Divisions
Controls the number of concentric circles:
typescript
{
radialDivisions: 5 // 5 concentric circles (default)
}Coordinate Conversion
The polar renderer automatically converts (r, θ) to Cartesian (x, y):
x = r × cos(θ)
y = r × sin(θ)You can access the conversion utilities directly:
typescript
import { polarToCartesian } from 'scichart-engine';
const cartesian = polarToCartesian(
new Float32Array([1, 2, 3]),
new Float32Array([0, 90, 180]),
'degrees'
);
// Returns: Float32Array [1, 0, 0, 2, -3, 0]Bounds and Scaling
Polar charts use symmetric bounds centered at the origin:
typescript
import { calculatePolarBounds } from 'scichart-engine';
const bounds = calculatePolarBounds(polarData);
// Returns: { xMin, xMax, yMin, yMax, maxRadius }The chart automatically:
- Centers the origin at (0, 0)
- Sets symmetric bounds:
[-maxR, maxR]for both axes - Scales to fit the plot area
Performance Tips
- Use Float32Array: For large datasets, use typed arrays for better performance
- Limit Points: Polar charts with 1000+ points may benefit from downsampling
- Disable Fill: Line-only mode is faster than filled mode
- Reduce Grid: Fewer divisions = faster rendering
Common Use Cases
Scientific Applications
- Electrochemistry: Cyclic voltammetry, Nyquist plots
- Antenna Patterns: Radiation patterns, directivity
- Crystallography: X-ray diffraction patterns
Data Visualization
- Wind Roses: Wind speed and direction distribution
- Radar Charts: Multi-dimensional comparisons
- Circular Histograms: Angular data distribution
Navigation & Mapping
- Compass Roses: Directional data
- Sonar/Radar: Detection patterns
- Satellite Orbits: Orbital mechanics
API Reference
Series Options
typescript
interface PolarOptions {
id: string;
type: 'polar';
name?: string;
data: PolarData;
style?: PolarStyle;
visible?: boolean;
}Utility Functions
typescript
// Convert polar to Cartesian
polarToCartesian(
r: Float32Array,
theta: Float32Array,
angleMode: 'degrees' | 'radians'
): Float32Array
// Generate polar grid
generatePolarGrid(
maxRadius: number,
radialDivisions: number,
angularDivisions: number,
angleMode: 'degrees' | 'radians'
): { radialLines: Float32Array; angularLines: Float32Array }
// Calculate bounds
calculatePolarBounds(
data: PolarData
): { xMin, xMax, yMin, yMax, maxRadius }
// Normalize angles
normalizeAngles(
theta: Float32Array,
angleMode: 'degrees' | 'radians'
): Float32ArraySee Also
- Polar Chart Demo - Interactive examples
- Series Types - Other chart types
- Styling - Theme customization