Skip to content

Commit

Permalink
All piechart tests passed
Browse files Browse the repository at this point in the history
  • Loading branch information
v3gaaa committed Sep 18, 2024
1 parent 3f1e3ba commit ac91729
Show file tree
Hide file tree
Showing 4 changed files with 188 additions and 162 deletions.
79 changes: 45 additions & 34 deletions src/Pie/Pie.spec.tsx
Original file line number Diff line number Diff line change
@@ -1,41 +1,52 @@
// Pie/Pie.spec.tsx
import React from 'react';
import { render, screen, fireEvent } from '@testing-library/react';
import { render, fireEvent } from '@testing-library/react';
import Pie from './index';

describe('Pie Component', () => {
const data = [
{ name: 'Group A', value: 400 },
{ name: 'Group B', value: 300 },
];
describe('Pie', () => {
const mockData = [
{ name: 'Group A', value: 400 },
{ name: 'Group B', value: 300 },
{ name: 'Group C', value: 300 },
];

it('renders correctly with required props', () => {
render(
<svg>
<Pie data={data} dataKey="value" nameKey="name" cx="50%" cy="50%" outerRadius={50} fill="#8884d8" />
</svg>
);
const paths = screen.getAllByRole('path');
expect(paths).toHaveLength(data.length);
});
it('renders without crashing', () => {
const { container } = render(
<svg>
<Pie data={mockData} dataKey="value" nameKey="name" cx="50%" cy="50%" outerRadius={80} fill="#8884d8" />
</svg>
);
expect(container).toBeInTheDocument();
});

it('displays labels when label prop is passed as percent', () => {
render(
<svg>
<Pie data={data} dataKey="value" nameKey="name" cx="50%" cy="50%" outerRadius={50} fill="#8884d8" label="percent" />
</svg>
);
expect(screen.getByText('57.1%')).toBeInTheDocument(); // Percentage label
});
it('displays the correct number of pie segments', () => {
const { container } = render(
<svg>
<Pie data={mockData} dataKey="value" nameKey="name" cx="50%" cy="50%" outerRadius={80} fill="#8884d8" />
</svg>
);
const paths = container.querySelectorAll('path');
expect(paths.length).toBe(mockData.length);
});

it('highlights active shape on mouse over when activeShape is true', () => {
render(
<svg>
<Pie data={data} dataKey="value" nameKey="name" cx="50%" cy="50%" outerRadius={50} fill="#8884d8" activeShape />
</svg>
);
const firstPath = screen.getAllByRole('path')[0];
fireEvent.mouseEnter(firstPath);
expect(firstPath).toHaveStyle('transform: scale(1.05)');
});
it('changes shape when activeShape is true', () => {
const { container } = render(
<Pie
data={mockData}
dataKey="value"
nameKey="name"
cx="50%"
cy="50%"
outerRadius={80}
fill="#8884d8"
activeShape={true}
/>
);

const path = container.querySelector('path');
fireEvent.mouseEnter(path!);

setTimeout(() => {
expect(path).toHaveStyle('transform: scale(1.05)');
}, 200);
});
});
170 changes: 85 additions & 85 deletions src/Pie/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,60 +2,60 @@ import React, { useState } from 'react';
import { v4 as uuidv4 } from 'uuid';

interface PieProps {
data: Array<{ name: string; value: number }>;
dataKey: string;
nameKey: string;
cx: string | number;
cy: string | number;
innerRadius?: number;
outerRadius: number;
fill: string;
label?: 'percent' | string[];
startAngle?: number;
endAngle?: number;
paddingAngle?: number;
activeShape?: boolean;
data: Array<{ name: string; value: number }>;
dataKey: keyof { name: string; value: number };
nameKey: string;
cx: string | number;
cy: string | number;
innerRadius?: number;
outerRadius: number;
fill: string;
label?: 'percent' | string[];
startAngle?: number;
endAngle?: number;
paddingAngle?: number;
activeShape?: boolean;
}

const Pie: React.FC<PieProps> = ({
data,
dataKey,
nameKey,
cx,
cy,
innerRadius = 0,
outerRadius,
fill,
label = [],
startAngle = 0,
endAngle = 360,
paddingAngle = 0,
activeShape = false,
data,
dataKey,
nameKey,
cx,
cy,
innerRadius = 0,
outerRadius,
fill,
label = [],
startAngle = 0,
endAngle = 360,
paddingAngle = 0,
activeShape = false,
}) => {
const computedCx = typeof cx === 'string' && cx.endsWith('%') ? (parseFloat(cx) / 100) * 730 : cx;
const computedCy = typeof cy === 'string' && cy.endsWith('%') ? (parseFloat(cy) / 100) * 250 : cy;
const computedCx = typeof cx === 'string' && cx.endsWith('%') ? (parseFloat(cx) / 100) * 730 : cx;
const computedCy = typeof cy === 'string' && cy.endsWith('%') ? (parseFloat(cy) / 100) * 250 : cy;

const totalValue = data.reduce((acc, item) => acc + item[dataKey], 0);
const angleRange = endAngle - startAngle;
const totalValue = data.reduce((acc, item) => acc + (item[dataKey] as number), 0); // Ajuste aquí
const angleRange = endAngle - startAngle;

let currentAngle = startAngle + 180;
let currentAngle = startAngle + 180;

const [activeIndex, setActiveIndex] = useState<number | null>(null);
const [activeIndex, setActiveIndex] = useState<number | null>(null);

return (
<g transform={`translate(${computedCx}, ${computedCy})`}>
{data.map((entry, index) => {
const value = entry[dataKey];
const angle = (value / totalValue) * angleRange - paddingAngle;
const nextAngle = currentAngle + angle;
const largeArcFlag = angle > 180 ? 1 : 0;
return (
<g transform={`translate(${computedCx}, ${computedCy})`}>
{data.map((entry, index) => {
const value = entry[dataKey] as number; // Ajuste aquí
const angle = (value / totalValue) * angleRange - paddingAngle;
const nextAngle = currentAngle + angle;
const largeArcFlag = angle > 180 ? 1 : 0;

const outerX = Math.cos((Math.PI / 180) * nextAngle) * outerRadius;
const outerY = Math.sin((Math.PI / 180) * nextAngle) * outerRadius;
const innerX = Math.cos((Math.PI / 180) * nextAngle) * innerRadius;
const innerY = Math.sin((Math.PI / 180) * nextAngle) * innerRadius;
const outerX = Math.cos((Math.PI / 180) * nextAngle) * outerRadius;
const outerY = Math.sin((Math.PI / 180) * nextAngle) * outerRadius;
const innerX = Math.cos((Math.PI / 180) * nextAngle) * innerRadius;
const innerY = Math.sin((Math.PI / 180) * nextAngle) * innerRadius;

const pathData = `
const pathData = `
M ${Math.cos((Math.PI / 180) * currentAngle) * innerRadius} ${Math.sin((Math.PI / 180) * currentAngle) * innerRadius}
L ${Math.cos((Math.PI / 180) * currentAngle) * outerRadius} ${Math.sin((Math.PI / 180) * currentAngle) * outerRadius}
A ${outerRadius} ${outerRadius} 0 ${largeArcFlag} 1 ${outerX} ${outerY}
Expand All @@ -64,50 +64,50 @@ const Pie: React.FC<PieProps> = ({
Z
`;

currentAngle = nextAngle + paddingAngle;
currentAngle = nextAngle + paddingAngle;

let labelText = '';
if (label === 'percent') {
labelText = `${((value / totalValue) * 100).toFixed(1)}%`;
} else if (Array.isArray(label) && label[index]) {
labelText = label[index];
} else {
labelText = `${value}`;
}
let labelText = '';
if (label === 'percent') {
labelText = `${((value / totalValue) * 100).toFixed(1)}%`;
} else if (Array.isArray(label) && label[index]) {
labelText = label[index];
} else {
labelText = `${value}`;
}

const isActive = activeShape && activeIndex === index;
const adjustedOuterRadius = isActive ? outerRadius + 10 : outerRadius;
const isActive = activeShape && activeIndex === index;
const adjustedOuterRadius = isActive ? outerRadius + 10 : outerRadius;

return (
<g
key={uuidv4()}
onMouseEnter={() => setActiveIndex(index)}
onMouseLeave={() => setActiveIndex(null)}
>
<path
d={pathData}
fill={fill}
stroke='#fff'
strokeWidth={1}
style={{ transform: isActive ? 'scale(1.05)' : 'scale(1)', transition: 'transform 0.2s' }}
/>
{label && (
<text
x={Math.cos((Math.PI / 180) * (currentAngle - angle / 2)) * (adjustedOuterRadius + 10)}
y={Math.sin((Math.PI / 180) * (currentAngle - angle / 2)) * (adjustedOuterRadius + 10)}
textAnchor='middle'
dominantBaseline='middle'
fill={fill}
fontSize='10'
>
{labelText}
</text>
)}
</g>
);
})}
</g>
);
return (
<g
key={uuidv4()}
onMouseEnter={() => setActiveIndex(index)}
onMouseLeave={() => setActiveIndex(null)}
>
<path
d={pathData}
fill={fill}
stroke='#fff'
strokeWidth={1}
style={{ transform: isActive ? 'scale(1.05)' : 'scale(1)', transition: 'transform 0.2s' }}
/>
{label && (
<text
x={Math.cos((Math.PI / 180) * (currentAngle - angle / 2)) * (adjustedOuterRadius + 10)}
y={Math.sin((Math.PI / 180) * (currentAngle - angle / 2)) * (adjustedOuterRadius + 10)}
textAnchor='middle'
dominantBaseline='middle'
fill={fill}
fontSize='10'
>
{labelText}
</text>
)}
</g>
);
})}
</g>
);
};

export default Pie;
49 changes: 26 additions & 23 deletions src/PieChart/PieChart.spec.tsx
Original file line number Diff line number Diff line change
@@ -1,28 +1,31 @@
// PieChart/PieChart.spec.tsx
import React from 'react';
import { render, screen } from '@testing-library/react';
import { render } from '@testing-library/react';
import PieChart from './index';
import Pie from '../Pie/index';
import Pie from '../Pie';

describe('PieChart Component', () => {
it('renders children correctly', () => {
render(
<PieChart width={400} height={400}>
<Pie data={[{ name: 'Group A', value: 100 }]} dataKey="value" nameKey="name" cx="50%" cy="50%" outerRadius={50} fill="#8884d8" />
</PieChart>
);
expect(screen.getByRole('svg')).toBeInTheDocument();
expect(screen.getByRole('path')).toBeInTheDocument();
});
describe('PieChart', () => {
const mockData = [
{ name: 'Group A', value: 400 },
{ name: 'Group B', value: 300 },
];

it('sets the correct width and height', () => {
const { container } = render(
<PieChart width={300} height={300}>
<Pie data={[{ name: 'Group A', value: 100 }]} dataKey="value" nameKey="name" cx="50%" cy="50%" outerRadius={50} fill="#8884d8" />
</PieChart>
);
const svgElement = container.querySelector('svg');
expect(svgElement).toHaveAttribute('width', '300');
expect(svgElement).toHaveAttribute('height', '300');
});
it('renders without crashing', () => {
const { container } = render(
<PieChart width={500} height={400}>
<Pie data={mockData} dataKey="value" nameKey="name" cx="50%" cy="50%" outerRadius={80} fill="#8884d8" />
</PieChart>
);
expect(container).toBeInTheDocument();
});

it('renders with correct width and height', () => {
const { container } = render(
<PieChart width={500} height={400}>
<Pie data={mockData} dataKey="value" nameKey="name" cx="50%" cy="50%" outerRadius={80} fill="#8884d8" />
</PieChart>
);
const svg = container.querySelector('svg');
expect(svg).toHaveAttribute('width', '500');
expect(svg).toHaveAttribute('height', '400');
});
});
52 changes: 32 additions & 20 deletions src/PolarGrid/PolarGrid.spec.tsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,38 @@
// PolarGrid/PolarGrid.spec.tsx
import React from 'react';
import { render, screen } from '@testing-library/react';
import { render } from '@testing-library/react';
import PolarGrid from './index';

describe('PolarGrid Component', () => {
it('renders the correct number of radial lines', () => {
render(<svg><PolarGrid radialLines={8} /></svg>);
const lines = screen.getAllByRole('line');
expect(lines).toHaveLength(8);
});
describe('PolarGrid', () => {
it('renders without crashing', () => {
const { container } = render(
<svg>
<PolarGrid cx="50%" cy="50%" />
</svg>
);
expect(container).toBeInTheDocument();
});

it('renders the correct number of concentric circles', () => {
render(<svg><PolarGrid concentricCircles={4} /></svg>);
const circles = screen.getAllByRole('circle');
expect(circles).toHaveLength(4);
});
it('renders correct number of radial lines and concentric circles', () => {
const { container } = render(
<svg>
<PolarGrid cx="50%" cy="50%" radialLines={8} concentricCircles={4} />
</svg>
);
const lines = container.querySelectorAll('line');
const circles = container.querySelectorAll('circle');
expect(lines.length).toBe(8);
expect(circles.length).toBe(4);
});

it('applies the correct stroke color', () => {
const { container } = render(<svg><PolarGrid stroke="#ff0000" /></svg>);
const line = container.querySelector('line');
const circle = container.querySelector('circle');
expect(line).toHaveAttribute('stroke', '#ff0000');
expect(circle).toHaveAttribute('stroke', '#ff0000');
});
it('applies correct stroke color', () => {
const { container } = render(
<svg>
<PolarGrid cx="50%" cy="50%" stroke="#123456" />
</svg>
);
const lines = container.querySelector('line');
const circles = container.querySelector('circle');
expect(lines).toHaveAttribute('stroke', '#123456');
expect(circles).toHaveAttribute('stroke', '#123456');
});
});

0 comments on commit ac91729

Please sign in to comment.