mirror of
https://github.com/harivansh-afk/React-Portfolio.git
synced 2026-04-17 03:03:48 +00:00
feat: enhance SkillsRadar component with mobile optimizations, including responsive design adjustments and improved label display for better usability on smaller screens
This commit is contained in:
parent
eb6610e7d0
commit
ae63547831
3 changed files with 87 additions and 10 deletions
|
|
@ -17,6 +17,9 @@ const SkillsRadar = ({ skills }) => {
|
||||||
document.documentElement.getAttribute('data-theme') !== 'light'
|
document.documentElement.getAttribute('data-theme') !== 'light'
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Check if the device is mobile
|
||||||
|
const [isMobile, setIsMobile] = useState(window.innerWidth < 768);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// Watch for theme changes
|
// Watch for theme changes
|
||||||
const observer = new MutationObserver((mutations) => {
|
const observer = new MutationObserver((mutations) => {
|
||||||
|
|
@ -29,7 +32,17 @@ const SkillsRadar = ({ skills }) => {
|
||||||
|
|
||||||
observer.observe(document.documentElement, { attributes: true });
|
observer.observe(document.documentElement, { attributes: true });
|
||||||
|
|
||||||
return () => observer.disconnect();
|
// Watch for resize events to detect mobile
|
||||||
|
const handleResize = () => {
|
||||||
|
setIsMobile(window.innerWidth < 768);
|
||||||
|
};
|
||||||
|
|
||||||
|
window.addEventListener('resize', handleResize);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
observer.disconnect();
|
||||||
|
window.removeEventListener('resize', handleResize);
|
||||||
|
};
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
@ -69,17 +82,45 @@ const SkillsRadar = ({ skills }) => {
|
||||||
r: {
|
r: {
|
||||||
angleLines: {
|
angleLines: {
|
||||||
color: isDarkMode ? 'rgba(255, 255, 255, 0.2)' : 'rgba(0, 0, 0, 0.2)',
|
color: isDarkMode ? 'rgba(255, 255, 255, 0.2)' : 'rgba(0, 0, 0, 0.2)',
|
||||||
|
lineWidth: isMobile ? 0.5 : 1
|
||||||
},
|
},
|
||||||
grid: {
|
grid: {
|
||||||
color: isDarkMode ? 'rgba(255, 255, 255, 0.1)' : 'rgba(0, 0, 0, 0.1)',
|
color: isDarkMode ? 'rgba(255, 255, 255, 0.1)' : 'rgba(0, 0, 0, 0.1)',
|
||||||
|
circular: true,
|
||||||
|
lineWidth: isMobile ? 0.5 : 1
|
||||||
},
|
},
|
||||||
pointLabels: {
|
pointLabels: {
|
||||||
color: isDarkMode ? 'rgba(255, 255, 255, 0.9)' : 'rgba(0, 0, 0, 0.9)',
|
color: isDarkMode ? 'rgba(255, 255, 255, 0.9)' : 'rgba(0, 0, 0, 0.9)',
|
||||||
font: {
|
font: {
|
||||||
size: 16,
|
size: isMobile ? 10 : 16,
|
||||||
family: 'Raleway',
|
family: 'Raleway',
|
||||||
weight: '600'
|
weight: '600'
|
||||||
},
|
},
|
||||||
|
// Improve label display on mobile
|
||||||
|
callback: function(value) {
|
||||||
|
if (isMobile) {
|
||||||
|
// Create mobile-friendly abbreviations
|
||||||
|
switch(value) {
|
||||||
|
case "Full-Stack Development":
|
||||||
|
return "Full-Stack";
|
||||||
|
case "Frontend (React/Next.js)":
|
||||||
|
return "Frontend";
|
||||||
|
case "Backend (Node.js)":
|
||||||
|
return "Backend";
|
||||||
|
case "AI & Machine Learning":
|
||||||
|
return "AI & ML";
|
||||||
|
case "Database & API Design":
|
||||||
|
return "Database";
|
||||||
|
case "DevOps & Deployment":
|
||||||
|
return "DevOps";
|
||||||
|
default:
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
},
|
||||||
|
// Ensure labels don't get cut off
|
||||||
|
padding: isMobile ? 8 : 4,
|
||||||
},
|
},
|
||||||
ticks: {
|
ticks: {
|
||||||
backdropColor: 'transparent',
|
backdropColor: 'transparent',
|
||||||
|
|
@ -87,16 +128,20 @@ const SkillsRadar = ({ skills }) => {
|
||||||
showLabelBackdrop: false,
|
showLabelBackdrop: false,
|
||||||
beginAtZero: true,
|
beginAtZero: true,
|
||||||
max: 100,
|
max: 100,
|
||||||
stepSize: 20,
|
stepSize: isMobile ? 25 : 20,
|
||||||
font: {
|
font: {
|
||||||
size: 12
|
size: isMobile ? 8 : 12
|
||||||
}
|
},
|
||||||
|
// Display fewer ticks on mobile
|
||||||
|
count: isMobile ? 4 : 6,
|
||||||
|
// Make sure the scale starts at 50
|
||||||
|
min: 50
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
plugins: {
|
plugins: {
|
||||||
legend: {
|
legend: {
|
||||||
display: true,
|
display: !isMobile, // Hide legend on mobile to save space
|
||||||
position: 'top',
|
position: 'top',
|
||||||
labels: {
|
labels: {
|
||||||
color: isDarkMode ? '#fff' : '#000',
|
color: isDarkMode ? '#fff' : '#000',
|
||||||
|
|
@ -115,13 +160,15 @@ const SkillsRadar = ({ skills }) => {
|
||||||
bodyColor: isDarkMode ? '#fff' : '#000',
|
bodyColor: isDarkMode ? '#fff' : '#000',
|
||||||
borderColor: 'rgba(204, 0, 0, 0.5)',
|
borderColor: 'rgba(204, 0, 0, 0.5)',
|
||||||
borderWidth: 1,
|
borderWidth: 1,
|
||||||
padding: 12,
|
padding: isMobile ? 8 : 12,
|
||||||
cornerRadius: 8,
|
cornerRadius: 8,
|
||||||
displayColors: false,
|
displayColors: false,
|
||||||
callbacks: {
|
callbacks: {
|
||||||
title: (items) => items[0].label,
|
title: (items) => items[0].label,
|
||||||
label: (context) => `Proficiency: ${context.raw}%`,
|
label: (context) => `Proficiency: ${context.raw}%`,
|
||||||
},
|
},
|
||||||
|
// Ensure tooltip doesn't go off-screen on mobile
|
||||||
|
position: 'nearest',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
maintainAspectRatio: false,
|
maintainAspectRatio: false,
|
||||||
|
|
|
||||||
|
|
@ -102,9 +102,21 @@
|
||||||
color: var(--text-color-3);
|
color: var(--text-color-3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Mobile Optimizations */
|
||||||
@media (max-width: 768px) {
|
@media (max-width: 768px) {
|
||||||
|
.skills-radar-container {
|
||||||
|
max-width: 100%;
|
||||||
|
padding: 0;
|
||||||
|
overflow: visible;
|
||||||
|
}
|
||||||
|
|
||||||
.skills-radar-chart {
|
.skills-radar-chart {
|
||||||
height: 350px;
|
height: 380px;
|
||||||
|
margin: 0 auto;
|
||||||
|
width: 100vw;
|
||||||
|
max-width: 100vw;
|
||||||
|
transform: scale(0.95);
|
||||||
|
transform-origin: center center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.skills-legend {
|
.skills-legend {
|
||||||
|
|
@ -119,3 +131,21 @@
|
||||||
font-size: 0.9rem;
|
font-size: 0.9rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Small Mobile Optimizations */
|
||||||
|
@media (max-width: 480px) {
|
||||||
|
.skills-radar-chart {
|
||||||
|
height: 340px;
|
||||||
|
transform: scale(0.9);
|
||||||
|
margin-left: -15px;
|
||||||
|
margin-right: -15px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Extra Small Mobile Optimizations */
|
||||||
|
@media (max-width: 375px) {
|
||||||
|
.skills-radar-chart {
|
||||||
|
height: 320px;
|
||||||
|
transform: scale(0.85);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -92,10 +92,10 @@ export const About = () => {
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
<Row className="sec_sp">
|
<Row className="sec_sp">
|
||||||
<Col lg="5">
|
<Col lg="5" className="mb-3 mb-lg-0">
|
||||||
<h3 className="color_sec py-4">Skills</h3>
|
<h3 className="color_sec py-4">Skills</h3>
|
||||||
</Col>
|
</Col>
|
||||||
<Col lg="7" className="d-flex justify-content-center">
|
<Col lg="7" xs="12" className="d-flex justify-content-center align-items-center px-0">
|
||||||
<SkillsRadar skills={skills} />
|
<SkillsRadar skills={skills} />
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue