Skip to Content
Veltix
Best Practices

Best Practices

This guide provides best practices for building efficient, maintainable, and scalable dashboards with Veltix.

Dashboard Design

1. Layout Principles

Visual Hierarchy

  • Place the most important information at the top-left (F-pattern reading)
  • Use consistent spacing and alignment
  • Group related components together
  • Use visual weight to guide attention
// Good layout structure function DashboardLayout() { return ( <div className="dashboard"> {/* Header with title and controls */} <header className="dashboard-header"> <h1>Sales Dashboard</h1> <div className="controls"> <DatePicker /> <ThemeToggle /> </div> </header> {/* Main content area */} <main className="dashboard-content"> {/* KPI row at top */} <section className="kpi-section"> <KPICard title="Total Revenue" value="$1.2M" /> <KPICard title="Growth Rate" value="+12.5%" /> <KPICard title="Active Users" value="45.2K" /> </section> {/* Charts in grid layout */} <section className="charts-grid"> <BarChart data={salesData} /> <LineChart data={trendData} /> <PieChart data={categoryData} /> </section> </main> </div> ); }

Responsive Design

  • Design for multiple screen sizes
  • Use flexible layouts
  • Test on different devices
  • Consider mobile interactions
// Responsive component sizing const responsiveConfig = { mobile: { columns: 1, spacing: 8, fontSize: 14 }, tablet: { columns: 2, spacing: 16, fontSize: 16 }, desktop: { columns: 3, spacing: 24, fontSize: 18 } };

2. Data Visualization

Chart Selection

  • Use bar charts for categorical comparisons
  • Use line charts for time series data
  • Use pie charts for proportions (limit to 5-7 segments)
  • Use scatter plots for correlations
  • Use heatmaps for matrix data
// Appropriate chart selection function ChartSelector({ data, type }) { const getChartComponent = () => { switch (type) { case 'categorical': return <BarChart data={data} />; case 'time-series': return <LineChart data={data} />; case 'proportion': return <PieChart data={data} />; case 'correlation': return <ScatterChart data={data} />; default: return <BarChart data={data} />; } }; return getChartComponent(); }

Color Usage

  • Use semantic colors consistently
  • Ensure sufficient contrast ratios
  • Consider color blindness
  • Limit color palette to 5-7 colors
// Semantic color usage const colorPalette = { primary: '#1890ff', success: '#52c41a', warning: '#faad14', error: '#f5222d', neutral: '#8c8c8c' }; // Color-blind friendly palette const accessibleColors = [ '#1f77b4', // blue '#ff7f0e', // orange '#2ca02c', // green '#d62728', // red '#9467bd', // purple '#8c564b', // brown '#e377c2' // pink ];

3. Performance Optimization

Data Management

  • Implement efficient data structures
  • Use pagination for large datasets
  • Cache frequently accessed data
  • Optimize data transformations
// Efficient data handling function OptimizedDataComponent({ data }) { // Memoize expensive calculations const processedData = useMemo(() => { return data.map(item => ({ ...item, normalizedValue: item.value / Math.max(...data.map(d => d.value)) })); }, [data]); // Use virtual scrolling for large lists const VirtualizedList = memo(({ items }) => ( <VirtualList height={400} itemCount={items.length} itemSize={50} itemData={items} > {({ index, style, data }) => ( <div style={style}> {data[index].name} </div> )} </VirtualList> )); return <VirtualizedList items={processedData} />; }

Component Optimization

  • Use React.memo for expensive components
  • Implement lazy loading
  • Optimize re-render cycles
  • Clean up event listeners
// Optimized component const OptimizedChart = memo(({ data, config }) => { const chartRef = useRef(null); useEffect(() => { const chart = chartRef.current; // Setup chart chart.setOption(config); // Cleanup return () => { chart.dispose(); }; }, [config]); return <div ref={chartRef} style={{ height: 300 }} />; }, (prevProps, nextProps) => { // Custom comparison for memo return ( prevProps.data === nextProps.data && JSON.stringify(prevProps.config) === JSON.stringify(nextProps.config) ); });

Code Organization

1. Project Structure

Monorepo Organization

veltix/ ├── apps/ │ ├── web/ # Main application │ ├── api/ # Backend API │ └── docs/ # Documentation ├── packages/ │ ├── charts/ # Chart components │ ├── ui/ # UI components │ ├── core/ # Core utilities │ └── types/ # TypeScript types └── shared/ ├── constants/ # Shared constants ├── utils/ # Shared utilities └── types/ # Shared types

Component Organization

components/ ├── charts/ # Chart components │ ├── bar/ │ ├── line/ │ └── pie/ ├── ui/ # UI components │ ├── buttons/ │ ├── inputs/ │ └── layout/ └── dashboard/ # Dashboard components ├── header/ ├── sidebar/ └── content/

2. Code Standards

TypeScript Usage

  • Use strict TypeScript configuration
  • Define proper interfaces
  • Avoid any type
  • Use generics for reusable components
// Proper TypeScript usage interface ChartData { id: string; value: number; category: string; timestamp: Date; } interface ChartConfig { type: 'bar' | 'line' | 'pie'; data: ChartData[]; options?: Partial<EChartsOption>; } const ChartComponent: React.FC<ChartConfig> = ({ type, data, options }) => { // Component implementation };

Naming Conventions

  • Use PascalCase for components
  • Use camelCase for functions and variables
  • Use kebab-case for CSS classes
  • Use UPPER_CASE for constants
// Good naming conventions const CHART_TYPES = { BAR: 'bar', LINE: 'line', PIE: 'pie' } as const; const useChartData = (dataSource: string) => { // Hook implementation }; const ChartComponent: React.FC<ChartProps> = ({ data, config }) => { // Component implementation };

3. State Management

Local State

  • Use useState for simple state
  • Use useReducer for complex state
  • Keep state as close to usage as possible
  • Avoid prop drilling
// Good state management function Dashboard() { const [components, setComponents] = useState<Component[]>([]); const [selectedComponent, setSelectedComponent] = useState<string | null>(null); const addComponent = useCallback((component: Component) => { setComponents(prev => [...prev, component]); }, []); const updateComponent = useCallback((id: string, updates: Partial<Component>) => { setComponents(prev => prev.map(comp => comp.id === id ? { ...comp, ...updates } : comp ) ); }, []); return ( <DashboardContext.Provider value={{ components, selectedComponent, addComponent, updateComponent }}> <DashboardContent /> </DashboardContext.Provider> ); }

Global State

  • Use Context for theme-wide state
  • Use Zustand for complex state
  • Keep state normalized
  • Implement proper state persistence
// Global state with Zustand interface DashboardStore { components: Component[]; selectedComponent: string | null; theme: Theme; addComponent: (component: Component) => void; updateComponent: (id: string, updates: Partial<Component>) => void; setTheme: (theme: Theme) => void; } const useDashboardStore = create<DashboardStore>((set) => ({ components: [], selectedComponent: null, theme: 'light', addComponent: (component) => set((state) => ({ components: [...state.components, component] })), updateComponent: (id, updates) => set((state) => ({ components: state.components.map(comp => comp.id === id ? { ...comp, ...updates } : comp ) })), setTheme: (theme) => set({ theme }) }));

Security Best Practices

1. Data Security

Input Validation

  • Validate all user inputs
  • Sanitize data before rendering
  • Use TypeScript for type safety
  • Implement proper error handling
// Input validation const validateComponentConfig = (config: unknown): ComponentConfig => { const schema = z.object({ id: z.string(), type: z.enum(['chart', 'table', 'text']), position: z.object({ x: z.number(), y: z.number() }), size: z.object({ width: z.number().positive(), height: z.number().positive() }) }); return schema.parse(config); };

Data Sanitization

  • Sanitize HTML content
  • Escape special characters
  • Validate URLs and file paths
  • Use Content Security Policy
// Data sanitization import DOMPurify from 'dompurify'; const sanitizeContent = (content: string): string => { return DOMPurify.sanitize(content, { ALLOWED_TAGS: ['b', 'i', 'em', 'strong', 'a'], ALLOWED_ATTR: ['href', 'target'] }); }; const SafeTextComponent: React.FC<{ content: string }> = ({ content }) => { const sanitizedContent = useMemo(() => sanitizeContent(content), [content]); return <div dangerouslySetInnerHTML={{ __html: sanitizedContent }} />; };

2. API Security

Authentication

  • Implement proper authentication
  • Use JWT tokens
  • Validate API keys
  • Implement rate limiting
// API authentication const apiClient = axios.create({ baseURL: process.env.REACT_APP_API_URL, headers: { 'Authorization': `Bearer ${getToken()}`, 'Content-Type': 'application/json' } }); // Request interceptor apiClient.interceptors.request.use((config) => { const token = getToken(); if (token) { config.headers.Authorization = `Bearer ${token}`; } return config; }); // Response interceptor apiClient.interceptors.response.use( (response) => response, (error) => { if (error.response?.status === 401) { // Handle unauthorized access logout(); } return Promise.reject(error); } );

Data Encryption

  • Use HTTPS for all communications
  • Encrypt sensitive data
  • Implement proper key management
  • Use secure storage for tokens
// Data encryption utilities import CryptoJS from 'crypto-js'; const encryptData = (data: string, key: string): string => { return CryptoJS.AES.encrypt(data, key).toString(); }; const decryptData = (encryptedData: string, key: string): string => { const bytes = CryptoJS.AES.decrypt(encryptedData, key); return bytes.toString(CryptoJS.enc.Utf8); }; // Secure storage const secureStorage = { set: (key: string, value: string) => { const encrypted = encryptData(value, process.env.REACT_APP_ENCRYPTION_KEY!); localStorage.setItem(key, encrypted); }, get: (key: string): string | null => { const encrypted = localStorage.getItem(key); if (!encrypted) return null; return decryptData(encrypted, process.env.REACT_APP_ENCRYPTION_KEY!); } };

Testing Best Practices

1. Unit Testing

Component Testing

  • Test component rendering
  • Test user interactions
  • Test prop changes
  • Test error states
// Component testing import { render, screen, fireEvent } from '@testing-library/react'; describe('ChartComponent', () => { it('renders chart with data', () => { const data = [{ category: 'A', value: 100 }]; render(<BarChart data={data} />); expect(screen.getByRole('img')).toBeInTheDocument(); }); it('handles click events', () => { const onClick = jest.fn(); const data = [{ category: 'A', value: 100 }]; render(<BarChart data={data} onClick={onClick} />); fireEvent.click(screen.getByRole('img')); expect(onClick).toHaveBeenCalled(); }); it('shows loading state', () => { render(<BarChart data={[]} loading={true} />); expect(screen.getByText('Loading...')).toBeInTheDocument(); }); });

Hook Testing

  • Test hook logic
  • Test state changes
  • Test side effects
  • Test error handling
// Hook testing import { renderHook, act } from '@testing-library/react-hooks'; describe('useDataSource', () => { it('loads data successfully', async () => { const { result } = renderHook(() => useDataSource('test-data')); expect(result.current.loading).toBe(true); await act(async () => { await result.current.refresh(); }); expect(result.current.loading).toBe(false); expect(result.current.data).toBeDefined(); }); it('handles errors', async () => { const { result } = renderHook(() => useDataSource('invalid-data')); await act(async () => { await result.current.refresh(); }); expect(result.current.error).toBeDefined(); }); });

2. Integration Testing

Dashboard Testing

  • Test complete workflows
  • Test data flow
  • Test component interactions
  • Test theme switching
// Integration testing describe('Dashboard Integration', () => { it('creates and saves dashboard', async () => { render(<Dashboard />); // Add component fireEvent.click(screen.getByText('Add Chart')); fireEvent.click(screen.getByText('Bar Chart')); // Configure component fireEvent.change(screen.getByLabelText('Title'), { target: { value: 'Sales Chart' } }); // Save dashboard fireEvent.click(screen.getByText('Save')); expect(screen.getByText('Dashboard saved')).toBeInTheDocument(); }); it('switches themes', () => { render(<Dashboard />); const themeToggle = screen.getByRole('button', { name: /theme/i }); fireEvent.click(themeToggle); expect(document.documentElement).toHaveAttribute('data-theme', 'dark'); }); });

Performance Monitoring

1. Metrics Collection

Performance Metrics

  • Monitor render times
  • Track memory usage
  • Measure API response times
  • Monitor user interactions
// Performance monitoring import { usePerformanceMonitor } from '@veltix/ui'; function DashboardWithMonitoring() { const { metrics, alerts } = usePerformanceMonitor({ fps: true, memory: true, network: true, renderTime: true }); useEffect(() => { // Log performance metrics if (metrics.fps < 30) { console.warn('Low FPS detected:', metrics.fps); } if (metrics.memory > 100 * 1024 * 1024) { // 100MB console.warn('High memory usage:', metrics.memory); } }, [metrics]); return <Dashboard />; }

Error Tracking

  • Implement error boundaries
  • Log errors to monitoring service
  • Track user actions leading to errors
  • Monitor API failures
// Error tracking import * as Sentry from '@sentry/react'; Sentry.init({ dsn: process.env.REACT_APP_SENTRY_DSN, environment: process.env.NODE_ENV, integrations: [ new Sentry.BrowserTracing(), new Sentry.Replay() ] }); function ErrorBoundary({ children }) { return ( <Sentry.ErrorBoundary fallback={<div>Something went wrong</div>} onError={(error, errorInfo) => { console.error('Dashboard error:', error, errorInfo); Sentry.captureException(error, { extra: errorInfo }); }} > {children} </Sentry.ErrorBoundary> ); }

2. User Analytics

Usage Tracking

  • Track component usage
  • Monitor user interactions
  • Analyze performance patterns
  • Identify popular features
// Analytics tracking import { useAnalytics } from '@veltix/ui'; function DashboardWithAnalytics() { const { track } = useAnalytics(); const handleComponentAdd = (component) => { track('component_added', { component_type: component.type, dashboard_id: dashboard.id }); }; const handleThemeChange = (theme) => { track('theme_changed', { theme: theme, user_id: user.id }); }; return ( <Dashboard onComponentAdd={handleComponentAdd} onThemeChange={handleThemeChange} /> ); }

Documentation Best Practices

1. Code Documentation

Component Documentation

  • Document component props
  • Provide usage examples
  • Explain complex logic
  • Include TypeScript types
/** * BarChart component for displaying categorical data * * @example * ```tsx * <BarChart * data={[{ category: 'A', value: 100 }]} * xField="category" * yField="value" * height={300} * /> * ``` */ interface BarChartProps { /** Chart data array */ data: ChartData[]; /** Field name for x-axis */ xField: string; /** Field name for y-axis */ yField: string; /** Chart height in pixels */ height?: number; /** Chart color */ color?: string; /** Enable animations */ animation?: boolean; } const BarChart: React.FC<BarChartProps> = ({ data, xField, yField, height = 300, color = '#1890ff', animation = true }) => { // Component implementation };

API Documentation

  • Document all public APIs
  • Provide code examples
  • Include error scenarios
  • Explain return types
/** * Hook for managing dashboard state * * @returns Dashboard state and actions * * @example * ```tsx * const { dashboard, addComponent, saveDashboard } = useDashboard(); * * addComponent({ * type: 'chart', * position: { x: 0, y: 0 }, * size: { width: 300, height: 200 } * }); * ``` */ export const useDashboard = () => { // Hook implementation };

2. User Documentation

Getting Started

  • Provide quick start guide
  • Include common use cases
  • Show best practices
  • Include troubleshooting

API Reference

  • Complete API documentation
  • Interactive examples
  • Type definitions
  • Migration guides

Tutorials

  • Step-by-step guides
  • Video tutorials
  • Sample projects
  • Community examples

Deployment Best Practices

1. Build Optimization

Bundle Optimization

  • Enable tree shaking
  • Use code splitting
  • Optimize images
  • Minimize bundle size
// Webpack optimization module.exports = { optimization: { splitChunks: { chunks: 'all', cacheGroups: { vendor: { test: /[\\/]node_modules[\\/]/, name: 'vendors', chunks: 'all' }, charts: { test: /[\\/]packages[\\/]charts[\\/]/, name: 'charts', chunks: 'all' } } } } };

Environment Configuration

  • Use environment variables
  • Configure different environments
  • Implement feature flags
  • Set up monitoring
// Environment configuration const config = { api: { url: process.env.REACT_APP_API_URL, timeout: parseInt(process.env.REACT_APP_API_TIMEOUT || '5000') }, features: { realTimeUpdates: process.env.REACT_APP_REAL_TIME === 'true', advancedCharts: process.env.REACT_APP_ADVANCED_CHARTS === 'true' }, monitoring: { enabled: process.env.NODE_ENV === 'production', dsn: process.env.REACT_APP_SENTRY_DSN } };

2. CI/CD Pipeline

Automated Testing

  • Run tests on every commit
  • Check code coverage
  • Validate TypeScript types
  • Test build process
# GitHub Actions workflow name: CI/CD on: [push, pull_request] jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - uses: actions/setup-node@v2 with: node-version: '18' - run: pnpm install - run: pnpm test - run: pnpm type-check - run: pnpm build

Deployment Strategy

  • Use blue-green deployment
  • Implement rollback strategy
  • Monitor deployment health
  • Set up staging environment
// Health check component const HealthCheck: React.FC = () => { const [health, setHealth] = useState('checking'); useEffect(() => { fetch('/api/health') .then(response => response.json()) .then(data => setHealth(data.status)) .catch(() => setHealth('error')); }, []); if (health === 'error') { return <div>Service unavailable</div>; } return null; };

Conclusion

Following these best practices will help you build robust, maintainable, and scalable dashboards with Veltix. Remember to:

  1. Start Simple: Begin with basic functionality and iterate
  2. Test Early: Write tests as you develop features
  3. Monitor Performance: Keep an eye on performance metrics
  4. Document Everything: Maintain comprehensive documentation
  5. Stay Updated: Keep dependencies and practices current
  6. Get Feedback: Gather user feedback and iterate
  7. Plan for Scale: Design with future growth in mind
  8. Security First: Implement security measures from the start

By following these guidelines, you’ll create dashboards that are not only functional but also maintainable, performant, and user-friendly.

Last updated on