react-native-ballast-charts
Version:
High-performance interactive charts for React Native with advanced gap handling and financial data visualization
396 lines (352 loc) • 9.22 kB
text/typescript
/**
* Core type definitions for React Native Lightweight Charting Library
* Financial data visualization with interactive features
*/
import { StyleProp, ViewStyle, TextStyle } from 'react-native';
import { ReactNode } from 'react';
// ============================================================================
// Core Data Types
// ============================================================================
/**
* Main data structure for chart input
* Pre-processed data with no transformation required
*/
export interface ChartData {
/** X-axis values (timestamps for stock, prices for distribution) */
x: number[];
/** Y-axis values (prices for stock, probabilities for distribution) */
y: number[];
}
/**
* Internal representation of a data point after scaling
*/
export interface ScaledPoint {
x: number;
y: number;
originalX: number;
originalY: number;
index: number;
}
/**
* Data range for scaling calculations
*/
export interface Range {
min: number;
max: number;
}
/**
* Chart area dimensions after padding
*/
export interface Rectangle {
x: number;
y: number;
width: number;
height: number;
}
/**
* Padding configuration for chart area
*/
export interface Padding {
top?: number;
right?: number;
bottom?: number;
left?: number;
}
// ============================================================================
// Styling Types
// ============================================================================
/**
* Line smoothing methods available for chart rendering
*/
export type LineSmoothingMethod = 'none' | 'bezier' | 'catmull-rom' | 'cardinal';
/**
* Line styling configuration with smoothing options
*/
export interface LineStyle {
color?: string;
width?: number;
opacity?: number;
/** Line smoothing method - default 'none' for sharp corners */
smoothing?: LineSmoothingMethod;
/** Smoothing tension (0-1) - affects curve tightness for splines */
tension?: number;
}
/**
* Fill styling for distribution graphs
*/
export interface FillStyle {
color?: string;
opacity?: number;
enabled?: boolean;
}
/**
* Axis styling configuration
*/
export interface AxisStyle {
lineColor?: string;
lineWidth?: number;
labelStyle?: TextStyle;
tickLength?: number;
tickColor?: string;
}
/**
* Tooltip styling configuration
*/
export interface TooltipStyle {
backgroundColor?: string;
textColor?: string;
borderColor?: string;
borderWidth?: number;
borderRadius?: number;
fontSize?: number;
padding?: number;
shadowColor?: string;
shadowOpacity?: number;
shadowRadius?: number;
}
// ============================================================================
// Feature Configuration Types
// ============================================================================
/**
* Axis configuration
*/
export interface AxisConfig {
x?: {
show?: boolean;
labels?: string[];
style?: AxisStyle;
};
y?: {
show?: boolean;
labels?: string[];
style?: AxisStyle;
formatter?: (value: number) => string; // Custom formatter function
};
}
/**
* Vertical indicator configuration
*/
export interface VerticalIndicator {
/** X-axis value where indicator should appear */
x: number;
/** Indicator line color */
color?: string;
/** Indicator line width */
width?: number;
/** Whether line should be dashed */
dashed?: boolean;
/** Optional label for the indicator */
label?: string;
/** Label position: 'top', 'bottom', or custom y offset from top */
labelPosition?: 'top' | 'bottom' | number;
/** Label font size */
fontSize?: number;
}
/**
* Interaction configuration
*/
export interface InteractionConfig {
/** Enable draggable vertical line */
enabled?: boolean;
/** Callback when drag position changes */
onDrag?: (x: number, y: number, index: number) => void;
/** Callback when drag starts */
onDragStart?: (x: number, y: number, index: number) => void;
/** Callback when drag ends */
onDragEnd?: (x: number, y: number, index: number) => void;
/** Callback for tap events */
onTap?: (x: number, y: number, index: number) => void;
/** Style for the drag line */
dragLineStyle?: LineStyle;
}
/**
* Tooltip configuration
*/
export interface TooltipConfig {
/** Show tooltip during interactions */
enabled?: boolean;
/** Tooltip position relative to chart */
position?: 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
/** Custom tooltip renderer */
renderer?: (x: number, y: number, index: number) => ReactNode;
/** Tooltip styling */
style?: TooltipStyle;
}
/**
* Gap detection configuration
*/
export interface GapConfig {
/** Enable gap detection */
enabled?: boolean;
/** Threshold multiplier for detecting gaps */
threshold?: number;
/** Visual style for gaps */
style?: {
color?: string;
width?: number;
dashArray?: string;
};
/** Enable fixed width gaps instead of proportional scaling */
fixedWidthGaps?: boolean;
/** Fixed width in pixels for each gap (when fixedWidthGaps is true) */
fixedWidth?: number;
}
// ============================================================================
// Main Component Props
// ============================================================================
/**
* Main Chart component props
* Single flexible component supporting line and distribution modes
*/
export interface ChartProps {
// Data
/** Chart data with pre-processed x/y arrays */
data: ChartData;
// Dimensions
/** Chart width in pixels */
width: number;
/** Chart height in pixels */
height: number;
/** Inner padding for chart area */
padding?: Padding;
// Styling
/** Container view style */
style?: StyleProp<ViewStyle>;
/** Line appearance configuration */
lineStyle?: LineStyle;
/** Fill configuration for distribution mode */
fillStyle?: FillStyle;
// Features
/** Axis configuration and styling */
axes?: AxisConfig;
/** Vertical indicator lines */
indicators?: VerticalIndicator[];
/** Interactive drag functionality */
interaction?: InteractionConfig;
/** Tooltip configuration */
tooltip?: TooltipConfig;
/** Gap detection for missing data */
gaps?: GapConfig;
// Scaling overrides
/** Override automatic Y-axis range calculation */
yRange?: Range;
// Accessibility
/** Accessibility label for the chart */
accessibilityLabel?: string;
}
// ============================================================================
// Internal Hook Types
// ============================================================================
/**
* Chart dimensions hook return type
*/
export interface UseChartDimensionsReturn {
chartArea: Rectangle;
padding: Required<Padding>;
}
/**
* Data scaling hook return type
*/
export interface UseDataScalingReturn {
scaledData: ScaledPoint[];
xRange: Range;
yRange: Range;
scaleX: (value: number) => number;
scaleY: (value: number) => number;
unscaleX: (coordinate: number) => number;
unscaleY: (coordinate: number) => number;
}
/**
* Gesture handling hook return type
*/
export interface UseGestureHandlingReturn {
dragX: any; // Reanimated SharedValue
dragY: any; // Reanimated SharedValue
isActive: any; // Reanimated SharedValue
gestureHandler: any; // Gesture from react-native-gesture-handler
}
/**
* Interpolation hook return type
*/
export interface UseInterpolationReturn {
interpolateAtX: (xPosition: number) => { x: number; y: number; index: number } | null;
findNearestPoint: (xPosition: number) => ScaledPoint | null;
}
// ============================================================================
// Utility Types
// ============================================================================
/**
* Data gap representation
*/
export interface Gap {
startIndex: number;
endIndex: number;
startX: number;
endX: number;
duration: number;
}
/**
* Binary search result for interpolation
*/
export interface BinarySearchResult {
exact?: number;
lower: number;
upper: number;
}
/**
* Default styling constants
*/
export const DEFAULT_STYLES = {
line: {
color: '#2563eb',
width: 2,
opacity: 1,
smoothing: 'none' as LineSmoothingMethod,
tension: 0.3,
} as LineStyle,
fill: {
color: '#2563eb',
opacity: 0.1,
enabled: false,
} as FillStyle,
axis: {
lineColor: '#e5e7eb',
lineWidth: 1,
labelStyle: {
fontSize: 12,
color: '#6b7280',
},
tickLength: 4,
tickColor: '#e5e7eb',
} as AxisStyle,
tooltip: {
backgroundColor: 'rgba(0, 0, 0, 0.8)',
textColor: '#ffffff',
borderRadius: 4,
fontSize: 12,
padding: 8,
shadowColor: '#000000',
shadowOpacity: 0.25,
shadowRadius: 4,
} as TooltipStyle,
padding: {
top: 20,
right: 20,
bottom: 40,
left: 60,
} as Required<Padding>,
dragLine: {
color: '#ef4444',
width: 1,
opacity: 0.8,
} as LineStyle,
};
/**
* Performance constants
*/
export const PERFORMANCE_CONSTANTS = {
MAX_DATA_POINTS: 50,
TARGET_FPS: 50,
GESTURE_REFRESH_RATE: 16, // 60fps = 16ms per frame
DEFAULT_GAP_THRESHOLD: 2.5, // 2.5x expected interval
} as const;