From ae6354783159cf9f1227937a796095a1e2afd9ce Mon Sep 17 00:00:00 2001 From: Harivansh Rathi Date: Fri, 21 Mar 2025 11:48:07 -0400 Subject: [PATCH] feat: enhance SkillsRadar component with mobile optimizations, including responsive design adjustments and improved label display for better usability on smaller screens --- src/components/SkillsRadar/index.js | 61 ++++++++++++++++++++++++---- src/components/SkillsRadar/style.css | 32 ++++++++++++++- src/pages/about/index.js | 4 +- 3 files changed, 87 insertions(+), 10 deletions(-) diff --git a/src/components/SkillsRadar/index.js b/src/components/SkillsRadar/index.js index 32332db..818fd47 100644 --- a/src/components/SkillsRadar/index.js +++ b/src/components/SkillsRadar/index.js @@ -17,6 +17,9 @@ const SkillsRadar = ({ skills }) => { document.documentElement.getAttribute('data-theme') !== 'light' ); + // Check if the device is mobile + const [isMobile, setIsMobile] = useState(window.innerWidth < 768); + useEffect(() => { // Watch for theme changes const observer = new MutationObserver((mutations) => { @@ -29,7 +32,17 @@ const SkillsRadar = ({ skills }) => { 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(() => { @@ -69,17 +82,45 @@ const SkillsRadar = ({ skills }) => { r: { angleLines: { color: isDarkMode ? 'rgba(255, 255, 255, 0.2)' : 'rgba(0, 0, 0, 0.2)', + lineWidth: isMobile ? 0.5 : 1 }, grid: { color: isDarkMode ? 'rgba(255, 255, 255, 0.1)' : 'rgba(0, 0, 0, 0.1)', + circular: true, + lineWidth: isMobile ? 0.5 : 1 }, pointLabels: { color: isDarkMode ? 'rgba(255, 255, 255, 0.9)' : 'rgba(0, 0, 0, 0.9)', font: { - size: 16, + size: isMobile ? 10 : 16, family: 'Raleway', 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: { backdropColor: 'transparent', @@ -87,16 +128,20 @@ const SkillsRadar = ({ skills }) => { showLabelBackdrop: false, beginAtZero: true, max: 100, - stepSize: 20, + stepSize: isMobile ? 25 : 20, 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: { legend: { - display: true, + display: !isMobile, // Hide legend on mobile to save space position: 'top', labels: { color: isDarkMode ? '#fff' : '#000', @@ -115,13 +160,15 @@ const SkillsRadar = ({ skills }) => { bodyColor: isDarkMode ? '#fff' : '#000', borderColor: 'rgba(204, 0, 0, 0.5)', borderWidth: 1, - padding: 12, + padding: isMobile ? 8 : 12, cornerRadius: 8, displayColors: false, callbacks: { title: (items) => items[0].label, label: (context) => `Proficiency: ${context.raw}%`, }, + // Ensure tooltip doesn't go off-screen on mobile + position: 'nearest', }, }, maintainAspectRatio: false, diff --git a/src/components/SkillsRadar/style.css b/src/components/SkillsRadar/style.css index 7ff6257..f66af55 100644 --- a/src/components/SkillsRadar/style.css +++ b/src/components/SkillsRadar/style.css @@ -102,9 +102,21 @@ color: var(--text-color-3); } +/* Mobile Optimizations */ @media (max-width: 768px) { + .skills-radar-container { + max-width: 100%; + padding: 0; + overflow: visible; + } + .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 { @@ -119,3 +131,21 @@ 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); + } +} diff --git a/src/pages/about/index.js b/src/pages/about/index.js index b74da17..9add710 100644 --- a/src/pages/about/index.js +++ b/src/pages/about/index.js @@ -92,10 +92,10 @@ export const About = () => { - +

Skills

- +