# React Flex Charts

A highly customizable and flexible React bar chart library built with **pure SVG** - no external charting dependencies! Create beautiful, responsive bar charts with minimal code and maximum customization options.

![npm version](https://img.shields.io/npm/v/react-flex-charts)
![license](https://img.shields.io/npm/l/react-flex-charts)

## Features

✨ **Pure SVG** - No external charting library dependencies  
📊 **6 Chart Types** - Vertical, Horizontal, Stacked, Stacked with Groups, and Floating bar charts  
🎨 **10 Built-in Themes** - Beautiful preset themes or create your own  
🔧 **Highly Customizable** - Every aspect of the chart can be customized  
📱 **Responsive** - Charts automatically adapt to all screen sizes including mobile  
🎯 **TypeScript Support** - Full TypeScript support with comprehensive types  
⚡ **Lightweight** - Only React as a peer dependency  
🎭 **Border Radius** - Support for rounded corners on bars  
🖱️ **Interactive** - Click and hover event handlers with cursor-following tooltips  
♿ **WCAG Accessible** - AAA contrast ratios, ARIA labels, keyboard navigation  
🎬 **Animations** - Smooth CSS-based animations  
🔤 **Unisys Font Family** - Professional typography with accessible fallbacks  

## Installation

```bash
npm install react-flex-charts
```

or

```bash
yarn add react-flex-charts
```

**Note:** This library has no external charting dependencies. Only React is required as a peer dependency.

## Quick Start

```tsx
import { BarChart } from 'react-flex-charts';

function App() {
  return (
    <BarChart
      labels={['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun']}
      datasets={[
        {
          label: 'Sales',
          data: [400, 300, 600, 800, 500, 700],
        }
      ]}
      theme="vibrant"
      borderRadius={8}
    />
  );
}
```

## Chart Types

### 1. Bar Chart (Vertical/Horizontal)

The base bar chart component that supports both vertical and horizontal orientations.

```tsx
import { BarChart } from 'react-flex-charts';

// Vertical Bar Chart
<BarChart
  labels={['Jan', 'Feb', 'Mar']}
  datasets={[
    { label: 'Revenue', data: [100, 200, 150] },
    { label: 'Expenses', data: [80, 120, 90] }
  ]}
  orientation="vertical"
  borderRadius={4}
/>

// Horizontal Bar Chart
<BarChart
  labels={['Product A', 'Product B', 'Product C']}
  datasets={[
    { label: 'Sales', data: [150, 200, 180] }
  ]}
  orientation="horizontal"
/>
```

### 2. Vertical Bar Chart

A dedicated component for vertical bar charts.

```tsx
import { VerticalBarChart } from 'react-flex-charts';

<VerticalBarChart
  labels={['Q1', 'Q2', 'Q3', 'Q4']}
  datasets={[
    { label: 'Revenue', data: [30000, 45000, 42000, 55000] },
    { label: 'Expenses', data: [20000, 25000, 23000, 28000] }
  ]}
  title="Quarterly Performance"
  borderRadius={6}
  theme="corporate"
/>
```

### 3. Horizontal Bar Chart

Optimized for comparing values across categories, especially with long category names.

```tsx
import { HorizontalBarChart } from 'react-flex-charts';

<HorizontalBarChart
  labels={['United States', 'United Kingdom', 'Germany', 'France', 'Japan']}
  datasets={[
    { label: 'Population (M)', data: [331, 67, 83, 67, 126] }
  ]}
  theme="ocean"
/>
```

### 4. Stacked Bar Chart

Shows composition of data with all datasets stacked on top of each other.

```tsx
import { StackedBarChart } from 'react-flex-charts';

<StackedBarChart
  labels={['2020', '2021', '2022', '2023']}
  datasets={[
    { label: 'Product A', data: [100, 150, 200, 250] },
    { label: 'Product B', data: [80, 120, 160, 200] },
    { label: 'Product C', data: [60, 90, 140, 180] }
  ]}
  title="Sales by Product"
  theme="vibrant"
/>
```

### 5. Stacked Bar Chart with Groups

Multiple stack groups side by side for comparing stacked series.

```tsx
import { StackedBarChartWithGroups } from 'react-flex-charts';

<StackedBarChartWithGroups
  labels={['Q1', 'Q2', 'Q3', 'Q4']}
  datasets={[
    { label: '2022 Online', data: [50, 60, 70, 80], stack: 'Stack 0' },
    { label: '2022 Store', data: [30, 40, 35, 45], stack: 'Stack 0' },
    { label: '2023 Online', data: [60, 75, 85, 95], stack: 'Stack 1' },
    { label: '2023 Store', data: [35, 45, 40, 50], stack: 'Stack 1' }
  ]}
  title="Year-over-Year Comparison"
/>
```

### 6. Floating Bar Chart

Bars that don't start from zero - specify a range `[start, end]` for each bar.

```tsx
import { FloatingBarChart } from 'react-flex-charts';

// Working hours example
<FloatingBarChart
  labels={['Mon', 'Tue', 'Wed', 'Thu', 'Fri']}
  datasets={[
    { 
      label: 'Working Hours', 
      data: [[9, 17], [8, 16], [10, 18], [9, 17], [8, 15]] 
    }
  ]}
  title="Weekly Schedule"
/>

// Temperature range
<FloatingBarChart
  labels={['Jan', 'Feb', 'Mar', 'Apr', 'May']}
  datasets={[
    { 
      label: 'Temperature °C', 
      data: [[-5, 10], [-3, 12], [2, 18], [8, 22], [12, 28]] 
    }
  ]}
  title="Monthly Temperature Range"
  theme="sunset"
/>
```

## Customization

### Themes

Choose from 10 built-in themes:

```tsx
// Available themes
type PresetTheme = 
  | 'default'    // Classic blue palette
  | 'vibrant'    // Bold, energetic colors
  | 'pastel'     // Soft, muted tones
  | 'monochrome' // Grayscale
  | 'dark'       // Dark mode optimized
  | 'ocean'      // Blue/teal palette
  | 'sunset'     // Warm oranges and yellows
  | 'forest'     // Green palette
  | 'candy'      // Pink and purple
  | 'corporate'; // Professional blue

<BarChart
  labels={['A', 'B', 'C']}
  datasets={[{ label: 'Data', data: [10, 20, 30] }]}
  theme="vibrant"
/>
```

### Custom Theme

Create your own theme:

```tsx
<BarChart
  labels={['A', 'B', 'C']}
  datasets={[{ label: 'Data', data: [10, 20, 30] }]}
  themeConfig={{
    colors: ['#FF6B6B', '#4ECDC4', '#45B7D1'],
    fontFamily: "'Poppins', sans-serif",
    fontSize: 14,
    gridColor: 'rgba(0, 0, 0, 0.05)',
    textColor: '#333333',
    backgroundColor: '#ffffff',
    borderRadius: 8,
    tooltipBackground: '#2D3436',
    tooltipTextColor: '#ffffff',
  }}
/>
```

### Dataset Colors

Customize colors per dataset or per bar:

```tsx
<BarChart
  labels={['Jan', 'Feb', 'Mar']}
  datasets={[
    {
      label: 'Revenue',
      data: [100, 150, 200],
      backgroundColor: '#4CAF50',
      borderColor: '#388E3C',
      borderWidth: 2,
      hoverBackgroundColor: '#66BB6A',
    },
    {
      label: 'Expenses',
      data: [80, 90, 110],
      backgroundColor: 'rgba(244, 67, 54, 0.7)',
    }
  ]}
/>

// Different color for each bar
<BarChart
  labels={['USA', 'China', 'Germany']}
  datasets={[
    {
      label: 'GDP',
      data: [25, 18, 4],
      backgroundColor: ['#3366CC', '#DC3912', '#FF9900'],
    }
  ]}
/>
```

### Border Radius

Apply rounded corners to bars:

```tsx
// Global border radius for all bars
<BarChart
  labels={['A', 'B', 'C']}
  datasets={[{ label: 'Data', data: [10, 20, 30] }]}
  borderRadius={8}
/>

// Per-dataset border radius
<BarChart
  labels={['A', 'B', 'C']}
  datasets={[
    { label: 'Set 1', data: [10, 20, 30], borderRadius: 4 },
    { label: 'Set 2', data: [15, 25, 35], borderRadius: 12 }
  ]}
/>

// Individual corner radius
<BarChart
  labels={['A', 'B', 'C']}
  datasets={[
    {
      label: 'Data',
      data: [10, 20, 30],
      borderRadius: {
        topLeft: 10,
        topRight: 10,
        bottomLeft: 0,
        bottomRight: 0,
      }
    }
  ]}
/>
```

### Axes Configuration

```tsx
<BarChart
  labels={['Jan', 'Feb', 'Mar']}
  datasets={[{ label: 'Sales', data: [1000, 2000, 1500] }]}
  xAxis={{
    display: true,
    title: {
      display: true,
      text: 'Month',
      color: '#666',
      fontSize: 14,
    },
    grid: {
      display: false,
    },
    ticks: {
      color: '#888',
      fontSize: 11,
    }
  }}
  yAxis={{
    display: true,
    title: {
      display: true,
      text: 'Revenue ($)',
    },
    beginAtZero: true,
    min: 0,
    max: 3000,
    ticks: {
      stepSize: 500,
      callback: (value) => `$${value}`,
    }
  }}
/>
```

### Legend Configuration

```tsx
<BarChart
  labels={['A', 'B', 'C']}
  datasets={[
    { label: 'Series 1', data: [10, 20, 30] },
    { label: 'Series 2', data: [15, 25, 35] }
  ]}
  legend={{
    display: true,
    position: 'bottom', // 'top' | 'left' | 'right' | 'bottom'
    align: 'center',    // 'start' | 'center' | 'end'
    labels: {
      color: '#333',
      fontSize: 12,
      padding: 20,
      boxWidth: 12,
      boxHeight: 12,
    },
    onClick: (index, dataset) => {
      console.log('Clicked legend item:', dataset.label);
    }
  }}
/>
```

### Tooltip Configuration

```tsx
<BarChart
  labels={['A', 'B', 'C']}
  datasets={[{ label: 'Data', data: [10, 20, 30] }]}
  tooltip={{
    enabled: true,
    backgroundColor: 'rgba(0, 0, 0, 0.8)',
    textColor: '#fff',
    fontSize: 12,
    cornerRadius: 8,
    padding: 12,
    formatter: (value, datasetLabel, label) => {
      return `${label}: $${value.toLocaleString()}`;
    }
  }}
/>
```

### Animation Configuration

```tsx
<BarChart
  labels={['A', 'B', 'C']}
  datasets={[{ label: 'Data', data: [10, 20, 30] }]}
  animation={{
    enabled: true,
    duration: 500,
    easing: 'ease-out',
    delay: 0,
    staggerDelay: 50, // Delay between each bar animation
  }}
/>

// Disable animation
<BarChart
  labels={['A', 'B', 'C']}
  datasets={[{ label: 'Data', data: [10, 20, 30] }]}
  animation={false}
/>
```

### Event Handlers

```tsx
<BarChart
  labels={['A', 'B', 'C']}
  datasets={[{ label: 'Data', data: [10, 20, 30] }]}
  onBarClick={(event, data) => {
    console.log('Clicked bar:', data);
    // { datasetIndex, dataIndex, value, label, datasetLabel }
  }}
  onBarHover={(event, data) => {
    if (data) {
      console.log('Hovering:', data.label, data.value);
    }
  }}
/>
```

### Sizing

```tsx
// Fixed size
<BarChart
  labels={['A', 'B', 'C']}
  datasets={[{ label: 'Data', data: [10, 20, 30] }]}
  width={600}
  height={400}
/>

// Responsive width with fixed height
<BarChart
  labels={['A', 'B', 'C']}
  datasets={[{ label: 'Data', data: [10, 20, 30] }]}
  width="100%"
  height={300}
/>

// Custom padding
<BarChart
  labels={['A', 'B', 'C']}
  datasets={[{ label: 'Data', data: [10, 20, 30] }]}
  padding={{ top: 40, right: 30, bottom: 50, left: 60 }}
/>
```

### Bar Spacing

```tsx
<BarChart
  labels={['A', 'B', 'C']}
  datasets={[
    { label: 'Set 1', data: [10, 20, 30] },
    { label: 'Set 2', data: [15, 25, 35] }
  ]}
  barGap={4}      // Gap between bars in a group (pixels)
  groupGap={0.3}  // Gap between groups (percentage of category width)
/>
```

## TypeScript

Full TypeScript support is included:

```tsx
import type {
  BarChartProps,
  DatasetConfig,
  ThemeConfig,
  AxisConfig,
  LegendConfig,
  TooltipConfig,
  AnimationConfig,
  PresetTheme,
  BarClickData,
} from 'react-flex-charts';

const myDataset: DatasetConfig = {
  label: 'My Data',
  data: [10, 20, 30],
  backgroundColor: '#4CAF50',
};

const myTheme: ThemeConfig = {
  colors: ['#FF6B6B', '#4ECDC4'],
  borderRadius: 8,
};

const handleClick = (event: React.MouseEvent, data: BarClickData) => {
  console.log(data.value);
};
```

## Utility Functions

The library exports utility functions for advanced use cases:

```tsx
import {
  // Color utilities
  getColorPalette,
  getTheme,
  withOpacity,
  lighten,
  darken,
  generateGradient,
  getContrastColor,
  
  // Scale utilities
  calculateScale,
  valueToPosition,
  formatValue,
  
  // SVG utilities
  roundedRectPath,
  topRoundedRadius,
  bottomRoundedRadius,
} from 'react-flex-charts';

// Example: Get a color palette
const colors = getColorPalette('vibrant');

// Example: Create gradient colors
const gradient = generateGradient('#FF6B6B', '#4ECDC4', 5);

// Example: Adjust opacity
const semiTransparent = withOpacity('#FF6B6B', 0.5);
```

## Core Components

For advanced customization, you can use the core SVG components directly:

```tsx
import {
  ChartContainer,
  Axis,
  Bar,
  Legend,
  Tooltip,
  Title,
} from 'react-flex-charts';

// Build your own custom chart using these primitives
```

## Accessibility

All charts are designed to meet **WCAG AAA** standards:

### Features
- **WCAG AAA Contrast Ratios** - All text colors have 7:1+ contrast ratio
- **ARIA Labels** - Descriptive labels for screen readers on all interactive elements
- **Role Attributes** - Semantic meaning for charts, bars, axes, and legends
- **Keyboard Navigation** - Legend items are focusable and interactive
- **Screen Reader Support** - Full descriptive text for data values
- **Reduced Motion** - Respects `prefers-reduced-motion` preference
- **High Contrast Mode** - Adapts to system high contrast settings

```tsx
<BarChart
  labels={['A', 'B', 'C']}
  datasets={[{ label: 'Data', data: [10, 20, 30] }]}
  ariaLabel="Sales data for Q1 2024 showing growth across three categories"
  id="sales-chart"
/>
```

## Typography

The library uses **Unisys font family** with accessible fallbacks:

```tsx
import { UNISYS_FONT_FAMILY, defaultFontFamily } from 'react-flex-charts';

// Font stack: 'Unisys', 'Segoe UI', 'Helvetica Neue', 'Arial', sans-serif
console.log(UNISYS_FONT_FAMILY);

// Use in custom theme
const customTheme = {
  fontFamily: UNISYS_FONT_FAMILY,
  textColor: '#1f2937', // WCAG AAA compliant
};
```

## Browser Support

- Chrome (latest)
- Firefox (latest)
- Safari (latest)
- Edge (latest)

## Why Pure SVG?

This library uses pure SVG instead of Canvas-based solutions:

- **No external dependencies** - Only React is required
- **Better accessibility** - SVG elements are part of the DOM
- **CSS animations** - Smooth, performant animations using CSS
- **Easier customization** - Style bars with CSS or inline styles
- **Better for SSR** - Works out of the box with server-side rendering
- **Smaller bundle size** - No charting library overhead

## License

MIT © Your Name

## Contributing

Contributions are welcome! Please read our contributing guidelines before submitting a PR.

## Changelog

### 1.0.0
- Initial release
- 6 chart types: Bar, Vertical, Horizontal, Stacked, Stacked with Groups, Floating
- Pure SVG implementation - no external charting dependencies
- 10 preset themes
- Full TypeScript support
- Comprehensive customization options
- Interactive tooltips and legends
- Responsive design
