npm package: @spteck/fluentui-react-charts
Description: A comprehensive collection of interactive chart components built with Chart.js and Fluent UI React. This library provides a complete set of data visualization components that seamlessly integrate with Microsoft's Fluent UI design system.
Author: João Mendes
Latest version: 1.1.13

# Fluent UI React Charts

A comprehensive collection of interactive chart components built with Chart.js and Fluent UI React. This library provides a complete set of data visualization components that seamlessly integrate with Microsoft's Fluent UI design system.

## 🚀 Features

- **Complete Chart Collection**: 13+ chart types including Bar, Line, Pie, Area, and more
- **Fluent UI Integration**: Native support for Fluent UI themes and design tokens
- **TypeScript Support**: Full TypeScript support with generic types for type-safe data handling
- **Interactive Components**: Built-in legends, tooltips, and data interaction capabilities
- **Responsive Design**: Charts automatically adapt to container dimensions
- **Performance Optimized**: Efficient rendering and updates for large datasets
- **Accessibility**: ARIA compliance and keyboard navigation support

## 📦 Installation

```bash
npm install @spteck/fluentui-react-charts
```

## 🎯 Quick Start

```tsx
import React from 'react';
import { BarChart } from '@spteck/fluentui-react-charts';
import { webLightTheme } from '@fluentui/react-components';

const data = [
  { month: 'Jan', sales: 10000 },
  { month: 'Feb', sales: 15000 },
  { month: 'Mar', sales: 12000 },
  { month: 'Apr', sales: 18000 },
  { month: 'May', sales: 16000 },
  { month: 'Jun', sales: 22000 },
];

function App() {
  return (
    <div style={{ width: '800px', height: '400px' }}>
      <BarChart
        data={[{ label: 'Monthly Sales', data }]}
        getPrimary={(d) => d.month}
        getSecondary={(d) => d.sales}
        title="Sales Performance"
        theme={webLightTheme}
      />
    </div>
  );
}
```

## 📊 Available Charts

### Bar Charts

#### BarChart

Perfect for comparing categories of data with vertical bars.

```tsx
import { BarChart } from '@spteck/fluentui-react-charts';

const salesData = [
  { category: 'Electronics', value: 125000 },
  { category: 'Clothing', value: 89000 },
  { category: 'Books', value: 45000 },
  { category: 'Home & Garden', value: 67000 },
  { category: 'Sports', value: 78000 },
];

<BarChart
  data={[{ label: 'Sales', data: salesData }]}
  getPrimary={(d) => d.category}
  getSecondary={(d) => d.value}
  title="Sales by Category"
  theme={webLightTheme}
/>
```

#### BarHorizontalChart

Horizontal orientation for better label readability with long category names.

```tsx
import { BarHorizontalChart } from '@spteck/fluentui-react-charts';

const revenueData = [
  { department: 'Engineering & Development', revenue: 450000 },
  { department: 'Sales & Marketing', revenue: 380000 },
  { department: 'Customer Support', revenue: 180000 },
  { department: 'Human Resources', revenue: 120000 },
  { department: 'Operations', revenue: 250000 },
];

<BarHorizontalChart
  data={[{ label: 'Revenue', data: revenueData }]}
  getPrimary={(d) => d.department}
  getSecondary={(d) => d.revenue}
  title="Revenue by Department"
  theme={webLightTheme}
/>
```

#### FloatingBarChart

Displays ranges with floating bars showing min-max values.

```tsx
import { FloatingBarChart } from '@spteck/fluentui-react-charts';

const tempData = [
  { month: 'January', minTemp: 25, maxTemp: 45 },
  { month: 'February', minTemp: 30, maxTemp: 50 },
  { month: 'March', minTemp: 40, maxTemp: 65 },
  { month: 'April', minTemp: 50, maxTemp: 75 },
  { month: 'May', minTemp: 60, maxTemp: 85 },
  { month: 'June', minTemp: 70, maxTemp: 95 },
];

<FloatingBarChart
  data={[{ label: 'Temperature Range', data: tempData }]}
  getPrimary={(d) => d.month}
  getRange={(d) => [d.minTemp, d.maxTemp]}
  title="Monthly Temperature Range"
  theme={webLightTheme}
/>
```

### Line Charts

#### LineChart

Ideal for showing trends and changes over time.

```tsx
import { LineChart } from '@spteck/fluentui-react-charts';

const growthData = [
  { quarter: 'Q1 2023', growth: 12.5 },
  { quarter: 'Q2 2023', growth: 15.8 },
  { quarter: 'Q3 2023', growth: 18.2 },
  { quarter: 'Q4 2023', growth: 22.1 },
  { quarter: 'Q1 2024', growth: 25.7 },
  { quarter: 'Q2 2024', growth: 28.3 },
];

<LineChart
  data={[{ label: 'Growth', data: growthData }]}
  getPrimary={(d) => d.quarter}
  getSecondary={(d) => d.growth}
  title="Quarterly Growth"
  theme={webLightTheme}
/>
```

#### StackedLineChart

Multiple line series with stacking capability for cumulative data.

```tsx
import { StackedLineChart } from '@spteck/fluentui-react-charts';

const productAData = [
  { month: 'Jan', sales: 25000 },
  { month: 'Feb', sales: 28000 },
  { month: 'Mar', sales: 32000 },
  { month: 'Apr', sales: 35000 },
  { month: 'May', sales: 38000 },
  { month: 'Jun', sales: 42000 },
];

const productBData = [
  { month: 'Jan', sales: 18000 },
  { month: 'Feb', sales: 22000 },
  { month: 'Mar', sales: 26000 },
  { month: 'Apr', sales: 24000 },
  { month: 'May', sales: 28000 },
  { month: 'Jun', sales: 31000 },
];

<StackedLineChart
  data={[
    { label: 'Product A', data: productAData },
    { label: 'Product B', data: productBData }
  ]}
  getPrimary={(d) => d.month}
  getSecondary={(d) => d.sales}
  title="Product Sales Comparison"
  theme={webLightTheme}
/>
```

### Area Charts

#### AreaChart

Shows trends with filled areas, perfect for volume data.

```tsx
import { AreaChart } from '@spteck/fluentui-react-charts';

const trafficData = [
  { hour: '00:00', visitors: 120 },
  { hour: '04:00', visitors: 85 },
  { hour: '08:00', visitors: 450 },
  { hour: '12:00', visitors: 680 },
  { hour: '16:00', visitors: 520 },
  { hour: '20:00', visitors: 340 },
];

<AreaChart
  data={[{ label: 'Traffic', data: trafficData }]}
  getPrimary={(d) => d.hour}
  getSecondary={(d) => d.visitors}
  title="Website Traffic"
  theme={webLightTheme}
/>
```

### Circular Charts

#### PieChart

Classic pie chart for showing proportional data.

```tsx
import { PieChart } from '@spteck/fluentui-react-charts';

const marketData = [
  { company: 'Company A', share: 35.2 },
  { company: 'Company B', share: 28.7 },
  { company: 'Company C', share: 18.5 },
  { company: 'Company D', share: 12.1 },
  { company: 'Others', share: 5.5 },
];

<PieChart
  data={[{ label: 'Market Share', data: marketData }]}
  getLabel={(d) => d.company}
  getValue={(d) => d.share}
  title="Market Share Distribution"
  theme={webLightTheme}
/>
```

#### DoughnutChart

Doughnut variation with center space for additional information.

```tsx
import { DoughnutChart } from '@spteck/fluentui-react-charts';

const expenseData = [
  { category: 'Personnel', amount: 450000 },
  { category: 'Infrastructure', amount: 180000 },
  { category: 'Marketing', amount: 120000 },
  { category: 'Operations', amount: 95000 },
  { category: 'Research', amount: 85000 },
];

<DoughnutChart
  data={[{ label: 'Expenses', data: expenseData }]}
  getLabel={(d) => d.category}
  getValue={(d) => d.amount}
  title="Expense Breakdown"
  theme={webLightTheme}
/>
```

### Specialized Charts

#### ComboChart

Combines multiple chart types (bar + line) in a single visualization.

```tsx
import { ComboChart } from '@spteck/fluentui-react-charts';

const salesData = [
  { month: 'Jan', value: 45000 },
  { month: 'Feb', value: 52000 },
  { month: 'Mar', value: 48000 },
  { month: 'Apr', value: 61000 },
  { month: 'May', value: 58000 },
  { month: 'Jun', value: 67000 },
];

const targetData = [
  { month: 'Jan', value: 50000 },
  { month: 'Feb', value: 55000 },
  { month: 'Mar', value: 53000 },
  { month: 'Apr', value: 58000 },
  { month: 'May', value: 60000 },
  { month: 'Jun', value: 65000 },
];

<ComboChart
  data={[
    { label: 'Sales', data: salesData, type: 'bar' },
    { label: 'Target', data: targetData, type: 'line' }
  ]}
  getPrimary={(d) => d.month}
  getSecondary={(d) => d.value}
  title="Sales vs Target"
  theme={webLightTheme}
/>
```

#### BubbleChart

Three-dimensional data visualization with x, y, and size dimensions.

```tsx
import { BubbleChart } from '@spteck/fluentui-react-charts';

const performanceData = [
  { efficiency: 85, satisfaction: 88, teamSize: 12, team: 'Frontend' },
  { efficiency: 78, satisfaction: 82, teamSize: 8, team: 'Backend' },
  { efficiency: 92, satisfaction: 94, teamSize: 6, team: 'DevOps' },
  { efficiency: 88, satisfaction: 86, teamSize: 10, team: 'QA' },
  { efficiency: 75, satisfaction: 79, teamSize: 15, team: 'Support' },
];

<BubbleChart
  data={[{ label: 'Performance', data: performanceData }]}
  getX={(d) => d.efficiency}
  getY={(d) => d.satisfaction}
  getSize={(d) => d.teamSize}
  title="Team Performance Analysis"
  theme={webLightTheme}
/>
```

#### ScatterChart

Shows correlations between two variables.

```tsx
import { ScatterChart } from '@spteck/fluentui-react-charts';

const correlationData = [
  { experience: 2, salary: 55000 },
  { experience: 5, salary: 72000 },
  { experience: 8, salary: 89000 },
  { experience: 12, salary: 105000 },
  { experience: 15, salary: 125000 },
  { experience: 18, salary: 142000 },
  { experience: 22, salary: 165000 },
];

<ScatterChart
  data={[{ label: 'Correlation', data: correlationData }]}
  getX={(d) => d.experience}
  getY={(d) => d.salary}
  title="Experience vs Salary"
  theme={webLightTheme}
/>
```

#### RadarChart

Multi-dimensional data comparison in a circular format.

```tsx
import { RadarChart } from '@spteck/fluentui-react-charts';

const skillsData = [
  { skill: 'Communication', level: 85 },
  { skill: 'Technical Skills', level: 92 },
  { skill: 'Leadership', level: 78 },
  { skill: 'Problem Solving', level: 88 },
  { skill: 'Teamwork', level: 90 },
  { skill: 'Creativity', level: 82 },
];

<RadarChart
  data={[{ label: 'Skills', data: skillsData }]}
  getLabel={(d) => d.skill}
  getValue={(d) => d.level)
  title="Skill Assessment"
  theme={webLightTheme}
/>
```

#### PolarChart

Circular chart with radial and angular dimensions.

```tsx
import { PolarChart } from '@spteck/fluentui-react-charts';

const metricsData = [
  { category: 'Speed', value: 85 },
  { category: 'Reliability', value: 92 },
  { category: 'Usability', value: 78 },
  { category: 'Security', value: 88 },
  { category: 'Scalability', value: 75 },
  { category: 'Maintainability', value: 82 },
];

<PolarChart
  data={[{ label: 'Metrics', data: metricsData }]}
  getLabel={(d) => d.category}
  getValue={(d) => d.value}
  title="Performance Metrics"
  theme={webLightTheme}
/>
```

*Interactive chart components with Fluent UI design system

## 📊 Dashboard Component

The Dashboard component provides a sophisticated grid-based layout for displaying multiple charts with drag & drop reordering and resizable grid spanning.

### Features

- **Grid-based Layout**: Responsive grid system with automatic column calculation
- **Drag & Drop**: Reorder charts by dragging and dropping
- **Grid Spanning**: Charts can span multiple columns and rows
- **Zoom Controls**: Interactive zoom controls for resizing chart containers
- **Responsive**: Automatically adapts to container width
- **Theme Integration**: Full Fluent UI theme support

### Basic Usage

```tsx
import React from 'react';
import { Dashboard } from '@spteck/fluentui-react-charts';
import { webLightTheme } from '@fluentui/react-components';

// Define your chart containers
const chartContainers = [
  {
    id: '1',
    cardTitle: 'Monthly Sales',
    chart: {
      id: '1',
      title: 'Sales Performance',
      type: 'line',
      data: [{ 
        label: 'Sales', 
        data: [
          { name: 'Jan', value: 10000 },
          { name: 'Feb', value: 15000 },
          { name: 'Mar', value: 12000 },
          { name: 'Apr', value: 18000 },
        ]
      }],
    },
    defaultSpan: { spanCols: 2, spanRows: 1 },
  },
  {
    id: '2',
    cardTitle: 'Revenue Distribution',
    chart: {
      id: '2',
      title: 'Q2 Revenue',
      type: 'pie',
      data: [{ 
        label: 'Revenue', 
        data: [
          { name: 'Product A', value: 35000 },
          { name: 'Product B', value: 25000 },
          { name: 'Product C', value: 18000 },
          { name: 'Services', value: 15000 },
        ]
      }],
    },
    defaultSpan: { spanCols: 1, spanRows: 1 },
  },
];

function MyDashboard() {
  return (
    <div style={{ width: '100%', height: '100vh' }}>
      <Dashboard
        dashBoardId="my-sales-dashboard"
        cardCharts={chartContainers}
        theme={webLightTheme}
        containerWidth={1200}
        containerHeight={800}
      />
    </div>
  );
}
```

### Advanced Dashboard Example

```tsx
import React, { useState, useEffect } from 'react';
import { Dashboard } from '@spteck/fluentui-react-charts';
import { webDarkTheme, tokens, Text } from '@fluentui/react-components';

function AdvancedDashboard() {
  const [containerWidth, setContainerWidth] = useState(1200);
  
  // Sample data for multiple charts
  const salesData = [
    { month: 'Jan', sales: 10000, expenses: 8000 },
    { month: 'Feb', sales: 15000, expenses: 9000 },
    { month: 'Mar', sales: 12000, expenses: 7500 },
    { month: 'Apr', sales: 18000, expenses: 10000 },
    { month: 'May', sales: 16000, expenses: 8500 },
    { month: 'Jun', sales: 22000, expenses: 11000 },
  ];

  const chartContainers = [
    {
      id: 'sales-trend',
      cardTitle: 'Sales Trend',
      chart: {
        id: 'sales-trend',
        title: 'Monthly Sales Performance',
        type: 'line',
        data: [{ 
          label: 'Sales', 
          data: salesData.map(d => ({ name: d.month, value: d.sales }))
        }],
      },
      defaultSpan: { spanCols: 2, spanRows: 1 },
    },
    {
      id: 'sales-vs-expenses',
      cardTitle: 'Financial Overview',
      chart: {
        id: 'sales-vs-expenses',
        title: 'Sales vs Expenses',
        type: 'bar',
        data: [
          { 
            label: 'Sales', 
            data: salesData.map(d => ({ name: d.month, value: d.sales }))
          },
          { 
            label: 'Expenses', 
            data: salesData.map(d => ({ name: d.month, value: d.expenses }))
          }
        ],
      },
      defaultSpan: { spanCols: 2, spanRows: 2 },
    },
    {
      id: 'revenue-breakdown',
      cardTitle: 'Revenue Breakdown',
      chart: {
        id: 'revenue-breakdown',
        title: 'Revenue by Category',
        type: 'doughnut',
        data: [{ 
          label: 'Revenue', 
          data: [
            { name: 'Product A', value: 35000 },
            { name: 'Product B', value: 25000 },
            { name: 'Product C', value: 18000 },
            { name: 'Services', value: 15000 },
          ]
        }],
      },
      defaultSpan: { spanCols: 1, spanRows: 1 },
    },
    {
      id: 'growth-trend',
      cardTitle: 'Growth Analysis',
      chart: {
        id: 'growth-trend',
        title: 'Monthly Growth Rate',
        type: 'area',
        data: [{ 
          label: 'Growth', 
          data: salesData.map(d => {
            const growthPercentage = ((d.sales - d.expenses) / d.expenses * 100);
            return { name: d.month, value: Number(growthPercentage.toFixed(1)) };
          })
        }],
      },
      defaultSpan: { spanCols: 2, spanRows: 1 },
    },
  ];

  // Handle responsive container width
  useEffect(() => {
    const handleResize = () => {
      setContainerWidth(window.innerWidth - 40); // Account for padding
    };
    
    window.addEventListener('resize', handleResize);
    handleResize(); // Initial call
    
    return () => window.removeEventListener('resize', handleResize);
  }, []);

  return (
    <div style={{ 
      padding: tokens.spacingHorizontalXL, 
      backgroundColor: tokens.colorNeutralBackground1, 
      minHeight: '100vh' 
    }}>
      <Text 
       
        size={900}
        weight="bold"
        style={{ 
          color: tokens.colorNeutralForeground1, 
          marginBottom: tokens.spacingVerticalL,
          display: 'block'
        }}
      >
        Analytics Dashboard
      </Text>
      <Dashboard
        dashBoardId="analytics-dashboard"
        cardCharts={chartContainers}
        theme={webDarkTheme}
        containerWidth={containerWidth}
        containerHeight={600}
      />
    </div>
  );
}
```

### Dashboard Props

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `cardCharts` | `ICardChartContainer[]` | ✅ | Array of chart container configurations |
| `theme` | `Theme` | ✅ | Fluent UI theme object |
| `containerWidth` | `number` | ✅ | Width of the dashboard container in pixels |
| `containerHeight` | `string` | ❌ | Height of the dashboard container (default: `'100%'`) |
| `dashBoardId` | `string` | ✅ | **Unique identifier for the dashboard. Used for caching layout settings and card order. Must be unique across all Dashboard instances.** |
| `maxSpanRows` | `number` | ❌ | Maximum number of rows a card can span (default: `4`) |

> ⚠️ **Important**: The `dashBoardId` must be unique across all Dashboard instances in your application. Duplicate IDs will cause caching conflicts where layout settings and card order from one dashboard may overwrite another. A warning will be logged in the console if duplicate IDs are detected.

### ICardChartContainer Interface

```tsx
interface ICardChartContainer {
  id: string;                    // Unique identifier for the chart container
  cardTitle: string;             // Title displayed in the card header
  chart: IChart;                 // Chart configuration object
  showZoom?: boolean;            // Whether to show zoom controls (optional)
  defaultSpan?: {                // Default grid spanning (optional)
    spanCols: number;            // Number of columns to span (1-4)
    spanRows: number;            // Number of rows to span (1-4)
  };
}
```

### Dashboard Features

#### Grid Spanning

Charts can span multiple grid cells for larger visualizations:

- `spanCols`: 1-4 columns
- `spanRows`: 1-4 rows

#### Responsive Behavior

- Grid automatically calculates columns based on container width
- Zoom controls are hidden on mobile devices (width < 600px)
- Charts automatically resize to fit their containers

#### Drag & Drop

- Click and drag any chart card to reorder
- Visual feedback during drag operations
- Smooth animations and transitions

## 🎨 Theming

All charts support Fluent UI themes for consistent styling:

```tsx
import { webLightTheme, webDarkTheme, teamsLightTheme } from '@fluentui/react-components';

// Light theme
<BarChart theme={webLightTheme} {...props} />

// Dark theme  
<BarChart theme={webDarkTheme} {...props} />

// Teams theme
<BarChart theme={teamsLightTheme} {...props} />
```

## 📱 Responsive Design

Charts automatically adapt to their container:

```tsx
<div style={{ width: '100%', height: '400px' }}>
  <BarChart {...props} />
</div>
```

## 🔧 Common Props

Most charts share these common properties:

| Prop | Type | Description |
|------|------|-------------|
| `data` | `IChart<T>[]` | Array of data series |
| `title` | `string` | Chart title |
| `theme` | `Theme` | Fluent UI theme |
| `showDataLabels` | `boolean` | Show values on chart elements |
| `showLegend` | `boolean` | Display interactive legend |
| `height` | `number` | Chart height in pixels |
| `width` | `number` | Chart width in pixels |

## 💼 Custom Features & Source Code

This is a private project. If you need additional features or access to the source code, please contact me directly .

## 📞 Contact

For any questions, issues, or feature requests, please reach out:

- **Email**: [joao..j.mendes@spteck.com](mailto:joao.j.mendes@spteck.com)
- **LinkedIn**: [João Mendes](https://www.linkedin.com/in/joaojmendes/)