1.0.2 â€Ē Published 10 months ago

@aniruddha1806/bubble-chart v1.0.2

Weekly downloads
-
License
MIT
Repository
-
Last release
10 months ago

React Bubble Chart

A powerful, customizable bubble chart component for React applications with TypeScript support. Perfect for visualizing three-dimensional data relationships with interactive features, smooth animations, and extensive customization options.

Installation

npm install @aniruddha1806/bubble-chart

Features

  • ðŸŦ§ Interactive bubble charts with three-dimensional data visualization
  • 🎭 Smooth entrance animations with scroll-triggered effects
  • ðŸ–ąïļ Hover tooltips and click handlers
  • 📊 Customizable axes with configurable ticks and labels
  • ðŸŽĻ Extensive styling options (colors, sizing, formatting)
  • ðŸ“ą Responsive SVG-based rendering
  • 📏 Flexible bubble sizing (relative or absolute)
  • 🔄 Real-time data updates with smooth transitions
  • 📝 TypeScript support with full type definitions
  • â™ŋ Accessibility-friendly structure
  • ðŸŠķ Zero dependencies for chart rendering

Quick Start

Basic Bubble Chart

import { BubbleChart } from '@aniruddha1806/bubble-chart';

function App() {
  const data = [
    { x: 10, y: 20, size: 15, label: 'Product A', color: '#3b82f6' },
    { x: 25, y: 35, size: 25, label: 'Product B', color: '#10b981' },
    { x: 40, y: 15, size: 20, label: 'Product C', color: '#f59e0b' },
    { x: 30, y: 45, size: 30, label: 'Product D', color: '#ef4444' },
    { x: 50, y: 30, size: 18, label: 'Product E', color: '#8b5cf6' }
  ];

  return (
    <BubbleChart
      data={data}
      width="100%"
      height={400}
      xAxisLabel="Revenue (millions)"
      yAxisLabel="Growth Rate (%)"
      showTooltip={true}
      animated={true}
    />
  );
}

Advanced Configuration

import { BubbleChart } from '@aniruddha1806/bubble-chart';

function AdvancedExample() {
  const data = [
    // ... your data
  ];

  return (
    <BubbleChart
      data={data}
      width={800}
      height={500}
      xAxisLabel="Market Share (%)"
      yAxisLabel="Customer Satisfaction"
      minRadius={8}
      maxRadius={60}
      xAxisTicks={8}
      yAxisTicks={6}
      bubbleSizeMultiplier={1.2}
      animated={true}
      animationDuration={1000}
      formatValue={(value) => `$${value}M`}
      onBubbleClick={(bubble) => console.log('Clicked:', bubble)}
    />
  );
}

Props

Core Props

PropTypeDefaultDescription
dataBubbleDataPoint[]requiredArray of bubble data points
widthnumber \| string"100%"Chart width
heightnumber \| string400Chart height

Styling Props

PropTypeDefaultDescription
colorsstring[]default paletteColor palette for bubbles
backgroundColorstring"transparent"Chart background color
classNamestring""CSS class for container
bubbleClassNamestring""CSS class for bubbles
tooltipClassNamestring""CSS class for tooltips

Axis Props

PropTypeDefaultDescription
xAxisLabelstring"X-Axis"X-axis label text
yAxisLabelstring"Y-Axis"Y-axis label text
xAxisTicksnumber5Number of X-axis tick marks
yAxisTicksnumber5Number of Y-axis tick marks

Bubble Sizing Props

PropTypeDefaultDescription
minRadiusnumber10Minimum bubble radius
maxRadiusnumber50Maximum bubble radius
bubbleSizeMultipliernumber1Size scaling multiplier
absoluteBubbleSizebooleanfalseUse absolute sizing instead of relative

Formatting Props

PropTypeDefaultDescription
formatValue(value: number) => stringtoStringGeneral value formatter
formatXAxisValue(value: number) => stringformatValueX-axis value formatter
formatYAxisValue(value: number) => stringformatValueY-axis value formatter

Interaction Props

PropTypeDefaultDescription
showTooltipbooleantrueShow hover tooltips
onBubbleClick(dataPoint: BubbleDataPoint) => voidundefinedBubble click handler
tooltipContent(bubble: BubbleDataPoint) => React.ReactNodeundefinedCustom tooltip content

Animation Props

PropTypeDefaultDescription
animatedbooleantrueEnable entrance animations
animationDurationnumber800Animation duration (ms)

Data Types

type BubbleDataPoint = {
  x: number;
  y: number;
  size: number;
  label?: string;
  color?: string;
  [key: string]: any; // Additional custom properties
};

Examples

Sales Performance Dashboard

Visualize sales data with revenue, growth, and market size:

import { BubbleChart } from '@aniruddha1806/bubble-chart';

function SalesPerformance() {
  const salesData = [
    {
      x: 45, // Revenue (millions)
      y: 12, // Growth rate (%)
      size: 25, // Market size
      label: 'North America',
      color: '#3b82f6',
      region: 'NA',
      customers: 1250
    },
    {
      x: 32,
      y: 18,
      size: 20,
      label: 'Europe',
      color: '#10b981',
      region: 'EU',
      customers: 980
    },
    {
      x: 28,
      y: 25,
      size: 30,
      label: 'Asia Pacific',
      color: '#f59e0b',
      region: 'APAC',
      customers: 1580
    },
    {
      x: 15,
      y: 35,
      size: 15,
      label: 'Latin America',
      color: '#ef4444',
      region: 'LATAM',
      customers: 650
    },
    {
      x: 8,
      y: 42,
      size: 12,
      label: 'Middle East',
      color: '#8b5cf6',
      region: 'ME',
      customers: 420
    }
  ];

  const handleBubbleClick = (bubble) => {
    alert(`Region: ${bubble.label}\\nRevenue: $${bubble.x}M\\nGrowth: ${bubble.y}%\\nCustomers: ${bubble.customers}`);
  };

  const customTooltip = (bubble) => (
    <div>
      <div style={{ fontWeight: 'bold', marginBottom: '4px' }}>{bubble.label}</div>
      <div>Revenue: $${bubble.x}M</div>
      <div>Growth: \${bubble.y}%</div>
      <div>Market Size: \${bubble.size}</div>
      <div>Customers: \${bubble.customers?.toLocaleString()}</div>
    </div>
  );

  return (
    <div style={{ padding: '20px' }}>
      <h2>Regional Sales Performance</h2>
      <p>Revenue vs Growth Rate (Bubble size = Market opportunity)</p>
      
      <BubbleChart
        data={salesData}
        width="100%"
        height={500}
        xAxisLabel="Revenue ($ millions)"
        yAxisLabel="Growth Rate (%)"
        minRadius={15}
        maxRadius={45}
        xAxisTicks={6}
        yAxisTicks={8}
        animated={true}
        animationDuration={1200}
        onBubbleClick={handleBubbleClick}
        tooltipContent={customTooltip}
        formatXAxisValue={(value) => `$${value}M`}
        formatYAxisValue={(value) => `${value}%`}
      />
      
      <div style={{ 
        marginTop: '20px',
        display: 'grid',
        gridTemplateColumns: 'repeat(auto-fit, minmax(200px, 1fr))',
        gap: '16px'
      }}>
        {salesData.map((region, index) => (
          <div
            key={index}
            style={{
              padding: '16px',
              backgroundColor: 'white',
              border: '1px solid #e2e8f0',
              borderRadius: '8px',
              textAlign: 'center'
            }}
          >
            <div style={{ 
              width: '20px', 
              height: '20px', 
              backgroundColor: region.color,
              borderRadius: '50%',
              margin: '0 auto 8px'
            }}></div>
            <h4 style={{ margin: '0 0 4px 0' }}>{region.label}</h4>
            <p style={{ margin: 0, fontSize: '14px', color: '#666' }}>
              $${region.x}M revenue
            </p>
          </div>
        ))}
      </div>
    </div>
  );
}

TypeScript Usage

The component provides full TypeScript support:

import { BubbleChart, BubbleDataPoint, BubbleChartProps } from '@aniruddha1806/bubble-chart';
import { useState, useCallback } from 'react';

interface AnalyticsData extends BubbleDataPoint {
  category: string;
  revenue: number;
  customers: number;
}

interface ChartConfig {
  title: string;
  xLabel: string;
  yLabel: string;
  colors: string[];
}

const AnalyticsDashboard: React.FC = () => {
  const [analyticsData, setAnalyticsData] = useState<AnalyticsData[]>([
    {
      x: 45,
      y: 12,
      size: 25,
      label: 'Product A',
      color: '#3b82f6',
      category: 'Electronics',
      revenue: 2500000,
      customers: 1250
    },
    {
      x: 32,
      y: 18,
      size: 20,
      label: 'Product B',
      color: '#10b981',
      category: 'Software',
      revenue: 1800000,
      customers: 980
    }
  ]);

  const handleBubbleClick = useCallback((dataPoint: BubbleDataPoint): void => {
    const analyticsPoint = dataPoint as AnalyticsData;
    console.log('Analytics data:', analyticsPoint);
    // Handle click logic
  }, []);

  const formatCurrency = useCallback((value: number): string => {
    return new Intl.NumberFormat('en-US', {
      style: 'currency',
      currency: 'USD',
      minimumFractionDigits: 0,
      maximumFractionDigits: 0
    }).format(value);
  }, []);

  const customTooltip = useCallback((bubble: BubbleDataPoint): React.ReactNode => {
    const data = bubble as AnalyticsData;
    return (
      <div>
        <div style={{ fontWeight: 'bold', marginBottom: '4px' }}>{data.label}</div>
        <div>Category: {data.category}</div>
        <div>Revenue: {formatCurrency(data.revenue)}</div>
        <div>Customers: {data.customers.toLocaleString()}</div>
        <div>Market Share: \${data.x}%</div>
        <div>Growth: \${data.y}%</div>
      </div>
    );
  }, [formatCurrency]);

  const chartConfig: ChartConfig = {
    title: 'Product Performance Analysis',
    xLabel: 'Market Share (%)',
    yLabel: 'Growth Rate (%)',
    colors: ['#3b82f6', '#10b981', '#f59e0b', '#ef4444', '#8b5cf6']
  };

  const bubbleChartProps: BubbleChartProps = {
    data: analyticsData,
    width: '100%',
    height: 500,
    colors: chartConfig.colors,
    xAxisLabel: chartConfig.xLabel,
    yAxisLabel: chartConfig.yLabel,
    minRadius: 15,
    maxRadius: 45,
    animated: true,
    animationDuration: 1000,
    onBubbleClick: handleBubbleClick,
    tooltipContent: customTooltip,
    formatXAxisValue: (value) => `\${value}%`,
    formatYAxisValue: (value) => `\${value}%`
  };

  return (
    <div>
      <h2>{chartConfig.title}</h2>
      <BubbleChart {...bubbleChartProps} />
      
      <div>
        <h3>Summary Statistics:</h3>
        <p>Total Products: {analyticsData.length}</p>
        <p>Total Revenue: {formatCurrency(analyticsData.reduce((sum, item) => sum + item.revenue, 0))}</p>
        <p>Total Customers: {analyticsData.reduce((sum, item) => sum + item.customers, 0).toLocaleString()}</p>
      </div>
    </div>
  );
};
1.0.2

10 months ago

1.0.1

12 months ago

1.0.0

12 months ago