Skip to content

Commit

Permalink
LineChart Inicial
Browse files Browse the repository at this point in the history
  • Loading branch information
v3gaaa committed Sep 20, 2024
1 parent 459e7a5 commit fbced3b
Show file tree
Hide file tree
Showing 7 changed files with 226 additions and 2 deletions.
4 changes: 2 additions & 2 deletions samples/App.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
// App.tsx

import React from 'react';
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
import NavBar from './utils/NavBar';
Expand All @@ -12,7 +11,7 @@ import StraightAnglePieChart from './pages/StraightAnglePieChart';
import PieChartWithPaddingAngle from './pages/PieChartWithPaddingAngle';
import PieChartWithCustomizedLabel from './pages/PieChartWithCustomizedLabel';
import CustomActiveShapePieChart from './pages/CustomActiveShapePieChart';

import LineChartExample from './pages/LineChartExample';

const App = () => {
return (
Expand All @@ -29,6 +28,7 @@ const App = () => {
<Route path="/pie-chart-with-padding-angle" element={<PieChartWithPaddingAngle />} />
<Route path="/pie-chart-with-customized-label" element={<PieChartWithCustomizedLabel />} />
<Route path="/custom-active-shape-pie" element={<CustomActiveShapePieChart />} />
<Route path="/line-chart" element={<LineChartExample />} />
</Routes>
</div>
</Router>
Expand Down
48 changes: 48 additions & 0 deletions samples/pages/LineChartExample.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// LineChartExample.tsx
import React, { useState } from 'react';
import LineChart from '../../src/LineChart'; // Assuming the path to the LineChart component
import Line from '../../src/Line'; // Assuming the path to the Line component
import CartesianGrid from '../../src/CartesianGrid';
import XAxis from '../../src/XAxis';
import YAxis from '../../src/YAxis';
import Tooltip from '../../src/Tooltip';
import Legend from '../../src/Legend';
import LineChartControls from '../utils/LineChartControls'; // Assuming the path to the LineChartControls component

const data = [
{ name: 'Page A', uv: 4000, pv: 2400, amt: 2400 },
{ name: 'Page B', uv: 3000, pv: 1398, amt: 2210 },
{ name: 'Page C', uv: 2000, pv: 9800, amt: 2290 },
{ name: 'Page D', uv: 2780, pv: 3908, amt: 2000 },
{ name: 'Page E', uv: 1890, pv: 4800, amt: 2181 },
{ name: 'Page F', uv: 2390, pv: 3800, amt: 2500 },
{ name: 'Page G', uv: 3490, pv: 4300, amt: 2100 },
];

const LineChartExample: React.FC = () => {
const [lines, setLines] = useState([
{ id: 1, dataKey: 'pv', stroke: '#8884d8' },
{ id: 2, dataKey: 'uv', stroke: '#82ca9d' },
]);

return (
<div className="p-6">
<h1 className="text-2xl font-semibold mb-4">LineChart Example</h1>
<div className="flex">
<LineChartControls lines={lines} setLines={setLines} />
<LineChart width={730} height={250} data={data} margin={{ top: 5, right: 30, left: 20, bottom: 5 }}>
<CartesianGrid strokeDasharray="3 3" />
<XAxis dataKey="name" />
<YAxis />
<Tooltip />
<Legend />
{lines.map((line) => (
<Line key={line.id} type="monotone" dataKey={line.dataKey} stroke={line.stroke} />
))}
</LineChart>
</div>
</div>
);
};

export default LineChartExample;
50 changes: 50 additions & 0 deletions samples/utils/LineChartControls.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// LineChartControls.tsx
import React from 'react';

interface LineChartControlsProps {
lines: Array<{ id: number; dataKey: string; stroke: string }>;
setLines: React.Dispatch<React.SetStateAction<Array<{ id: number; dataKey: string; stroke: string }>>>;
}

const LineChartControls: React.FC<LineChartControlsProps> = ({ lines, setLines }) => {
const handleLineChange = (index: number, key: keyof typeof lines[number], value: string) => {
const updatedLines = [...lines];
updatedLines[index][key] = value;
setLines(updatedLines);
};

return (
<div className="bg-white p-6 shadow-lg rounded-lg mb-5 max-w-md">
<h2 className="text-2xl font-semibold mb-6 text-purple-600">Line Chart Settings</h2>
<form className="space-y-6">
{lines.map((line, index) => (
<div key={line.id} className="bg-gray-100 p-4 rounded-lg mb-4">
<h3 className="text-lg font-medium text-purple-600 mb-2">Line {index + 1} Settings</h3>
<div className="grid grid-cols-2 gap-4">
<div>
<label className="block text-sm font-medium text-purple-600 mb-1">Data Key</label>
<input
type="text"
value={line.dataKey}
onChange={(e) => handleLineChange(index, 'dataKey', e.target.value)}
className="w-full px-3 py-2 border border-purple-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-purple-500 transition duration-300 ease-in-out"
/>
</div>
<div>
<label className="block text-sm font-medium text-purple-600 mb-1">Stroke Color</label>
<input
type="color"
value={line.stroke}
onChange={(e) => handleLineChange(index, 'stroke', e.target.value)}
className="w-full h-10 border-none rounded-lg"
/>
</div>
</div>
</div>
))}
</form>
</div>
);
};

export default LineChartControls;
6 changes: 6 additions & 0 deletions samples/utils/NavBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@ const NavBar = () => {
{ name: 'Custom Active Shape Pie Chart', path: '/custom-active-shape-pie' },
],
},
{
category: 'Line Charts',
items: [
{ name: 'Line Chart', path: '/line-chart' }, // New item
],
},
];

return (
Expand Down
44 changes: 44 additions & 0 deletions src/Line/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Line.tsx
import React from 'react';

interface LineProps {
data: Array<{ [key: string]: any }>;
dataKey: string;
stroke: string;
type?: 'monotone' | 'linear';
onMouseOver?: (event: React.MouseEvent, entry: { name: string; [key: string]: any }) => void;
onMouseOut?: () => void;
}

const Line: React.FC<LineProps> = ({
data = [],
dataKey,
stroke,
type = 'linear',
onMouseOver = () => {},
onMouseOut = () => {},
}) => {
if (!data.length) return null;

const points = data
.map((entry, index) => {
const x = (index / (data.length - 1)) * 730;
const y = 250 - (entry[dataKey] / Math.max(...data.map((d) => d[dataKey]))) * 250;
return `${x},${y}`;
})
.join(' ');

return (
<polyline
points={points}
fill="none"
stroke={stroke}
strokeWidth={2}
onMouseOver={(event) => onMouseOver(event, { name: dataKey })}
onMouseOut={onMouseOut}
style={{ transition: 'all 0.3s' }}
/>
);
};

export default Line;
74 changes: 74 additions & 0 deletions src/LineChart/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
// LineChart.tsx
import React, { ReactNode, Children, cloneElement, useState, useRef, useEffect } from 'react';
import CartesianGrid from '../CartesianGrid';
import XAxis from '../XAxis';
import YAxis from '../YAxis';
import Tooltip from '../Tooltip';
import Legend from '../Legend';
import Line from '../Line';

interface LineChartProps {
width: number;
height: number;
data: Array<{ [key: string]: any }>;
margin?: { top?: number; right?: number; bottom?: number; left?: number };
children: ReactNode;
}

const LineChart: React.FC<LineChartProps> = ({
width,
height,
data,
margin = { top: 20, right: 30, bottom: 20, left: 40 },
children,
}) => {
const chartWidth = width - (margin.left + margin.right);
const chartHeight = height - (margin.top + margin.bottom);
const [tooltipData, setTooltipData] = useState(null);
const [position, setPosition] = useState({ x: 0, y: 0 });
const svgRef = useRef<SVGSVGElement>(null);

useEffect(() => {
if (svgRef.current) {
// Add any adjustments based on rendered dimensions here if needed
}
}, [data]);

const handleMouseOver = (event: React.MouseEvent, entry: { name: string }) => {
const values = Children.toArray(children)
.filter((child) => React.isValidElement(child) && child.type === Line)
.map((child) => {
const { dataKey, stroke } = child.props;
const value = entry[dataKey];
return { key: dataKey, value, color: stroke };
});

setTooltipData({ name: entry.name, values });
setPosition({ x: event.clientX, y: event.clientY });
};

const handleMouseOut = () => {
setTooltipData(null);
};

return (
<div className="relative inline-block" style={{ padding: '10px' }}>
<svg ref={svgRef} width={width} height={height} className="bg-white">
<g transform={`translate(${margin.left}, ${margin.top})`}>
<CartesianGrid width={chartWidth} height={chartHeight} layout="horizontal" />
<XAxis data={data} width={chartWidth} height={chartHeight} dataKey="name" layout="horizontal" />
<YAxis height={chartHeight} maxValue={Math.max(...data.map((d) => d.pv))} minValue={0} layout="horizontal" />
{Children.map(children, (child) =>
React.isValidElement(child) && child.type === Line
? cloneElement(child, { data, onMouseOver: handleMouseOver, onMouseOut: handleMouseOut })
: child
)}
</g>
</svg>
<Legend />
{tooltipData && <Tooltip tooltipData={tooltipData} position={position} />}
</div>
);
};

export default LineChart;
2 changes: 2 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,5 @@ export { default as Bar } from './Bar';
export { default as PieChart } from './PieChart';
export { default as Pie } from './Pie';
export { default as PolarGrid } from './PolarGrid';
export { default as LineChart } from './LineChart';
export { default as Line } from './Line';

0 comments on commit fbced3b

Please sign in to comment.