Skip to content

Commit

Permalink
Add public-samples/mint-mobile-app-fq9nqt/src/web/src/components/char…
Browse files Browse the repository at this point in the history
…ts/LineChart.tsx
  • Loading branch information
siddhantpp committed Nov 10, 2024
1 parent 462c44f commit 56c5107
Showing 1 changed file with 167 additions and 0 deletions.
167 changes: 167 additions & 0 deletions src/web/src/components/charts/LineChart.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
/**
* LineChart component for visualizing time-series data
* Addresses requirements:
* - Investment Portfolio Tracking (Technical Specification/1.2 Scope/Core Features)
* - Budget Monitoring (Technical Specification/1.2 Scope/Core Features)
* - Analytics and Reporting (Technical Specification/1.1 System Overview)
*/

// Third-party imports
// @version: react ^18.0.0
import React, { useRef, useEffect } from 'react';
// @version: chart.js ^4.0.0
import { Chart as ChartJS, CategoryScale, LinearScale, PointElement, LineElement, Title, Tooltip, Legend, Filler } from 'chart.js';
// @version: react-chartjs-2 ^5.0.0
import { Line } from 'react-chartjs-2';

// Internal imports
import { formatChartData, generateChartOptions } from '../../utils/chart.utils';
import { chartConfig } from '../../config/chart.config';
import type { ChartProps } from '../../types/components.types';

// Register Chart.js components
ChartJS.register(
CategoryScale,
LinearScale,
PointElement,
LineElement,
Title,
Tooltip,
Legend,
Filler
);

// Human Tasks:
// 1. Verify Chart.js and react-chartjs-2 versions in package.json
// 2. Test responsive behavior across different screen sizes
// 3. Validate theme integration with application's theme system
// 4. Ensure accessibility features are properly configured
// 5. Test touch interactions on mobile devices

interface LineChartProps extends Omit<ChartProps, 'type'> {
data: Array<{ x: string | number; y: number }>;
options?: ChartProps['options'];
height?: string | number;
className?: string;
}

const LineChart: React.FC<LineChartProps> = ({
data,
options = {},
height = 300,
className = ''
}) => {
const chartRef = useRef<ChartJS>(null);
const containerRef = useRef<HTMLDivElement>(null);

useEffect(() => {
const handleResize = () => {
if (chartRef.current && containerRef.current) {
chartRef.current.resize();
}
};

window.addEventListener('resize', handleResize);
return () => window.removeEventListener('resize', handleResize);
}, []);

// Format data for Chart.js consumption
const formattedData = formatChartData(data, {
type: 'line',
theme: 'light', // TODO: Integrate with app theme
enableAnimation: true,
showLegend: true
});

// Generate chart options with defaults and custom settings
const chartOptions = generateChartOptions('line', 'light', {
...chartConfig.defaultOptions,
...options,
responsive: true,
maintainAspectRatio: false,
interaction: {
mode: 'nearest',
axis: 'x',
intersect: false
},
plugins: {
...chartConfig.defaultOptions.plugins,
tooltip: {
...chartConfig.defaultOptions.plugins.tooltip,
callbacks: {
label: (context: any) => {
const value = context.parsed.y;
return new Intl.NumberFormat('en-US', {
style: 'currency',
currency: 'USD'
}).format(value);
}
}
}
},
scales: {
x: {
...chartConfig.defaultOptions.scales.x,
type: 'category',
display: true,
title: {
display: true,
text: 'Date'
}
},
y: {
...chartConfig.defaultOptions.scales.y,
display: true,
title: {
display: true,
text: 'Amount ($)'
},
ticks: {
callback: (value: number) => {
return new Intl.NumberFormat('en-US', {
style: 'currency',
currency: 'USD',
minimumFractionDigits: 0
}).format(value);
}
}
}
}
});

return (
<div
ref={containerRef}
className={`line-chart-container ${className}`}
style={{
height: typeof height === 'number' ? `${height}px` : height,
width: '100%'
}}
role="img"
aria-label="Line chart visualization"
>
<Line
ref={chartRef}
data={formattedData}
options={chartOptions}
plugins={[
{
id: 'customCanvasBackgroundColor',
beforeDraw: (chart) => {
const ctx = chart.canvas.getContext('2d');
if (ctx) {
ctx.save();
ctx.globalCompositeOperation = 'destination-over';
ctx.fillStyle = 'white'; // TODO: Use theme background color
ctx.fillRect(0, 0, chart.width, chart.height);
ctx.restore();
}
}
}
]}
/>
</div>
);
};

export default LineChart;

0 comments on commit 56c5107

Please sign in to comment.