Improve school modal charts for mobile visualization
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 58s
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 58s
- Make charts taller on mobile with better aspect ratios (0.9 for <480px, 1.1 for <768px) - Shorten chart title and dataset labels on mobile - Add responsive font sizes for legend, title, and axis ticks - Add mobile-specific styling for chart container, stats grid, and modal - Add extra-small screen breakpoint (480px) for very narrow devices Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -160,7 +160,14 @@ const schoolMaps = new Map();
|
|||||||
|
|
||||||
// Helper to get chart aspect ratio based on screen size
|
// Helper to get chart aspect ratio based on screen size
|
||||||
function getChartAspectRatio() {
|
function getChartAspectRatio() {
|
||||||
return window.innerWidth <= 768 ? 1.2 : 2;
|
if (window.innerWidth <= 480) return 0.9; // Very small screens - taller chart
|
||||||
|
if (window.innerWidth <= 768) return 1.1; // Mobile - taller chart
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper to check if we're on mobile
|
||||||
|
function isMobile() {
|
||||||
|
return window.innerWidth <= 768;
|
||||||
}
|
}
|
||||||
|
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
@@ -1442,25 +1449,26 @@ async function openSchoolModal(urn) {
|
|||||||
const years = validData.map((d) => d.year);
|
const years = validData.map((d) => d.year);
|
||||||
const ctx = elements.schoolDetailChart.getContext("2d");
|
const ctx = elements.schoolDetailChart.getContext("2d");
|
||||||
|
|
||||||
|
const mobile = isMobile();
|
||||||
schoolDetailChart = new Chart(ctx, {
|
schoolDetailChart = new Chart(ctx, {
|
||||||
type: "bar",
|
type: "bar",
|
||||||
data: {
|
data: {
|
||||||
labels: years,
|
labels: years,
|
||||||
datasets: [
|
datasets: [
|
||||||
{
|
{
|
||||||
label: "Reading %",
|
label: mobile ? "Reading" : "Reading %",
|
||||||
data: validData.map((d) => d.reading_expected_pct),
|
data: validData.map((d) => d.reading_expected_pct),
|
||||||
backgroundColor: "#2d7d7d",
|
backgroundColor: "#2d7d7d",
|
||||||
borderRadius: 4,
|
borderRadius: 4,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Writing %",
|
label: mobile ? "Writing" : "Writing %",
|
||||||
data: validData.map((d) => d.writing_expected_pct),
|
data: validData.map((d) => d.writing_expected_pct),
|
||||||
backgroundColor: "#c9a227",
|
backgroundColor: "#c9a227",
|
||||||
borderRadius: 4,
|
borderRadius: 4,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Maths %",
|
label: mobile ? "Maths" : "Maths %",
|
||||||
data: validData.map((d) => d.maths_expected_pct),
|
data: validData.map((d) => d.maths_expected_pct),
|
||||||
backgroundColor: "#e07256",
|
backgroundColor: "#e07256",
|
||||||
borderRadius: 4,
|
borderRadius: 4,
|
||||||
@@ -1475,14 +1483,36 @@ async function openSchoolModal(urn) {
|
|||||||
legend: {
|
legend: {
|
||||||
position: "bottom",
|
position: "bottom",
|
||||||
labels: {
|
labels: {
|
||||||
font: { family: "'DM Sans', sans-serif" },
|
font: {
|
||||||
|
family: "'DM Sans', sans-serif",
|
||||||
|
size: mobile ? 11 : 12,
|
||||||
|
},
|
||||||
usePointStyle: true,
|
usePointStyle: true,
|
||||||
|
pointStyle: "circle",
|
||||||
|
padding: mobile ? 12 : 16,
|
||||||
|
boxWidth: mobile ? 8 : 12,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
title: {
|
title: {
|
||||||
display: true,
|
display: true,
|
||||||
text: "KS2 Attainment Over Time (% meeting expected standard)",
|
text: mobile
|
||||||
font: { family: "'Playfair Display', serif", size: 16, weight: 600 },
|
? "KS2 Attainment (% expected)"
|
||||||
|
: "KS2 Attainment Over Time (% meeting expected standard)",
|
||||||
|
font: {
|
||||||
|
family: "'Playfair Display', serif",
|
||||||
|
size: mobile ? 14 : 16,
|
||||||
|
weight: 600,
|
||||||
|
},
|
||||||
|
padding: {
|
||||||
|
bottom: mobile ? 12 : 16,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
tooltip: {
|
||||||
|
callbacks: {
|
||||||
|
label: function(context) {
|
||||||
|
return `${context.dataset.label}: ${context.parsed.y}%`;
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
scales: {
|
scales: {
|
||||||
@@ -1490,9 +1520,18 @@ async function openSchoolModal(urn) {
|
|||||||
beginAtZero: true,
|
beginAtZero: true,
|
||||||
max: 100,
|
max: 100,
|
||||||
grid: { color: "#e5dfd5" },
|
grid: { color: "#e5dfd5" },
|
||||||
|
ticks: {
|
||||||
|
font: { size: mobile ? 10 : 12 },
|
||||||
|
callback: function(value) {
|
||||||
|
return value + "%";
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
x: {
|
x: {
|
||||||
grid: { display: false },
|
grid: { display: false },
|
||||||
|
ticks: {
|
||||||
|
font: { size: mobile ? 10 : 12 },
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1420,12 +1420,76 @@ body {
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.modal-body {
|
||||||
|
padding: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-chart-container {
|
||||||
|
margin-bottom: 1.5rem;
|
||||||
|
padding: 0.5rem;
|
||||||
|
background: var(--bg-secondary);
|
||||||
|
border-radius: var(--radius-md);
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-chart-container canvas {
|
||||||
|
max-height: 280px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-stats-grid {
|
||||||
|
grid-template-columns: repeat(2, 1fr);
|
||||||
|
gap: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-stat {
|
||||||
|
padding: 0.75rem 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-stat-value {
|
||||||
|
font-size: 1.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-stat-label {
|
||||||
|
font-size: 0.65rem;
|
||||||
|
}
|
||||||
|
|
||||||
.rankings-controls {
|
.rankings-controls {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: stretch;
|
align-items: stretch;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Extra small screens */
|
||||||
|
@media (max-width: 480px) {
|
||||||
|
.modal-content {
|
||||||
|
margin: 0.5rem;
|
||||||
|
max-height: calc(100vh - 1rem);
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-header {
|
||||||
|
padding: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-header h2 {
|
||||||
|
font-size: 1.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-chart-container canvas {
|
||||||
|
max-height: 260px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-stats-grid {
|
||||||
|
grid-template-columns: repeat(2, 1fr);
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-stat-value {
|
||||||
|
font-size: 1.1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-map {
|
||||||
|
height: 160px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* =============================================================================
|
/* =============================================================================
|
||||||
TOOLTIP SYSTEM
|
TOOLTIP SYSTEM
|
||||||
============================================================================= */
|
============================================================================= */
|
||||||
|
|||||||
Reference in New Issue
Block a user