Technology

15 “kinda gross” charts from the Iron Bowl ‘25

2025-11-30 23:52
690 views
15 “kinda gross” charts from the Iron Bowl ‘25

Even watching this game live, I knew the charts wouldn’t be kind to the Tide: too many 3-and-outs, too much late-down desperation, and too much leakage once their mobile QB started gettin’ scrambly on...

15 “kinda gross” charts from the Iron Bowl ‘25Story byballoonsSun, November 30, 2025 at 11:52 PM UTC·98 min read

Even watching this game live, I knew the charts wouldn’t be kind to the Tide: too many 3-and-outs, too much late-down desperation, and too much leakage once their mobile QB started gettin’ scrambly on us.

But the Crimson Tide won the thing anyway, 27-20, on the backs of timely 4th down conversions, Red Zone efficiency, and turnovers. Sure, it’s always more “complicated” than how the numbers add up, but it wasn’t pretty.

AdvertisementAdvertisementAdvertisement

I ended up sticking with the usual format instead, but I had a few alternate title ideas for this article:

  • “Alabama Pulls an ‘Auburn’ in an Iron Bowl Win”

  • “Oklahoma infects ‘Bama with ‘The Luck-Ball Virus’”

  • “The Tide Deliver the Type of Win that Balloons Complains About When Opponents Do It”

But I settled on “kinda gross” instead. Let’s take a look:

Box Score – Alabama vs Auburn body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', sans-serif; margin: 0; padding: 0; background: #f8fafc; } .embed-container { background: white; border-radius: 12px; border: 1px solid #e5e5e5; box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); overflow: hidden; max-width: 800px; margin: 0 auto; padding: 0; } .header { padding: 18px 24px 14px; border-bottom: 1px solid #e5e5e5; background: white; } .title { font-size: 18px; font-weight: 600; color: #171717; margin: 0; } .subtitle { font-size: 11px; font-weight: 400; color: #737373; margin: 4px 0 0 0; } .table-wrapper { padding: 0; } table { min-width: 100%; table-layout: fixed; border-collapse: collapse; } .col-stat { width: auto; } .col-team { width: 140px; } thead tr { background-color: #525252; color: white; } th { padding: 12px 16px; text-align: left; font-size: 14px; font-weight: 600; border-bottom: 4px solid #475569; text-align: center; } th.stat-header { text-align: left; } tbody tr { border-bottom: 1px solid #e5e5e5; } .bg-white { background-color: #ffffff; } .bg-neutral-50 { background-color: #fafafa; } .px-4 { padding-left: 1rem; padding-right: 1rem; } .py-3 { padding-top: 0.75rem; padding-bottom: 0.75rem; } .text-sm { font-size: 0.875rem; } .font-medium { font-weight: 500; } .font-semibold { font-weight: 600; } .text-neutral-900 { color: #171717; } .text-center { text-align: center; } .embed-footer { border-top: 1px solid #e5e5e5; font-size: 12px; color: #737373; } .embed-footer-top { display: flex; justify-content: center; align-items: center; padding: 12px 16px; } .embed-footer-link { color: #737373; text-decoration: none; font-weight: 500; } .embed-footer-link:hover { color: #525252; text-decoration: underline; } @media (max-width: 640px) { .header { padding: 12px 16px; } th, td { padding: 8px 12px; } .title { font-size: 16px; } .embed-footer-top { padding: 8px 12px; } .col-team { width: 80px; } th, td { font-size: 13px; } }

Box Score

Alabama vs. Auburn • Nov 29, 2025

Stats

Alabama

Auburn

Points

27

20

Game Excitement

6.5

6.5

Total yards

280

411

Rush yards

158

152

Rush attempts

38

36

Yards per rush

4.2

4.2

Pass yards

122

259

Pass attempts

19-35

18-39

Yards per pass

3.5

6.6

1st downs

18

20

3rd down eff

4-17

8-19

4th down eff

3-3

2-3

Explosiveness

0.98

1.12

Turnovers

0

2

Tackles

48

45

Sacks

1

3

Penalties-Yds

8-87

10-84

Possession

34:29

25:31

See all charts

AdvertisementAdvertisementAdvertisement

Let’s talk about the positives from the Box Score (there aren’t many):

  • 4.2 Yards per rush (tied with Auburn)

  • 0 Turnovers

  • 3/3 on 4th down (though the Barn was 2/3 too)

  • +10 minutes time of possession

  • Alabama scored more points. Roll Tide!

Otherwise, the numbers are unkind, and these were especially bad:

  • 3.5 Yards per pass (gross)

  • Related, a sub-1 Explosivness Index (I think 0.98 is the lowest I’ve seen in games I’ve charted this season).

  • 131 fewer yards than Auburn (yes, very much including their chunk plays)

  • Still only 1 sack (against a team famous for being sacked)

.cfb-chart-embed-cfb-chart-1764536539335-q3e2y9ygr { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', sans-serif; margin: 0; padding: 0; } .cfb-chart-embed-cfb-chart-1764536539335-q3e2y9ygr .chart-container { background: white; border-radius: 12px; border: 1px solid #e5e5e5; box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); overflow: hidden; } .cfb-chart-embed-cfb-chart-1764536539335-q3e2y9ygr .chart-header { padding: 18px 24px 14px; border-bottom: 1px solid #e5e5e5; background: white; } .cfb-chart-embed-cfb-chart-1764536539335-q3e2y9ygr .chart-title { font-size: 18px; font-weight: 600; color: #171717; margin: 0; } .cfb-chart-embed-cfb-chart-1764536539335-q3e2y9ygr .chart-subtitle { font-size: 11px; font-weight: 400; color: #737373; margin: 4px 0 0 0; } .cfb-chart-embed-cfb-chart-1764536539335-q3e2y9ygr .chart-content { padding: 20px 24px 24px !important; } .cfb-chart-embed-cfb-chart-1764536539335-q3e2y9ygr .chart-content { height: 325px; } @media (max-width: 640px) { .cfb-chart-embed-cfb-chart-1764536539335-q3e2y9ygr .chart-content { padding: 12px 16px 20px !important; height: 280px !important; } .cfb-chart-embed-cfb-chart-1764536539335-q3e2y9ygr .chart-header { padding: 12px 16px 12px !important; } .cfb-chart-embed-cfb-chart-1764536539335-q3e2y9ygr .embed-footer-top { padding: 8px 12px !important; } .cfb-chart-embed-cfb-chart-1764536539335-q3e2y9ygr .data-definitions { padding: 12px !important; } } .cfb-chart-embed-cfb-chart-1764536539335-q3e2y9ygr .embed-footer { border-top: 1px solid #e5e5e5; font-size: 12px; color: #737373; } .cfb-chart-embed-cfb-chart-1764536539335-q3e2y9ygr .embed-footer-top { display: flex; justify-content: space-between; align-items: center; padding: 12px 16px; } .cfb-chart-embed-cfb-chart-1764536539335-q3e2y9ygr .embed-footer-link { color: #737373; text-decoration: none; font-weight: 500; } .cfb-chart-embed-cfb-chart-1764536539335-q3e2y9ygr .embed-footer-link:hover { color: #525252; text-decoration: underline; } .cfb-chart-embed-cfb-chart-1764536539335-q3e2y9ygr .data-definitions-toggle { background: none; border: none; color: #737373; font-size: 12px; font-weight: 500; cursor: pointer; display: flex; align-items: center; gap: 4px; padding: 0; } .cfb-chart-embed-cfb-chart-1764536539335-q3e2y9ygr .data-definitions-toggle:hover { color: #525252; } .cfb-chart-embed-cfb-chart-1764536539335-q3e2y9ygr .caret { transition: transform 0.2s ease; font-size: 10px; } .cfb-chart-embed-cfb-chart-1764536539335-q3e2y9ygr .caret.expanded { transform: rotate(180deg); } .cfb-chart-embed-cfb-chart-1764536539335-q3e2y9ygr .data-definitions { display: none; padding: 16px; background: #fafafa; border-top: 1px solid #e5e5e5; font-size: 12px; line-height: 1.4; } .cfb-chart-embed-cfb-chart-1764536539335-q3e2y9ygr .data-definitions.expanded { display: block; } .cfb-chart-embed-cfb-chart-1764536539335-q3e2y9ygr .data-definitions ul { margin: 0; padding-left: 0; list-style: none; } .cfb-chart-embed-cfb-chart-1764536539335-q3e2y9ygr .data-definitions li { margin-bottom: 4px; }

Overall Team Performance

Alabama vs. Auburn • Nov 29, 2025

AdvertisementAdvertisementAdvertisement

See all charts Data definitions ▼

  • Based roughly on the SP+ analytic system

  • Successful play: Gains enough needed yards (50% 1st down, 70% on 2nd, 100% on 3rd/4th)

  • Success Rate (SR): Percentage of plays that were successful

  • Explosiveness Rate (XR): Percentage of plays gaining 15+ yards

  • # Plays: Numbers shown in bars represent total play counts

  • NCAA Avg: Dashed line shows 42% (roughly NCAA average) success rate

// Toggle data definitions accordion - unique function per embed function toggleDefinitions_cfb_chart_1764536539335_q3e2y9ygr() { const definitions = document.getElementById('dataDefinitions_cfb-chart-1764536539335-q3e2y9ygr'); const caret = document.getElementById('caret_cfb-chart-1764536539335-q3e2y9ygr'); if (definitions.classList.contains('expanded')) { definitions.classList.remove('expanded'); caret.classList.remove('expanded'); } else { definitions.classList.add('expanded'); caret.classList.add('expanded'); } } // Sequential script loading for better reliability (function() { 'use strict'; let retryCount = 0; const maxRetries = 50; // 5 seconds total // Load scripts sequentially function loadScript(url, callback) { const script = document.createElement('script'); script.src = url; script.onload = callback; script.onerror = function() { console.error('Failed to load script:', url); showError('Failed to load required chart library'); }; document.head.appendChild(script); } function showError(message) { const canvas = document.getElementById('cfb-chart-1764536539335-q3e2y9ygr'); if (canvas && canvas.parentNode) { canvas.parentNode.innerHTML = '

' + message + '

'; } } function initChart() { retryCount++; // Check if Chart.js is available if (typeof Chart === 'undefined') { if (retryCount >= maxRetries) { showError('Chart library failed to load. Please refresh the page.'); return; } setTimeout(initChart, 100); return; } // Check if datalabels plugin is available if (typeof ChartDataLabels === 'undefined') { if (retryCount >= maxRetries) { showError('Chart plugin failed to load. Please refresh the page.'); return; } setTimeout(initChart, 100); return; } // Check if canvas element exists const canvas = document.getElementById('cfb-chart-1764536539335-q3e2y9ygr'); if (!canvas) { console.warn('Canvas element not found yet, retrying...'); setTimeout(initChart, 100); return; } // Prevent multiple chart instances if (canvas.chartInstance) { console.log('Chart already initialized'); return; } try { // Register the datalabels plugin Chart.register(ChartDataLabels); // Embed actual chart data directly const chartData = { "labels": [ "Alabama", "Auburn" ], "datasets": [ { "label": "Explosiveness Rate (XR)", "data": [ 0.06944444444444445, 0.06944444444444445 ], "backgroundColor": [ "rgba(101, 0, 20, 0.8)", "rgba(20, 59, 107, 0.8)" ], "stack": "SRXR", "datalabels": { "display": false } }, { "label": "Success Rate (SR)", "data": [ 0.3472222222222222, 0.3888888888888889 ], "backgroundColor": [ "rgba(175, 40, 60, 0.8)", "rgba(73, 133, 207, 0.8)" ], "stack": "SRXR", "datalabels": { "display": true }, "playCountData": [ 72, 72 ] }, { "type": "line", "data": [ 0.42, 0.42 ], "label": "NCAA Avg SR", "borderColor": "#757575", "borderWidth": 2, "borderDash": [ 3, 3 ], "pointRadius": 0, "datalabels": { "display": false } }, { "type": "line", "data": [ null, null ], "label": "# Plays", "backgroundColor": "rgba(0, 0, 0, 0)", "borderColor": "rgba(0, 0, 0, 0)", "borderWidth": 0, "pointRadius": 0, "showLine": false, "fill": false, "datalabels": { "display": false } } ], "teamColors": { "success": "rgba(175, 40, 60, 0.8)", "explosive": "rgba(101, 0, 20, 0.8)", "light": "rgba(245, 229, 233, 0.8)" }, "opponentColors": { "success": "rgba(73, 133, 207, 0.8)", "explosive": "rgba(20, 59, 107, 0.8)", "light": "rgba(234, 241, 251, 0.8)" }, "teamPlayCount": 72, "opponentPlayCount": 72, "currentParams": { "year": 2025, "week": 14, "seasonType": "regular", "team": "Alabama", "gameId": "401752784" } }; // Chart options (WordPress-safe) const chartOptions = { responsive: true, maintainAspectRatio: false, animation: { duration: 1 // Minimal animation to trigger layout calculation (fixes label positioning) }, elements: 'bar' === 'line' ? 'overall-team-performance'.includes('play-map') ? { line: { tension: 0, borderWidth: 0 } } : 'overall-team-performance' === 'win-probability' ? { line: { tension: 0.15, borderWidth: 2.2, fill: false }, point: { pointRadius: 0, pointHoverRadius: 4 } } : { line: { tension: 0.25, borderWidth: 2.2 }, point: { pointRadius: 'overall-team-performance'.includes('team-lines') ? 0 : undefined } } : {}, plugins: { datalabels: { display: function(context) { // Suppress data labels on line charts if ('bar' === 'line') { return false; } return context.dataset.datalabels && context.dataset.datalabels.display === true; }, formatter: function(value, context) { // Special handling for Overall Team Performance chart if ('overall-team-performance' === 'overall-team-performance' && context.dataset.label === 'Success Rate (SR)') { // Use the stored play count data if (context.dataset.playCountData && context.dataset.playCountData[context.dataIndex]) { return context.dataset.playCountData[context.dataIndex]; } // Fallback to percentage if play count data not available return Math.round(value * 100) + '%'; } // Handle bar charts with count data (play-type, quarter, down, etc.) if (context.dataset.label && context.dataset.label.includes(' SR') && (chartData.teamCounts || chartData.oppCounts)) { // Find the first team SR dataset in the chart to determine team order const allDatasets = context.chart.data.datasets; const teamSRDataset = allDatasets.find(d => d.label && d.label.includes(' SR') && !d.label.includes('NCAA')); // If this is the first team's SR dataset, use teamCounts if (teamSRDataset && context.dataset.label === teamSRDataset.label && chartData.teamCounts) { return chartData.teamCounts[context.dataIndex] || 0; } // Otherwise, use oppCounts for the second team else if (chartData.oppCounts) { return chartData.oppCounts[context.dataIndex] || 0; } } // For player charts, show value only if > 0 (matches non-embedded behavior) if ('overall-team-performance'.includes('top-rushers') || 'overall-team-performance'.includes('top-passers') || 'overall-team-performance'.includes('top-receivers')) { // Hide data labels for zero or negative values, show actual value for positive values return value > 0 ? value : null; } // For other charts, show values based on type if (typeof value === 'number') { // If value is between 0 and 1, treat as percentage if (value >= 0 && value 0 ? '#26262660' : 'transparent'; }, borderColor: function(context) { const value = context.dataset.data[context.dataIndex]; return value > 0 ? 'rgba(255, 255, 255, 0.2)' : 'transparent'; }, borderRadius: 4, align: 'center', anchor: 'center' }, legend: 'overall-team-performance' === 'win-probability' ? { display: false } : 'bar' === 'line' ? { position: 'top', align: 'start', labels: 'overall-team-performance'.includes('play-map') ? { usePointStyle: true, generateLabels: function(chart) { // Call the original generateLabels to get default styling const original = Chart.defaults.plugins.legend.labels.generateLabels; const labels = original.call(this, chart); // Filter and customize each label const filteredLabels = labels.filter(label => { return !label.text.includes(' { const dataset = chart.data.datasets[label.datasetIndex]; if (dataset && dataset.label) { if (dataset.label.includes('Rush')) { label.pointStyle = 'circle'; label.pointStyleWidth = 4; label.fillStyle = 'white'; } else if (dataset.label.includes('Pass')) { label.pointStyle = 'triangle'; label.pointStyleWidth = 4; label.fillStyle = 'white'; } else { label.pointStyle = 'rect'; label.pointStyleWidth = 4; label.fillStyle = 'white'; } } }); return filteredLabels; }, boxWidth: 20, padding: 12 } : { usePointStyle: false, boxWidth: 12, boxHeight: 12, padding: 12, generateLabels: function(chart) { const original = Chart.defaults.plugins.legend.labels.generateLabels; const labels = original.call(this, chart); // Filter out reference areas and ensure white fill const filteredLabels = labels.filter(label => { return !label.text.includes('NCAA Avg SR') && !label.text.includes('50/50') && !label.text.includes('Quarters'); }); // Ensure white fill for all line chart legend boxes filteredLabels.forEach((label) => { label.fillStyle = 'white'; }); return filteredLabels; } } } : { position: 'top', align: 'start', labels: { usePointStyle: false, boxWidth: 12, boxHeight: 12, padding: 12, filter: function(legendItem, chartData) { return !legendItem.text.includes('NCAA Avg SR') && !legendItem.text.includes('Quarters') && !legendItem.text.includes('50/50'); }, generateLabels: function(chart) { const data = chart.data; if (data.datasets.length) { return data.datasets.map((dataset, i) => { // Handle backgroundColor arrays (like in Overall Team Performance chart) let fillColor = dataset.backgroundColor; if (dataset.label === '# Plays') { fillColor = 'white'; } else if (Array.isArray(dataset.backgroundColor)) { // For datasets with backgroundColor arrays, use the first color for legend fillColor = dataset.backgroundColor[0]; } return { text: dataset.label, fillStyle: fillColor, strokeStyle: dataset.label === '# Plays' ? '#666' : dataset.borderColor, lineWidth: dataset.label === '# Plays' ? 1 : dataset.borderWidth, hidden: !chart.isDatasetVisible(i), datasetIndex: i }; }).filter((item, index) => { // Apply the same filter logic as above const dataset = chart.data.datasets[index]; if (!dataset || !dataset.data) return false; if (dataset.label === '# Plays') return true; // Always show # Plays if (dataset.label && (dataset.label.includes('NCAA Avg SR') || dataset.label.includes('Quarters') || dataset.label.includes('50/50'))) return false; return dataset.data.some((value) => value > 0); }); } return []; } } }, tooltip: 'overall-team-performance' === 'win-probability' ? { mode: 'index', intersect: false, callbacks: { title: function(tooltipItems) { if (tooltipItems && tooltipItems[0]) { return 'Play ' + (tooltipItems[0].dataIndex + 1); } return ''; }, label: function(context) { const selectedTeamWinProb = context.parsed.y; const opponentWinProb = 100 - selectedTeamWinProb; const selectedTeam = context.dataset.selectedTeam || 'Team'; const opponentTeam = context.dataset.opponentTeam || 'Opponent'; return [ selectedTeam + ': ' + selectedTeamWinProb.toFixed(1) + '%', opponentTeam + ': ' + opponentWinProb.toFixed(1) + '%' ]; }, afterLabel: function(context) { if (context.dataset.playTexts && context.dataset.playTexts[context.dataIndex]) { return '\n' + context.dataset.playTexts[context.dataIndex]; } return ''; } } } : { filter: function(tooltipItem) { if ('overall-team-performance'.includes('play-map')) { return !tooltipItem.dataset.label.includes('< 0') && !tooltipItem.dataset.label.includes('Quarters') && !tooltipItem.dataset.label.includes('Drive'); } return !tooltipItem.dataset.label.includes('NCAA Avg SR') && !tooltipItem.dataset.label.includes('50/50') && !tooltipItem.dataset.label.includes(' ds.label === 'Win Probability'); if (wpDataset && wpDataset.segmentColors) { wpDataset.segment = { borderColor: function(ctx) { // Use p1DataIndex (ending point) so the line inherits the destination color // This makes momentum shifts more visually intuitive const index = ctx.p1DataIndex; if (index !== undefined && wpDataset.segmentColors[index]) { return wpDataset.segmentColors[index]; } return wpDataset.borderColor || '#8B0000'; } }; } } // Initialize the chart const ctx = canvas.getContext('2d'); const chart = new Chart(ctx, { type: 'bar', data: chartData, options: chartOptions }); // Store reference to prevent re-initialization canvas.chartInstance = chart; console.log('CFB Chart initialized successfully'); } catch (error) { console.error('Error initializing CFB chart:', error); // Fallback: show error message in canvas container const container = document.getElementById('cfb-chart-1764536539335-q3e2y9ygr').parentNode; if (container) { container.innerHTML = '

AdvertisementAdvertisementAdvertisement

Chart failed to load. Please refresh the page.

'; } } } // Start loading scripts sequentially function startLoading() { // First, check if scripts are already loaded (multiple embeds on same page) if (typeof Chart !== 'undefined' && typeof ChartDataLabels !== 'undefined') { initChart(); return; } // Load Chart.js first if (typeof Chart === 'undefined') { loadScript('https://cdn.jsdelivr.net/npm/[email protected]/dist/chart.min.js', function() { // Then load ChartDataLabels if (typeof ChartDataLabels === 'undefined') { loadScript('https://cdn.jsdelivr.net/npm/[email protected]', function() { initChart(); }); } else { initChart(); } }); } else if (typeof ChartDataLabels === 'undefined') { // Chart.js loaded but not ChartDataLabels loadScript('https://cdn.jsdelivr.net/npm/[email protected]', function() { initChart(); }); } else { initChart(); } } // Initialize when DOM is ready if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', startLoading); } else { startLoading(); } })();

And guess what? while SR (Success Rate) and XR (Explosiveness Rate) aren’t quite as unkind to Alabama, it’s still an underperformance by a team that I’d say didn’t necessarily deserve to win on these numbers.

The 35% SR is, I believe, the worst we’ve seen from Alabama in recent memory:

  • It’s worse than games vs. South Carolina, Georgia, or LSU this season (LSU being the closest)

  • It’s even worse than the loss at Oklahoma last year

  • It’s notably worse than the loss at FSU in August (which, I’ll continue trying to educate the world that that loss wasn’t as bad as everyone seems to accept)

AdvertisementAdvertisementAdvertisement

And then the XR’s are tied at a also-recent-record-low 7%.

Yeah, neither team was hitting many explosives. But here’s where we get the funny part about Explosiveness Rate: there were only 10 explosive plays in the game across both teams, but only 2 of them were even particularly long explosives (and both were Auburns).

Just compare the Play Maps here:

.cfb-chart-embed-cfb-chart-1764537088250-s3l7558x3 { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', sans-serif; margin: 0; padding: 0; } .cfb-chart-embed-cfb-chart-1764537088250-s3l7558x3 .chart-container { background: white; border-radius: 12px; border: 1px solid #e5e5e5; box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); overflow: hidden; } .cfb-chart-embed-cfb-chart-1764537088250-s3l7558x3 .chart-header { padding: 18px 24px 14px; border-bottom: 1px solid #e5e5e5; background: white; } .cfb-chart-embed-cfb-chart-1764537088250-s3l7558x3 .chart-title { font-size: 18px; font-weight: 600; color: #171717; margin: 0; } .cfb-chart-embed-cfb-chart-1764537088250-s3l7558x3 .chart-subtitle { font-size: 11px; font-weight: 400; color: #737373; margin: 4px 0 0 0; } .cfb-chart-embed-cfb-chart-1764537088250-s3l7558x3 .chart-content { padding: 20px 24px 24px !important; } .cfb-chart-embed-cfb-chart-1764537088250-s3l7558x3 .chart-content { height: 325px; } @media (max-width: 640px) { .cfb-chart-embed-cfb-chart-1764537088250-s3l7558x3 .chart-content { padding: 12px 16px 20px !important; height: 280px !important; } .cfb-chart-embed-cfb-chart-1764537088250-s3l7558x3 .chart-header { padding: 12px 16px 12px !important; } .cfb-chart-embed-cfb-chart-1764537088250-s3l7558x3 .embed-footer-top { padding: 8px 12px !important; } .cfb-chart-embed-cfb-chart-1764537088250-s3l7558x3 .data-definitions { padding: 12px !important; } } .cfb-chart-embed-cfb-chart-1764537088250-s3l7558x3 .embed-footer { border-top: 1px solid #e5e5e5; font-size: 12px; color: #737373; } .cfb-chart-embed-cfb-chart-1764537088250-s3l7558x3 .embed-footer-top { display: flex; justify-content: space-between; align-items: center; padding: 12px 16px; } .cfb-chart-embed-cfb-chart-1764537088250-s3l7558x3 .embed-footer-link { color: #737373; text-decoration: none; font-weight: 500; } .cfb-chart-embed-cfb-chart-1764537088250-s3l7558x3 .embed-footer-link:hover { color: #525252; text-decoration: underline; } .cfb-chart-embed-cfb-chart-1764537088250-s3l7558x3 .data-definitions-toggle { background: none; border: none; color: #737373; font-size: 12px; font-weight: 500; cursor: pointer; display: flex; align-items: center; gap: 4px; padding: 0; } .cfb-chart-embed-cfb-chart-1764537088250-s3l7558x3 .data-definitions-toggle:hover { color: #525252; } .cfb-chart-embed-cfb-chart-1764537088250-s3l7558x3 .caret { transition: transform 0.2s ease; font-size: 10px; } .cfb-chart-embed-cfb-chart-1764537088250-s3l7558x3 .caret.expanded { transform: rotate(180deg); } .cfb-chart-embed-cfb-chart-1764537088250-s3l7558x3 .data-definitions { display: none; padding: 16px; background: #fafafa; border-top: 1px solid #e5e5e5; font-size: 12px; line-height: 1.4; } .cfb-chart-embed-cfb-chart-1764537088250-s3l7558x3 .data-definitions.expanded { display: block; } .cfb-chart-embed-cfb-chart-1764537088250-s3l7558x3 .data-definitions ul { margin: 0; padding-left: 0; list-style: none; } .cfb-chart-embed-cfb-chart-1764537088250-s3l7558x3 .data-definitions li { margin-bottom: 4px; }

AdvertisementAdvertisementAdvertisement

Play Map: Alabama

Alabama vs. Auburn • Nov 29, 2025

See all charts Data definitions ▼

  • Based roughly on the SP+ analytic system

  • Successful play: Gains enough needed yards (50% 1st down, 70% on 2nd, 100% on 3rd/4th)

  • Success Rate (SR): Percentage of plays that were successful

  • Explosiveness Rate (XR): Percentage of plays gaining 15+ yards

  • Play Map: Each point represents yards gained on a single play

  • Circles: Rushing plays, Triangles: Passing plays

// Toggle data definitions accordion - unique function per embed function toggleDefinitions_cfb_chart_1764537088250_s3l7558x3() { const definitions = document.getElementById('dataDefinitions_cfb-chart-1764537088250-s3l7558x3'); const caret = document.getElementById('caret_cfb-chart-1764537088250-s3l7558x3'); if (definitions.classList.contains('expanded')) { definitions.classList.remove('expanded'); caret.classList.remove('expanded'); } else { definitions.classList.add('expanded'); caret.classList.add('expanded'); } } // Sequential script loading for better reliability (function() { 'use strict'; let retryCount = 0; const maxRetries = 50; // 5 seconds total // Load scripts sequentially function loadScript(url, callback) { const script = document.createElement('script'); script.src = url; script.onload = callback; script.onerror = function() { console.error('Failed to load script:', url); showError('Failed to load required chart library'); }; document.head.appendChild(script); } function showError(message) { const canvas = document.getElementById('cfb-chart-1764537088250-s3l7558x3'); if (canvas && canvas.parentNode) { canvas.parentNode.innerHTML = '

AdvertisementAdvertisementAdvertisement

' + message + '

'; } } function initChart() { retryCount++; // Check if Chart.js is available if (typeof Chart === 'undefined') { if (retryCount >= maxRetries) { showError('Chart library failed to load. Please refresh the page.'); return; } setTimeout(initChart, 100); return; } // Check if datalabels plugin is available if (typeof ChartDataLabels === 'undefined') { if (retryCount >= maxRetries) { showError('Chart plugin failed to load. Please refresh the page.'); return; } setTimeout(initChart, 100); return; } // Check if canvas element exists const canvas = document.getElementById('cfb-chart-1764537088250-s3l7558x3'); if (!canvas) { console.warn('Canvas element not found yet, retrying...'); setTimeout(initChart, 100); return; } // Prevent multiple chart instances if (canvas.chartInstance) { console.log('Chart already initialized'); return; } try { // Register the datalabels plugin Chart.register(ChartDataLabels); // Embed actual chart data directly const chartData = { "datasets": [ { "label": " d.label && d.label.includes(' SR') && !d.label.includes('NCAA')); // If this is the first team's SR dataset, use teamCounts if (teamSRDataset && context.dataset.label === teamSRDataset.label && chartData.teamCounts) { return chartData.teamCounts[context.dataIndex] || 0; } // Otherwise, use oppCounts for the second team else if (chartData.oppCounts) { return chartData.oppCounts[context.dataIndex] || 0; } } // For player charts, show value only if > 0 (matches non-embedded behavior) if ('team-play-map'.includes('top-rushers') || 'team-play-map'.includes('top-passers') || 'team-play-map'.includes('top-receivers')) { // Hide data labels for zero or negative values, show actual value for positive values return value > 0 ? value : null; } // For other charts, show values based on type if (typeof value === 'number') { // If value is between 0 and 1, treat as percentage if (value >= 0 && value 0 ? '#26262660' : 'transparent'; }, borderColor: function(context) { const value = context.dataset.data[context.dataIndex]; return value > 0 ? 'rgba(255, 255, 255, 0.2)' : 'transparent'; }, borderRadius: 4, align: 'center', anchor: 'center' }, legend: 'team-play-map' === 'win-probability' ? { display: false } : 'line' === 'line' ? { position: 'top', align: 'start', labels: 'team-play-map'.includes('play-map') ? { usePointStyle: true, generateLabels: function(chart) { // Call the original generateLabels to get default styling const original = Chart.defaults.plugins.legend.labels.generateLabels; const labels = original.call(this, chart); // Filter and customize each label const filteredLabels = labels.filter(label => { return !label.text.includes(' { const dataset = chart.data.datasets[label.datasetIndex]; if (dataset && dataset.label) { if (dataset.label.includes('Rush')) { label.pointStyle = 'circle'; label.pointStyleWidth = 4; label.fillStyle = 'white'; } else if (dataset.label.includes('Pass')) { label.pointStyle = 'triangle'; label.pointStyleWidth = 4; label.fillStyle = 'white'; } else { label.pointStyle = 'rect'; label.pointStyleWidth = 4; label.fillStyle = 'white'; } } }); return filteredLabels; }, boxWidth: 20, padding: 12 } : { usePointStyle: false, boxWidth: 12, boxHeight: 12, padding: 12, generateLabels: function(chart) { const original = Chart.defaults.plugins.legend.labels.generateLabels; const labels = original.call(this, chart); // Filter out reference areas and ensure white fill const filteredLabels = labels.filter(label => { return !label.text.includes('NCAA Avg SR') && !label.text.includes('50/50') && !label.text.includes('Quarters'); }); // Ensure white fill for all line chart legend boxes filteredLabels.forEach((label) => { label.fillStyle = 'white'; }); return filteredLabels; } } } : { position: 'top', align: 'start', labels: { usePointStyle: false, boxWidth: 12, boxHeight: 12, padding: 12, filter: function(legendItem, chartData) { return !legendItem.text.includes('NCAA Avg SR') && !legendItem.text.includes('Quarters') && !legendItem.text.includes('50/50'); }, generateLabels: function(chart) { const data = chart.data; if (data.datasets.length) { return data.datasets.map((dataset, i) => { // Handle backgroundColor arrays (like in Overall Team Performance chart) let fillColor = dataset.backgroundColor; if (dataset.label === '# Plays') { fillColor = 'white'; } else if (Array.isArray(dataset.backgroundColor)) { // For datasets with backgroundColor arrays, use the first color for legend fillColor = dataset.backgroundColor[0]; } return { text: dataset.label, fillStyle: fillColor, strokeStyle: dataset.label === '# Plays' ? '#666' : dataset.borderColor, lineWidth: dataset.label === '# Plays' ? 1 : dataset.borderWidth, hidden: !chart.isDatasetVisible(i), datasetIndex: i }; }).filter((item, index) => { // Apply the same filter logic as above const dataset = chart.data.datasets[index]; if (!dataset || !dataset.data) return false; if (dataset.label === '# Plays') return true; // Always show # Plays if (dataset.label && (dataset.label.includes('NCAA Avg SR') || dataset.label.includes('Quarters') || dataset.label.includes('50/50'))) return false; return dataset.data.some((value) => value > 0); }); } return []; } } }, tooltip: 'team-play-map' === 'win-probability' ? { mode: 'index', intersect: false, callbacks: { title: function(tooltipItems) { if (tooltipItems && tooltipItems[0]) { return 'Play ' + (tooltipItems[0].dataIndex + 1); } return ''; }, label: function(context) { const selectedTeamWinProb = context.parsed.y; const opponentWinProb = 100 - selectedTeamWinProb; const selectedTeam = context.dataset.selectedTeam || 'Team'; const opponentTeam = context.dataset.opponentTeam || 'Opponent'; return [ selectedTeam + ': ' + selectedTeamWinProb.toFixed(1) + '%', opponentTeam + ': ' + opponentWinProb.toFixed(1) + '%' ]; }, afterLabel: function(context) { if (context.dataset.playTexts && context.dataset.playTexts[context.dataIndex]) { return '\n' + context.dataset.playTexts[context.dataIndex]; } return ''; } } } : { filter: function(tooltipItem) { if ('team-play-map'.includes('play-map')) { return !tooltipItem.dataset.label.includes('< 0') && !tooltipItem.dataset.label.includes('Quarters') && !tooltipItem.dataset.label.includes('Drive'); } return !tooltipItem.dataset.label.includes('NCAA Avg SR') && !tooltipItem.dataset.label.includes('50/50') && !tooltipItem.dataset.label.includes(' ds.label === 'Win Probability'); if (wpDataset && wpDataset.segmentColors) { wpDataset.segment = { borderColor: function(ctx) { // Use p1DataIndex (ending point) so the line inherits the destination color // This makes momentum shifts more visually intuitive const index = ctx.p1DataIndex; if (index !== undefined && wpDataset.segmentColors[index]) { return wpDataset.segmentColors[index]; } return wpDataset.borderColor || '#8B0000'; } }; } } // Initialize the chart const ctx = canvas.getContext('2d'); const chart = new Chart(ctx, { type: 'line', data: chartData, options: chartOptions }); // Store reference to prevent re-initialization canvas.chartInstance = chart; console.log('CFB Chart initialized successfully'); } catch (error) { console.error('Error initializing CFB chart:', error); // Fallback: show error message in canvas container const container = document.getElementById('cfb-chart-1764537088250-s3l7558x3').parentNode; if (container) { container.innerHTML = '

Chart failed to load. Please refresh the page.

'; } } } // Start loading scripts sequentially function startLoading() { // First, check if scripts are already loaded (multiple embeds on same page) if (typeof Chart !== 'undefined' && typeof ChartDataLabels !== 'undefined') { initChart(); return; } // Load Chart.js first if (typeof Chart === 'undefined') { loadScript('https://cdn.jsdelivr.net/npm/[email protected]/dist/chart.min.js', function() { // Then load ChartDataLabels if (typeof ChartDataLabels === 'undefined') { loadScript('https://cdn.jsdelivr.net/npm/[email protected]', function() { initChart(); }); } else { initChart(); } }); } else if (typeof ChartDataLabels === 'undefined') { // Chart.js loaded but not ChartDataLabels loadScript('https://cdn.jsdelivr.net/npm/[email protected]', function() { initChart(); }); } else { initChart(); } } // Initialize when DOM is ready if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', startLoading); } else { startLoading(); } })();

AdvertisementAdvertisementAdvertisement

.cfb-chart-embed-cfb-chart-1764537097599-n1kzox8sz { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', sans-serif; margin: 0; padding: 0; } .cfb-chart-embed-cfb-chart-1764537097599-n1kzox8sz .chart-container { background: white; border-radius: 12px; border: 1px solid #e5e5e5; box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); overflow: hidden; } .cfb-chart-embed-cfb-chart-1764537097599-n1kzox8sz .chart-header { padding: 18px 24px 14px; border-bottom: 1px solid #e5e5e5; background: white; } .cfb-chart-embed-cfb-chart-1764537097599-n1kzox8sz .chart-title { font-size: 18px; font-weight: 600; color: #171717; margin: 0; } .cfb-chart-embed-cfb-chart-1764537097599-n1kzox8sz .chart-subtitle { font-size: 11px; font-weight: 400; color: #737373; margin: 4px 0 0 0; } .cfb-chart-embed-cfb-chart-1764537097599-n1kzox8sz .chart-content { padding: 20px 24px 24px !important; } .cfb-chart-embed-cfb-chart-1764537097599-n1kzox8sz .chart-content { height: 325px; } @media (max-width: 640px) { .cfb-chart-embed-cfb-chart-1764537097599-n1kzox8sz .chart-content { padding: 12px 16px 20px !important; height: 280px !important; } .cfb-chart-embed-cfb-chart-1764537097599-n1kzox8sz .chart-header { padding: 12px 16px 12px !important; } .cfb-chart-embed-cfb-chart-1764537097599-n1kzox8sz .embed-footer-top { padding: 8px 12px !important; } .cfb-chart-embed-cfb-chart-1764537097599-n1kzox8sz .data-definitions { padding: 12px !important; } } .cfb-chart-embed-cfb-chart-1764537097599-n1kzox8sz .embed-footer { border-top: 1px solid #e5e5e5; font-size: 12px; color: #737373; } .cfb-chart-embed-cfb-chart-1764537097599-n1kzox8sz .embed-footer-top { display: flex; justify-content: space-between; align-items: center; padding: 12px 16px; } .cfb-chart-embed-cfb-chart-1764537097599-n1kzox8sz .embed-footer-link { color: #737373; text-decoration: none; font-weight: 500; } .cfb-chart-embed-cfb-chart-1764537097599-n1kzox8sz .embed-footer-link:hover { color: #525252; text-decoration: underline; } .cfb-chart-embed-cfb-chart-1764537097599-n1kzox8sz .data-definitions-toggle { background: none; border: none; color: #737373; font-size: 12px; font-weight: 500; cursor: pointer; display: flex; align-items: center; gap: 4px; padding: 0; } .cfb-chart-embed-cfb-chart-1764537097599-n1kzox8sz .data-definitions-toggle:hover { color: #525252; } .cfb-chart-embed-cfb-chart-1764537097599-n1kzox8sz .caret { transition: transform 0.2s ease; font-size: 10px; } .cfb-chart-embed-cfb-chart-1764537097599-n1kzox8sz .caret.expanded { transform: rotate(180deg); } .cfb-chart-embed-cfb-chart-1764537097599-n1kzox8sz .data-definitions { display: none; padding: 16px; background: #fafafa; border-top: 1px solid #e5e5e5; font-size: 12px; line-height: 1.4; } .cfb-chart-embed-cfb-chart-1764537097599-n1kzox8sz .data-definitions.expanded { display: block; } .cfb-chart-embed-cfb-chart-1764537097599-n1kzox8sz .data-definitions ul { margin: 0; padding-left: 0; list-style: none; } .cfb-chart-embed-cfb-chart-1764537097599-n1kzox8sz .data-definitions li { margin-bottom: 4px; }

Play Map: Auburn

Alabama vs. Auburn • Nov 29, 2025

See all charts Data definitions ▼

AdvertisementAdvertisementAdvertisement
  • Based roughly on the SP+ analytic system

  • Successful play: Gains enough needed yards (50% 1st down, 70% on 2nd, 100% on 3rd/4th)

  • Success Rate (SR): Percentage of plays that were successful

  • Explosiveness Rate (XR): Percentage of plays gaining 15+ yards

  • Play Map: Each point represents yards gained on a single play

  • Circles: Rushing plays, Triangles: Passing plays

// Toggle data definitions accordion - unique function per embed function toggleDefinitions_cfb_chart_1764537097599_n1kzox8sz() { const definitions = document.getElementById('dataDefinitions_cfb-chart-1764537097599-n1kzox8sz'); const caret = document.getElementById('caret_cfb-chart-1764537097599-n1kzox8sz'); if (definitions.classList.contains('expanded')) { definitions.classList.remove('expanded'); caret.classList.remove('expanded'); } else { definitions.classList.add('expanded'); caret.classList.add('expanded'); } } // Sequential script loading for better reliability (function() { 'use strict'; let retryCount = 0; const maxRetries = 50; // 5 seconds total // Load scripts sequentially function loadScript(url, callback) { const script = document.createElement('script'); script.src = url; script.onload = callback; script.onerror = function() { console.error('Failed to load script:', url); showError('Failed to load required chart library'); }; document.head.appendChild(script); } function showError(message) { const canvas = document.getElementById('cfb-chart-1764537097599-n1kzox8sz'); if (canvas && canvas.parentNode) { canvas.parentNode.innerHTML = '

' + message + '

'; } } function initChart() { retryCount++; // Check if Chart.js is available if (typeof Chart === 'undefined') { if (retryCount >= maxRetries) { showError('Chart library failed to load. Please refresh the page.'); return; } setTimeout(initChart, 100); return; } // Check if datalabels plugin is available if (typeof ChartDataLabels === 'undefined') { if (retryCount >= maxRetries) { showError('Chart plugin failed to load. Please refresh the page.'); return; } setTimeout(initChart, 100); return; } // Check if canvas element exists const canvas = document.getElementById('cfb-chart-1764537097599-n1kzox8sz'); if (!canvas) { console.warn('Canvas element not found yet, retrying...'); setTimeout(initChart, 100); return; } // Prevent multiple chart instances if (canvas.chartInstance) { console.log('Chart already initialized'); return; } try { // Register the datalabels plugin Chart.register(ChartDataLabels); // Embed actual chart data directly const chartData = { "datasets": [ { "label": " d.label && d.label.includes(' SR') && !d.label.includes('NCAA')); // If this is the first team's SR dataset, use teamCounts if (teamSRDataset && context.dataset.label === teamSRDataset.label && chartData.teamCounts) { return chartData.teamCounts[context.dataIndex] || 0; } // Otherwise, use oppCounts for the second team else if (chartData.oppCounts) { return chartData.oppCounts[context.dataIndex] || 0; } } // For player charts, show value only if > 0 (matches non-embedded behavior) if ('opponent-play-map'.includes('top-rushers') || 'opponent-play-map'.includes('top-passers') || 'opponent-play-map'.includes('top-receivers')) { // Hide data labels for zero or negative values, show actual value for positive values return value > 0 ? value : null; } // For other charts, show values based on type if (typeof value === 'number') { // If value is between 0 and 1, treat as percentage if (value >= 0 && value 0 ? '#26262660' : 'transparent'; }, borderColor: function(context) { const value = context.dataset.data[context.dataIndex]; return value > 0 ? 'rgba(255, 255, 255, 0.2)' : 'transparent'; }, borderRadius: 4, align: 'center', anchor: 'center' }, legend: 'opponent-play-map' === 'win-probability' ? { display: false } : 'line' === 'line' ? { position: 'top', align: 'start', labels: 'opponent-play-map'.includes('play-map') ? { usePointStyle: true, generateLabels: function(chart) { // Call the original generateLabels to get default styling const original = Chart.defaults.plugins.legend.labels.generateLabels; const labels = original.call(this, chart); // Filter and customize each label const filteredLabels = labels.filter(label => { return !label.text.includes(' { const dataset = chart.data.datasets[label.datasetIndex]; if (dataset && dataset.label) { if (dataset.label.includes('Rush')) { label.pointStyle = 'circle'; label.pointStyleWidth = 4; label.fillStyle = 'white'; } else if (dataset.label.includes('Pass')) { label.pointStyle = 'triangle'; label.pointStyleWidth = 4; label.fillStyle = 'white'; } else { label.pointStyle = 'rect'; label.pointStyleWidth = 4; label.fillStyle = 'white'; } } }); return filteredLabels; }, boxWidth: 20, padding: 12 } : { usePointStyle: false, boxWidth: 12, boxHeight: 12, padding: 12, generateLabels: function(chart) { const original = Chart.defaults.plugins.legend.labels.generateLabels; const labels = original.call(this, chart); // Filter out reference areas and ensure white fill const filteredLabels = labels.filter(label => { return !label.text.includes('NCAA Avg SR') && !label.text.includes('50/50') && !label.text.includes('Quarters'); }); // Ensure white fill for all line chart legend boxes filteredLabels.forEach((label) => { label.fillStyle = 'white'; }); return filteredLabels; } } } : { position: 'top', align: 'start', labels: { usePointStyle: false, boxWidth: 12, boxHeight: 12, padding: 12, filter: function(legendItem, chartData) { return !legendItem.text.includes('NCAA Avg SR') && !legendItem.text.includes('Quarters') && !legendItem.text.includes('50/50'); }, generateLabels: function(chart) { const data = chart.data; if (data.datasets.length) { return data.datasets.map((dataset, i) => { // Handle backgroundColor arrays (like in Overall Team Performance chart) let fillColor = dataset.backgroundColor; if (dataset.label === '# Plays') { fillColor = 'white'; } else if (Array.isArray(dataset.backgroundColor)) { // For datasets with backgroundColor arrays, use the first color for legend fillColor = dataset.backgroundColor[0]; } return { text: dataset.label, fillStyle: fillColor, strokeStyle: dataset.label === '# Plays' ? '#666' : dataset.borderColor, lineWidth: dataset.label === '# Plays' ? 1 : dataset.borderWidth, hidden: !chart.isDatasetVisible(i), datasetIndex: i }; }).filter((item, index) => { // Apply the same filter logic as above const dataset = chart.data.datasets[index]; if (!dataset || !dataset.data) return false; if (dataset.label === '# Plays') return true; // Always show # Plays if (dataset.label && (dataset.label.includes('NCAA Avg SR') || dataset.label.includes('Quarters') || dataset.label.includes('50/50'))) return false; return dataset.data.some((value) => value > 0); }); } return []; } } }, tooltip: 'opponent-play-map' === 'win-probability' ? { mode: 'index', intersect: false, callbacks: { title: function(tooltipItems) { if (tooltipItems && tooltipItems[0]) { return 'Play ' + (tooltipItems[0].dataIndex + 1); } return ''; }, label: function(context) { const selectedTeamWinProb = context.parsed.y; const opponentWinProb = 100 - selectedTeamWinProb; const selectedTeam = context.dataset.selectedTeam || 'Team'; const opponentTeam = context.dataset.opponentTeam || 'Opponent'; return [ selectedTeam + ': ' + selectedTeamWinProb.toFixed(1) + '%', opponentTeam + ': ' + opponentWinProb.toFixed(1) + '%' ]; }, afterLabel: function(context) { if (context.dataset.playTexts && context.dataset.playTexts[context.dataIndex]) { return '\n' + context.dataset.playTexts[context.dataIndex]; } return ''; } } } : { filter: function(tooltipItem) { if ('opponent-play-map'.includes('play-map')) { return !tooltipItem.dataset.label.includes('< 0') && !tooltipItem.dataset.label.includes('Quarters') && !tooltipItem.dataset.label.includes('Drive'); } return !tooltipItem.dataset.label.includes('NCAA Avg SR') && !tooltipItem.dataset.label.includes('50/50') && !tooltipItem.dataset.label.includes(' ds.label === 'Win Probability'); if (wpDataset && wpDataset.segmentColors) { wpDataset.segment = { borderColor: function(ctx) { // Use p1DataIndex (ending point) so the line inherits the destination color // This makes momentum shifts more visually intuitive const index = ctx.p1DataIndex; if (index !== undefined && wpDataset.segmentColors[index]) { return wpDataset.segmentColors[index]; } return wpDataset.borderColor || '#8B0000'; } }; } } // Initialize the chart const ctx = canvas.getContext('2d'); const chart = new Chart(ctx, { type: 'line', data: chartData, options: chartOptions }); // Store reference to prevent re-initialization canvas.chartInstance = chart; console.log('CFB Chart initialized successfully'); } catch (error) { console.error('Error initializing CFB chart:', error); // Fallback: show error message in canvas container const container = document.getElementById('cfb-chart-1764537097599-n1kzox8sz').parentNode; if (container) { container.innerHTML = '

Chart failed to load. Please refresh the page.

AdvertisementAdvertisementAdvertisement

'; } } } // Start loading scripts sequentially function startLoading() { // First, check if scripts are already loaded (multiple embeds on same page) if (typeof Chart !== 'undefined' && typeof ChartDataLabels !== 'undefined') { initChart(); return; } // Load Chart.js first if (typeof Chart === 'undefined') { loadScript('https://cdn.jsdelivr.net/npm/[email protected]/dist/chart.min.js', function() { // Then load ChartDataLabels if (typeof ChartDataLabels === 'undefined') { loadScript('https://cdn.jsdelivr.net/npm/[email protected]', function() { initChart(); }); } else { initChart(); } }); } else if (typeof ChartDataLabels === 'undefined') { // Chart.js loaded but not ChartDataLabels loadScript('https://cdn.jsdelivr.net/npm/[email protected]', function() { initChart(); }); } else { initChart(); } } // Initialize when DOM is ready if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', startLoading); } else { startLoading(); } })();

Yikes. I mean, Auburn’s offense was a total graveyard in the first half (especially before middle of the 2nd quarter), but those two massive receptions really made this a game after halftime. It was basically the Tigers’ entire offense (which, I’ll add, does make me consider the yardage differential in a different light).

This Auburn chart vaguely reminds me of some of the Play Maps we’d see from the Milroe offense, like in this 2023 game against Texas A&M, where we floundered around for the most part, but then hit some huge passes to win a close one 26-20:

.cfb-chart-embed-cfb-chart-1764544876985-66h22q6ky { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', sans-serif; margin: 0; padding: 0; } .cfb-chart-embed-cfb-chart-1764544876985-66h22q6ky .chart-container { background: white; border-radius: 12px; border: 1px solid #e5e5e5; box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); overflow: hidden; } .cfb-chart-embed-cfb-chart-1764544876985-66h22q6ky .chart-header { padding: 18px 24px 14px; border-bottom: 1px solid #e5e5e5; background: white; } .cfb-chart-embed-cfb-chart-1764544876985-66h22q6ky .chart-title { font-size: 18px; font-weight: 600; color: #171717; margin: 0; } .cfb-chart-embed-cfb-chart-1764544876985-66h22q6ky .chart-subtitle { font-size: 11px; font-weight: 400; color: #737373; margin: 4px 0 0 0; } .cfb-chart-embed-cfb-chart-1764544876985-66h22q6ky .chart-content { padding: 20px 24px 24px !important; } .cfb-chart-embed-cfb-chart-1764544876985-66h22q6ky .chart-content { height: 325px; } @media (max-width: 640px) { .cfb-chart-embed-cfb-chart-1764544876985-66h22q6ky .chart-content { padding: 12px 16px 20px !important; height: 280px !important; } .cfb-chart-embed-cfb-chart-1764544876985-66h22q6ky .chart-header { padding: 12px 16px 12px !important; } .cfb-chart-embed-cfb-chart-1764544876985-66h22q6ky .embed-footer-top { padding: 8px 12px !important; } .cfb-chart-embed-cfb-chart-1764544876985-66h22q6ky .data-definitions { padding: 12px !important; } } .cfb-chart-embed-cfb-chart-1764544876985-66h22q6ky .embed-footer { border-top: 1px solid #e5e5e5; font-size: 12px; color: #737373; } .cfb-chart-embed-cfb-chart-1764544876985-66h22q6ky .embed-footer-top { display: flex; justify-content: space-between; align-items: center; padding: 12px 16px; } .cfb-chart-embed-cfb-chart-1764544876985-66h22q6ky .embed-footer-link { color: #737373; text-decoration: none; font-weight: 500; } .cfb-chart-embed-cfb-chart-1764544876985-66h22q6ky .embed-footer-link:hover { color: #525252; text-decoration: underline; } .cfb-chart-embed-cfb-chart-1764544876985-66h22q6ky .data-definitions-toggle { background: none; border: none; color: #737373; font-size: 12px; font-weight: 500; cursor: pointer; display: flex; align-items: center; gap: 4px; padding: 0; } .cfb-chart-embed-cfb-chart-1764544876985-66h22q6ky .data-definitions-toggle:hover { color: #525252; } .cfb-chart-embed-cfb-chart-1764544876985-66h22q6ky .caret { transition: transform 0.2s ease; font-size: 10px; } .cfb-chart-embed-cfb-chart-1764544876985-66h22q6ky .caret.expanded { transform: rotate(180deg); } .cfb-chart-embed-cfb-chart-1764544876985-66h22q6ky .data-definitions { display: none; padding: 16px; background: #fafafa; border-top: 1px solid #e5e5e5; font-size: 12px; line-height: 1.4; } .cfb-chart-embed-cfb-chart-1764544876985-66h22q6ky .data-definitions.expanded { display: block; } .cfb-chart-embed-cfb-chart-1764544876985-66h22q6ky .data-definitions ul { margin: 0; padding-left: 0; list-style: none; } .cfb-chart-embed-cfb-chart-1764544876985-66h22q6ky .data-definitions li { margin-bottom: 4px; }

AdvertisementAdvertisementAdvertisement

Play Map: Alabama

Alabama vs. Texas A&M • Oct 7, 2023

See all charts Data definitions ▼

  • Based roughly on the SP+ analytic system

  • Successful play: Gains enough needed yards (50% 1st down, 70% on 2nd, 100% on 3rd/4th)

  • Success Rate (SR): Percentage of plays that were successful

  • Explosiveness Rate (XR): Percentage of plays gaining 15+ yards

  • Play Map: Each point represents yards gained on a single play

  • Circles: Rushing plays, Triangles: Passing plays

// Toggle data definitions accordion - unique function per embed function toggleDefinitions_cfb_chart_1764544876985_66h22q6ky() { const definitions = document.getElementById('dataDefinitions_cfb-chart-1764544876985-66h22q6ky'); const caret = document.getElementById('caret_cfb-chart-1764544876985-66h22q6ky'); if (definitions.classList.contains('expanded')) { definitions.classList.remove('expanded'); caret.classList.remove('expanded'); } else { definitions.classList.add('expanded'); caret.classList.add('expanded'); } } // Sequential script loading for better reliability (function() { 'use strict'; let retryCount = 0; const maxRetries = 50; // 5 seconds total // Load scripts sequentially function loadScript(url, callback) { const script = document.createElement('script'); script.src = url; script.onload = callback; script.onerror = function() { console.error('Failed to load script:', url); showError('Failed to load required chart library'); }; document.head.appendChild(script); } function showError(message) { const canvas = document.getElementById('cfb-chart-1764544876985-66h22q6ky'); if (canvas && canvas.parentNode) { canvas.parentNode.innerHTML = '

AdvertisementAdvertisementAdvertisement

' + message + '

'; } } function initChart() { retryCount++; // Check if Chart.js is available if (typeof Chart === 'undefined') { if (retryCount >= maxRetries) { showError('Chart library failed to load. Please refresh the page.'); return; } setTimeout(initChart, 100); return; } // Check if datalabels plugin is available if (typeof ChartDataLabels === 'undefined') { if (retryCount >= maxRetries) { showError('Chart plugin failed to load. Please refresh the page.'); return; } setTimeout(initChart, 100); return; } // Check if canvas element exists const canvas = document.getElementById('cfb-chart-1764544876985-66h22q6ky'); if (!canvas) { console.warn('Canvas element not found yet, retrying...'); setTimeout(initChart, 100); return; } // Prevent multiple chart instances if (canvas.chartInstance) { console.log('Chart already initialized'); return; } try { // Register the datalabels plugin Chart.register(ChartDataLabels); // Embed actual chart data directly const chartData = { "datasets": [ { "label": " d.label && d.label.includes(' SR') && !d.label.includes('NCAA')); // If this is the first team's SR dataset, use teamCounts if (teamSRDataset && context.dataset.label === teamSRDataset.label && chartData.teamCounts) { return chartData.teamCounts[context.dataIndex] || 0; } // Otherwise, use oppCounts for the second team else if (chartData.oppCounts) { return chartData.oppCounts[context.dataIndex] || 0; } } // For player charts, show value only if > 0 (matches non-embedded behavior) if ('team-play-map'.includes('top-rushers') || 'team-play-map'.includes('top-passers') || 'team-play-map'.includes('top-receivers')) { // Hide data labels for zero or negative values, show actual value for positive values return value > 0 ? value : null; } // For other charts, show values based on type if (typeof value === 'number') { // If value is between 0 and 1, treat as percentage if (value >= 0 && value 0 ? '#26262660' : 'transparent'; }, borderColor: function(context) { const value = context.dataset.data[context.dataIndex]; return value > 0 ? 'rgba(255, 255, 255, 0.2)' : 'transparent'; }, borderRadius: 4, align: 'center', anchor: 'center' }, legend: 'team-play-map' === 'win-probability' ? { display: false } : 'line' === 'line' ? { position: 'top', align: 'start', labels: 'team-play-map'.includes('play-map') ? { usePointStyle: true, generateLabels: function(chart) { // Call the original generateLabels to get default styling const original = Chart.defaults.plugins.legend.labels.generateLabels; const labels = original.call(this, chart); // Filter and customize each label const filteredLabels = labels.filter(label => { return !label.text.includes(' { const dataset = chart.data.datasets[label.datasetIndex]; if (dataset && dataset.label) { if (dataset.label.includes('Rush')) { label.pointStyle = 'circle'; label.pointStyleWidth = 4; label.fillStyle = 'white'; } else if (dataset.label.includes('Pass')) { label.pointStyle = 'triangle'; label.pointStyleWidth = 4; label.fillStyle = 'white'; } else { label.pointStyle = 'rect'; label.pointStyleWidth = 4; label.fillStyle = 'white'; } } }); return filteredLabels; }, boxWidth: 20, padding: 12 } : { usePointStyle: false, boxWidth: 12, boxHeight: 12, padding: 12, generateLabels: function(chart) { const original = Chart.defaults.plugins.legend.labels.generateLabels; const labels = original.call(this, chart); // Filter out reference areas and ensure white fill const filteredLabels = labels.filter(label => { return !label.text.includes('NCAA Avg SR') && !label.text.includes('50/50') && !label.text.includes('Quarters'); }); // Ensure white fill for all line chart legend boxes filteredLabels.forEach((label) => { label.fillStyle = 'white'; }); return filteredLabels; } } } : { position: 'top', align: 'start', labels: { usePointStyle: false, boxWidth: 12, boxHeight: 12, padding: 12, filter: function(legendItem, chartData) { return !legendItem.text.includes('NCAA Avg SR') && !legendItem.text.includes('Quarters') && !legendItem.text.includes('50/50'); }, generateLabels: function(chart) { const data = chart.data; if (data.datasets.length) { return data.datasets.map((dataset, i) => { // Handle backgroundColor arrays (like in Overall Team Performance chart) let fillColor = dataset.backgroundColor; if (dataset.label === '# Plays') { fillColor = 'white'; } else if (Array.isArray(dataset.backgroundColor)) { // For datasets with backgroundColor arrays, use the first color for legend fillColor = dataset.backgroundColor[0]; } return { text: dataset.label, fillStyle: fillColor, strokeStyle: dataset.label === '# Plays' ? '#666' : dataset.borderColor, lineWidth: dataset.label === '# Plays' ? 1 : dataset.borderWidth, hidden: !chart.isDatasetVisible(i), datasetIndex: i }; }).filter((item, index) => { // Apply the same filter logic as above const dataset = chart.data.datasets[index]; if (!dataset || !dataset.data) return false; if (dataset.label === '# Plays') return true; // Always show # Plays if (dataset.label && (dataset.label.includes('NCAA Avg SR') || dataset.label.includes('Quarters') || dataset.label.includes('50/50'))) return false; return dataset.data.some((value) => value > 0); }); } return []; } } }, tooltip: 'team-play-map' === 'win-probability' ? { mode: 'index', intersect: false, callbacks: { title: function(tooltipItems) { if (tooltipItems && tooltipItems[0]) { return 'Play ' + (tooltipItems[0].dataIndex + 1); } return ''; }, label: function(context) { const selectedTeamWinProb = context.parsed.y; const opponentWinProb = 100 - selectedTeamWinProb; const selectedTeam = context.dataset.selectedTeam || 'Team'; const opponentTeam = context.dataset.opponentTeam || 'Opponent'; return [ selectedTeam + ': ' + selectedTeamWinProb.toFixed(1) + '%', opponentTeam + ': ' + opponentWinProb.toFixed(1) + '%' ]; }, afterLabel: function(context) { if (context.dataset.playTexts && context.dataset.playTexts[context.dataIndex]) { return '\n' + context.dataset.playTexts[context.dataIndex]; } return ''; } } } : { filter: function(tooltipItem) { if ('team-play-map'.includes('play-map')) { return !tooltipItem.dataset.label.includes('< 0') && !tooltipItem.dataset.label.includes('Quarters') && !tooltipItem.dataset.label.includes('Drive'); } return !tooltipItem.dataset.label.includes('NCAA Avg SR') && !tooltipItem.dataset.label.includes('50/50') && !tooltipItem.dataset.label.includes(' ds.label === 'Win Probability'); if (wpDataset && wpDataset.segmentColors) { wpDataset.segment = { borderColor: function(ctx) { // Use p1DataIndex (ending point) so the line inherits the destination color // This makes momentum shifts more visually intuitive const index = ctx.p1DataIndex; if (index !== undefined && wpDataset.segmentColors[index]) { return wpDataset.segmentColors[index]; } return wpDataset.borderColor || '#8B0000'; } }; } } // Initialize the chart const ctx = canvas.getContext('2d'); const chart = new Chart(ctx, { type: 'line', data: chartData, options: chartOptions }); // Store reference to prevent re-initialization canvas.chartInstance = chart; console.log('CFB Chart initialized successfully'); } catch (error) { console.error('Error initializing CFB chart:', error); // Fallback: show error message in canvas container const container = document.getElementById('cfb-chart-1764544876985-66h22q6ky').parentNode; if (container) { container.innerHTML = '

Chart failed to load. Please refresh the page.

'; } } } // Start loading scripts sequentially function startLoading() { // First, check if scripts are already loaded (multiple embeds on same page) if (typeof Chart !== 'undefined' && typeof ChartDataLabels !== 'undefined') { initChart(); return; } // Load Chart.js first if (typeof Chart === 'undefined') { loadScript('https://cdn.jsdelivr.net/npm/[email protected]/dist/chart.min.js', function() { // Then load ChartDataLabels if (typeof ChartDataLabels === 'undefined') { loadScript('https://cdn.jsdelivr.net/npm/[email protected]', function() { initChart(); }); } else { initChart(); } }); } else if (typeof ChartDataLabels === 'undefined') { // Chart.js loaded but not ChartDataLabels loadScript('https://cdn.jsdelivr.net/npm/[email protected]', function() { initChart(); }); } else { initChart(); } } // Initialize when DOM is ready if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', startLoading); } else { startLoading(); } })();

AdvertisementAdvertisementAdvertisement

Some bad charts

You know what? Let’s just speed through some of the bad from this game:

.cfb-chart-embed-cfb-chart-1764545298888-r3yh9f4m5 { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', sans-serif; margin: 0; padding: 0; } .cfb-chart-embed-cfb-chart-1764545298888-r3yh9f4m5 .chart-container { background: white; border-radius: 12px; border: 1px solid #e5e5e5; box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); overflow: hidden; } .cfb-chart-embed-cfb-chart-1764545298888-r3yh9f4m5 .chart-header { padding: 18px 24px 14px; border-bottom: 1px solid #e5e5e5; background: white; } .cfb-chart-embed-cfb-chart-1764545298888-r3yh9f4m5 .chart-title { font-size: 18px; font-weight: 600; color: #171717; margin: 0; } .cfb-chart-embed-cfb-chart-1764545298888-r3yh9f4m5 .chart-subtitle { font-size: 11px; font-weight: 400; color: #737373; margin: 4px 0 0 0; } .cfb-chart-embed-cfb-chart-1764545298888-r3yh9f4m5 .chart-content { padding: 20px 24px 24px !important; } .cfb-chart-embed-cfb-chart-1764545298888-r3yh9f4m5 .chart-content { height: 325px; } @media (max-width: 640px) { .cfb-chart-embed-cfb-chart-1764545298888-r3yh9f4m5 .chart-content { padding: 12px 16px 20px !important; height: 280px !important; } .cfb-chart-embed-cfb-chart-1764545298888-r3yh9f4m5 .chart-header { padding: 12px 16px 12px !important; } .cfb-chart-embed-cfb-chart-1764545298888-r3yh9f4m5 .embed-footer-top { padding: 8px 12px !important; } .cfb-chart-embed-cfb-chart-1764545298888-r3yh9f4m5 .data-definitions { padding: 12px !important; } } .cfb-chart-embed-cfb-chart-1764545298888-r3yh9f4m5 .embed-footer { border-top: 1px solid #e5e5e5; font-size: 12px; color: #737373; } .cfb-chart-embed-cfb-chart-1764545298888-r3yh9f4m5 .embed-footer-top { display: flex; justify-content: space-between; align-items: center; padding: 12px 16px; } .cfb-chart-embed-cfb-chart-1764545298888-r3yh9f4m5 .embed-footer-link { color: #737373; text-decoration: none; font-weight: 500; } .cfb-chart-embed-cfb-chart-1764545298888-r3yh9f4m5 .embed-footer-link:hover { color: #525252; text-decoration: underline; } .cfb-chart-embed-cfb-chart-1764545298888-r3yh9f4m5 .data-definitions-toggle { background: none; border: none; color: #737373; font-size: 12px; font-weight: 500; cursor: pointer; display: flex; align-items: center; gap: 4px; padding: 0; } .cfb-chart-embed-cfb-chart-1764545298888-r3yh9f4m5 .data-definitions-toggle:hover { color: #525252; } .cfb-chart-embed-cfb-chart-1764545298888-r3yh9f4m5 .caret { transition: transform 0.2s ease; font-size: 10px; } .cfb-chart-embed-cfb-chart-1764545298888-r3yh9f4m5 .caret.expanded { transform: rotate(180deg); } .cfb-chart-embed-cfb-chart-1764545298888-r3yh9f4m5 .data-definitions { display: none; padding: 16px; background: #fafafa; border-top: 1px solid #e5e5e5; font-size: 12px; line-height: 1.4; } .cfb-chart-embed-cfb-chart-1764545298888-r3yh9f4m5 .data-definitions.expanded { display: block; } .cfb-chart-embed-cfb-chart-1764545298888-r3yh9f4m5 .data-definitions ul { margin: 0; padding-left: 0; list-style: none; } .cfb-chart-embed-cfb-chart-1764545298888-r3yh9f4m5 .data-definitions li { margin-bottom: 4px; }

SR, XR, and Play Count by Drive: Alabama

Alabama vs. Auburn • Nov 29, 2025

AdvertisementAdvertisementAdvertisement

See all charts Data definitions ▼

  • Based roughly on the SP+ analytic system

  • Successful play: Gains enough needed yards (50% 1st down, 70% on 2nd, 100% on 3rd/4th)

  • Success Rate (SR): Percentage of plays that were successful

  • Explosiveness Rate (XR): Percentage of plays gaining 15+ yards

  • Drive Metrics: Success and explosiveness rates calculated per drive

  • Play counts: Gray bars show number of plays in each drive

// Toggle data definitions accordion - unique function per embed function toggleDefinitions_cfb_chart_1764545298888_r3yh9f4m5() { const definitions = document.getElementById('dataDefinitions_cfb-chart-1764545298888-r3yh9f4m5'); const caret = document.getElementById('caret_cfb-chart-1764545298888-r3yh9f4m5'); if (definitions.classList.contains('expanded')) { definitions.classList.remove('expanded'); caret.classList.remove('expanded'); } else { definitions.classList.add('expanded'); caret.classList.add('expanded'); } } // Sequential script loading for better reliability (function() { 'use strict'; let retryCount = 0; const maxRetries = 50; // 5 seconds total // Load scripts sequentially function loadScript(url, callback) { const script = document.createElement('script'); script.src = url; script.onload = callback; script.onerror = function() { console.error('Failed to load script:', url); showError('Failed to load required chart library'); }; document.head.appendChild(script); } function showError(message) { const canvas = document.getElementById('cfb-chart-1764545298888-r3yh9f4m5'); if (canvas && canvas.parentNode) { canvas.parentNode.innerHTML = '

' + message + '

'; } } function initChart() { retryCount++; // Check if Chart.js is available if (typeof Chart === 'undefined') { if (retryCount >= maxRetries) { showError('Chart library failed to load. Please refresh the page.'); return; } setTimeout(initChart, 100); return; } // Check if datalabels plugin is available if (typeof ChartDataLabels === 'undefined') { if (retryCount >= maxRetries) { showError('Chart plugin failed to load. Please refresh the page.'); return; } setTimeout(initChart, 100); return; } // Check if canvas element exists const canvas = document.getElementById('cfb-chart-1764545298888-r3yh9f4m5'); if (!canvas) { console.warn('Canvas element not found yet, retrying...'); setTimeout(initChart, 100); return; } // Prevent multiple chart instances if (canvas.chartInstance) { console.log('Chart already initialized'); return; } try { // Register the datalabels plugin Chart.register(ChartDataLabels); // Embed actual chart data directly const chartData = { "labels": [ "Drive 1", "Drive 3", "Drive 5", "Drive 7", "Drive 9", "Drive 11", "Drive 13", "Drive 16", "Drive 18", "Drive 20", "Drive 23", "Drive 25" ], "datasets": [ { "label": "Alabama XR", "data": [ 0, 0, 0, 0.2857142857142857, 0.3333333333333333, 0, 0, 0.08333333333333333, 0, 0, 0, 0 ], "backgroundColor": "rgba(101, 0, 20, 0.8)", "stack": "SRXR", "yAxisID": "y", "datalabels": { "display": false } }, { "label": "Alabama SR", "data": [ 0.2, 0.4444444444444444, 0, 0.5714285714285714, 0.8333333333333334, 0, 0, 0.25, 0.3333333333333333, 0, 0.4666666666666667, 0 ], "backgroundColor": "rgba(175, 40, 60, 0.8)", "stack": "SRXR", "yAxisID": "y", "datalabels": { "display": false } }, { "label": "Plays in drive", "data": [ 5, 9, 3, 7, 6, 3, 3, 12, 3, 3, 15, 3 ], "backgroundColor": "rgba(148, 148, 148, 0.8)", "stack": "Plays", "yAxisID": "y1", "datalabels": { "display": true } } ], "currentParams": { "year": 2025, "week": 14, "seasonType": "regular", "team": "Alabama", "gameId": "401752784" } }; // Chart options (WordPress-safe) const chartOptions = { responsive: true, maintainAspectRatio: false, animation: { duration: 1 // Minimal animation to trigger layout calculation (fixes label positioning) }, elements: 'bar' === 'line' ? 'team-drive-metrics'.includes('play-map') ? { line: { tension: 0, borderWidth: 0 } } : 'team-drive-metrics' === 'win-probability' ? { line: { tension: 0.15, borderWidth: 2.2, fill: false }, point: { pointRadius: 0, pointHoverRadius: 4 } } : { line: { tension: 0.25, borderWidth: 2.2 }, point: { pointRadius: 'team-drive-metrics'.includes('team-lines') ? 0 : undefined } } : {}, plugins: { datalabels: { display: function(context) { // Suppress data labels on line charts if ('bar' === 'line') { return false; } return context.dataset.datalabels && context.dataset.datalabels.display === true; }, formatter: function(value, context) { // Special handling for Overall Team Performance chart if ('team-drive-metrics' === 'overall-team-performance' && context.dataset.label === 'Success Rate (SR)') { // Use the stored play count data if (context.dataset.playCountData && context.dataset.playCountData[context.dataIndex]) { return context.dataset.playCountData[context.dataIndex]; } // Fallback to percentage if play count data not available return Math.round(value * 100) + '%'; } // Handle bar charts with count data (play-type, quarter, down, etc.) if (context.dataset.label && context.dataset.label.includes(' SR') && (chartData.teamCounts || chartData.oppCounts)) { // Find the first team SR dataset in the chart to determine team order const allDatasets = context.chart.data.datasets; const teamSRDataset = allDatasets.find(d => d.label && d.label.includes(' SR') && !d.label.includes('NCAA')); // If this is the first team's SR dataset, use teamCounts if (teamSRDataset && context.dataset.label === teamSRDataset.label && chartData.teamCounts) { return chartData.teamCounts[context.dataIndex] || 0; } // Otherwise, use oppCounts for the second team else if (chartData.oppCounts) { return chartData.oppCounts[context.dataIndex] || 0; } } // For player charts, show value only if > 0 (matches non-embedded behavior) if ('team-drive-metrics'.includes('top-rushers') || 'team-drive-metrics'.includes('top-passers') || 'team-drive-metrics'.includes('top-receivers')) { // Hide data labels for zero or negative values, show actual value for positive values return value > 0 ? value : null; } // For other charts, show values based on type if (typeof value === 'number') { // If value is between 0 and 1, treat as percentage if (value >= 0 && value 0 ? '#26262660' : 'transparent'; }, borderColor: function(context) { const value = context.dataset.data[context.dataIndex]; return value > 0 ? 'rgba(255, 255, 255, 0.2)' : 'transparent'; }, borderRadius: 4, align: 'center', anchor: 'center' }, legend: 'team-drive-metrics' === 'win-probability' ? { display: false } : 'bar' === 'line' ? { position: 'top', align: 'start', labels: 'team-drive-metrics'.includes('play-map') ? { usePointStyle: true, generateLabels: function(chart) { // Call the original generateLabels to get default styling const original = Chart.defaults.plugins.legend.labels.generateLabels; const labels = original.call(this, chart); // Filter and customize each label const filteredLabels = labels.filter(label => { return !label.text.includes(' { const dataset = chart.data.datasets[label.datasetIndex]; if (dataset && dataset.label) { if (dataset.label.includes('Rush')) { label.pointStyle = 'circle'; label.pointStyleWidth = 4; label.fillStyle = 'white'; } else if (dataset.label.includes('Pass')) { label.pointStyle = 'triangle'; label.pointStyleWidth = 4; label.fillStyle = 'white'; } else { label.pointStyle = 'rect'; label.pointStyleWidth = 4; label.fillStyle = 'white'; } } }); return filteredLabels; }, boxWidth: 20, padding: 12 } : { usePointStyle: false, boxWidth: 12, boxHeight: 12, padding: 12, generateLabels: function(chart) { const original = Chart.defaults.plugins.legend.labels.generateLabels; const labels = original.call(this, chart); // Filter out reference areas and ensure white fill const filteredLabels = labels.filter(label => { return !label.text.includes('NCAA Avg SR') && !label.text.includes('50/50') && !label.text.includes('Quarters'); }); // Ensure white fill for all line chart legend boxes filteredLabels.forEach((label) => { label.fillStyle = 'white'; }); return filteredLabels; } } } : { position: 'top', align: 'start', labels: { usePointStyle: false, boxWidth: 12, boxHeight: 12, padding: 12, filter: function(legendItem, chartData) { return !legendItem.text.includes('NCAA Avg SR') && !legendItem.text.includes('Quarters') && !legendItem.text.includes('50/50'); }, generateLabels: function(chart) { const data = chart.data; if (data.datasets.length) { return data.datasets.map((dataset, i) => { // Handle backgroundColor arrays (like in Overall Team Performance chart) let fillColor = dataset.backgroundColor; if (dataset.label === '# Plays') { fillColor = 'white'; } else if (Array.isArray(dataset.backgroundColor)) { // For datasets with backgroundColor arrays, use the first color for legend fillColor = dataset.backgroundColor[0]; } return { text: dataset.label, fillStyle: fillColor, strokeStyle: dataset.label === '# Plays' ? '#666' : dataset.borderColor, lineWidth: dataset.label === '# Plays' ? 1 : dataset.borderWidth, hidden: !chart.isDatasetVisible(i), datasetIndex: i }; }).filter((item, index) => { // Apply the same filter logic as above const dataset = chart.data.datasets[index]; if (!dataset || !dataset.data) return false; if (dataset.label === '# Plays') return true; // Always show # Plays if (dataset.label && (dataset.label.includes('NCAA Avg SR') || dataset.label.includes('Quarters') || dataset.label.includes('50/50'))) return false; return dataset.data.some((value) => value > 0); }); } return []; } } }, tooltip: 'team-drive-metrics' === 'win-probability' ? { mode: 'index', intersect: false, callbacks: { title: function(tooltipItems) { if (tooltipItems && tooltipItems[0]) { return 'Play ' + (tooltipItems[0].dataIndex + 1); } return ''; }, label: function(context) { const selectedTeamWinProb = context.parsed.y; const opponentWinProb = 100 - selectedTeamWinProb; const selectedTeam = context.dataset.selectedTeam || 'Team'; const opponentTeam = context.dataset.opponentTeam || 'Opponent'; return [ selectedTeam + ': ' + selectedTeamWinProb.toFixed(1) + '%', opponentTeam + ': ' + opponentWinProb.toFixed(1) + '%' ]; }, afterLabel: function(context) { if (context.dataset.playTexts && context.dataset.playTexts[context.dataIndex]) { return '\n' + context.dataset.playTexts[context.dataIndex]; } return ''; } } } : { filter: function(tooltipItem) { if ('team-drive-metrics'.includes('play-map')) { return !tooltipItem.dataset.label.includes('< 0') && !tooltipItem.dataset.label.includes('Quarters') && !tooltipItem.dataset.label.includes('Drive'); } return !tooltipItem.dataset.label.includes('NCAA Avg SR') && !tooltipItem.dataset.label.includes('50/50') && !tooltipItem.dataset.label.includes(' ds.label === 'Win Probability'); if (wpDataset && wpDataset.segmentColors) { wpDataset.segment = { borderColor: function(ctx) { // Use p1DataIndex (ending point) so the line inherits the destination color // This makes momentum shifts more visually intuitive const index = ctx.p1DataIndex; if (index !== undefined && wpDataset.segmentColors[index]) { return wpDataset.segmentColors[index]; } return wpDataset.borderColor || '#8B0000'; } }; } } // Initialize the chart const ctx = canvas.getContext('2d'); const chart = new Chart(ctx, { type: 'bar', data: chartData, options: chartOptions }); // Store reference to prevent re-initialization canvas.chartInstance = chart; console.log('CFB Chart initialized successfully'); } catch (error) { console.error('Error initializing CFB chart:', error); // Fallback: show error message in canvas container const container = document.getElementById('cfb-chart-1764545298888-r3yh9f4m5').parentNode; if (container) { container.innerHTML = '

AdvertisementAdvertisementAdvertisement

Chart failed to load. Please refresh the page.

'; } } } // Start loading scripts sequentially function startLoading() { // First, check if scripts are already loaded (multiple embeds on same page) if (typeof Chart !== 'undefined' && typeof ChartDataLabels !== 'undefined') { initChart(); return; } // Load Chart.js first if (typeof Chart === 'undefined') { loadScript('https://cdn.jsdelivr.net/npm/[email protected]/dist/chart.min.js', function() { // Then load ChartDataLabels if (typeof ChartDataLabels === 'undefined') { loadScript('https://cdn.jsdelivr.net/npm/[email protected]', function() { initChart(); }); } else { initChart(); } }); } else if (typeof ChartDataLabels === 'undefined') { // Chart.js loaded but not ChartDataLabels loadScript('https://cdn.jsdelivr.net/npm/[email protected]', function() { initChart(); }); } else { initChart(); } } // Initialize when DOM is ready if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', startLoading); } else { startLoading(); } })();

Lots of 3-and-outs! Plus a 5-and-out. Good thing we also had a few longer drives, especially that gutsy 15-play closer near the end.

.cfb-chart-embed-cfb-chart-1764545430264-gsrp1bjiv { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', sans-serif; margin: 0; padding: 0; } .cfb-chart-embed-cfb-chart-1764545430264-gsrp1bjiv .chart-container { background: white; border-radius: 12px; border: 1px solid #e5e5e5; box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); overflow: hidden; } .cfb-chart-embed-cfb-chart-1764545430264-gsrp1bjiv .chart-header { padding: 18px 24px 14px; border-bottom: 1px solid #e5e5e5; background: white; } .cfb-chart-embed-cfb-chart-1764545430264-gsrp1bjiv .chart-title { font-size: 18px; font-weight: 600; color: #171717; margin: 0; } .cfb-chart-embed-cfb-chart-1764545430264-gsrp1bjiv .chart-subtitle { font-size: 11px; font-weight: 400; color: #737373; margin: 4px 0 0 0; } .cfb-chart-embed-cfb-chart-1764545430264-gsrp1bjiv .chart-content { padding: 20px 24px 24px !important; } .cfb-chart-embed-cfb-chart-1764545430264-gsrp1bjiv .chart-content { height: 325px; } @media (max-width: 640px) { .cfb-chart-embed-cfb-chart-1764545430264-gsrp1bjiv .chart-content { padding: 12px 16px 20px !important; height: 280px !important; } .cfb-chart-embed-cfb-chart-1764545430264-gsrp1bjiv .chart-header { padding: 12px 16px 12px !important; } .cfb-chart-embed-cfb-chart-1764545430264-gsrp1bjiv .embed-footer-top { padding: 8px 12px !important; } .cfb-chart-embed-cfb-chart-1764545430264-gsrp1bjiv .data-definitions { padding: 12px !important; } } .cfb-chart-embed-cfb-chart-1764545430264-gsrp1bjiv .embed-footer { border-top: 1px solid #e5e5e5; font-size: 12px; color: #737373; } .cfb-chart-embed-cfb-chart-1764545430264-gsrp1bjiv .embed-footer-top { display: flex; justify-content: space-between; align-items: center; padding: 12px 16px; } .cfb-chart-embed-cfb-chart-1764545430264-gsrp1bjiv .embed-footer-link { color: #737373; text-decoration: none; font-weight: 500; } .cfb-chart-embed-cfb-chart-1764545430264-gsrp1bjiv .embed-footer-link:hover { color: #525252; text-decoration: underline; } .cfb-chart-embed-cfb-chart-1764545430264-gsrp1bjiv .data-definitions-toggle { background: none; border: none; color: #737373; font-size: 12px; font-weight: 500; cursor: pointer; display: flex; align-items: center; gap: 4px; padding: 0; } .cfb-chart-embed-cfb-chart-1764545430264-gsrp1bjiv .data-definitions-toggle:hover { color: #525252; } .cfb-chart-embed-cfb-chart-1764545430264-gsrp1bjiv .caret { transition: transform 0.2s ease; font-size: 10px; } .cfb-chart-embed-cfb-chart-1764545430264-gsrp1bjiv .caret.expanded { transform: rotate(180deg); } .cfb-chart-embed-cfb-chart-1764545430264-gsrp1bjiv .data-definitions { display: none; padding: 16px; background: #fafafa; border-top: 1px solid #e5e5e5; font-size: 12px; line-height: 1.4; } .cfb-chart-embed-cfb-chart-1764545430264-gsrp1bjiv .data-definitions.expanded { display: block; } .cfb-chart-embed-cfb-chart-1764545430264-gsrp1bjiv .data-definitions ul { margin: 0; padding-left: 0; list-style: none; } .cfb-chart-embed-cfb-chart-1764545430264-gsrp1bjiv .data-definitions li { margin-bottom: 4px; }

AdvertisementAdvertisementAdvertisement

SR and XR by Play Type

Alabama vs. Auburn • Nov 29, 2025

See all charts Data definitions ▼

  • Based roughly on the SP+ analytic system

  • Successful play: Gains enough needed yards (50% 1st down, 70% on 2nd, 100% on 3rd/4th)

  • Success Rate (SR): Percentage of plays that were successful

  • Explosiveness Rate (XR): Percentage of plays gaining 15+ yards

  • # Plays: Numbers shown in bars represent total play counts

  • NCAA Avg: Dashed line shows 42% (roughly NCAA average) success rate

// Toggle data definitions accordion - unique function per embed function toggleDefinitions_cfb_chart_1764545430264_gsrp1bjiv() { const definitions = document.getElementById('dataDefinitions_cfb-chart-1764545430264-gsrp1bjiv'); const caret = document.getElementById('caret_cfb-chart-1764545430264-gsrp1bjiv'); if (definitions.classList.contains('expanded')) { definitions.classList.remove('expanded'); caret.classList.remove('expanded'); } else { definitions.classList.add('expanded'); caret.classList.add('expanded'); } } // Sequential script loading for better reliability (function() { 'use strict'; let retryCount = 0; const maxRetries = 50; // 5 seconds total // Load scripts sequentially function loadScript(url, callback) { const script = document.createElement('script'); script.src = url; script.onload = callback; script.onerror = function() { console.error('Failed to load script:', url); showError('Failed to load required chart library'); }; document.head.appendChild(script); } function showError(message) { const canvas = document.getElementById('cfb-chart-1764545430264-gsrp1bjiv'); if (canvas && canvas.parentNode) { canvas.parentNode.innerHTML = '

AdvertisementAdvertisementAdvertisement

' + message + '

'; } } function initChart() { retryCount++; // Check if Chart.js is available if (typeof Chart === 'undefined') { if (retryCount >= maxRetries) { showError('Chart library failed to load. Please refresh the page.'); return; } setTimeout(initChart, 100); return; } // Check if datalabels plugin is available if (typeof ChartDataLabels === 'undefined') { if (retryCount >= maxRetries) { showError('Chart plugin failed to load. Please refresh the page.'); return; } setTimeout(initChart, 100); return; } // Check if canvas element exists const canvas = document.getElementById('cfb-chart-1764545430264-gsrp1bjiv'); if (!canvas) { console.warn('Canvas element not found yet, retrying...'); setTimeout(initChart, 100); return; } // Prevent multiple chart instances if (canvas.chartInstance) { console.log('Chart already initialized'); return; } try { // Register the datalabels plugin Chart.register(ChartDataLabels); // Embed actual chart data directly const chartData = { "labels": [ "Rush", "Pass" ], "datasets": [ { "data": [ 0.08823529411764706, 0.05263157894736842 ], "stack": "Team", "label": "Alabama XR", "backgroundColor": "rgba(101, 0, 20, 0.8)", "datalabels": { "display": false } }, { "data": [ 0.4117647058823529, 0.2894736842105263 ], "stack": "Team", "label": "Alabama SR", "backgroundColor": "rgba(175, 40, 60, 0.8)", "datalabels": { "display": true } }, { "data": [ 0.029411764705882353, 0.10526315789473684 ], "stack": "Opponent", "label": "Auburn XR", "backgroundColor": "rgba(20, 59, 107, 0.8)", "datalabels": { "display": false } }, { "data": [ 0.47058823529411764, 0.3157894736842105 ], "stack": "Opponent", "label": "Auburn SR", "backgroundColor": "rgba(73, 133, 207, 0.8)", "datalabels": { "display": true } }, { "type": "line", "data": [ 0.42, 0.42 ], "label": "NCAA Avg SR", "borderColor": "#757575", "borderWidth": 2, "borderDash": [ 3, 3 ], "pointRadius": 0, "datalabels": { "display": false } }, { "type": "line", "data": [ null, null ], "label": "# Plays", "backgroundColor": "rgba(0, 0, 0, 0)", "borderColor": "rgba(0, 0, 0, 0)", "borderWidth": 0, "pointRadius": 0, "showLine": false, "fill": false, "datalabels": { "display": false } } ], "teamCounts": [ 34, 38 ], "oppCounts": [ 34, 38 ], "currentParams": { "year": 2025, "week": 14, "seasonType": "regular", "team": "Alabama", "gameId": "401752784" } }; // Chart options (WordPress-safe) const chartOptions = { responsive: true, maintainAspectRatio: false, animation: { duration: 1 // Minimal animation to trigger layout calculation (fixes label positioning) }, elements: 'bar' === 'line' ? 'play-type-bars'.includes('play-map') ? { line: { tension: 0, borderWidth: 0 } } : 'play-type-bars' === 'win-probability' ? { line: { tension: 0.15, borderWidth: 2.2, fill: false }, point: { pointRadius: 0, pointHoverRadius: 4 } } : { line: { tension: 0.25, borderWidth: 2.2 }, point: { pointRadius: 'play-type-bars'.includes('team-lines') ? 0 : undefined } } : {}, plugins: { datalabels: { display: function(context) { // Suppress data labels on line charts if ('bar' === 'line') { return false; } return context.dataset.datalabels && context.dataset.datalabels.display === true; }, formatter: function(value, context) { // Special handling for Overall Team Performance chart if ('play-type-bars' === 'overall-team-performance' && context.dataset.label === 'Success Rate (SR)') { // Use the stored play count data if (context.dataset.playCountData && context.dataset.playCountData[context.dataIndex]) { return context.dataset.playCountData[context.dataIndex]; } // Fallback to percentage if play count data not available return Math.round(value * 100) + '%'; } // Handle bar charts with count data (play-type, quarter, down, etc.) if (context.dataset.label && context.dataset.label.includes(' SR') && (chartData.teamCounts || chartData.oppCounts)) { // Find the first team SR dataset in the chart to determine team order const allDatasets = context.chart.data.datasets; const teamSRDataset = allDatasets.find(d => d.label && d.label.includes(' SR') && !d.label.includes('NCAA')); // If this is the first team's SR dataset, use teamCounts if (teamSRDataset && context.dataset.label === teamSRDataset.label && chartData.teamCounts) { return chartData.teamCounts[context.dataIndex] || 0; } // Otherwise, use oppCounts for the second team else if (chartData.oppCounts) { return chartData.oppCounts[context.dataIndex] || 0; } } // For player charts, show value only if > 0 (matches non-embedded behavior) if ('play-type-bars'.includes('top-rushers') || 'play-type-bars'.includes('top-passers') || 'play-type-bars'.includes('top-receivers')) { // Hide data labels for zero or negative values, show actual value for positive values return value > 0 ? value : null; } // For other charts, show values based on type if (typeof value === 'number') { // If value is between 0 and 1, treat as percentage if (value >= 0 && value 0 ? '#26262660' : 'transparent'; }, borderColor: function(context) { const value = context.dataset.data[context.dataIndex]; return value > 0 ? 'rgba(255, 255, 255, 0.2)' : 'transparent'; }, borderRadius: 4, align: 'center', anchor: 'center' }, legend: 'play-type-bars' === 'win-probability' ? { display: false } : 'bar' === 'line' ? { position: 'top', align: 'start', labels: 'play-type-bars'.includes('play-map') ? { usePointStyle: true, generateLabels: function(chart) { // Call the original generateLabels to get default styling const original = Chart.defaults.plugins.legend.labels.generateLabels; const labels = original.call(this, chart); // Filter and customize each label const filteredLabels = labels.filter(label => { return !label.text.includes(' { const dataset = chart.data.datasets[label.datasetIndex]; if (dataset && dataset.label) { if (dataset.label.includes('Rush')) { label.pointStyle = 'circle'; label.pointStyleWidth = 4; label.fillStyle = 'white'; } else if (dataset.label.includes('Pass')) { label.pointStyle = 'triangle'; label.pointStyleWidth = 4; label.fillStyle = 'white'; } else { label.pointStyle = 'rect'; label.pointStyleWidth = 4; label.fillStyle = 'white'; } } }); return filteredLabels; }, boxWidth: 20, padding: 12 } : { usePointStyle: false, boxWidth: 12, boxHeight: 12, padding: 12, generateLabels: function(chart) { const original = Chart.defaults.plugins.legend.labels.generateLabels; const labels = original.call(this, chart); // Filter out reference areas and ensure white fill const filteredLabels = labels.filter(label => { return !label.text.includes('NCAA Avg SR') && !label.text.includes('50/50') && !label.text.includes('Quarters'); }); // Ensure white fill for all line chart legend boxes filteredLabels.forEach((label) => { label.fillStyle = 'white'; }); return filteredLabels; } } } : { position: 'top', align: 'start', labels: { usePointStyle: false, boxWidth: 12, boxHeight: 12, padding: 12, filter: function(legendItem, chartData) { return !legendItem.text.includes('NCAA Avg SR') && !legendItem.text.includes('Quarters') && !legendItem.text.includes('50/50'); }, generateLabels: function(chart) { const data = chart.data; if (data.datasets.length) { return data.datasets.map((dataset, i) => { // Handle backgroundColor arrays (like in Overall Team Performance chart) let fillColor = dataset.backgroundColor; if (dataset.label === '# Plays') { fillColor = 'white'; } else if (Array.isArray(dataset.backgroundColor)) { // For datasets with backgroundColor arrays, use the first color for legend fillColor = dataset.backgroundColor[0]; } return { text: dataset.label, fillStyle: fillColor, strokeStyle: dataset.label === '# Plays' ? '#666' : dataset.borderColor, lineWidth: dataset.label === '# Plays' ? 1 : dataset.borderWidth, hidden: !chart.isDatasetVisible(i), datasetIndex: i }; }).filter((item, index) => { // Apply the same filter logic as above const dataset = chart.data.datasets[index]; if (!dataset || !dataset.data) return false; if (dataset.label === '# Plays') return true; // Always show # Plays if (dataset.label && (dataset.label.includes('NCAA Avg SR') || dataset.label.includes('Quarters') || dataset.label.includes('50/50'))) return false; return dataset.data.some((value) => value > 0); }); } return []; } } }, tooltip: 'play-type-bars' === 'win-probability' ? { mode: 'index', intersect: false, callbacks: { title: function(tooltipItems) { if (tooltipItems && tooltipItems[0]) { return 'Play ' + (tooltipItems[0].dataIndex + 1); } return ''; }, label: function(context) { const selectedTeamWinProb = context.parsed.y; const opponentWinProb = 100 - selectedTeamWinProb; const selectedTeam = context.dataset.selectedTeam || 'Team'; const opponentTeam = context.dataset.opponentTeam || 'Opponent'; return [ selectedTeam + ': ' + selectedTeamWinProb.toFixed(1) + '%', opponentTeam + ': ' + opponentWinProb.toFixed(1) + '%' ]; }, afterLabel: function(context) { if (context.dataset.playTexts && context.dataset.playTexts[context.dataIndex]) { return '\n' + context.dataset.playTexts[context.dataIndex]; } return ''; } } } : { filter: function(tooltipItem) { if ('play-type-bars'.includes('play-map')) { return !tooltipItem.dataset.label.includes('< 0') && !tooltipItem.dataset.label.includes('Quarters') && !tooltipItem.dataset.label.includes('Drive'); } return !tooltipItem.dataset.label.includes('NCAA Avg SR') && !tooltipItem.dataset.label.includes('50/50') && !tooltipItem.dataset.label.includes(' ds.label === 'Win Probability'); if (wpDataset && wpDataset.segmentColors) { wpDataset.segment = { borderColor: function(ctx) { // Use p1DataIndex (ending point) so the line inherits the destination color // This makes momentum shifts more visually intuitive const index = ctx.p1DataIndex; if (index !== undefined && wpDataset.segmentColors[index]) { return wpDataset.segmentColors[index]; } return wpDataset.borderColor || '#8B0000'; } }; } } // Initialize the chart const ctx = canvas.getContext('2d'); const chart = new Chart(ctx, { type: 'bar', data: chartData, options: chartOptions }); // Store reference to prevent re-initialization canvas.chartInstance = chart; console.log('CFB Chart initialized successfully'); } catch (error) { console.error('Error initializing CFB chart:', error); // Fallback: show error message in canvas container const container = document.getElementById('cfb-chart-1764545430264-gsrp1bjiv').parentNode; if (container) { container.innerHTML = '

Chart failed to load. Please refresh the page.

'; } } } // Start loading scripts sequentially function startLoading() { // First, check if scripts are already loaded (multiple embeds on same page) if (typeof Chart !== 'undefined' && typeof ChartDataLabels !== 'undefined') { initChart(); return; } // Load Chart.js first if (typeof Chart === 'undefined') { loadScript('https://cdn.jsdelivr.net/npm/[email protected]/dist/chart.min.js', function() { // Then load ChartDataLabels if (typeof ChartDataLabels === 'undefined') { loadScript('https://cdn.jsdelivr.net/npm/[email protected]', function() { initChart(); }); } else { initChart(); } }); } else if (typeof ChartDataLabels === 'undefined') { // Chart.js loaded but not ChartDataLabels loadScript('https://cdn.jsdelivr.net/npm/[email protected]', function() { initChart(); }); } else { initChart(); } } // Initialize when DOM is ready if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', startLoading); } else { startLoading(); } })();

AdvertisementAdvertisementAdvertisement

Worse at rushing? Check. Worse at passing? Check (with the caveat of rushing explosiveness).

.cfb-chart-embed-cfb-chart-1764545489664-a2sq3l1xo { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', sans-serif; margin: 0; padding: 0; } .cfb-chart-embed-cfb-chart-1764545489664-a2sq3l1xo .chart-container { background: white; border-radius: 12px; border: 1px solid #e5e5e5; box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); overflow: hidden; } .cfb-chart-embed-cfb-chart-1764545489664-a2sq3l1xo .chart-header { padding: 18px 24px 14px; border-bottom: 1px solid #e5e5e5; background: white; } .cfb-chart-embed-cfb-chart-1764545489664-a2sq3l1xo .chart-title { font-size: 18px; font-weight: 600; color: #171717; margin: 0; } .cfb-chart-embed-cfb-chart-1764545489664-a2sq3l1xo .chart-subtitle { font-size: 11px; font-weight: 400; color: #737373; margin: 4px 0 0 0; } .cfb-chart-embed-cfb-chart-1764545489664-a2sq3l1xo .chart-content { padding: 20px 24px 24px !important; } .cfb-chart-embed-cfb-chart-1764545489664-a2sq3l1xo .chart-content { height: 325px; } @media (max-width: 640px) { .cfb-chart-embed-cfb-chart-1764545489664-a2sq3l1xo .chart-content { padding: 12px 16px 20px !important; height: 280px !important; } .cfb-chart-embed-cfb-chart-1764545489664-a2sq3l1xo .chart-header { padding: 12px 16px 12px !important; } .cfb-chart-embed-cfb-chart-1764545489664-a2sq3l1xo .embed-footer-top { padding: 8px 12px !important; } .cfb-chart-embed-cfb-chart-1764545489664-a2sq3l1xo .data-definitions { padding: 12px !important; } } .cfb-chart-embed-cfb-chart-1764545489664-a2sq3l1xo .embed-footer { border-top: 1px solid #e5e5e5; font-size: 12px; color: #737373; } .cfb-chart-embed-cfb-chart-1764545489664-a2sq3l1xo .embed-footer-top { display: flex; justify-content: space-between; align-items: center; padding: 12px 16px; } .cfb-chart-embed-cfb-chart-1764545489664-a2sq3l1xo .embed-footer-link { color: #737373; text-decoration: none; font-weight: 500; } .cfb-chart-embed-cfb-chart-1764545489664-a2sq3l1xo .embed-footer-link:hover { color: #525252; text-decoration: underline; } .cfb-chart-embed-cfb-chart-1764545489664-a2sq3l1xo .data-definitions-toggle { background: none; border: none; color: #737373; font-size: 12px; font-weight: 500; cursor: pointer; display: flex; align-items: center; gap: 4px; padding: 0; } .cfb-chart-embed-cfb-chart-1764545489664-a2sq3l1xo .data-definitions-toggle:hover { color: #525252; } .cfb-chart-embed-cfb-chart-1764545489664-a2sq3l1xo .caret { transition: transform 0.2s ease; font-size: 10px; } .cfb-chart-embed-cfb-chart-1764545489664-a2sq3l1xo .caret.expanded { transform: rotate(180deg); } .cfb-chart-embed-cfb-chart-1764545489664-a2sq3l1xo .data-definitions { display: none; padding: 16px; background: #fafafa; border-top: 1px solid #e5e5e5; font-size: 12px; line-height: 1.4; } .cfb-chart-embed-cfb-chart-1764545489664-a2sq3l1xo .data-definitions.expanded { display: block; } .cfb-chart-embed-cfb-chart-1764545489664-a2sq3l1xo .data-definitions ul { margin: 0; padding-left: 0; list-style: none; } .cfb-chart-embed-cfb-chart-1764545489664-a2sq3l1xo .data-definitions li { margin-bottom: 4px; }

SR and XR by Down

Alabama vs. Auburn • Nov 29, 2025

AdvertisementAdvertisementAdvertisement

See all charts Data definitions ▼

  • Based roughly on the SP+ analytic system

  • Successful play: Gains enough needed yards (50% 1st down, 70% on 2nd, 100% on 3rd/4th)

  • Success Rate (SR): Percentage of plays that were successful

  • Explosiveness Rate (XR): Percentage of plays gaining 15+ yards

  • # Plays: Numbers shown in bars represent total play counts

  • NCAA Avg: Dashed line shows 42% (roughly NCAA average) success rate

// Toggle data definitions accordion - unique function per embed function toggleDefinitions_cfb_chart_1764545489664_a2sq3l1xo() { const definitions = document.getElementById('dataDefinitions_cfb-chart-1764545489664-a2sq3l1xo'); const caret = document.getElementById('caret_cfb-chart-1764545489664-a2sq3l1xo'); if (definitions.classList.contains('expanded')) { definitions.classList.remove('expanded'); caret.classList.remove('expanded'); } else { definitions.classList.add('expanded'); caret.classList.add('expanded'); } } // Sequential script loading for better reliability (function() { 'use strict'; let retryCount = 0; const maxRetries = 50; // 5 seconds total // Load scripts sequentially function loadScript(url, callback) { const script = document.createElement('script'); script.src = url; script.onload = callback; script.onerror = function() { console.error('Failed to load script:', url); showError('Failed to load required chart library'); }; document.head.appendChild(script); } function showError(message) { const canvas = document.getElementById('cfb-chart-1764545489664-a2sq3l1xo'); if (canvas && canvas.parentNode) { canvas.parentNode.innerHTML = '

' + message + '

'; } } function initChart() { retryCount++; // Check if Chart.js is available if (typeof Chart === 'undefined') { if (retryCount >= maxRetries) { showError('Chart library failed to load. Please refresh the page.'); return; } setTimeout(initChart, 100); return; } // Check if datalabels plugin is available if (typeof ChartDataLabels === 'undefined') { if (retryCount >= maxRetries) { showError('Chart plugin failed to load. Please refresh the page.'); return; } setTimeout(initChart, 100); return; } // Check if canvas element exists const canvas = document.getElementById('cfb-chart-1764545489664-a2sq3l1xo'); if (!canvas) { console.warn('Canvas element not found yet, retrying...'); setTimeout(initChart, 100); return; } // Prevent multiple chart instances if (canvas.chartInstance) { console.log('Chart already initialized'); return; } try { // Register the datalabels plugin Chart.register(ChartDataLabels); // Embed actual chart data directly const chartData = { "labels": [ "1st Down", "2nd Down", "3rd Down", "4th Down" ], "datasets": [ { "data": [ 0.07142857142857142, 0.041666666666666664, 0.11764705882352941, 0 ], "stack": "Team", "label": "Alabama XR", "backgroundColor": "rgba(101, 0, 20, 0.8)", "datalabels": { "display": false } }, { "data": [ 0.39285714285714285, 0.2916666666666667, 0.23529411764705882, 1 ], "stack": "Team", "label": "Alabama SR", "backgroundColor": "rgba(175, 40, 60, 0.8)", "datalabels": { "display": true } }, { "data": [ 0.034482758620689655, 0, 0.15789473684210525, 0.3333333333333333 ], "stack": "Opponent", "label": "Auburn XR", "backgroundColor": "rgba(20, 59, 107, 0.8)", "datalabels": { "display": false } }, { "data": [ 0.41379310344827586, 0.2857142857142857, 0.42105263157894735, 0.6666666666666666 ], "stack": "Opponent", "label": "Auburn SR", "backgroundColor": "rgba(73, 133, 207, 0.8)", "datalabels": { "display": true } }, { "type": "line", "data": [ 0.42, 0.42, 0.42, 0.42 ], "label": "NCAA Avg SR", "borderColor": "#757575", "borderWidth": 2, "borderDash": [ 3, 3 ], "pointRadius": 0, "datalabels": { "display": false } }, { "type": "line", "data": [ null, null, null, null ], "label": "# Plays", "backgroundColor": "rgba(0, 0, 0, 0)", "borderColor": "rgba(0, 0, 0, 0)", "borderWidth": 0, "pointRadius": 0, "showLine": false, "fill": false, "datalabels": { "display": false } } ], "teamCounts": [ 28, 24, 17, 3 ], "oppCounts": [ 29, 21, 19, 3 ], "currentParams": { "year": 2025, "week": 14, "seasonType": "regular", "team": "Alabama", "gameId": "401752784" } }; // Chart options (WordPress-safe) const chartOptions = { responsive: true, maintainAspectRatio: false, animation: { duration: 1 // Minimal animation to trigger layout calculation (fixes label positioning) }, elements: 'bar' === 'line' ? 'down-bars'.includes('play-map') ? { line: { tension: 0, borderWidth: 0 } } : 'down-bars' === 'win-probability' ? { line: { tension: 0.15, borderWidth: 2.2, fill: false }, point: { pointRadius: 0, pointHoverRadius: 4 } } : { line: { tension: 0.25, borderWidth: 2.2 }, point: { pointRadius: 'down-bars'.includes('team-lines') ? 0 : undefined } } : {}, plugins: { datalabels: { display: function(context) { // Suppress data labels on line charts if ('bar' === 'line') { return false; } return context.dataset.datalabels && context.dataset.datalabels.display === true; }, formatter: function(value, context) { // Special handling for Overall Team Performance chart if ('down-bars' === 'overall-team-performance' && context.dataset.label === 'Success Rate (SR)') { // Use the stored play count data if (context.dataset.playCountData && context.dataset.playCountData[context.dataIndex]) { return context.dataset.playCountData[context.dataIndex]; } // Fallback to percentage if play count data not available return Math.round(value * 100) + '%'; } // Handle bar charts with count data (play-type, quarter, down, etc.) if (context.dataset.label && context.dataset.label.includes(' SR') && (chartData.teamCounts || chartData.oppCounts)) { // Find the first team SR dataset in the chart to determine team order const allDatasets = context.chart.data.datasets; const teamSRDataset = allDatasets.find(d => d.label && d.label.includes(' SR') && !d.label.includes('NCAA')); // If this is the first team's SR dataset, use teamCounts if (teamSRDataset && context.dataset.label === teamSRDataset.label && chartData.teamCounts) { return chartData.teamCounts[context.dataIndex] || 0; } // Otherwise, use oppCounts for the second team else if (chartData.oppCounts) { return chartData.oppCounts[context.dataIndex] || 0; } } // For player charts, show value only if > 0 (matches non-embedded behavior) if ('down-bars'.includes('top-rushers') || 'down-bars'.includes('top-passers') || 'down-bars'.includes('top-receivers')) { // Hide data labels for zero or negative values, show actual value for positive values return value > 0 ? value : null; } // For other charts, show values based on type if (typeof value === 'number') { // If value is between 0 and 1, treat as percentage if (value >= 0 && value 0 ? '#26262660' : 'transparent'; }, borderColor: function(context) { const value = context.dataset.data[context.dataIndex]; return value > 0 ? 'rgba(255, 255, 255, 0.2)' : 'transparent'; }, borderRadius: 4, align: 'center', anchor: 'center' }, legend: 'down-bars' === 'win-probability' ? { display: false } : 'bar' === 'line' ? { position: 'top', align: 'start', labels: 'down-bars'.includes('play-map') ? { usePointStyle: true, generateLabels: function(chart) { // Call the original generateLabels to get default styling const original = Chart.defaults.plugins.legend.labels.generateLabels; const labels = original.call(this, chart); // Filter and customize each label const filteredLabels = labels.filter(label => { return !label.text.includes(' { const dataset = chart.data.datasets[label.datasetIndex]; if (dataset && dataset.label) { if (dataset.label.includes('Rush')) { label.pointStyle = 'circle'; label.pointStyleWidth = 4; label.fillStyle = 'white'; } else if (dataset.label.includes('Pass')) { label.pointStyle = 'triangle'; label.pointStyleWidth = 4; label.fillStyle = 'white'; } else { label.pointStyle = 'rect'; label.pointStyleWidth = 4; label.fillStyle = 'white'; } } }); return filteredLabels; }, boxWidth: 20, padding: 12 } : { usePointStyle: false, boxWidth: 12, boxHeight: 12, padding: 12, generateLabels: function(chart) { const original = Chart.defaults.plugins.legend.labels.generateLabels; const labels = original.call(this, chart); // Filter out reference areas and ensure white fill const filteredLabels = labels.filter(label => { return !label.text.includes('NCAA Avg SR') && !label.text.includes('50/50') && !label.text.includes('Quarters'); }); // Ensure white fill for all line chart legend boxes filteredLabels.forEach((label) => { label.fillStyle = 'white'; }); return filteredLabels; } } } : { position: 'top', align: 'start', labels: { usePointStyle: false, boxWidth: 12, boxHeight: 12, padding: 12, filter: function(legendItem, chartData) { return !legendItem.text.includes('NCAA Avg SR') && !legendItem.text.includes('Quarters') && !legendItem.text.includes('50/50'); }, generateLabels: function(chart) { const data = chart.data; if (data.datasets.length) { return data.datasets.map((dataset, i) => { // Handle backgroundColor arrays (like in Overall Team Performance chart) let fillColor = dataset.backgroundColor; if (dataset.label === '# Plays') { fillColor = 'white'; } else if (Array.isArray(dataset.backgroundColor)) { // For datasets with backgroundColor arrays, use the first color for legend fillColor = dataset.backgroundColor[0]; } return { text: dataset.label, fillStyle: fillColor, strokeStyle: dataset.label === '# Plays' ? '#666' : dataset.borderColor, lineWidth: dataset.label === '# Plays' ? 1 : dataset.borderWidth, hidden: !chart.isDatasetVisible(i), datasetIndex: i }; }).filter((item, index) => { // Apply the same filter logic as above const dataset = chart.data.datasets[index]; if (!dataset || !dataset.data) return false; if (dataset.label === '# Plays') return true; // Always show # Plays if (dataset.label && (dataset.label.includes('NCAA Avg SR') || dataset.label.includes('Quarters') || dataset.label.includes('50/50'))) return false; return dataset.data.some((value) => value > 0); }); } return []; } } }, tooltip: 'down-bars' === 'win-probability' ? { mode: 'index', intersect: false, callbacks: { title: function(tooltipItems) { if (tooltipItems && tooltipItems[0]) { return 'Play ' + (tooltipItems[0].dataIndex + 1); } return ''; }, label: function(context) { const selectedTeamWinProb = context.parsed.y; const opponentWinProb = 100 - selectedTeamWinProb; const selectedTeam = context.dataset.selectedTeam || 'Team'; const opponentTeam = context.dataset.opponentTeam || 'Opponent'; return [ selectedTeam + ': ' + selectedTeamWinProb.toFixed(1) + '%', opponentTeam + ': ' + opponentWinProb.toFixed(1) + '%' ]; }, afterLabel: function(context) { if (context.dataset.playTexts && context.dataset.playTexts[context.dataIndex]) { return '\n' + context.dataset.playTexts[context.dataIndex]; } return ''; } } } : { filter: function(tooltipItem) { if ('down-bars'.includes('play-map')) { return !tooltipItem.dataset.label.includes('< 0') && !tooltipItem.dataset.label.includes('Quarters') && !tooltipItem.dataset.label.includes('Drive'); } return !tooltipItem.dataset.label.includes('NCAA Avg SR') && !tooltipItem.dataset.label.includes('50/50') && !tooltipItem.dataset.label.includes(' ds.label === 'Win Probability'); if (wpDataset && wpDataset.segmentColors) { wpDataset.segment = { borderColor: function(ctx) { // Use p1DataIndex (ending point) so the line inherits the destination color // This makes momentum shifts more visually intuitive const index = ctx.p1DataIndex; if (index !== undefined && wpDataset.segmentColors[index]) { return wpDataset.segmentColors[index]; } return wpDataset.borderColor || '#8B0000'; } }; } } // Initialize the chart const ctx = canvas.getContext('2d'); const chart = new Chart(ctx, { type: 'bar', data: chartData, options: chartOptions }); // Store reference to prevent re-initialization canvas.chartInstance = chart; console.log('CFB Chart initialized successfully'); } catch (error) { console.error('Error initializing CFB chart:', error); // Fallback: show error message in canvas container const container = document.getElementById('cfb-chart-1764545489664-a2sq3l1xo').parentNode; if (container) { container.innerHTML = '

AdvertisementAdvertisementAdvertisement

Chart failed to load. Please refresh the page.

'; } } } // Start loading scripts sequentially function startLoading() { // First, check if scripts are already loaded (multiple embeds on same page) if (typeof Chart !== 'undefined' && typeof ChartDataLabels !== 'undefined') { initChart(); return; } // Load Chart.js first if (typeof Chart === 'undefined') { loadScript('https://cdn.jsdelivr.net/npm/[email protected]/dist/chart.min.js', function() { // Then load ChartDataLabels if (typeof ChartDataLabels === 'undefined') { loadScript('https://cdn.jsdelivr.net/npm/[email protected]', function() { initChart(); }); } else { initChart(); } }); } else if (typeof ChartDataLabels === 'undefined') { // Chart.js loaded but not ChartDataLabels loadScript('https://cdn.jsdelivr.net/npm/[email protected]', function() { initChart(); }); } else { initChart(); } } // Initialize when DOM is ready if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', startLoading); } else { startLoading(); } })();

Worse across every down? Well, almost, but we edged ‘em on already-bad 2nd downs and were 3/3 on 4th downs.

.cfb-chart-embed-cfb-chart-1764545543308-ed7bwryx0 { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', sans-serif; margin: 0; padding: 0; } .cfb-chart-embed-cfb-chart-1764545543308-ed7bwryx0 .chart-container { background: white; border-radius: 12px; border: 1px solid #e5e5e5; box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); overflow: hidden; } .cfb-chart-embed-cfb-chart-1764545543308-ed7bwryx0 .chart-header { padding: 18px 24px 14px; border-bottom: 1px solid #e5e5e5; background: white; } .cfb-chart-embed-cfb-chart-1764545543308-ed7bwryx0 .chart-title { font-size: 18px; font-weight: 600; color: #171717; margin: 0; } .cfb-chart-embed-cfb-chart-1764545543308-ed7bwryx0 .chart-subtitle { font-size: 11px; font-weight: 400; color: #737373; margin: 4px 0 0 0; } .cfb-chart-embed-cfb-chart-1764545543308-ed7bwryx0 .chart-content { padding: 20px 24px 24px !important; } .cfb-chart-embed-cfb-chart-1764545543308-ed7bwryx0 .chart-content { height: 325px; } @media (max-width: 640px) { .cfb-chart-embed-cfb-chart-1764545543308-ed7bwryx0 .chart-content { padding: 12px 16px 20px !important; height: 280px !important; } .cfb-chart-embed-cfb-chart-1764545543308-ed7bwryx0 .chart-header { padding: 12px 16px 12px !important; } .cfb-chart-embed-cfb-chart-1764545543308-ed7bwryx0 .embed-footer-top { padding: 8px 12px !important; } .cfb-chart-embed-cfb-chart-1764545543308-ed7bwryx0 .data-definitions { padding: 12px !important; } } .cfb-chart-embed-cfb-chart-1764545543308-ed7bwryx0 .embed-footer { border-top: 1px solid #e5e5e5; font-size: 12px; color: #737373; } .cfb-chart-embed-cfb-chart-1764545543308-ed7bwryx0 .embed-footer-top { display: flex; justify-content: space-between; align-items: center; padding: 12px 16px; } .cfb-chart-embed-cfb-chart-1764545543308-ed7bwryx0 .embed-footer-link { color: #737373; text-decoration: none; font-weight: 500; } .cfb-chart-embed-cfb-chart-1764545543308-ed7bwryx0 .embed-footer-link:hover { color: #525252; text-decoration: underline; } .cfb-chart-embed-cfb-chart-1764545543308-ed7bwryx0 .data-definitions-toggle { background: none; border: none; color: #737373; font-size: 12px; font-weight: 500; cursor: pointer; display: flex; align-items: center; gap: 4px; padding: 0; } .cfb-chart-embed-cfb-chart-1764545543308-ed7bwryx0 .data-definitions-toggle:hover { color: #525252; } .cfb-chart-embed-cfb-chart-1764545543308-ed7bwryx0 .caret { transition: transform 0.2s ease; font-size: 10px; } .cfb-chart-embed-cfb-chart-1764545543308-ed7bwryx0 .caret.expanded { transform: rotate(180deg); } .cfb-chart-embed-cfb-chart-1764545543308-ed7bwryx0 .data-definitions { display: none; padding: 16px; background: #fafafa; border-top: 1px solid #e5e5e5; font-size: 12px; line-height: 1.4; } .cfb-chart-embed-cfb-chart-1764545543308-ed7bwryx0 .data-definitions.expanded { display: block; } .cfb-chart-embed-cfb-chart-1764545543308-ed7bwryx0 .data-definitions ul { margin: 0; padding-left: 0; list-style: none; } .cfb-chart-embed-cfb-chart-1764545543308-ed7bwryx0 .data-definitions li { margin-bottom: 4px; }

SR and XR by Distance to Go

Alabama vs. Auburn • Nov 29, 2025

See all charts Data definitions ▼

  • Based roughly on the SP+ analytic system

  • Successful play: Gains enough needed yards (50% 1st down, 70% on 2nd, 100% on 3rd/4th)

  • Success Rate (SR): Percentage of plays that were successful

  • Explosiveness Rate (XR): Percentage of plays gaining 15+ yards

  • # Plays: Numbers shown in bars represent total play counts

  • NCAA Avg: Dashed line shows 42% (roughly NCAA average) success rate

// Toggle data definitions accordion - unique function per embed function toggleDefinitions_cfb_chart_1764545543308_ed7bwryx0() { const definitions = document.getElementById('dataDefinitions_cfb-chart-1764545543308-ed7bwryx0'); const caret = document.getElementById('caret_cfb-chart-1764545543308-ed7bwryx0'); if (definitions.classList.contains('expanded')) { definitions.classList.remove('expanded'); caret.classList.remove('expanded'); } else { definitions.classList.add('expanded'); caret.classList.add('expanded'); } } // Sequential script loading for better reliability (function() { 'use strict'; let retryCount = 0; const maxRetries = 50; // 5 seconds total // Load scripts sequentially function loadScript(url, callback) { const script = document.createElement('script'); script.src = url; script.onload = callback; script.onerror = function() { console.error('Failed to load script:', url); showError('Failed to load required chart library'); }; document.head.appendChild(script); } function showError(message) { const canvas = document.getElementById('cfb-chart-1764545543308-ed7bwryx0'); if (canvas && canvas.parentNode) { canvas.parentNode.innerHTML = '

' + message + '

'; } } function initChart() { retryCount++; // Check if Chart.js is available if (typeof Chart === 'undefined') { if (retryCount >= maxRetries) { showError('Chart library failed to load. Please refresh the page.'); return; } setTimeout(initChart, 100); return; } // Check if datalabels plugin is available if (typeof ChartDataLabels === 'undefined') { if (retryCount >= maxRetries) { showError('Chart plugin failed to load. Please refresh the page.'); return; } setTimeout(initChart, 100); return; } // Check if canvas element exists const canvas = document.getElementById('cfb-chart-1764545543308-ed7bwryx0'); if (!canvas) { console.warn('Canvas element not found yet, retrying...'); setTimeout(initChart, 100); return; } // Prevent multiple chart instances if (canvas.chartInstance) { console.log('Chart already initialized'); return; } try { // Register the datalabels plugin Chart.register(ChartDataLabels); // Embed actual chart data directly const chartData = { "labels": [ "Long (8+)", "Medium (4-7)", "Short (1-3)" ], "datasets": [ { "data": [ 0.02631578947368421, 0.10526315789473684, 0.13333333333333333 ], "stack": "Team", "label": "Alabama XR", "backgroundColor": "rgba(101, 0, 20, 0.8)", "datalabels": { "display": false } }, { "data": [ 0.2894736842105263, 0.3157894736842105, 0.5333333333333333 ], "stack": "Team", "label": "Alabama SR", "backgroundColor": "rgba(175, 40, 60, 0.8)", "datalabels": { "display": true } }, { "data": [ 0.06666666666666667, 0.05555555555555555, 0.1111111111111111 ], "stack": "Opponent", "label": "Auburn XR", "backgroundColor": "rgba(20, 59, 107, 0.8)", "datalabels": { "display": false } }, { "data": [ 0.3333333333333333, 0.3888888888888889, 0.6666666666666666 ], "stack": "Opponent", "label": "Auburn SR", "backgroundColor": "rgba(73, 133, 207, 0.8)", "datalabels": { "display": true } }, { "type": "line", "data": [ 0.42, 0.42, 0.42 ], "label": "NCAA Avg SR", "borderColor": "#757575", "borderWidth": 2, "borderDash": [ 3, 3 ], "pointRadius": 0, "datalabels": { "display": false } }, { "type": "line", "data": [ null, null, null ], "label": "# Plays", "backgroundColor": "rgba(0, 0, 0, 0)", "borderColor": "rgba(0, 0, 0, 0)", "borderWidth": 0, "pointRadius": 0, "showLine": false, "fill": false, "datalabels": { "display": false } } ], "teamCounts": [ 38, 19, 15 ], "oppCounts": [ 45, 18, 9 ], "currentParams": { "year": 2025, "week": 14, "seasonType": "regular", "team": "Alabama", "gameId": "401752784" } }; // Chart options (WordPress-safe) const chartOptions = { responsive: true, maintainAspectRatio: false, animation: { duration: 1 // Minimal animation to trigger layout calculation (fixes label positioning) }, elements: 'bar' === 'line' ? 'distance-bars'.includes('play-map') ? { line: { tension: 0, borderWidth: 0 } } : 'distance-bars' === 'win-probability' ? { line: { tension: 0.15, borderWidth: 2.2, fill: false }, point: { pointRadius: 0, pointHoverRadius: 4 } } : { line: { tension: 0.25, borderWidth: 2.2 }, point: { pointRadius: 'distance-bars'.includes('team-lines') ? 0 : undefined } } : {}, plugins: { datalabels: { display: function(context) { // Suppress data labels on line charts if ('bar' === 'line') { return false; } return context.dataset.datalabels && context.dataset.datalabels.display === true; }, formatter: function(value, context) { // Special handling for Overall Team Performance chart if ('distance-bars' === 'overall-team-performance' && context.dataset.label === 'Success Rate (SR)') { // Use the stored play count data if (context.dataset.playCountData && context.dataset.playCountData[context.dataIndex]) { return context.dataset.playCountData[context.dataIndex]; } // Fallback to percentage if play count data not available return Math.round(value * 100) + '%'; } // Handle bar charts with count data (play-type, quarter, down, etc.) if (context.dataset.label && context.dataset.label.includes(' SR') && (chartData.teamCounts || chartData.oppCounts)) { // Find the first team SR dataset in the chart to determine team order const allDatasets = context.chart.data.datasets; const teamSRDataset = allDatasets.find(d => d.label && d.label.includes(' SR') && !d.label.includes('NCAA')); // If this is the first team's SR dataset, use teamCounts if (teamSRDataset && context.dataset.label === teamSRDataset.label && chartData.teamCounts) { return chartData.teamCounts[context.dataIndex] || 0; } // Otherwise, use oppCounts for the second team else if (chartData.oppCounts) { return chartData.oppCounts[context.dataIndex] || 0; } } // For player charts, show value only if > 0 (matches non-embedded behavior) if ('distance-bars'.includes('top-rushers') || 'distance-bars'.includes('top-passers') || 'distance-bars'.includes('top-receivers')) { // Hide data labels for zero or negative values, show actual value for positive values return value > 0 ? value : null; } // For other charts, show values based on type if (typeof value === 'number') { // If value is between 0 and 1, treat as percentage if (value >= 0 && value 0 ? '#26262660' : 'transparent'; }, borderColor: function(context) { const value = context.dataset.data[context.dataIndex]; return value > 0 ? 'rgba(255, 255, 255, 0.2)' : 'transparent'; }, borderRadius: 4, align: 'center', anchor: 'center' }, legend: 'distance-bars' === 'win-probability' ? { display: false } : 'bar' === 'line' ? { position: 'top', align: 'start', labels: 'distance-bars'.includes('play-map') ? { usePointStyle: true, generateLabels: function(chart) { // Call the original generateLabels to get default styling const original = Chart.defaults.plugins.legend.labels.generateLabels; const labels = original.call(this, chart); // Filter and customize each label const filteredLabels = labels.filter(label => { return !label.text.includes(' { const dataset = chart.data.datasets[label.datasetIndex]; if (dataset && dataset.label) { if (dataset.label.includes('Rush')) { label.pointStyle = 'circle'; label.pointStyleWidth = 4; label.fillStyle = 'white'; } else if (dataset.label.includes('Pass')) { label.pointStyle = 'triangle'; label.pointStyleWidth = 4; label.fillStyle = 'white'; } else { label.pointStyle = 'rect'; label.pointStyleWidth = 4; label.fillStyle = 'white'; } } }); return filteredLabels; }, boxWidth: 20, padding: 12 } : { usePointStyle: false, boxWidth: 12, boxHeight: 12, padding: 12, generateLabels: function(chart) { const original = Chart.defaults.plugins.legend.labels.generateLabels; const labels = original.call(this, chart); // Filter out reference areas and ensure white fill const filteredLabels = labels.filter(label => { return !label.text.includes('NCAA Avg SR') && !label.text.includes('50/50') && !label.text.includes('Quarters'); }); // Ensure white fill for all line chart legend boxes filteredLabels.forEach((label) => { label.fillStyle = 'white'; }); return filteredLabels; } } } : { position: 'top', align: 'start', labels: { usePointStyle: false, boxWidth: 12, boxHeight: 12, padding: 12, filter: function(legendItem, chartData) { return !legendItem.text.includes('NCAA Avg SR') && !legendItem.text.includes('Quarters') && !legendItem.text.includes('50/50'); }, generateLabels: function(chart) { const data = chart.data; if (data.datasets.length) { return data.datasets.map((dataset, i) => { // Handle backgroundColor arrays (like in Overall Team Performance chart) let fillColor = dataset.backgroundColor; if (dataset.label === '# Plays') { fillColor = 'white'; } else if (Array.isArray(dataset.backgroundColor)) { // For datasets with backgroundColor arrays, use the first color for legend fillColor = dataset.backgroundColor[0]; } return { text: dataset.label, fillStyle: fillColor, strokeStyle: dataset.label === '# Plays' ? '#666' : dataset.borderColor, lineWidth: dataset.label === '# Plays' ? 1 : dataset.borderWidth, hidden: !chart.isDatasetVisible(i), datasetIndex: i }; }).filter((item, index) => { // Apply the same filter logic as above const dataset = chart.data.datasets[index]; if (!dataset || !dataset.data) return false; if (dataset.label === '# Plays') return true; // Always show # Plays if (dataset.label && (dataset.label.includes('NCAA Avg SR') || dataset.label.includes('Quarters') || dataset.label.includes('50/50'))) return false; return dataset.data.some((value) => value > 0); }); } return []; } } }, tooltip: 'distance-bars' === 'win-probability' ? { mode: 'index', intersect: false, callbacks: { title: function(tooltipItems) { if (tooltipItems && tooltipItems[0]) { return 'Play ' + (tooltipItems[0].dataIndex + 1); } return ''; }, label: function(context) { const selectedTeamWinProb = context.parsed.y; const opponentWinProb = 100 - selectedTeamWinProb; const selectedTeam = context.dataset.selectedTeam || 'Team'; const opponentTeam = context.dataset.opponentTeam || 'Opponent'; return [ selectedTeam + ': ' + selectedTeamWinProb.toFixed(1) + '%', opponentTeam + ': ' + opponentWinProb.toFixed(1) + '%' ]; }, afterLabel: function(context) { if (context.dataset.playTexts && context.dataset.playTexts[context.dataIndex]) { return '\n' + context.dataset.playTexts[context.dataIndex]; } return ''; } } } : { filter: function(tooltipItem) { if ('distance-bars'.includes('play-map')) { return !tooltipItem.dataset.label.includes('< 0') && !tooltipItem.dataset.label.includes('Quarters') && !tooltipItem.dataset.label.includes('Drive'); } return !tooltipItem.dataset.label.includes('NCAA Avg SR') && !tooltipItem.dataset.label.includes('50/50') && !tooltipItem.dataset.label.includes(' ds.label === 'Win Probability'); if (wpDataset && wpDataset.segmentColors) { wpDataset.segment = { borderColor: function(ctx) { // Use p1DataIndex (ending point) so the line inherits the destination color // This makes momentum shifts more visually intuitive const index = ctx.p1DataIndex; if (index !== undefined && wpDataset.segmentColors[index]) { return wpDataset.segmentColors[index]; } return wpDataset.borderColor || '#8B0000'; } }; } } // Initialize the chart const ctx = canvas.getContext('2d'); const chart = new Chart(ctx, { type: 'bar', data: chartData, options: chartOptions }); // Store reference to prevent re-initialization canvas.chartInstance = chart; console.log('CFB Chart initialized successfully'); } catch (error) { console.error('Error initializing CFB chart:', error); // Fallback: show error message in canvas container const container = document.getElementById('cfb-chart-1764545543308-ed7bwryx0').parentNode; if (container) { container.innerHTML = '

Chart failed to load. Please refresh the page.

'; } } } // Start loading scripts sequentially function startLoading() { // First, check if scripts are already loaded (multiple embeds on same page) if (typeof Chart !== 'undefined' && typeof ChartDataLabels !== 'undefined') { initChart(); return; } // Load Chart.js first if (typeof Chart === 'undefined') { loadScript('https://cdn.jsdelivr.net/npm/[email protected]/dist/chart.min.js', function() { // Then load ChartDataLabels if (typeof ChartDataLabels === 'undefined') { loadScript('https://cdn.jsdelivr.net/npm/[email protected]', function() { initChart(); }); } else { initChart(); } }); } else if (typeof ChartDataLabels === 'undefined') { // Chart.js loaded but not ChartDataLabels loadScript('https://cdn.jsdelivr.net/npm/[email protected]', function() { initChart(); }); } else { initChart(); } } // Initialize when DOM is ready if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', startLoading); } else { startLoading(); } })();

Worse from every distance? You got it!

.cfb-chart-embed-cfb-chart-1764545584181-yzcul67s8 { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', sans-serif; margin: 0; padding: 0; } .cfb-chart-embed-cfb-chart-1764545584181-yzcul67s8 .chart-container { background: white; border-radius: 12px; border: 1px solid #e5e5e5; box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); overflow: hidden; } .cfb-chart-embed-cfb-chart-1764545584181-yzcul67s8 .chart-header { padding: 18px 24px 14px; border-bottom: 1px solid #e5e5e5; background: white; } .cfb-chart-embed-cfb-chart-1764545584181-yzcul67s8 .chart-title { font-size: 18px; font-weight: 600; color: #171717; margin: 0; } .cfb-chart-embed-cfb-chart-1764545584181-yzcul67s8 .chart-subtitle { font-size: 11px; font-weight: 400; color: #737373; margin: 4px 0 0 0; } .cfb-chart-embed-cfb-chart-1764545584181-yzcul67s8 .chart-content { padding: 20px 24px 24px !important; } .cfb-chart-embed-cfb-chart-1764545584181-yzcul67s8 .chart-content { height: 325px; } @media (max-width: 640px) { .cfb-chart-embed-cfb-chart-1764545584181-yzcul67s8 .chart-content { padding: 12px 16px 20px !important; height: 280px !important; } .cfb-chart-embed-cfb-chart-1764545584181-yzcul67s8 .chart-header { padding: 12px 16px 12px !important; } .cfb-chart-embed-cfb-chart-1764545584181-yzcul67s8 .embed-footer-top { padding: 8px 12px !important; } .cfb-chart-embed-cfb-chart-1764545584181-yzcul67s8 .data-definitions { padding: 12px !important; } } .cfb-chart-embed-cfb-chart-1764545584181-yzcul67s8 .embed-footer { border-top: 1px solid #e5e5e5; font-size: 12px; color: #737373; } .cfb-chart-embed-cfb-chart-1764545584181-yzcul67s8 .embed-footer-top { display: flex; justify-content: space-between; align-items: center; padding: 12px 16px; } .cfb-chart-embed-cfb-chart-1764545584181-yzcul67s8 .embed-footer-link { color: #737373; text-decoration: none; font-weight: 500; } .cfb-chart-embed-cfb-chart-1764545584181-yzcul67s8 .embed-footer-link:hover { color: #525252; text-decoration: underline; } .cfb-chart-embed-cfb-chart-1764545584181-yzcul67s8 .data-definitions-toggle { background: none; border: none; color: #737373; font-size: 12px; font-weight: 500; cursor: pointer; display: flex; align-items: center; gap: 4px; padding: 0; } .cfb-chart-embed-cfb-chart-1764545584181-yzcul67s8 .data-definitions-toggle:hover { color: #525252; } .cfb-chart-embed-cfb-chart-1764545584181-yzcul67s8 .caret { transition: transform 0.2s ease; font-size: 10px; } .cfb-chart-embed-cfb-chart-1764545584181-yzcul67s8 .caret.expanded { transform: rotate(180deg); } .cfb-chart-embed-cfb-chart-1764545584181-yzcul67s8 .data-definitions { display: none; padding: 16px; background: #fafafa; border-top: 1px solid #e5e5e5; font-size: 12px; line-height: 1.4; } .cfb-chart-embed-cfb-chart-1764545584181-yzcul67s8 .data-definitions.expanded { display: block; } .cfb-chart-embed-cfb-chart-1764545584181-yzcul67s8 .data-definitions ul { margin: 0; padding-left: 0; list-style: none; } .cfb-chart-embed-cfb-chart-1764545584181-yzcul67s8 .data-definitions li { margin-bottom: 4px; }

SR and XR by Red Zone

Alabama vs. Auburn • Nov 29, 2025

See all charts Data definitions ▼

  • Based roughly on the SP+ analytic system

  • Successful play: Gains enough needed yards (50% 1st down, 70% on 2nd, 100% on 3rd/4th)

  • Success Rate (SR): Percentage of plays that were successful

  • Explosiveness Rate (XR): Percentage of plays gaining 15+ yards

  • # Plays: Numbers shown in bars represent total play counts

  • NCAA Avg: Dashed line shows 42% (roughly NCAA average) success rate

// Toggle data definitions accordion - unique function per embed function toggleDefinitions_cfb_chart_1764545584181_yzcul67s8() { const definitions = document.getElementById('dataDefinitions_cfb-chart-1764545584181-yzcul67s8'); const caret = document.getElementById('caret_cfb-chart-1764545584181-yzcul67s8'); if (definitions.classList.contains('expanded')) { definitions.classList.remove('expanded'); caret.classList.remove('expanded'); } else { definitions.classList.add('expanded'); caret.classList.add('expanded'); } } // Sequential script loading for better reliability (function() { 'use strict'; let retryCount = 0; const maxRetries = 50; // 5 seconds total // Load scripts sequentially function loadScript(url, callback) { const script = document.createElement('script'); script.src = url; script.onload = callback; script.onerror = function() { console.error('Failed to load script:', url); showError('Failed to load required chart library'); }; document.head.appendChild(script); } function showError(message) { const canvas = document.getElementById('cfb-chart-1764545584181-yzcul67s8'); if (canvas && canvas.parentNode) { canvas.parentNode.innerHTML = '

' + message + '

'; } } function initChart() { retryCount++; // Check if Chart.js is available if (typeof Chart === 'undefined') { if (retryCount >= maxRetries) { showError('Chart library failed to load. Please refresh the page.'); return; } setTimeout(initChart, 100); return; } // Check if datalabels plugin is available if (typeof ChartDataLabels === 'undefined') { if (retryCount >= maxRetries) { showError('Chart plugin failed to load. Please refresh the page.'); return; } setTimeout(initChart, 100); return; } // Check if canvas element exists const canvas = document.getElementById('cfb-chart-1764545584181-yzcul67s8'); if (!canvas) { console.warn('Canvas element not found yet, retrying...'); setTimeout(initChart, 100); return; } // Prevent multiple chart instances if (canvas.chartInstance) { console.log('Chart already initialized'); return; } try { // Register the datalabels plugin Chart.register(ChartDataLabels); // Embed actual chart data directly const chartData = { "labels": [ "Red Zone", "Other" ], "datasets": [ { "data": [ 0, 0.08620689655172414 ], "stack": "Team", "label": "Alabama XR", "backgroundColor": "rgba(101, 0, 20, 0.8)", "datalabels": { "display": false } }, { "data": [ 0.5714285714285714, 0.29310344827586204 ], "stack": "Team", "label": "Alabama SR", "backgroundColor": "rgba(175, 40, 60, 0.8)", "datalabels": { "display": true } }, { "data": [ 0, 0.07575757575757576 ], "stack": "Opponent", "label": "Auburn XR", "backgroundColor": "rgba(20, 59, 107, 0.8)", "datalabels": { "display": false } }, { "data": [ 0.3333333333333333, 0.3939393939393939 ], "stack": "Opponent", "label": "Auburn SR", "backgroundColor": "rgba(73, 133, 207, 0.8)", "datalabels": { "display": true } }, { "type": "line", "data": [ 0.42, 0.42 ], "label": "NCAA Avg SR", "borderColor": "#757575", "borderWidth": 2, "borderDash": [ 3, 3 ], "pointRadius": 0, "datalabels": { "display": false } }, { "type": "line", "data": [ null, null ], "label": "# Plays", "backgroundColor": "rgba(0, 0, 0, 0)", "borderColor": "rgba(0, 0, 0, 0)", "borderWidth": 0, "pointRadius": 0, "showLine": false, "fill": false, "datalabels": { "display": false } } ], "teamCounts": [ 14, 58 ], "oppCounts": [ 6, 66 ], "currentParams": { "year": 2025, "week": 14, "seasonType": "regular", "team": "Alabama", "gameId": "401752784" } }; // Chart options (WordPress-safe) const chartOptions = { responsive: true, maintainAspectRatio: false, animation: { duration: 1 // Minimal animation to trigger layout calculation (fixes label positioning) }, elements: 'bar' === 'line' ? 'red-zone-bars'.includes('play-map') ? { line: { tension: 0, borderWidth: 0 } } : 'red-zone-bars' === 'win-probability' ? { line: { tension: 0.15, borderWidth: 2.2, fill: false }, point: { pointRadius: 0, pointHoverRadius: 4 } } : { line: { tension: 0.25, borderWidth: 2.2 }, point: { pointRadius: 'red-zone-bars'.includes('team-lines') ? 0 : undefined } } : {}, plugins: { datalabels: { display: function(context) { // Suppress data labels on line charts if ('bar' === 'line') { return false; } return context.dataset.datalabels && context.dataset.datalabels.display === true; }, formatter: function(value, context) { // Special handling for Overall Team Performance chart if ('red-zone-bars' === 'overall-team-performance' && context.dataset.label === 'Success Rate (SR)') { // Use the stored play count data if (context.dataset.playCountData && context.dataset.playCountData[context.dataIndex]) { return context.dataset.playCountData[context.dataIndex]; } // Fallback to percentage if play count data not available return Math.round(value * 100) + '%'; } // Handle bar charts with count data (play-type, quarter, down, etc.) if (context.dataset.label && context.dataset.label.includes(' SR') && (chartData.teamCounts || chartData.oppCounts)) { // Find the first team SR dataset in the chart to determine team order const allDatasets = context.chart.data.datasets; const teamSRDataset = allDatasets.find(d => d.label && d.label.includes(' SR') && !d.label.includes('NCAA')); // If this is the first team's SR dataset, use teamCounts if (teamSRDataset && context.dataset.label === teamSRDataset.label && chartData.teamCounts) { return chartData.teamCounts[context.dataIndex] || 0; } // Otherwise, use oppCounts for the second team else if (chartData.oppCounts) { return chartData.oppCounts[context.dataIndex] || 0; } } // For player charts, show value only if > 0 (matches non-embedded behavior) if ('red-zone-bars'.includes('top-rushers') || 'red-zone-bars'.includes('top-passers') || 'red-zone-bars'.includes('top-receivers')) { // Hide data labels for zero or negative values, show actual value for positive values return value > 0 ? value : null; } // For other charts, show values based on type if (typeof value === 'number') { // If value is between 0 and 1, treat as percentage if (value >= 0 && value 0 ? '#26262660' : 'transparent'; }, borderColor: function(context) { const value = context.dataset.data[context.dataIndex]; return value > 0 ? 'rgba(255, 255, 255, 0.2)' : 'transparent'; }, borderRadius: 4, align: 'center', anchor: 'center' }, legend: 'red-zone-bars' === 'win-probability' ? { display: false } : 'bar' === 'line' ? { position: 'top', align: 'start', labels: 'red-zone-bars'.includes('play-map') ? { usePointStyle: true, generateLabels: function(chart) { // Call the original generateLabels to get default styling const original = Chart.defaults.plugins.legend.labels.generateLabels; const labels = original.call(this, chart); // Filter and customize each label const filteredLabels = labels.filter(label => { return !label.text.includes(' { const dataset = chart.data.datasets[label.datasetIndex]; if (dataset && dataset.label) { if (dataset.label.includes('Rush')) { label.pointStyle = 'circle'; label.pointStyleWidth = 4; label.fillStyle = 'white'; } else if (dataset.label.includes('Pass')) { label.pointStyle = 'triangle'; label.pointStyleWidth = 4; label.fillStyle = 'white'; } else { label.pointStyle = 'rect'; label.pointStyleWidth = 4; label.fillStyle = 'white'; } } }); return filteredLabels; }, boxWidth: 20, padding: 12 } : { usePointStyle: false, boxWidth: 12, boxHeight: 12, padding: 12, generateLabels: function(chart) { const original = Chart.defaults.plugins.legend.labels.generateLabels; const labels = original.call(this, chart); // Filter out reference areas and ensure white fill const filteredLabels = labels.filter(label => { return !label.text.includes('NCAA Avg SR') && !label.text.includes('50/50') && !label.text.includes('Quarters'); }); // Ensure white fill for all line chart legend boxes filteredLabels.forEach((label) => { label.fillStyle = 'white'; }); return filteredLabels; } } } : { position: 'top', align: 'start', labels: { usePointStyle: false, boxWidth: 12, boxHeight: 12, padding: 12, filter: function(legendItem, chartData) { return !legendItem.text.includes('NCAA Avg SR') && !legendItem.text.includes('Quarters') && !legendItem.text.includes('50/50'); }, generateLabels: function(chart) { const data = chart.data; if (data.datasets.length) { return data.datasets.map((dataset, i) => { // Handle backgroundColor arrays (like in Overall Team Performance chart) let fillColor = dataset.backgroundColor; if (dataset.label === '# Plays') { fillColor = 'white'; } else if (Array.isArray(dataset.backgroundColor)) { // For datasets with backgroundColor arrays, use the first color for legend fillColor = dataset.backgroundColor[0]; } return { text: dataset.label, fillStyle: fillColor, strokeStyle: dataset.label === '# Plays' ? '#666' : dataset.borderColor, lineWidth: dataset.label === '# Plays' ? 1 : dataset.borderWidth, hidden: !chart.isDatasetVisible(i), datasetIndex: i }; }).filter((item, index) => { // Apply the same filter logic as above const dataset = chart.data.datasets[index]; if (!dataset || !dataset.data) return false; if (dataset.label === '# Plays') return true; // Always show # Plays if (dataset.label && (dataset.label.includes('NCAA Avg SR') || dataset.label.includes('Quarters') || dataset.label.includes('50/50'))) return false; return dataset.data.some((value) => value > 0); }); } return []; } } }, tooltip: 'red-zone-bars' === 'win-probability' ? { mode: 'index', intersect: false, callbacks: { title: function(tooltipItems) { if (tooltipItems && tooltipItems[0]) { return 'Play ' + (tooltipItems[0].dataIndex + 1); } return ''; }, label: function(context) { const selectedTeamWinProb = context.parsed.y; const opponentWinProb = 100 - selectedTeamWinProb; const selectedTeam = context.dataset.selectedTeam || 'Team'; const opponentTeam = context.dataset.opponentTeam || 'Opponent'; return [ selectedTeam + ': ' + selectedTeamWinProb.toFixed(1) + '%', opponentTeam + ': ' + opponentWinProb.toFixed(1) + '%' ]; }, afterLabel: function(context) { if (context.dataset.playTexts && context.dataset.playTexts[context.dataIndex]) { return '\n' + context.dataset.playTexts[context.dataIndex]; } return ''; } } } : { filter: function(tooltipItem) { if ('red-zone-bars'.includes('play-map')) { return !tooltipItem.dataset.label.includes('< 0') && !tooltipItem.dataset.label.includes('Quarters') && !tooltipItem.dataset.label.includes('Drive'); } return !tooltipItem.dataset.label.includes('NCAA Avg SR') && !tooltipItem.dataset.label.includes('50/50') && !tooltipItem.dataset.label.includes(' ds.label === 'Win Probability'); if (wpDataset && wpDataset.segmentColors) { wpDataset.segment = { borderColor: function(ctx) { // Use p1DataIndex (ending point) so the line inherits the destination color // This makes momentum shifts more visually intuitive const index = ctx.p1DataIndex; if (index !== undefined && wpDataset.segmentColors[index]) { return wpDataset.segmentColors[index]; } return wpDataset.borderColor || '#8B0000'; } }; } } // Initialize the chart const ctx = canvas.getContext('2d'); const chart = new Chart(ctx, { type: 'bar', data: chartData, options: chartOptions }); // Store reference to prevent re-initialization canvas.chartInstance = chart; console.log('CFB Chart initialized successfully'); } catch (error) { console.error('Error initializing CFB chart:', error); // Fallback: show error message in canvas container const container = document.getElementById('cfb-chart-1764545584181-yzcul67s8').parentNode; if (container) { container.innerHTML = '

Chart failed to load. Please refresh the page.

'; } } } // Start loading scripts sequentially function startLoading() { // First, check if scripts are already loaded (multiple embeds on same page) if (typeof Chart !== 'undefined' && typeof ChartDataLabels !== 'undefined') { initChart(); return; } // Load Chart.js first if (typeof Chart === 'undefined') { loadScript('https://cdn.jsdelivr.net/npm/[email protected]/dist/chart.min.js', function() { // Then load ChartDataLabels if (typeof ChartDataLabels === 'undefined') { loadScript('https://cdn.jsdelivr.net/npm/[email protected]', function() { initChart(); }); } else { initChart(); } }); } else if (typeof ChartDataLabels === 'undefined') { // Chart.js loaded but not ChartDataLabels loadScript('https://cdn.jsdelivr.net/npm/[email protected]', function() { initChart(); }); } else { initChart(); } } // Initialize when DOM is ready if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', startLoading); } else { startLoading(); } })();

Worse in the Red Zone? Um, well, no, Alabama was only efficient while in the Red Zone, which is another ingredient for winning this game despite lackluster metrics otherwise.

Statistical silver linings

Now that I’m done griping (never for long); I do want to mention that some of the statistical deficits that ‘Bama showed in this game — yardage, explosiveness, efficiency — aren’t as simple as they look. After all, Connelly (SP+) had Bama’s postgame win expectancy at 44.5% this week.

A 44.5% win probability does suggest we ‘stole’ a win here, but within reasonable “close game” range. Notably, UGA apparently really pulled one out against GT with a 28.2%, and Cal one-upped them with their win over SMU (15.3% probability).

And anyone who’s read this column in November has likely seen me complain about Oklahoma stealing their game against Alabama with a 5.1% win probability. (For what it’s worth, they’ve been much more statistically well-behaved since, though while still escaping their wins with low-efficiency offense).

Alabama was, weirdly, a “rushing team” in this game

In a reversal of 2025 trends, Alabama both tried to run the ball, and they mostly looked good doing it.

.cfb-chart-embed-cfb-chart-1764545014238-b8xdgrerq { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', sans-serif; margin: 0; padding: 0; } .cfb-chart-embed-cfb-chart-1764545014238-b8xdgrerq .chart-container { background: white; border-radius: 12px; border: 1px solid #e5e5e5; box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); overflow: hidden; } .cfb-chart-embed-cfb-chart-1764545014238-b8xdgrerq .chart-header { padding: 18px 24px 14px; border-bottom: 1px solid #e5e5e5; background: white; } .cfb-chart-embed-cfb-chart-1764545014238-b8xdgrerq .chart-title { font-size: 18px; font-weight: 600; color: #171717; margin: 0; } .cfb-chart-embed-cfb-chart-1764545014238-b8xdgrerq .chart-subtitle { font-size: 11px; font-weight: 400; color: #737373; margin: 4px 0 0 0; } .cfb-chart-embed-cfb-chart-1764545014238-b8xdgrerq .chart-content { padding: 20px 24px 24px !important; } .cfb-chart-embed-cfb-chart-1764545014238-b8xdgrerq .chart-content { height: 325px; } @media (max-width: 640px) { .cfb-chart-embed-cfb-chart-1764545014238-b8xdgrerq .chart-content { padding: 12px 16px 20px !important; height: 280px !important; } .cfb-chart-embed-cfb-chart-1764545014238-b8xdgrerq .chart-header { padding: 12px 16px 12px !important; } .cfb-chart-embed-cfb-chart-1764545014238-b8xdgrerq .embed-footer-top { padding: 8px 12px !important; } .cfb-chart-embed-cfb-chart-1764545014238-b8xdgrerq .data-definitions { padding: 12px !important; } } .cfb-chart-embed-cfb-chart-1764545014238-b8xdgrerq .embed-footer { border-top: 1px solid #e5e5e5; font-size: 12px; color: #737373; } .cfb-chart-embed-cfb-chart-1764545014238-b8xdgrerq .embed-footer-top { display: flex; justify-content: space-between; align-items: center; padding: 12px 16px; } .cfb-chart-embed-cfb-chart-1764545014238-b8xdgrerq .embed-footer-link { color: #737373; text-decoration: none; font-weight: 500; } .cfb-chart-embed-cfb-chart-1764545014238-b8xdgrerq .embed-footer-link:hover { color: #525252; text-decoration: underline; } .cfb-chart-embed-cfb-chart-1764545014238-b8xdgrerq .data-definitions-toggle { background: none; border: none; color: #737373; font-size: 12px; font-weight: 500; cursor: pointer; display: flex; align-items: center; gap: 4px; padding: 0; } .cfb-chart-embed-cfb-chart-1764545014238-b8xdgrerq .data-definitions-toggle:hover { color: #525252; } .cfb-chart-embed-cfb-chart-1764545014238-b8xdgrerq .caret { transition: transform 0.2s ease; font-size: 10px; } .cfb-chart-embed-cfb-chart-1764545014238-b8xdgrerq .caret.expanded { transform: rotate(180deg); } .cfb-chart-embed-cfb-chart-1764545014238-b8xdgrerq .data-definitions { display: none; padding: 16px; background: #fafafa; border-top: 1px solid #e5e5e5; font-size: 12px; line-height: 1.4; } .cfb-chart-embed-cfb-chart-1764545014238-b8xdgrerq .data-definitions.expanded { display: block; } .cfb-chart-embed-cfb-chart-1764545014238-b8xdgrerq .data-definitions ul { margin: 0; padding-left: 0; list-style: none; } .cfb-chart-embed-cfb-chart-1764545014238-b8xdgrerq .data-definitions li { margin-bottom: 4px; }

SR by Play Type: Alabama

Alabama vs. Auburn • Nov 29, 2025

See all charts Data definitions ▼

  • Based roughly on the SP+ analytic system

  • Successful play: Gains enough needed yards (50% 1st down, 70% on 2nd, 100% on 3rd/4th)

  • Success Rate (SR): Percentage of plays that were successful

  • Explosiveness Rate (XR): Percentage of plays gaining 15+ yards

  • Gray area: Represents 42% (roughly NCAA average) success rate

// Toggle data definitions accordion - unique function per embed function toggleDefinitions_cfb_chart_1764545014238_b8xdgrerq() { const definitions = document.getElementById('dataDefinitions_cfb-chart-1764545014238-b8xdgrerq'); const caret = document.getElementById('caret_cfb-chart-1764545014238-b8xdgrerq'); if (definitions.classList.contains('expanded')) { definitions.classList.remove('expanded'); caret.classList.remove('expanded'); } else { definitions.classList.add('expanded'); caret.classList.add('expanded'); } } // Sequential script loading for better reliability (function() { 'use strict'; let retryCount = 0; const maxRetries = 50; // 5 seconds total // Load scripts sequentially function loadScript(url, callback) { const script = document.createElement('script'); script.src = url; script.onload = callback; script.onerror = function() { console.error('Failed to load script:', url); showError('Failed to load required chart library'); }; document.head.appendChild(script); } function showError(message) { const canvas = document.getElementById('cfb-chart-1764545014238-b8xdgrerq'); if (canvas && canvas.parentNode) { canvas.parentNode.innerHTML = '

' + message + '

'; } } function initChart() { retryCount++; // Check if Chart.js is available if (typeof Chart === 'undefined') { if (retryCount >= maxRetries) { showError('Chart library failed to load. Please refresh the page.'); return; } setTimeout(initChart, 100); return; } // Check if datalabels plugin is available if (typeof ChartDataLabels === 'undefined') { if (retryCount >= maxRetries) { showError('Chart plugin failed to load. Please refresh the page.'); return; } setTimeout(initChart, 100); return; } // Check if canvas element exists const canvas = document.getElementById('cfb-chart-1764545014238-b8xdgrerq'); if (!canvas) { console.warn('Canvas element not found yet, retrying...'); setTimeout(initChart, 100); return; } // Prevent multiple chart instances if (canvas.chartInstance) { console.log('Chart already initialized'); return; } try { // Register the datalabels plugin Chart.register(ChartDataLabels); // Embed actual chart data directly const chartData = { "datasets": [ { "label": "NCAA Avg SR", "data": [ { "x": 1, "y": 0 }, { "x": 1, "y": 0.42 }, { "x": 72, "y": 0.42 }, { "x": 72, "y": 0 } ], "backgroundColor": "rgba(0,0,0,0.03)", "borderColor": "transparent", "pointRadius": 0, "fill": true, "tension": 0, "showLine": true, "datalabels": { "display": false } }, { "data": [ { "x": 1, "y": 0, "text": "T.Simpson pass incomplete deep middle to #5 G.Bernard thrown to AUB50" }, { "x": 2, "y": 0, "text": "T.Simpson pass complete short right to #26 J.Miller caught at ALA15, for 4 yards to the ALA25 (#4 K.Lee), out of bounds PENALTY AUB Face Mask (#4 K.Lee) 15 yards from ALA25 to ALA40, 1ST DOWN" }, { "x": 3, "y": 0, "text": "T.Simpson pass incomplete short left to #5 G.Bernard thrown to AUB44" }, { "x": 4, "y": 0, "text": "T.Simpson pass complete short left to #5 G.Bernard caught at ALA45, for 7 yards to the ALA47 (#28 K.Louidor-Faustin; #25 E.Winters)" }, { "x": 5, "y": 0, "text": "T.Simpson pass incomplete deep middle to #5 G.Bernard thrown to AUB15" }, { "x": 6, "y": 0, "text": "D.Hill rush right for 1 yard gain to the AUB48 (#15 K.Faulk)" }, { "x": 7, "y": 0, "text": "T.Simpson pass incomplete short middle to #17 L.Brooks thrown to AUB34" }, { "x": 8, "y": 0, "text": "T.Simpson pass complete short left to #4 D.Hill caught at AUB45, for 3 yards to the AUB45 (#23 J.Crawford)" }, { "x": 9, "y": 0.5, "text": "T.Simpson rush middle for 2 yards gain to the AUB43 (#47 M.Blocton), 1ST DOWN" }, { "x": 10, "y": 0.6666666666666666, "text": "J.Miller rush left for 7 yards gain to the AUB36 (#24 K.Crawford)" }, { "x": 11, "y": 0.75, "text": "J.Miller rush middle for 4 yards gain to the AUB32 (#91 Z.Walker; #9 E.Melendez), 1ST DOWN" }, { "x": 12, "y": 0.8, "text": "J.Miller rush middle for 5 yards gain to the AUB27 (#91 Z.Walker)" }, { "x": 13, "y": 0.8, "text": "T.Simpson pass incomplete short right thrown to AUB25 QB hurried by #24 K.Crawford" }, { "x": 14, "y": 0.8, "text": "T.Simpson pass incomplete short left to #1 I.Horton thrown to AUB10 QB hurried by #24 K.Crawford" }, { "x": 15, "y": 0.8, "text": "T.Simpson pass incomplete short right to #88 J.Lindsey thrown to ALA34 broken up by #16 B.Deas" }, { "x": 16, "y": 0.6666666666666666, "text": "J.Miller rush right for 1 yard gain to the ALA36 (#16 B.Deas)" }, { "x": 17, "y": 0.6666666666666666, "text": "T.Simpson pass incomplete short right to #5 G.Bernard thrown to ALA45 QB hurried by #24 K.Crawford" }, { "x": 18, "y": 0.6666666666666666, "text": "T.Simpson pass complete short left to #17 L.Brooks caught at AUB45, for 15 yards to the AUB45, out of bounds at AUB45, 1ST DOWN. The previous play is under automatic review - \"Pass completion\". CALL OVERTURNED. (Original Play: (04:54) #15 T.Simpson pass incomplete short left to #17 L.Brooks thrown to AUB44)" }, { "x": 19, "y": 0.5714285714285714, "text": "G.Bernard rush left for 4 yards gain to the AUB41 (#24 K.Crawford), out of bounds" }, { "x": 20, "y": 0.5, "text": "D.Hill rush left for 3 yards gain to the AUB38 (#15 K.Faulk)" }, { "x": 21, "y": 0.5555555555555556, "text": "T.Simpson rush left for 26 yards gain to the AUB12 (#25 E.Winters), out of bounds, 1ST DOWN" }, { "x": 22, "y": 0.6, "text": "D.Hill rush middle for 7 yards gain to the AUB05 (#8 K.Harris)" }, { "x": 23, "y": 0.6, "text": "T.Simpson sacked for loss of 1 yard to the AUB06 (#8 K.Harris)" }, { "x": 24, "y": 0.6, "text": "Isaiah Horton 6 Yd pass from Ty Simpson (Conor Talty Kick)" }, { "x": 25, "y": 0.6, "text": "T.Simpson pass complete short left to #26 J.Miller caught at ALA33, for 8 yards to the ALA44 (#14 R.Pleasant), out of bounds" }, { "x": 26, "y": 0.6363636363636364, "text": "J.Miller rush middle for 20 yards gain to the AUB36 (#5 J.Robinson), out of bounds, 1ST DOWN" }, { "x": 27, "y": 0.6666666666666666, "text": "J.Miller rush middle for 17 yards gain to the AUB19 (#8 K.Harris), 1ST DOWN" }, { "x": 28, "y": 0.6153846153846154, "text": "J.Miller rush middle for 3 yards gain to the AUB16 (#97 B.Jamison-Travis)" }, { "x": 29, "y": 0.6153846153846154, "text": "T.Simpson pass complete short right to #17 L.Brooks caught at AUB12, for 13 yards to the AUB03 (#23 J.Crawford), 1ST DOWN" }, { "x": 30, "y": 0.6153846153846154, "text": "Isaiah Horton 3 Yd pass from Ty Simpson (Conor Talty Kick)" }, { "x": 31, "y": 0.6153846153846154, "text": "T.Simpson p...ass incomplete deep middle to #11 R.Scott thrown to AUB45 QB hurried by #0 R.Woodyard Jr." }, { "x": 32, "y": 0.5714285714285714, "text": "J.Miller rush middle for 3 yards gain to the ALA36 (#91 Z.Walker)" }, { "x": 33, "y": 0.5714285714285714, "text": "T.Simpson sacked for loss of 9 yards to the ALA27 (#17 X.Atkins, #47 M.Blocton)" }, { "x": 34, "y": 0.5333333333333333, "text": "J.Miller rush left for 2 yards gain to the ALA27 (#17 X.Atkins)" }, { "x": 35, "y": 0.5, "text": "J.Miller rush middle for 2 yards gain to the ALA29 (#92 J.Hardy)" }, { "x": 36, "y": 0.5, "text": "T.Simpson pass incomplete deep left to #5 G.Bernard thrown to AUB40 QB hurried by #17 X.Atkins and #24 K.Crawford" }, { "x": 37, "y": 0.5, "text": "T.Simpson pass complete short right to #17 L.Brooks caught at ALA25, for 1 yard to the ALA26 (#25 E.Winters; #0 R.Woodyard Jr.)" }, { "x": 38, "y": 0.47058823529411764, "text": "D.Hill rush right for 3 yards gain to the ALA29 (#24 K.Crawford)" }, { "x": 39, "y": 0.47058823529411764, "text": "Ty Simpson pass to I. Horton for 16 yds for a 1ST down" }, { "x": 40, "y": 0.4444444444444444, "text": "J.Miller rush left for 3 yards gain to the AUB37 (#19 S.Smith)" }, { "x": 41, "y": 0.42105263157894735, "text": "J.Miller rush left for 4 yards gain to the AUB33 (#19 S.Smith)" }, { "x": 42, "y": 0.42105263157894735, "text": "T.Simpson pass incomplete deep middle to #5 G.Bernard thrown to AUB12 broken up by #19 S.Smith" }, { "x": 43, "y": 0.42105263157894735, "text": "T.Simpson pass incomplete short left to #14 M.Pritchett thrown to AUB23" }, { "x": 44, "y": 0.42105263157894735, "text": "T.Simpson pass complete short left to #81 K.Edwards caught at AUB28, for 3 yards to the AUB25 (#24 K.Crawford)" }, { "x": 45, "y": 0.45, "text": "T.Simpson rush right for 8 yards gain to the AUB17 (#14 R.Pleasant), 1ST DOWN" }, { "x": 46, "y": 0.47619047619047616, "text": "J.Miller rush middle for 7 yards gain to the AUB10 (#0 R.Woodyard Jr.)" }, { "x": 47, "y": 0.47619047619047616, "text": "T.Simpson pass complete short right to #88 J.Lindsey caught at AUB11, for 1 yard loss to the AUB11, out of bounds at AUB11" }, { "x": 48, "y": 0.47619047619047616, "text": "T.Simpson pass incomplete short left to #5 G.Bernard thrown to AUB00 broken up by #19 S.Smith" }, { "x": 49, "y": 0.47619047619047616, "text": "T.Simpson pass complete short middle to #81 K.Edwards caught at ALA40, for 5 yards to the ALA40 (#4 K.Lee)" }, { "x": 50, "y": 0.45454545454545453, "text": "J.Miller rush middle for 3 yards gain to the ALA43 (#35 D.Walker)" }, { "x": 51, "y": 0.45454545454545453, "text": "T.Simpson pass incomplete short left to #26 J.Miller thrown to ALA47" }, { "x": 52, "y": 0.45454545454545453, "text": "T.Simpson sacked for loss of 9 yards to the ALA40 (#17 X.Atkins)" }, { "x": 53, "y": 0.45454545454545453, "text": "T.Simpson pass complete short right to #5 G.Bernard caught at ALA35, for 8 yards to the ALA48 (#0 R.Woodyard Jr.)" }, { "x": 54, "y": 0.45454545454545453, "text": "T.Simpson pass complete short left to #4 D.Hill caught at ALA47, for 6 yards to the AUB46 (#24 K.Crawford; #16 B.Deas)" }, { "x": 55, "y": 0.43478260869565216, "text": "J.Miller rush middle for 2 yards gain to the ALA27 (#97 B.Jamison-Travis)" }, { "x": 56, "y": 0.43478260869565216, "text": "T.Simpson pass complete short right to #1 I.Horton caught at ALA30, for 4 yards to the ALA31 (#19 S.Smith)" }, { "x": 57, "y": 0.4166666666666667, "text": "D.Hill rush middle for 3 yards gain to the ALA44 (#97 B.Jamison-Travis)" }, { "x": 58, "y": 0.4166666666666667, "text": "T.Simpson pass complete short middle to #0 A.Dear caught at ALA44, for 6 yards to the ALA50 (#97 B.Jamison-Travis)" }, { "x": 59, "y": 0.4166666666666667, "text": "T.Simpson pass incomplete deep left to #14 M.Pritchett thrown to AUB30 QB hurried by #3 C.Murray and #24 K.Crawford" }, { "x": 60, "y": 0.44, "text": "T.Simpson rush middle for 2 yards gain to the AUB48, End Of Play, 1ST DOWN" }, { "x": 61, "y": 0.46153846153846156, "text": "D.Hill rush middle for 9 yards gain to the AUB39 (#8 K.Harris)" }, { "x": 62, "y": 0.48148148148148145, "text": "D.Hill rush middle for 8 yards gain to the AUB31 (#8 K.Harris), 1ST DOWN" }, { "x": 63, "y": 0.4642857142857143, "text": "D.Hill rush middle for 3 yards gain to the AUB28 (#35 D.Walker)" }, { "x": 64, "y": 0.4482758620689655, "text": "D.Hill rush right for 0 yards to the AUB28 (#3 C.Murray)" }, { "x": 65, "y": 0.4666666666666667, "text": "T.Simpson rush left for 14 yards gain (10) to the AUB00 TOUCHDOWN nullified by penalty, clock 05:31 PENALTY ALA Holding (#1 I.Horton) 10 yards from AUB04 to AUB14" }, { "x": 66, "y": 0.45161290322580644, "text": "D.Hill rush left for 1 yard loss to the AUB15 (#92 J.Hardy)" }, { "x": 67, "y": 0.45161290322580644, "text": "T.Simpson pass complete short right to #5 G.Bernard caught at AUB05, for 9 yards to the AUB06 (#4 K.Lee), out of bounds" }, { "x": 68, "y": 0.45161290322580644, "text": "T.Simpson pass incomplete short middle to #14 M.Pritchett thrown to AUB00 broken up by #15 K.Faulk" }, { "x": 69, "y": 0.45161290322580644, "text": "Isaiah Horton 6 Yd pass from Ty Simpson (Conor Talty Kick)" }, { "x": 70, "y": 0.4375, "text": "T.Simpson rush right for 1 yard gain to the ALA21, End Of Play" }, { "x": 71, "y": 0.42424242424242425, "text": "D.Hill rush middle for 3 yards gain to the ALA24 (#15 K.Faulk)" }, { "x": 72, "y": 0.4117647058823529, "text": "T.Simpson rush right for 1 yard gain to the ALA25 (#97 B.Jamison-Travis)" } ], "label": "Alabama Rush SR", "borderColor": "rgba(101, 0, 20, 0.8)", "backgroundColor": [ "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(175, 40, 60, 0.8)", "rgba(175, 40, 60, 0.8)", "rgba(175, 40, 60, 0.8)", "rgba(175, 40, 60, 0.8)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(101, 0, 20, 0.8)", "rgba(175, 40, 60, 0.8)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(101, 0, 20, 0.8)", "rgba(101, 0, 20, 0.8)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(175, 40, 60, 0.8)", "rgba(175, 40, 60, 0.8)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(175, 40, 60, 0.8)", "rgba(175, 40, 60, 0.8)", "rgba(175, 40, 60, 0.8)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(175, 40, 60, 0.8)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)" ], "borderWidth": 2, "pointStyle": "circle", "pointRadius": [ 0, 0, 0, 0, 0, 4, 0, 0, 4, 4, 4, 4, 0, 0, 0, 4, 0, 0, 4, 4, 4, 4, 0, 0, 0, 4, 4, 4, 0, 0, 0, 4, 0, 4, 4, 0, 0, 4, 0, 4, 4, 0, 0, 0, 4, 4, 0, 0, 0, 4, 0, 0, 0, 0, 4, 0, 4, 0, 0, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 4, 4, 4 ], "pointBorderWidth": 1, "pointBorderColor": "rgba(101, 0, 20, 0.8)", "showLine": true }, { "data": [ { "x": 1, "y": 0, "text": "T.Simpson pass incomplete deep middle to #5 G.Bernard thrown to AUB50" }, { "x": 2, "y": 0, "text": "T.Simpson pass complete short right to #26 J.Miller caught at ALA15, for 4 yards to the ALA25 (#4 K.Lee), out of bounds PENALTY AUB Face Mask (#4 K.Lee) 15 yards from ALA25 to ALA40, 1ST DOWN" }, { "x": 3, "y": 0, "text": "T.Simpson pass incomplete short left to #5 G.Bernard thrown to AUB44" }, { "x": 4, "y": 0.25, "text": "T.Simpson pass complete short left to #5 G.Bernard caught at ALA45, for 7 yards to the ALA47 (#28 K.Louidor-Faustin; #25 E.Winters)" }, { "x": 5, "y": 0.2, "text": "T.Simpson pass incomplete deep middle to #5 G.Bernard thrown to AUB15" }, { "x": 6, "y": 0.2, "text": "D.Hill rush right for 1 yard gain to the AUB48 (#15 K.Faulk)" }, { "x": 7, "y": 0.16666666666666666, "text": "T.Simpson pass incomplete short middle to #17 L.Brooks thrown to AUB34" }, { "x": 8, "y": 0.14285714285714285, "text": "T.Simpson pass complete short left to #4 D.Hill caught at AUB45, for 3 yards to the AUB45 (#23 J.Crawford)" }, { "x": 9, "y": 0.14285714285714285, "text": "T.Simpson rush middle for 2 yards gain to the AUB43 (#47 M.Blocton), 1ST DOWN" }, { "x": 10, "y": 0.14285714285714285, "text": "J.Miller rush left for 7 yards gain to the AUB36 (#24 K.Crawford)" }, { "x": 11, "y": 0.14285714285714285, "text": "J.Miller rush middle for 4 yards gain to the AUB32 (#91 Z.Walker; #9 E.Melendez), 1ST DOWN" }, { "x": 12, "y": 0.14285714285714285, "text": "J.Miller rush middle for 5 yards gain to the AUB27 (#91 Z.Walker)" }, { "x": 13, "y": 0.125, "text": "T.Simpson pass incomplete short right thrown to AUB25 QB hurried by #24 K.Crawford" }, { "x": 14, "y": 0.1111111111111111, "text": "T.Simpson pass incomplete short left to #1 I.Horton thrown to AUB10 QB hurried by #24 K.Crawford" }, { "x": 15, "y": 0.1, "text": "T.Simpson pass incomplete short right to #88 J.Lindsey thrown to ALA34 broken up by #16 B.Deas" }, { "x": 16, "y": 0.1, "text": "J.Miller rush right for 1 yard gain to the ALA36 (#16 B.Deas)" }, { "x": 17, "y": 0.09090909090909091, "text": "T.Simpson pass incomplete short right to #5 G.Bernard thrown to ALA45 QB hurried by #24 K.Crawford" }, { "x": 18, "y": 0.16666666666666666, "text": "T.Simpson pass complete short left to #17 L.Brooks caught at AUB45, for 15 yards to the AUB45, out of bounds at AUB45, 1ST DOWN. The previous play is under automatic review - \"Pass completion\". CALL OVERTURNED. (Original Play: (04:54) #15 T.Simpson pass incomplete short left to #17 L.Brooks thrown to AUB44)" }, { "x": 19, "y": 0.16666666666666666, "text": "G.Bernard rush left for 4 yards gain to the AUB41 (#24 K.Crawford), out of bounds" }, { "x": 20, "y": 0.16666666666666666, "text": "D.Hill rush left for 3 yards gain to the AUB38 (#15 K.Faulk)" }, { "x": 21, "y": 0.16666666666666666, "text": "T.Simpson rush left for 26 yards gain to the AUB12 (#25 E.Winters), out of bounds, 1ST DOWN" }, { "x": 22, "y": 0.16666666666666666, "text": "D.Hill rush middle for 7 yards gain to the AUB05 (#8 K.Harris)" }, { "x": 23, "y": 0.15384615384615385, "text": "T.Simpson sacked for loss of 1 yard to the AUB06 (#8 K.Harris)" }, { "x": 24, "y": 0.21428571428571427, "text": "Isaiah Horton 6 Yd pass from Ty Simpson (Conor Talty Kick)" }, { "x": 25, "y": 0.26666666666666666, "text": "T.Simpson pass complete short left to #26 J.Miller caught at ALA33, for 8 yards to the ALA44 (#14 R.Pleasant), out of bounds" }, { "x": 26, "y": 0.26666666666666666, "text": "J.Miller rush middle for 20 yards gain to the AUB36 (#5 J.Robinson), out of bounds, 1ST DOWN" }, { "x": 27, "y": 0.26666666666666666, "text": "J.Miller rush middle for 17 yards gain to the AUB19 (#8 K.Harris), 1ST DOWN" }, { "x": 28, "y": 0.26666666666666666, "text": "J.Miller rush middle for 3 yards gain to the AUB16 (#97 B.Jamison-Travis)" }, { "x": 29, "y": 0.3125, "text": "T.Simpson pass complete short right to #17 L.Brooks caught at AUB12, for 13 yards to the AUB03 (#23 J.Crawford), 1ST DOWN" }, { "x": 30, "y": 0.35294117647058826, "text": "Isaiah Horton 3 Yd pass from Ty Simpson (Conor Talty Kick)" }, { "x": 31, "y": 0.3333333333333333, "text": "T.Simpson pass incomplete deep middle to #11 R.Scott thrown to AUB45 QB hurried by #0 R.Woodyard Jr." }, { "x": 32, "y": 0.3333333333333333, "text": "J.Miller rush middle for 3 yards gain to the ALA36 (#91 Z.Walker)" }, { "x": 33, "y": 0.3157894736842105, "text": "T.Simpson sacked for loss of 9 yards to the ALA27 (#17 X.Atkins, #47 M.Blocton)" }, { "x": 34, "y": 0.3157894736842105, "text": "J.Miller rush left for 2 yards gain to the ALA27 (#17 X.Atkins)" }, { "x": 35, "y": 0.3157894736842105, "text": "J.Miller rush middle for 2 yards gain to the ALA29 (#92 J.Hardy)" }, { "x": 36, "y": 0.3, "text": "T.Simpson pass incomplete deep left to #5 G.Bernard thrown to AUB40 QB hurried by #17 X.Atkins and #24 K.Crawford" }, { "x": 37, "y": 0.2857142857142857, "text": "T.Simpson pass complete short right to #17 L.Brooks caught at ALA25, for 1 yard to the ALA26 (#25 E.Winters; #0 R.Woodyard Jr.)" }, { "x": 38, "y": 0.2857142857142857, "text": "D.Hill rush right for 3 yards gain to the ALA29 (#24 K.Crawford)" }, { "x": 39, "y": 0.3181818181818182, "text": "Ty Simpson pass to I. Horton for 16 yds for a 1ST down" }, { "x": 40, "y": 0.3181818181818182, "text": "J.Miller rush left for 3 yards gain to the AUB37 (#19 S.Smith)" }, { "x": 41, "y": 0.3181818181818182, "text": "J.Miller rush left for 4 yards gain to the AUB33 (#19 S.Smith)" }, { "x": 42, "y": 0.30434782608695654, "text": "T.Simpson pass incomplete deep middle to #5 G.Bernard thrown to AUB12 broken up by #19 S.Smith" }, { "x": 43, "y": 0.2916666666666667, "text": "T.Simpson pass incomplete short left to #14 M.Pritchett thrown to AUB23" }, { "x": 44, "y": 0.28, "text": "T.Simpson pass complete short left to #81 K.Edwards caught at AUB28, for 3 yards to the AUB25 (#24 K.Crawford)" }, { "x": 45, "y": 0.28, "text": "T.Simpson rush right for 8 yards gain to the AUB17 (#14 R.Pleasant), 1ST DOWN" }, { "x": 46, "y": 0.28, "text": "J.Miller rush middle for 7 yards gain to the AUB10 (#0 R.Woodyard Jr.)" }, { "x": 47, "y": 0.2692307692307692, "text": "T.Simpson pass complete short right to #88 J.Lindsey caught at AUB11, for 1 yard loss to the AUB11, out of bounds at AUB11" }, { "x": 48, "y": 0.25925925925925924, "text": "T.Simpson pass incomplete short left to #5 G.Bernard thrown to AUB00 broken up by #19 S.Smith" }, { "x": 49, "y": 0.2857142857142857, "text": "T.Simpson pass complete short middle to #81 K.Edwards caught at ALA40, for 5 yards to the ALA40 (#4 K.Lee)" }, { "x": 50, "y": 0.2857142857142857, "text": "J.Miller rush middle for 3 yards gain to the ALA43 (#35 D.Walker)" }, { "x": 51, "y": 0.27586206896551724, "text": "T.Simpson pass incomplete short left to #26 J.Miller thrown to ALA47" }, { "x": 52, "y": 0.26666666666666666, "text": "T.Simpson sacked for loss of 9 yards to the ALA40 (#17 X.Atkins)" }, { "x": 53, "y": 0.25806451612903225, "text": "T.Simpson pass complete short right to #5 G.Bernard caught at ALA35, for 8 yards to the ALA48 (#0 R.Woodyard Jr.)" }, { "x": 54, "y": 0.25, "text": "T.Simpson pass complete short left to #4 D.Hill caught at ALA47, for 6 yards to the AUB46 (#24 K.Crawford; #16 B.Deas)" }, { "x": 55, "y": 0.25, "text": "J.Miller rush middle for 2 yards gain to the ALA27 (#97 B.Jamison-Travis)" }, { "x": 56, "y": 0.24242424242424243, "text": "T.Simpson pass complete short right to #1 I.Horton caught at ALA30, for 4 yards to the ALA31 (#19 S.Smith)" }, { "x": 57, "y": 0.24242424242424243, "text": "D.Hill rush middle for 3 yards gain to the ALA44 (#97 B.Jamison-Travis)" }, { "x": 58, "y": 0.2647058823529412, "text": "T.Simpson pass complete short middle to #0 A.Dear caught at ALA44, for 6 yards to the ALA50 (#97 B.Jamison-Travis)" }, { "x": 59, "y": 0.2571428571428571, "text": "T.Simpson pass incomplete deep left to #14 M.Pritchett thrown to AUB30 QB hurried by #3 C.Murray and #24 K.Crawford" }, { "x": 60, "y": 0.2571428571428571, "text": "T.Simpson rush middle for 2 yards gain to the AUB48, End Of Play, 1ST DOWN" }, { "x": 61, "y": 0.2571428571428571, "text": "D.Hill rush middle for 9 yards gain to the AUB39 (#8 K.Harris)" }, { "x": 62, "y": 0.2571428571428571, "text": "D.Hill rush middle for 8 yards gain to the AUB31 (#8 K.Harris), 1ST DOWN" }, { "x": 63, "y": 0.2571428571428571, "text": "D.Hill rush middle for 3 yards gain to the AUB28 (#35 D.Walker)" }, { "x": 64, "y": 0.2571428571428571, "text": "D.Hill rush right for 0 yards to the AUB28 (#3 C.Murray)" }, { "x": 65, "y": 0.2571428571428571, "text": "T.Simpson rush left for 14 yards gain (10) to the AUB00 TOUCHDOWN nullified by penalty, clock 05:31 PENALTY ALA Holding (#1 I.Horton) 10 yards from AUB04 to AUB14" }, { "x": 66, "y": 0.2571428571428571, "text": "D.Hill rush left for 1 yard loss to the AUB15 (#92 J.Hardy)" }, { "x": 67, "y": 0.2777777777777778, "text": "T.Simpson pass complete short right to #5 G.Bernard caught at AUB05, for 9 yards to the AUB06 (#4 K.Lee), out of bounds" }, { "x": 68, "y": 0.2702702702702703, "text": "T.Simpson pass incomplete short middle to #14 M.Pritchett thrown to AUB00 broken up by #15 K.Faulk" }, { "x": 69, "y": 0.2894736842105263, "text": "Isaiah Horton 6 Yd pass from Ty Simpson (Conor Talty Kick)" }, { "x": 70, "y": 0.2894736842105263, "text": "T.Simpson rush right for 1 yard gain to the ALA21, End Of Play" }, { "x": 71, "y": 0.2894736842105263, "text": "D.Hill rush middle for 3 yards gain to the ALA24 (#15 K.Faulk)" }, { "x": 72, "y": 0.2894736842105263, "text": "T.Simpson rush right for 1 yard gain to the ALA25 (#97 B.Jamison-Travis)" } ], "label": "Alabama Pass SR", "borderColor": "rgba(101, 0, 20, 0.8)", "backgroundColor": [ "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(175, 40, 60, 0.8)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(101, 0, 20, 0.8)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(175, 40, 60, 0.8)", "rgba(175, 40, 60, 0.8)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(175, 40, 60, 0.8)", "rgba(175, 40, 60, 0.8)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(101, 0, 20, 0.8)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(175, 40, 60, 0.8)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(175, 40, 60, 0.8)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(175, 40, 60, 0.8)", "rgba(255,255,255,0.9)", "rgba(175, 40, 60, 0.8)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)" ], "borderWidth": 2, "pointStyle": "triangle", "pointRadius": [ 6, 6, 6, 6, 6, 0, 6, 6, 0, 0, 0, 0, 6, 6, 6, 0, 6, 6, 0, 0, 0, 0, 6, 6, 6, 0, 0, 0, 6, 6, 6, 0, 6, 0, 0, 6, 6, 0, 6, 0, 0, 6, 6, 6, 0, 0, 6, 6, 6, 0, 6, 6, 6, 6, 0, 6, 0, 6, 6, 0, 0, 0, 0, 0, 0, 0, 6, 6, 6, 0, 0, 0 ], "pointBorderWidth": 1, "pointBorderColor": "rgba(101, 0, 20, 0.8)", "borderDash": [ 4, 4 ], "showLine": true }, { "label": "Quarters", "data": [ { "x": 1, "y": 0 }, { "x": 1, "y": 1 }, { "x": 72, "y": 1 }, { "x": 72, "y": 0 }, { "x": 25, "y": 0 }, { "x": 25, "y": 1 }, { "x": 72, "y": 1 }, { "x": 72, "y": 0 }, { "x": 37, "y": 0 }, { "x": 37, "y": 1 }, { "x": 72, "y": 1 }, { "x": 72, "y": 0 }, { "x": 54, "y": 0 }, { "x": 54, "y": 1 }, { "x": 72, "y": 1 }, { "x": 72, "y": 0 } ], "borderColor": "rgba(0,0,0,0.1)", "borderWidth": 1, "tension": 0, "fill": false, "pointRadius": 0, "showLine": true, "datalabels": { "display": false } } ], "currentParams": { "year": 2025, "week": 14, "seasonType": "regular", "team": "Alabama", "gameId": "401752784" } }; // Chart options (WordPress-safe) const chartOptions = { responsive: true, maintainAspectRatio: false, animation: { duration: 1 // Minimal animation to trigger layout calculation (fixes label positioning) }, elements: 'line' === 'line' ? 'team-play-type-lines'.includes('play-map') ? { line: { tension: 0, borderWidth: 0 } } : 'team-play-type-lines' === 'win-probability' ? { line: { tension: 0.15, borderWidth: 2.2, fill: false }, point: { pointRadius: 0, pointHoverRadius: 4 } } : { line: { tension: 0.25, borderWidth: 2.2 }, point: { pointRadius: 'team-play-type-lines'.includes('team-lines') ? 0 : undefined } } : {}, plugins: { datalabels: { display: function(context) { // Suppress data labels on line charts if ('line' === 'line') { return false; } return context.dataset.datalabels && context.dataset.datalabels.display === true; }, formatter: function(value, context) { // Special handling for Overall Team Performance chart if ('team-play-type-lines' === 'overall-team-performance' && context.dataset.label === 'Success Rate (SR)') { // Use the stored play count data if (context.dataset.playCountData && context.dataset.playCountData[context.dataIndex]) { return context.dataset.playCountData[context.dataIndex]; } // Fallback to percentage if play count data not available return Math.round(value * 100) + '%'; } // Handle bar charts with count data (play-type, quarter, down, etc.) if (context.dataset.label && context.dataset.label.includes(' SR') && (chartData.teamCounts || chartData.oppCounts)) { // Find the first team SR dataset in the chart to determine team order const allDatasets = context.chart.data.datasets; const teamSRDataset = allDatasets.find(d => d.label && d.label.includes(' SR') && !d.label.includes('NCAA')); // If this is the first team's SR dataset, use teamCounts if (teamSRDataset && context.dataset.label === teamSRDataset.label && chartData.teamCounts) { return chartData.teamCounts[context.dataIndex] || 0; } // Otherwise, use oppCounts for the second team else if (chartData.oppCounts) { return chartData.oppCounts[context.dataIndex] || 0; } } // For player charts, show value only if > 0 (matches non-embedded behavior) if ('team-play-type-lines'.includes('top-rushers') || 'team-play-type-lines'.includes('top-passers') || 'team-play-type-lines'.includes('top-receivers')) { // Hide data labels for zero or negative values, show actual value for positive values return value > 0 ? value : null; } // For other charts, show values based on type if (typeof value === 'number') { // If value is between 0 and 1, treat as percentage if (value >= 0 && value 0 ? '#26262660' : 'transparent'; }, borderColor: function(context) { const value = context.dataset.data[context.dataIndex]; return value > 0 ? 'rgba(255, 255, 255, 0.2)' : 'transparent'; }, borderRadius: 4, align: 'center', anchor: 'center' }, legend: 'team-play-type-lines' === 'win-probability' ? { display: false } : 'line' === 'line' ? { position: 'top', align: 'start', labels: 'team-play-type-lines'.includes('play-map') ? { usePointStyle: true, generateLabels: function(chart) { // Call the original generateLabels to get default styling const original = Chart.defaults.plugins.legend.labels.generateLabels; const labels = original.call(this, chart); // Filter and customize each label const filteredLabels = labels.filter(label => { return !label.text.includes(' { const dataset = chart.data.datasets[label.datasetIndex]; if (dataset && dataset.label) { if (dataset.label.includes('Rush')) { label.pointStyle = 'circle'; label.pointStyleWidth = 4; label.fillStyle = 'white'; } else if (dataset.label.includes('Pass')) { label.pointStyle = 'triangle'; label.pointStyleWidth = 4; label.fillStyle = 'white'; } else { label.pointStyle = 'rect'; label.pointStyleWidth = 4; label.fillStyle = 'white'; } } }); return filteredLabels; }, boxWidth: 20, padding: 12 } : { usePointStyle: false, boxWidth: 12, boxHeight: 12, padding: 12, generateLabels: function(chart) { const original = Chart.defaults.plugins.legend.labels.generateLabels; const labels = original.call(this, chart); // Filter out reference areas and ensure white fill const filteredLabels = labels.filter(label => { return !label.text.includes('NCAA Avg SR') && !label.text.includes('50/50') && !label.text.includes('Quarters'); }); // Ensure white fill for all line chart legend boxes filteredLabels.forEach((label) => { label.fillStyle = 'white'; }); return filteredLabels; } } } : { position: 'top', align: 'start', labels: { usePointStyle: false, boxWidth: 12, boxHeight: 12, padding: 12, filter: function(legendItem, chartData) { return !legendItem.text.includes('NCAA Avg SR') && !legendItem.text.includes('Quarters') && !legendItem.text.includes('50/50'); }, generateLabels: function(chart) { const data = chart.data; if (data.datasets.length) { return data.datasets.map((dataset, i) => { // Handle backgroundColor arrays (like in Overall Team Performance chart) let fillColor = dataset.backgroundColor; if (dataset.label === '# Plays') { fillColor = 'white'; } else if (Array.isArray(dataset.backgroundColor)) { // For datasets with backgroundColor arrays, use the first color for legend fillColor = dataset.backgroundColor[0]; } return { text: dataset.label, fillStyle: fillColor, strokeStyle: dataset.label === '# Plays' ? '#666' : dataset.borderColor, lineWidth: dataset.label === '# Plays' ? 1 : dataset.borderWidth, hidden: !chart.isDatasetVisible(i), datasetIndex: i }; }).filter((item, index) => { // Apply the same filter logic as above const dataset = chart.data.datasets[index]; if (!dataset || !dataset.data) return false; if (dataset.label === '# Plays') return true; // Always show # Plays if (dataset.label && (dataset.label.includes('NCAA Avg SR') || dataset.label.includes('Quarters') || dataset.label.includes('50/50'))) return false; return dataset.data.some((value) => value > 0); }); } return []; } } }, tooltip: 'team-play-type-lines' === 'win-probability' ? { mode: 'index', intersect: false, callbacks: { title: function(tooltipItems) { if (tooltipItems && tooltipItems[0]) { return 'Play ' + (tooltipItems[0].dataIndex + 1); } return ''; }, label: function(context) { const selectedTeamWinProb = context.parsed.y; const opponentWinProb = 100 - selectedTeamWinProb; const selectedTeam = context.dataset.selectedTeam || 'Team'; const opponentTeam = context.dataset.opponentTeam || 'Opponent'; return [ selectedTeam + ': ' + selectedTeamWinProb.toFixed(1) + '%', opponentTeam + ': ' + opponentWinProb.toFixed(1) + '%' ]; }, afterLabel: function(context) { if (context.dataset.playTexts && context.dataset.playTexts[context.dataIndex]) { return '\n' + context.dataset.playTexts[context.dataIndex]; } return ''; } } } : { filter: function(tooltipItem) { if ('team-play-type-lines'.includes('play-map')) { return !tooltipItem.dataset.label.includes('< 0') && !tooltipItem.dataset.label.includes('Quarters') && !tooltipItem.dataset.label.includes('Drive'); } return !tooltipItem.dataset.label.includes('NCAA Avg SR') && !tooltipItem.dataset.label.includes('50/50') && !tooltipItem.dataset.label.includes(' ds.label === 'Win Probability'); if (wpDataset && wpDataset.segmentColors) { wpDataset.segment = { borderColor: function(ctx) { // Use p1DataIndex (ending point) so the line inherits the destination color // This makes momentum shifts more visually intuitive const index = ctx.p1DataIndex; if (index !== undefined && wpDataset.segmentColors[index]) { return wpDataset.segmentColors[index]; } return wpDataset.borderColor || '#8B0000'; } }; } } // Initialize the chart const ctx = canvas.getContext('2d'); const chart = new Chart(ctx, { type: 'line', data: chartData, options: chartOptions }); // Store reference to prevent re-initialization canvas.chartInstance = chart; console.log('CFB Chart initialized successfully'); } catch (error) { console.error('Error initializing CFB chart:', error); // Fallback: show error message in canvas container const container = document.getElementById('cfb-chart-1764545014238-b8xdgrerq').parentNode; if (container) { container.innerHTML = '

Chart failed to load. Please refresh the page.

'; } } } // Start loading scripts sequentially function startLoading() { // First, check if scripts are already loaded (multiple embeds on same page) if (typeof Chart !== 'undefined' && typeof ChartDataLabels !== 'undefined') { initChart(); return; } // Load Chart.js first if (typeof Chart === 'undefined') { loadScript('https://cdn.jsdelivr.net/npm/[email protected]/dist/chart.min.js', function() { // Then load ChartDataLabels if (typeof ChartDataLabels === 'undefined') { loadScript('https://cdn.jsdelivr.net/npm/[email protected]', function() { initChart(); }); } else { initChart(); } }); } else if (typeof ChartDataLabels === 'undefined') { // Chart.js loaded but not ChartDataLabels loadScript('https://cdn.jsdelivr.net/npm/[email protected]', function() { initChart(); }); } else { initChart(); } } // Initialize when DOM is ready if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', startLoading); } else { startLoading(); } })();

Sure, things drifted dramatically in the 2nd and 3rd quarters — what’s new? — but overall the rushing game was much more efficient than the passing game (and even contributed a few explosives this time, for a change).

.cfb-chart-embed-cfb-chart-1764545155763-d6esgcdi0 { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', sans-serif; margin: 0; padding: 0; } .cfb-chart-embed-cfb-chart-1764545155763-d6esgcdi0 .chart-container { background: white; border-radius: 12px; border: 1px solid #e5e5e5; box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); overflow: hidden; } .cfb-chart-embed-cfb-chart-1764545155763-d6esgcdi0 .chart-header { padding: 18px 24px 14px; border-bottom: 1px solid #e5e5e5; background: white; } .cfb-chart-embed-cfb-chart-1764545155763-d6esgcdi0 .chart-title { font-size: 18px; font-weight: 600; color: #171717; margin: 0; } .cfb-chart-embed-cfb-chart-1764545155763-d6esgcdi0 .chart-subtitle { font-size: 11px; font-weight: 400; color: #737373; margin: 4px 0 0 0; } .cfb-chart-embed-cfb-chart-1764545155763-d6esgcdi0 .chart-content { padding: 20px 24px 24px !important; } .cfb-chart-embed-cfb-chart-1764545155763-d6esgcdi0 .chart-content { height: 325px; } @media (max-width: 640px) { .cfb-chart-embed-cfb-chart-1764545155763-d6esgcdi0 .chart-content { padding: 12px 16px 20px !important; height: 280px !important; } .cfb-chart-embed-cfb-chart-1764545155763-d6esgcdi0 .chart-header { padding: 12px 16px 12px !important; } .cfb-chart-embed-cfb-chart-1764545155763-d6esgcdi0 .embed-footer-top { padding: 8px 12px !important; } .cfb-chart-embed-cfb-chart-1764545155763-d6esgcdi0 .data-definitions { padding: 12px !important; } } .cfb-chart-embed-cfb-chart-1764545155763-d6esgcdi0 .embed-footer { border-top: 1px solid #e5e5e5; font-size: 12px; color: #737373; } .cfb-chart-embed-cfb-chart-1764545155763-d6esgcdi0 .embed-footer-top { display: flex; justify-content: space-between; align-items: center; padding: 12px 16px; } .cfb-chart-embed-cfb-chart-1764545155763-d6esgcdi0 .embed-footer-link { color: #737373; text-decoration: none; font-weight: 500; } .cfb-chart-embed-cfb-chart-1764545155763-d6esgcdi0 .embed-footer-link:hover { color: #525252; text-decoration: underline; } .cfb-chart-embed-cfb-chart-1764545155763-d6esgcdi0 .data-definitions-toggle { background: none; border: none; color: #737373; font-size: 12px; font-weight: 500; cursor: pointer; display: flex; align-items: center; gap: 4px; padding: 0; } .cfb-chart-embed-cfb-chart-1764545155763-d6esgcdi0 .data-definitions-toggle:hover { color: #525252; } .cfb-chart-embed-cfb-chart-1764545155763-d6esgcdi0 .caret { transition: transform 0.2s ease; font-size: 10px; } .cfb-chart-embed-cfb-chart-1764545155763-d6esgcdi0 .caret.expanded { transform: rotate(180deg); } .cfb-chart-embed-cfb-chart-1764545155763-d6esgcdi0 .data-definitions { display: none; padding: 16px; background: #fafafa; border-top: 1px solid #e5e5e5; font-size: 12px; line-height: 1.4; } .cfb-chart-embed-cfb-chart-1764545155763-d6esgcdi0 .data-definitions.expanded { display: block; } .cfb-chart-embed-cfb-chart-1764545155763-d6esgcdi0 .data-definitions ul { margin: 0; padding-left: 0; list-style: none; } .cfb-chart-embed-cfb-chart-1764545155763-d6esgcdi0 .data-definitions li { margin-bottom: 4px; }

Rush Rate: Alabama

Alabama vs. Auburn • Nov 29, 2025

See all charts Data definitions ▼

  • Based roughly on the SP+ analytic system

  • Successful play: Gains enough needed yards (50% 1st down, 70% on 2nd, 100% on 3rd/4th)

  • Success Rate (SR): Percentage of plays that were successful

  • Explosiveness Rate (XR): Percentage of plays gaining 15+ yards

  • Rush Rate: Percentage of offensive plays that are rushing attempts

  • Gray area: Represents 50/50 balanced offense

// Toggle data definitions accordion - unique function per embed function toggleDefinitions_cfb_chart_1764545155763_d6esgcdi0() { const definitions = document.getElementById('dataDefinitions_cfb-chart-1764545155763-d6esgcdi0'); const caret = document.getElementById('caret_cfb-chart-1764545155763-d6esgcdi0'); if (definitions.classList.contains('expanded')) { definitions.classList.remove('expanded'); caret.classList.remove('expanded'); } else { definitions.classList.add('expanded'); caret.classList.add('expanded'); } } // Sequential script loading for better reliability (function() { 'use strict'; let retryCount = 0; const maxRetries = 50; // 5 seconds total // Load scripts sequentially function loadScript(url, callback) { const script = document.createElement('script'); script.src = url; script.onload = callback; script.onerror = function() { console.error('Failed to load script:', url); showError('Failed to load required chart library'); }; document.head.appendChild(script); } function showError(message) { const canvas = document.getElementById('cfb-chart-1764545155763-d6esgcdi0'); if (canvas && canvas.parentNode) { canvas.parentNode.innerHTML = '

' + message + '

'; } } function initChart() { retryCount++; // Check if Chart.js is available if (typeof Chart === 'undefined') { if (retryCount >= maxRetries) { showError('Chart library failed to load. Please refresh the page.'); return; } setTimeout(initChart, 100); return; } // Check if datalabels plugin is available if (typeof ChartDataLabels === 'undefined') { if (retryCount >= maxRetries) { showError('Chart plugin failed to load. Please refresh the page.'); return; } setTimeout(initChart, 100); return; } // Check if canvas element exists const canvas = document.getElementById('cfb-chart-1764545155763-d6esgcdi0'); if (!canvas) { console.warn('Canvas element not found yet, retrying...'); setTimeout(initChart, 100); return; } // Prevent multiple chart instances if (canvas.chartInstance) { console.log('Chart already initialized'); return; } try { // Register the datalabels plugin Chart.register(ChartDataLabels); // Embed actual chart data directly const chartData = { "datasets": [ { "label": "50/50", "data": [ { "x": 1, "y": 0 }, { "x": 1, "y": 0.5 }, { "x": 72, "y": 0.5 }, { "x": 72, "y": 0 } ], "backgroundColor": "rgba(0,0,0,0.03)", "borderColor": "transparent", "pointRadius": 0, "fill": true, "tension": 0, "showLine": true, "datalabels": { "display": false } }, { "data": [ { "x": 1, "y": 0, "text": "T.Simpson pass incomplete deep middle to #5 G.Bernard thrown to AUB50" }, { "x": 2, "y": 0, "text": "T.Simpson pass complete short right to #26 J.Miller caught at ALA15, for 4 yards to the ALA25 (#4 K.Lee), out of bounds PENALTY AUB Face Mask (#4 K.Lee) 15 yards from ALA25 to ALA40, 1ST DOWN" }, { "x": 3, "y": 0, "text": "T.Simpson pass incomplete short left to #5 G.Bernard thrown to AUB44" }, { "x": 4, "y": 0, "text": "T.Simpson pass complete short left to #5 G.Bernard caught at ALA45, for 7 yards to the ALA47 (#28 K.Louidor-Faustin; #25 E.Winters)" }, { "x": 5, "y": 0, "text": "T.Simpson pass incomplete deep middle to #5 G.Bernard thrown to AUB15" }, { "x": 6, "y": 0.16666666666666666, "text": "D.Hill rush right for 1 yard gain to the AUB48 (#15 K.Faulk)" }, { "x": 7, "y": 0.14285714285714285, "text": "T.Simpson pass incomplete short middle to #17 L.Brooks thrown to AUB34" }, { "x": 8, "y": 0.125, "text": "T.Simpson pass complete short left to #4 D.Hill caught at AUB45, for 3 yards to the AUB45 (#23 J.Crawford)" }, { "x": 9, "y": 0.2222222222222222, "text": "T.Simpson rush middle for 2 yards gain to the AUB43 (#47 M.Blocton), 1ST DOWN" }, { "x": 10, "y": 0.3, "text": "J.Miller rush left for 7 yards gain to the AUB36 (#24 K.Crawford)" }, { "x": 11, "y": 0.36363636363636365, "text": "J.Miller rush middle for 4 yards gain to the AUB32 (#91 Z.Walker; #9 E.Melendez), 1ST DOWN" }, { "x": 12, "y": 0.4166666666666667, "text": "J.Miller rush middle for 5 yards gain to the AUB27 (#91 Z.Walker)" }, { "x": 13, "y": 0.38461538461538464, "text": "T.Simpson pass incomplete short right thrown to AUB25 QB hurried by #24 K.Crawford" }, { "x": 14, "y": 0.35714285714285715, "text": "T.Simpson pass incomplete short left to #1 I.Horton thrown to AUB10 QB hurried by #24 K.Crawford" }, { "x": 15, "y": 0.3333333333333333, "text": "T.Simpson pass incomplete short right to #88 J.Lindsey thrown to ALA34 broken up by #16 B.Deas" }, { "x": 16, "y": 0.375, "text": "J.Miller rush right for 1 yard gain to the ALA36 (#16 B.Deas)" }, { "x": 17, "y": 0.35294117647058826, "text": "T.Simpson pass incomplete short right to #5 G.Bernard thrown to ALA45 QB hurried by #24 K.Crawford" }, { "x": 18, "y": 0.3333333333333333, "text": "T.Simpson pass complete short left to #17 L.Brooks caught at AUB45, for 15 yards to the AUB45, out of bounds at AUB45, 1ST DOWN. The previous play is under automatic review - \"Pass completion\". CALL OVERTURNED. (Original Play: (04:54) #15 T.Simpson pass incomplete short left to #17 L.Brooks thrown to AUB44)" }, { "x": 19, "y": 0.3684210526315789, "text": "G.Bernard rush left for 4 yards gain to the AUB41 (#24 K.Crawford), out of bounds" }, { "x": 20, "y": 0.4, "text": "D.Hill rush left for 3 yards gain to the AUB38 (#15 K.Faulk)" }, { "x": 21, "y": 0.42857142857142855, "text": "T.Simpson rush left for 26 yards gain to the AUB12 (#25 E.Winters), out of bounds, 1ST DOWN" }, { "x": 22, "y": 0.45454545454545453, "text": "D.Hill rush middle for 7 yards gain to the AUB05 (#8 K.Harris)" }, { "x": 23, "y": 0.43478260869565216, "text": "T.Simpson sacked for loss of 1 yard to the AUB06 (#8 K.Harris)" }, { "x": 24, "y": 0.4166666666666667, "text": "Isaiah Horton 6 Yd pass from Ty Simpson (Conor Talty Kick)" }, { "x": 25, "y": 0.4, "text": "T.Simpson pass complete short left to #26 J.Miller caught at ALA33, for 8 yards to the ALA44 (#14 R.Pleasant), out of bounds" }, { "x": 26, "y": 0.4230769230769231, "text": "J.Miller rush middle for 20 yards gain to the AUB36 (#5 J.Robinson), out of bounds, 1ST DOWN" }, { "x": 27, "y": 0.4444444444444444, "text": "J.Miller rush middle for 17 yards gain to the AUB19 (#8 K.Harris), 1ST DOWN" }, { "x": 28, "y": 0.4642857142857143, "text": "J.Miller rush middle for 3 yards gain to the AUB16 (#97 B.Jamison-Travis)" }, { "x": 29, "y": 0.4482758620689655, "text": "T.Simpson pass complete short right to #17 L.Brooks caught at AUB12, for 13 yards to the AUB03 (#23 J.Crawford), 1ST DOWN" }, { "x": 30, "y": 0.43333333333333335, "text": "Isaiah Horton 3 Yd pass from Ty Simpson (Conor Talty Kick)" }, { "x": 31, "y": 0.41935483870967744, "text": "T.Simpson pass incomplete deep middle to #11 R.Scott thrown to AUB45 QB hurried by #0 R.Woodyard Jr." }, { "x": 32, "y": 0.4375, "text": "J.Miller rush middle for 3 yards gain to the ALA36 (#91 Z.Walker)" }, { "x": 33, "y": 0.42424242424242425, "text": "T.Simpson sacked for loss of 9 yards to the ALA27 (#17 X.Atkins, #47 M.Blocton)" }, { "x": 34, "y": 0.4411764705882353, "text": "J.Miller rush left for 2 yards gain to the ALA27 (#17 X.Atkins)" }, { "x": 35, "y": 0.45714285714285713, "text": "J.Miller rush middle for 2 yards gain to the ALA29 (#92 J.Hardy)" }, { "x": 36, "y": 0.4444444444444444, "text": "T.Simpson pass incomplete deep left to #5 G.Bernard thrown to AUB40 QB hurried by #17 X.Atkins and #24 K.Crawford" }, { "x": 37, "y": 0.43243243243243246, "text": "T.Simpson pass complete short right to #17 L.Brooks caught at ALA25, for 1 yard to the ALA26 (#25 E.Winters; #0 R.Woodyard Jr.)" }, { "x": 38, "y": 0.4473684210526316, "text": "D.Hill rush right for 3 yards gain to the ALA29 (#24 K.Crawford)" }, { "x": 39, "y": 0.4358974358974359, "text": "Ty Simpson pass to I. Horton for 16 yds for a 1ST down" }, { "x": 40, "y": 0.45, "text": "J.Miller rush left for 3 yards gain to the AUB37 (#19 S.Smith)" }, { "x": 41, "y": 0.4634146341463415, "text": "J.Miller rush left for 4 yards gain to the AUB33 (#19 S.Smith)" }, { "x": 42, "y": 0.4523809523809524, "text": "T.Simpson pass incomplete deep middle to #5 G.Bernard thrown to AUB12 broken up by #19 S.Smith" }, { "x": 43, "y": 0.4418604651162791, "text": "T.Simpson pass incomplete short left to #14 M.Pritchett thrown to AUB23" }, { "x": 44, "y": 0.4318181818181818, "text": "T.Simpson pass complete short left to #81 K.Edwards caught at AUB28, for 3 yards to the AUB25 (#24 K.Crawford)" }, { "x": 45, "y": 0.4444444444444444, "text": "T.Simpson rush right for 8 yards gain to the AUB17 (#14 R.Pleasant), 1ST DOWN" }, { "x": 46, "y": 0.45652173913043476, "text": "J.Miller rush middle for 7 yards gain to the AUB10 (#0 R.Woodyard Jr.)" }, { "x": 47, "y": 0.44680851063829785, "text": "T.Simpson pass complete short right to #88 J.Lindsey caught at AUB11, for 1 yard loss to the AUB11, out of bounds at AUB11" }, { "x": 48, "y": 0.4375, "text": "T.Simpson pass incomplete short left to #5 G.Bernard thrown to AUB00 broken up by #19 S.Smith" }, { "x": 49, "y": 0.42857142857142855, "text": "T.Simpson pass complete short middle to #81 K.Edwards caught at ALA40, for 5 yards to the ALA40 (#4 K.Lee)" }, { "x": 50, "y": 0.44, "text": "J.Miller rush middle for 3 yards gain to the ALA43 (#35 D.Walker)" }, { "x": 51, "y": 0.43137254901960786, "text": "T.Simpson pass incomplete short left to #26 J.Miller thrown to ALA47" }, { "x": 52, "y": 0.4230769230769231, "text": "T.Simpson sacked for loss of 9 yards to the ALA40 (#17 X.Atkins)" }, { "x": 53, "y": 0.41509433962264153, "text": "T.Simpson pass complete short right to #5 G.Bernard caught at ALA35, for 8 yards to the ALA48 (#0 R.Woodyard Jr.)" }, { "x": 54, "y": 0.4074074074074074, "text": "T.Simpson pass complete short left to #4 D.Hill caught at ALA47, for 6 yards to the AUB46 (#24 K.Crawford; #16 B.Deas)" }, { "x": 55, "y": 0.41818181818181815, "text": "J.Miller rush middle for 2 yards gain to the ALA27 (#97 B.Jamison-Travis)" }, { "x": 56, "y": 0.4107142857142857, "text": "T.Simpson pass complete short right to #1 I.Horton caught at ALA30, for 4 yards to the ALA31 (#19 S.Smith)" }, { "x": 57, "y": 0.42105263157894735, "text": "D.Hill rush middle for 3 yards gain to the ALA44 (#97 B.Jamison-Travis)" }, { "x": 58, "y": 0.41379310344827586, "text": "T.Simpson pass complete short middle to #0 A.Dear caught at ALA44, for 6 yards to the ALA50 (#97 B.Jamison-Travis)" }, { "x": 59, "y": 0.4067796610169492, "text": "T.Simpson pass incomplete deep left to #14 M.Pritchett thrown to AUB30 QB hurried by #3 C.Murray and #24 K.Crawford" }, { "x": 60, "y": 0.4166666666666667, "text": "T.Simpson rush middle for 2 yards gain to the AUB48, End Of Play, 1ST DOWN" }, { "x": 61, "y": 0.4262295081967213, "text": "D.Hill rush middle for 9 yards gain to the AUB39 (#8 K.Harris)" }, { "x": 62, "y": 0.43548387096774194, "text": "D.Hill rush middle for 8 yards gain to the AUB31 (#8 K.Harris), 1ST DOWN" }, { "x": 63, "y": 0.4444444444444444, "text": "D.Hill rush middle for 3 yards gain to the AUB28 (#35 D.Walker)" }, { "x": 64, "y": 0.453125, "text": "D.Hill rush right for 0 yards to the AUB28 (#3 C.Murray)" }, { "x": 65, "y": 0.46153846153846156, "text": "T.Simpson rush left for 14 yards gain (10) to the AUB00 TOUCHDOWN nullified by penalty, clock 05:31 PENALTY ALA Holding (#1 I.Horton) 10 yards from AUB04 to AUB14" }, { "x": 66, "y": 0.4696969696969697, "text": "D.Hill rush left for 1 yard loss to the AUB15 (#92 J.Hardy)" }, { "x": 67, "y": 0.4626865671641791, "text": "T.Simpson pass complete short right to #5 G.Bernard caught at AUB05, for 9 yards to the AUB06 (#4 K.Lee), out of bounds" }, { "x": 68, "y": 0.45588235294117646, "text": "T.Simpson pass incomplete short middle to #14 M.Pritchett thrown to AUB00 broken up by #15 K.Faulk" }, { "x": 69, "y": 0.4492753623188406, "text": "Isaiah Horton 6 Yd pass from Ty Simpson (Conor Talty Kick)" }, { "x": 70, "y": 0.45714285714285713, "text": "T.Simpson rush right for 1 yard gain to the ALA21, End Of Play" }, { "x": 71, "y": 0.4647887323943662, "text": "D.Hill rush middle for 3 yards gain to the ALA24 (#15 K.Faulk)" }, { "x": 72, "y": 0.4722222222222222, "text": "T.Simpson rush right for 1 yard gain to the ALA25 (#97 B.Jamison-Travis)" } ], "label": "Alabama Rush Rate", "borderColor": "rgba(101, 0, 20, 0.8)", "backgroundColor": "rgba(245, 229, 233, 0.8)", "borderWidth": 2, "pointBackgroundColor": [ "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(175, 40, 60, 0.8)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(175, 40, 60, 0.8)", "rgba(175, 40, 60, 0.8)", "rgba(175, 40, 60, 0.8)", "rgba(175, 40, 60, 0.8)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(101, 0, 20, 0.8)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(101, 0, 20, 0.8)", "rgba(175, 40, 60, 0.8)", "rgba(255,255,255,0.9)", "rgba(175, 40, 60, 0.8)", "rgba(175, 40, 60, 0.8)", "rgba(101, 0, 20, 0.8)", "rgba(101, 0, 20, 0.8)", "rgba(255,255,255,0.9)", "rgba(175, 40, 60, 0.8)", "rgba(175, 40, 60, 0.8)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(101, 0, 20, 0.8)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(175, 40, 60, 0.8)", "rgba(175, 40, 60, 0.8)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(175, 40, 60, 0.8)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(175, 40, 60, 0.8)", "rgba(255,255,255,0.9)", "rgba(175, 40, 60, 0.8)", "rgba(175, 40, 60, 0.8)", "rgba(175, 40, 60, 0.8)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(175, 40, 60, 0.8)", "rgba(255,255,255,0.9)", "rgba(175, 40, 60, 0.8)", "rgba(255,255,255,0.9)", "rgba(175, 40, 60, 0.8)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)", "rgba(255,255,255,0.9)" ], "pointStyle": [ "triangle", "triangle", "triangle", "triangle", "triangle", "circle", "triangle", "triangle", "circle", "circle", "circle", "circle", "triangle", "triangle", "triangle", "circle", "triangle", "triangle", "circle", "circle", "circle", "circle", "triangle", "triangle", "triangle", "circle", "circle", "circle", "triangle", "triangle", "triangle", "circle", "triangle", "circle", "circle", "triangle", "triangle", "circle", "triangle", "circle", "circle", "triangle", "triangle", "triangle", "circle", "circle", "triangle", "triangle", "triangle", "circle", "triangle", "triangle", "triangle", "triangle", "circle", "triangle", "circle", "triangle", "triangle", "circle", "circle", "circle", "circle", "circle", "circle", "circle", "triangle", "triangle", "triangle", "circle", "circle", "circle" ], "pointRadius": [ 5.5, 5.5, 5.5, 5.5, 5.5, 4, 5.5, 5.5, 4, 4, 4, 4, 5.5, 5.5, 5.5, 4, 5.5, 5.5, 4, 4, 4, 4, 5.5, 5.5, 5.5, 4, 4, 4, 5.5, 5.5, 5.5, 4, 5.5, 4, 4, 5.5, 5.5, 4, 5.5, 4, 4, 5.5, 5.5, 5.5, 4, 4, 5.5, 5.5, 5.5, 4, 5.5, 5.5, 5.5, 5.5, 4, 5.5, 4, 5.5, 5.5, 4, 4, 4, 4, 4, 4, 4, 5.5, 5.5, 5.5, 4, 4, 4 ], "pointBorderWidth": 1, "pointBorderColor": "rgba(101, 0, 20, 0.8)", "fill": true }, { "label": "Quarters", "data": [ { "x": 1, "y": 0 }, { "x": 1, "y": 1 }, { "x": 72, "y": 1 }, { "x": 72, "y": 0 }, { "x": 25, "y": 0 }, { "x": 25, "y": 1 }, { "x": 72, "y": 1 }, { "x": 72, "y": 0 }, { "x": 37, "y": 0 }, { "x": 37, "y": 1 }, { "x": 72, "y": 1 }, { "x": 72, "y": 0 }, { "x": 54, "y": 0 }, { "x": 54, "y": 1 }, { "x": 72, "y": 1 }, { "x": 72, "y": 0 } ], "borderColor": "rgba(0,0,0,0.1)", "borderWidth": 1, "tension": 0, "fill": false, "pointRadius": 0, "showLine": true, "datalabels": { "display": false } } ], "currentParams": { "year": 2025, "week": 14, "seasonType": "regular", "team": "Alabama", "gameId": "401752784" } }; // Chart options (WordPress-safe) const chartOptions = { responsive: true, maintainAspectRatio: false, animation: { duration: 1 // Minimal animation to trigger layout calculation (fixes label positioning) }, elements: 'line' === 'line' ? 'team-rush-rate'.includes('play-map') ? { line: { tension: 0, borderWidth: 0 } } : 'team-rush-rate' === 'win-probability' ? { line: { tension: 0.15, borderWidth: 2.2, fill: false }, point: { pointRadius: 0, pointHoverRadius: 4 } } : { line: { tension: 0.25, borderWidth: 2.2 }, point: { pointRadius: 'team-rush-rate'.includes('team-lines') ? 0 : undefined } } : {}, plugins: { datalabels: { display: function(context) { // Suppress data labels on line charts if ('line' === 'line') { return false; } return context.dataset.datalabels && context.dataset.datalabels.display === true; }, formatter: function(value, context) { // Special handling for Overall Team Performance chart if ('team-rush-rate' === 'overall-team-performance' && context.dataset.label === 'Success Rate (SR)') { // Use the stored play count data if (context.dataset.playCountData && context.dataset.playCountData[context.dataIndex]) { return context.dataset.playCountData[context.dataIndex]; } // Fallback to percentage if play count data not available return Math.round(value * 100) + '%'; } // Handle bar charts with count data (play-type, quarter, down, etc.) if (context.dataset.label && context.dataset.label.includes(' SR') && (chartData.teamCounts || chartData.oppCounts)) { // Find the first team SR dataset in the chart to determine team order const allDatasets = context.chart.data.datasets; const teamSRDataset = allDatasets.find(d => d.label && d.label.includes(' SR') && !d.label.includes('NCAA')); // If this is the first team's SR dataset, use teamCounts if (teamSRDataset && context.dataset.label === teamSRDataset.label && chartData.teamCounts) { return chartData.teamCounts[context.dataIndex] || 0; } // Otherwise, use oppCounts for the second team else if (chartData.oppCounts) { return chartData.oppCounts[context.dataIndex] || 0; } } // For player charts, show value only if > 0 (matches non-embedded behavior) if ('team-rush-rate'.includes('top-rushers') || 'team-rush-rate'.includes('top-passers') || 'team-rush-rate'.includes('top-receivers')) { // Hide data labels for zero or negative values, show actual value for positive values return value > 0 ? value : null; } // For other charts, show values based on type if (typeof value === 'number') { // If value is between 0 and 1, treat as percentage if (value >= 0 && value 0 ? '#26262660' : 'transparent'; }, borderColor: function(context) { const value = context.dataset.data[context.dataIndex]; return value > 0 ? 'rgba(255, 255, 255, 0.2)' : 'transparent'; }, borderRadius: 4, align: 'center', anchor: 'center' }, legend: 'team-rush-rate' === 'win-probability' ? { display: false } : 'line' === 'line' ? { position: 'top', align: 'start', labels: 'team-rush-rate'.includes('play-map') ? { usePointStyle: true, generateLabels: function(chart) { // Call the original generateLabels to get default styling const original = Chart.defaults.plugins.legend.labels.generateLabels; const labels = original.call(this, chart); // Filter and customize each label const filteredLabels = labels.filter(label => { return !label.text.includes(' { const dataset = chart.data.datasets[label.datasetIndex]; if (dataset && dataset.label) { if (dataset.label.includes('Rush')) { label.pointStyle = 'circle'; label.pointStyleWidth = 4; label.fillStyle = 'white'; } else if (dataset.label.includes('Pass')) { label.pointStyle = 'triangle'; label.pointStyleWidth = 4; label.fillStyle = 'white'; } else { label.pointStyle = 'rect'; label.pointStyleWidth = 4; label.fillStyle = 'white'; } } }); return filteredLabels; }, boxWidth: 20, padding: 12 } : { usePointStyle: false, boxWidth: 12, boxHeight: 12, padding: 12, generateLabels: function(chart) { const original = Chart.defaults.plugins.legend.labels.generateLabels; const labels = original.call(this, chart); // Filter out reference areas and ensure white fill const filteredLabels = labels.filter(label => { return !label.text.includes('NCAA Avg SR') && !label.text.includes('50/50') && !label.text.includes('Quarters'); }); // Ensure white fill for all line chart legend boxes filteredLabels.forEach((label) => { label.fillStyle = 'white'; }); return filteredLabels; } } } : { position: 'top', align: 'start', labels: { usePointStyle: false, boxWidth: 12, boxHeight: 12, padding: 12, filter: function(legendItem, chartData) { return !legendItem.text.includes('NCAA Avg SR') && !legendItem.text.includes('Quarters') && !legendItem.text.includes('50/50'); }, generateLabels: function(chart) { const data = chart.data; if (data.datasets.length) { return data.datasets.map((dataset, i) => { // Handle backgroundColor arrays (like in Overall Team Performance chart) let fillColor = dataset.backgroundColor; if (dataset.label === '# Plays') { fillColor = 'white'; } else if (Array.isArray(dataset.backgroundColor)) { // For datasets with backgroundColor arrays, use the first color for legend fillColor = dataset.backgroundColor[0]; } return { text: dataset.label, fillStyle: fillColor, strokeStyle: dataset.label === '# Plays' ? '#666' : dataset.borderColor, lineWidth: dataset.label === '# Plays' ? 1 : dataset.borderWidth, hidden: !chart.isDatasetVisible(i), datasetIndex: i }; }).filter((item, index) => { // Apply the same filter logic as above const dataset = chart.data.datasets[index]; if (!dataset || !dataset.data) return false; if (dataset.label === '# Plays') return true; // Always show # Plays if (dataset.label && (dataset.label.includes('NCAA Avg SR') || dataset.label.includes('Quarters') || dataset.label.includes('50/50'))) return false; return dataset.data.some((value) => value > 0); }); } return []; } } }, tooltip: 'team-rush-rate' === 'win-probability' ? { mode: 'index', intersect: false, callbacks: { title: function(tooltipItems) { if (tooltipItems && tooltipItems[0]) { return 'Play ' + (tooltipItems[0].dataIndex + 1); } return ''; }, label: function(context) { const selectedTeamWinProb = context.parsed.y; const opponentWinProb = 100 - selectedTeamWinProb; const selectedTeam = context.dataset.selectedTeam || 'Team'; const opponentTeam = context.dataset.opponentTeam || 'Opponent'; return [ selectedTeam + ': ' + selectedTeamWinProb.toFixed(1) + '%', opponentTeam + ': ' + opponentWinProb.toFixed(1) + '%' ]; }, afterLabel: function(context) { if (context.dataset.playTexts && context.dataset.playTexts[context.dataIndex]) { return '\n' + context.dataset.playTexts[context.dataIndex]; } return ''; } } } : { filter: function(tooltipItem) { if ('team-rush-rate'.includes('play-map')) { return !tooltipItem.dataset.label.includes('< 0') && !tooltipItem.dataset.label.includes('Quarters') && !tooltipItem.dataset.label.includes('Drive'); } return !tooltipItem.dataset.label.includes('NCAA Avg SR') && !tooltipItem.dataset.label.includes('50/50') && !tooltipItem.dataset.label.includes(' ds.label === 'Win Probability'); if (wpDataset && wpDataset.segmentColors) { wpDataset.segment = { borderColor: function(ctx) { // Use p1DataIndex (ending point) so the line inherits the destination color // This makes momentum shifts more visually intuitive const index = ctx.p1DataIndex; if (index !== undefined && wpDataset.segmentColors[index]) { return wpDataset.segmentColors[index]; } return wpDataset.borderColor || '#8B0000'; } }; } } // Initialize the chart const ctx = canvas.getContext('2d'); const chart = new Chart(ctx, { type: 'line', data: chartData, options: chartOptions }); // Store reference to prevent re-initialization canvas.chartInstance = chart; console.log('CFB Chart initialized successfully'); } catch (error) { console.error('Error initializing CFB chart:', error); // Fallback: show error message in canvas container const container = document.getElementById('cfb-chart-1764545155763-d6esgcdi0').parentNode; if (container) { container.innerHTML = '

Chart failed to load. Please refresh the page.

'; } } } // Start loading scripts sequentially function startLoading() { // First, check if scripts are already loaded (multiple embeds on same page) if (typeof Chart !== 'undefined' && typeof ChartDataLabels !== 'undefined') { initChart(); return; } // Load Chart.js first if (typeof Chart === 'undefined') { loadScript('https://cdn.jsdelivr.net/npm/[email protected]/dist/chart.min.js', function() { // Then load ChartDataLabels if (typeof ChartDataLabels === 'undefined') { loadScript('https://cdn.jsdelivr.net/npm/[email protected]', function() { initChart(); }); } else { initChart(); } }); } else if (typeof ChartDataLabels === 'undefined') { // Chart.js loaded but not ChartDataLabels loadScript('https://cdn.jsdelivr.net/npm/[email protected]', function() { initChart(); }); } else { initChart(); } } // Initialize when DOM is ready if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', startLoading); } else { startLoading(); } })();

And while a 47% cumulative rush rate isn’t exactly a 1980’s offense, it is a high rush rate for this 2025 Grubb-led Tide offense.

And some players showed out

.cfb-chart-embed-cfb-chart-1764544202637-dthkjjeby { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', sans-serif; margin: 0; padding: 0; } .cfb-chart-embed-cfb-chart-1764544202637-dthkjjeby .chart-container { background: white; border-radius: 12px; border: 1px solid #e5e5e5; box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); overflow: hidden; } .cfb-chart-embed-cfb-chart-1764544202637-dthkjjeby .chart-header { padding: 18px 24px 14px; border-bottom: 1px solid #e5e5e5; background: white; } .cfb-chart-embed-cfb-chart-1764544202637-dthkjjeby .chart-title { font-size: 18px; font-weight: 600; color: #171717; margin: 0; } .cfb-chart-embed-cfb-chart-1764544202637-dthkjjeby .chart-subtitle { font-size: 11px; font-weight: 400; color: #737373; margin: 4px 0 0 0; } .cfb-chart-embed-cfb-chart-1764544202637-dthkjjeby .chart-content { padding: 20px 24px 24px !important; } .cfb-chart-embed-cfb-chart-1764544202637-dthkjjeby .chart-content.top-rushers { height: 400px; } @media (max-width: 640px) { .cfb-chart-embed-cfb-chart-1764544202637-dthkjjeby .chart-content { padding: 12px 16px 20px !important; } .cfb-chart-embed-cfb-chart-1764544202637-dthkjjeby .chart-header { padding: 12px 16px 12px !important; } .cfb-chart-embed-cfb-chart-1764544202637-dthkjjeby .embed-footer-top { padding: 8px 12px !important; } .cfb-chart-embed-cfb-chart-1764544202637-dthkjjeby .data-definitions { padding: 12px !important; } } .cfb-chart-embed-cfb-chart-1764544202637-dthkjjeby .embed-footer { border-top: 1px solid #e5e5e5; font-size: 12px; color: #737373; } .cfb-chart-embed-cfb-chart-1764544202637-dthkjjeby .embed-footer-top { display: flex; justify-content: space-between; align-items: center; padding: 12px 16px; } .cfb-chart-embed-cfb-chart-1764544202637-dthkjjeby .embed-footer-link { color: #737373; text-decoration: none; font-weight: 500; } .cfb-chart-embed-cfb-chart-1764544202637-dthkjjeby .embed-footer-link:hover { color: #525252; text-decoration: underline; } .cfb-chart-embed-cfb-chart-1764544202637-dthkjjeby .data-definitions-toggle { background: none; border: none; color: #737373; font-size: 12px; font-weight: 500; cursor: pointer; display: flex; align-items: center; gap: 4px; padding: 0; } .cfb-chart-embed-cfb-chart-1764544202637-dthkjjeby .data-definitions-toggle:hover { color: #525252; } .cfb-chart-embed-cfb-chart-1764544202637-dthkjjeby .caret { transition: transform 0.2s ease; font-size: 10px; } .cfb-chart-embed-cfb-chart-1764544202637-dthkjjeby .caret.expanded { transform: rotate(180deg); } .cfb-chart-embed-cfb-chart-1764544202637-dthkjjeby .data-definitions { display: none; padding: 16px; background: #fafafa; border-top: 1px solid #e5e5e5; font-size: 12px; line-height: 1.4; } .cfb-chart-embed-cfb-chart-1764544202637-dthkjjeby .data-definitions.expanded { display: block; } .cfb-chart-embed-cfb-chart-1764544202637-dthkjjeby .data-definitions ul { margin: 0; padding-left: 0; list-style: none; } .cfb-chart-embed-cfb-chart-1764544202637-dthkjjeby .data-definitions li { margin-bottom: 4px; }

Top rushers

Alabama vs. Auburn • Nov 29, 2025

See all charts Data definitions ▼

  • Based roughly on the SP+ analytic system

  • Successful play: Gains enough needed yards (50% 1st down, 70% on 2nd, 100% on 3rd/4th)

  • Success Rate (SR): Percentage of plays that were successful

  • Explosiveness Rate (XR): Percentage of plays gaining 15+ yards

// Toggle data definitions accordion - unique function per embed function toggleDefinitions_cfb_chart_1764544202637_dthkjjeby() { const definitions = document.getElementById('dataDefinitions_cfb-chart-1764544202637-dthkjjeby'); const caret = document.getElementById('caret_cfb-chart-1764544202637-dthkjjeby'); if (definitions.classList.contains('expanded')) { definitions.classList.remove('expanded'); caret.classList.remove('expanded'); } else { definitions.classList.add('expanded'); caret.classList.add('expanded'); } } // Sequential script loading for better reliability (function() { 'use strict'; let retryCount = 0; const maxRetries = 50; // 5 seconds total // Load scripts sequentially function loadScript(url, callback) { const script = document.createElement('script'); script.src = url; script.onload = callback; script.onerror = function() { console.error('Failed to load script:', url); showError('Failed to load required chart library'); }; document.head.appendChild(script); } function showError(message) { const canvas = document.getElementById('cfb-chart-1764544202637-dthkjjeby'); if (canvas && canvas.parentNode) { canvas.parentNode.innerHTML = '

' + message + '

'; } } function initChart() { retryCount++; // Check if Chart.js is available if (typeof Chart === 'undefined') { if (retryCount >= maxRetries) { showError('Chart library failed to load. Please refresh the page.'); return; } setTimeout(initChart, 100); return; } // Check if datalabels plugin is available if (typeof ChartDataLabels === 'undefined') { if (retryCount >= maxRetries) { showError('Chart plugin failed to load. Please refresh the page.'); return; } setTimeout(initChart, 100); return; } // Check if canvas element exists const canvas = document.getElementById('cfb-chart-1764544202637-dthkjjeby'); if (!canvas) { console.warn('Canvas element not found yet, retrying...'); setTimeout(initChart, 100); return; } // Prevent multiple chart instances if (canvas.chartInstance) { console.log('Chart already initialized'); return; } try { // Register the datalabels plugin Chart.register(ChartDataLabels); // Embed actual chart data directly const chartData = { "labels": [ "J.Miller", "D.Hill", "T.Simpson", "G.Bernard", "A.Daniels", "J.Cobb", "J.Jones", "E.Singleton" ], "datasets": [ { "label": "Explosive rushes", "data": [ 2, 0, 1, 0, 1, 0, 0, 0 ], "backgroundColor": [ "#3c000cCC", "#3c000cCC", "#3c000cCC", "#3c000cCC", "#09284dCC", "#09284dCC", "#09284dCC", "#09284dCC" ], "borderColor": "#374151", "borderWidth": 1 }, { "label": "Successful rushes", "data": [ 4, 3, 4, 0, 9, 4, 1, 0 ], "backgroundColor": [ "rgba(175, 40, 60, 0.8)", "rgba(175, 40, 60, 0.8)", "rgba(175, 40, 60, 0.8)", "rgba(175, 40, 60, 0.8)", "rgba(73, 133, 207, 0.8)", "rgba(73, 133, 207, 0.8)", "rgba(73, 133, 207, 0.8)", "rgba(73, 133, 207, 0.8)" ], "borderColor": "#374151", "borderWidth": 1 }, { "label": "Unsuccessful rushes", "data": [ 9, 8, 2, 1, 12, 5, 0, 1 ], "backgroundColor": "#FFFFFF", "borderColor": "#374151", "borderWidth": 1 } ], "currentParams": { "year": 2025, "week": 14, "seasonType": "regular", "team": "Alabama", "gameId": "401752784" }, "teamFilter": "both" }; // Chart options (WordPress-safe) const chartOptions = { responsive: true, maintainAspectRatio: false, animation: { duration: 1 // Minimal animation to trigger layout calculation (fixes label positioning) }, elements: 'bar' === 'line' ? 'top-rushers'.includes('play-map') ? { line: { tension: 0, borderWidth: 0 } } : 'top-rushers' === 'win-probability' ? { line: { tension: 0.15, borderWidth: 2.2, fill: false }, point: { pointRadius: 0, pointHoverRadius: 4 } } : { line: { tension: 0.25, borderWidth: 2.2 }, point: { pointRadius: 'top-rushers'.includes('team-lines') ? 0 : undefined } } : {}, plugins: { datalabels: { display: function(context) { // Suppress data labels on line charts if ('bar' === 'line') { return false; } return context.dataset.datalabels && context.dataset.datalabels.display === true; }, formatter: function(value, context) { // Special handling for Overall Team Performance chart if ('top-rushers' === 'overall-team-performance' && context.dataset.label === 'Success Rate (SR)') { // Use the stored play count data if (context.dataset.playCountData && context.dataset.playCountData[context.dataIndex]) { return context.dataset.playCountData[context.dataIndex]; } // Fallback to percentage if play count data not available return Math.round(value * 100) + '%'; } // Handle bar charts with count data (play-type, quarter, down, etc.) if (context.dataset.label && context.dataset.label.includes(' SR') && (chartData.teamCounts || chartData.oppCounts)) { // Find the first team SR dataset in the chart to determine team order const allDatasets = context.chart.data.datasets; const teamSRDataset = allDatasets.find(d => d.label && d.label.includes(' SR') && !d.label.includes('NCAA')); // If this is the first team's SR dataset, use teamCounts if (teamSRDataset && context.dataset.label === teamSRDataset.label && chartData.teamCounts) { return chartData.teamCounts[context.dataIndex] || 0; } // Otherwise, use oppCounts for the second team else if (chartData.oppCounts) { return chartData.oppCounts[context.dataIndex] || 0; } } // For player charts, show value only if > 0 (matches non-embedded behavior) if ('top-rushers'.includes('top-rushers') || 'top-rushers'.includes('top-passers') || 'top-rushers'.includes('top-receivers')) { // Hide data labels for zero or negative values, show actual value for positive values return value > 0 ? value : null; } // For other charts, show values based on type if (typeof value === 'number') { // If value is between 0 and 1, treat as percentage if (value >= 0 && value 0 ? '#26262660' : 'transparent'; }, borderColor: function(context) { const value = context.dataset.data[context.dataIndex]; return value > 0 ? 'rgba(255, 255, 255, 0.2)' : 'transparent'; }, borderRadius: 4, align: 'center', anchor: 'center' }, legend: 'top-rushers' === 'win-probability' ? { display: false } : 'bar' === 'line' ? { position: 'top', align: 'start', labels: 'top-rushers'.includes('play-map') ? { usePointStyle: true, generateLabels: function(chart) { // Call the original generateLabels to get default styling const original = Chart.defaults.plugins.legend.labels.generateLabels; const labels = original.call(this, chart); // Filter and customize each label const filteredLabels = labels.filter(label => { return !label.text.includes(' { const dataset = chart.data.datasets[label.datasetIndex]; if (dataset && dataset.label) { if (dataset.label.includes('Rush')) { label.pointStyle = 'circle'; label.pointStyleWidth = 4; label.fillStyle = 'white'; } else if (dataset.label.includes('Pass')) { label.pointStyle = 'triangle'; label.pointStyleWidth = 4; label.fillStyle = 'white'; } else { label.pointStyle = 'rect'; label.pointStyleWidth = 4; label.fillStyle = 'white'; } } }); return filteredLabels; }, boxWidth: 20, padding: 12 } : { usePointStyle: false, boxWidth: 12, boxHeight: 12, padding: 12, generateLabels: function(chart) { const original = Chart.defaults.plugins.legend.labels.generateLabels; const labels = original.call(this, chart); // Filter out reference areas and ensure white fill const filteredLabels = labels.filter(label => { return !label.text.includes('NCAA Avg SR') && !label.text.includes('50/50') && !label.text.includes('Quarters'); }); // Ensure white fill for all line chart legend boxes filteredLabels.forEach((label) => { label.fillStyle = 'white'; }); return filteredLabels; } } } : { position: 'top', align: 'start', labels: { usePointStyle: false, boxWidth: 12, boxHeight: 12, padding: 12, filter: function(legendItem, chartData) { return !legendItem.text.includes('NCAA Avg SR') && !legendItem.text.includes('Quarters') && !legendItem.text.includes('50/50'); }, generateLabels: function(chart) { const data = chart.data; if (data.datasets.length) { return data.datasets.map((dataset, i) => { // Handle backgroundColor arrays (like in Overall Team Performance chart) let fillColor = dataset.backgroundColor; if (dataset.label === '# Plays') { fillColor = 'white'; } else if (Array.isArray(dataset.backgroundColor)) { // For datasets with backgroundColor arrays, use the first color for legend fillColor = dataset.backgroundColor[0]; } return { text: dataset.label, fillStyle: fillColor, strokeStyle: dataset.label === '# Plays' ? '#666' : dataset.borderColor, lineWidth: dataset.label === '# Plays' ? 1 : dataset.borderWidth, hidden: !chart.isDatasetVisible(i), datasetIndex: i }; }).filter((item, index) => { // Apply the same filter logic as above const dataset = chart.data.datasets[index]; if (!dataset || !dataset.data) return false; if (dataset.label === '# Plays') return true; // Always show # Plays if (dataset.label && (dataset.label.includes('NCAA Avg SR') || dataset.label.includes('Quarters') || dataset.label.includes('50/50'))) return false; return dataset.data.some((value) => value > 0); }); } return []; } } }, tooltip: 'top-rushers' === 'win-probability' ? { mode: 'index', intersect: false, callbacks: { title: function(tooltipItems) { if (tooltipItems && tooltipItems[0]) { return 'Play ' + (tooltipItems[0].dataIndex + 1); } return ''; }, label: function(context) { const selectedTeamWinProb = context.parsed.y; const opponentWinProb = 100 - selectedTeamWinProb; const selectedTeam = context.dataset.selectedTeam || 'Team'; const opponentTeam = context.dataset.opponentTeam || 'Opponent'; return [ selectedTeam + ': ' + selectedTeamWinProb.toFixed(1) + '%', opponentTeam + ': ' + opponentWinProb.toFixed(1) + '%' ]; }, afterLabel: function(context) { if (context.dataset.playTexts && context.dataset.playTexts[context.dataIndex]) { return '\n' + context.dataset.playTexts[context.dataIndex]; } return ''; } } } : { filter: function(tooltipItem) { if ('top-rushers'.includes('play-map')) { return !tooltipItem.dataset.label.includes('< 0') && !tooltipItem.dataset.label.includes('Quarters') && !tooltipItem.dataset.label.includes('Drive'); } return !tooltipItem.dataset.label.includes('NCAA Avg SR') && !tooltipItem.dataset.label.includes('50/50') && !tooltipItem.dataset.label.includes(' ds.label === 'Win Probability'); if (wpDataset && wpDataset.segmentColors) { wpDataset.segment = { borderColor: function(ctx) { // Use p1DataIndex (ending point) so the line inherits the destination color // This makes momentum shifts more visually intuitive const index = ctx.p1DataIndex; if (index !== undefined && wpDataset.segmentColors[index]) { return wpDataset.segmentColors[index]; } return wpDataset.borderColor || '#8B0000'; } }; } } // Initialize the chart const ctx = canvas.getContext('2d'); const chart = new Chart(ctx, { type: 'bar', data: chartData, options: chartOptions }); // Store reference to prevent re-initialization canvas.chartInstance = chart; console.log('CFB Chart initialized successfully'); } catch (error) { console.error('Error initializing CFB chart:', error); // Fallback: show error message in canvas container const container = document.getElementById('cfb-chart-1764544202637-dthkjjeby').parentNode; if (container) { container.innerHTML = '

Chart failed to load. Please refresh the page.

'; } } } // Start loading scripts sequentially function startLoading() { // First, check if scripts are already loaded (multiple embeds on same page) if (typeof Chart !== 'undefined' && typeof ChartDataLabels !== 'undefined') { initChart(); return; } // Load Chart.js first if (typeof Chart === 'undefined') { loadScript('https://cdn.jsdelivr.net/npm/[email protected]/dist/chart.min.js', function() { // Then load ChartDataLabels if (typeof ChartDataLabels === 'undefined') { loadScript('https://cdn.jsdelivr.net/npm/[email protected]', function() { initChart(); }); } else { initChart(); } }); } else if (typeof ChartDataLabels === 'undefined') { // Chart.js loaded but not ChartDataLabels loadScript('https://cdn.jsdelivr.net/npm/[email protected]', function() { initChart(); }); } else { initChart(); } } // Initialize when DOM is ready if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', startLoading); } else { startLoading(); } })();

Jam Miller finally had a “leading back” day again. It wasn’t particularly efficient (40% Rushing SR), but he did have 2 Explosive rushes in there, which in 2025 has been unheard of for an Alabama running back. His recently-lauded backup, Daniel Hill, had a less efficient game than we were hoping, though. Really a bad time (again) for a Jam Miller injury that seems like it’ll have him out for at least the SECCG next weekend.

But, the most efficient rusher in Crimson was actually Ty Simpson, who finally used his legs a little more to pick up some first downs and more (including an explosive rush).

For the defense: Auburn also leaned on their QB to rush, but less “occasional scramble” and more “at an order of magnitude higher than the other rushers.” This is more exaggerated than a Jalen Milroe chart.

.cfb-chart-embed-cfb-chart-1764544289987-h28yvfpwp { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', sans-serif; margin: 0; padding: 0; } .cfb-chart-embed-cfb-chart-1764544289987-h28yvfpwp .chart-container { background: white; border-radius: 12px; border: 1px solid #e5e5e5; box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); overflow: hidden; } .cfb-chart-embed-cfb-chart-1764544289987-h28yvfpwp .chart-header { padding: 18px 24px 14px; border-bottom: 1px solid #e5e5e5; background: white; } .cfb-chart-embed-cfb-chart-1764544289987-h28yvfpwp .chart-title { font-size: 18px; font-weight: 600; color: #171717; margin: 0; } .cfb-chart-embed-cfb-chart-1764544289987-h28yvfpwp .chart-subtitle { font-size: 11px; font-weight: 400; color: #737373; margin: 4px 0 0 0; } .cfb-chart-embed-cfb-chart-1764544289987-h28yvfpwp .chart-content { padding: 20px 24px 24px !important; } .cfb-chart-embed-cfb-chart-1764544289987-h28yvfpwp .chart-content.top-passers { height: 240px !important; } @media (max-width: 640px) { .cfb-chart-embed-cfb-chart-1764544289987-h28yvfpwp .chart-content { padding: 12px 16px 20px !important; } .cfb-chart-embed-cfb-chart-1764544289987-h28yvfpwp .chart-header { padding: 12px 16px 12px !important; } .cfb-chart-embed-cfb-chart-1764544289987-h28yvfpwp .embed-footer-top { padding: 8px 12px !important; } .cfb-chart-embed-cfb-chart-1764544289987-h28yvfpwp .data-definitions { padding: 12px !important; } } .cfb-chart-embed-cfb-chart-1764544289987-h28yvfpwp .embed-footer { border-top: 1px solid #e5e5e5; font-size: 12px; color: #737373; } .cfb-chart-embed-cfb-chart-1764544289987-h28yvfpwp .embed-footer-top { display: flex; justify-content: space-between; align-items: center; padding: 12px 16px; } .cfb-chart-embed-cfb-chart-1764544289987-h28yvfpwp .embed-footer-link { color: #737373; text-decoration: none; font-weight: 500; } .cfb-chart-embed-cfb-chart-1764544289987-h28yvfpwp .embed-footer-link:hover { color: #525252; text-decoration: underline; } .cfb-chart-embed-cfb-chart-1764544289987-h28yvfpwp .data-definitions-toggle { background: none; border: none; color: #737373; font-size: 12px; font-weight: 500; cursor: pointer; display: flex; align-items: center; gap: 4px; padding: 0; } .cfb-chart-embed-cfb-chart-1764544289987-h28yvfpwp .data-definitions-toggle:hover { color: #525252; } .cfb-chart-embed-cfb-chart-1764544289987-h28yvfpwp .caret { transition: transform 0.2s ease; font-size: 10px; } .cfb-chart-embed-cfb-chart-1764544289987-h28yvfpwp .caret.expanded { transform: rotate(180deg); } .cfb-chart-embed-cfb-chart-1764544289987-h28yvfpwp .data-definitions { display: none; padding: 16px; background: #fafafa; border-top: 1px solid #e5e5e5; font-size: 12px; line-height: 1.4; } .cfb-chart-embed-cfb-chart-1764544289987-h28yvfpwp .data-definitions.expanded { display: block; } .cfb-chart-embed-cfb-chart-1764544289987-h28yvfpwp .data-definitions ul { margin: 0; padding-left: 0; list-style: none; } .cfb-chart-embed-cfb-chart-1764544289987-h28yvfpwp .data-definitions li { margin-bottom: 4px; }

Top passers

Alabama vs. Auburn • Nov 29, 2025

See all charts Data definitions ▼

  • Based roughly on the SP+ analytic system

  • Successful play: Gains enough needed yards (50% 1st down, 70% on 2nd, 100% on 3rd/4th)

  • Success Rate (SR): Percentage of plays that were successful

  • Explosiveness Rate (XR): Percentage of plays gaining 15+ yards

// Toggle data definitions accordion - unique function per embed function toggleDefinitions_cfb_chart_1764544289987_h28yvfpwp() { const definitions = document.getElementById('dataDefinitions_cfb-chart-1764544289987-h28yvfpwp'); const caret = document.getElementById('caret_cfb-chart-1764544289987-h28yvfpwp'); if (definitions.classList.contains('expanded')) { definitions.classList.remove('expanded'); caret.classList.remove('expanded'); } else { definitions.classList.add('expanded'); caret.classList.add('expanded'); } } // Sequential script loading for better reliability (function() { 'use strict'; let retryCount = 0; const maxRetries = 50; // 5 seconds total // Load scripts sequentially function loadScript(url, callback) { const script = document.createElement('script'); script.src = url; script.onload = callback; script.onerror = function() { console.error('Failed to load script:', url); showError('Failed to load required chart library'); }; document.head.appendChild(script); } function showError(message) { const canvas = document.getElementById('cfb-chart-1764544289987-h28yvfpwp'); if (canvas && canvas.parentNode) { canvas.parentNode.innerHTML = '

' + message + '

'; } } function initChart() { retryCount++; // Check if Chart.js is available if (typeof Chart === 'undefined') { if (retryCount >= maxRetries) { showError('Chart library failed to load. Please refresh the page.'); return; } setTimeout(initChart, 100); return; } // Check if datalabels plugin is available if (typeof ChartDataLabels === 'undefined') { if (retryCount >= maxRetries) { showError('Chart plugin failed to load. Please refresh the page.'); return; } setTimeout(initChart, 100); return; } // Check if canvas element exists const canvas = document.getElementById('cfb-chart-1764544289987-h28yvfpwp'); if (!canvas) { console.warn('Canvas element not found yet, retrying...'); setTimeout(initChart, 100); return; } // Prevent multiple chart instances if (canvas.chartInstance) { console.log('Chart already initialized'); return; } try { // Register the datalabels plugin Chart.register(ChartDataLabels); // Embed actual chart data directly const chartData = { "labels": [ "T.Simpson", "A.Daniels" ], "datasets": [ { "label": "Explosive", "data": [ 2, 4 ], "backgroundColor": [ "#3c000cCC", "#09284dCC" ], "borderColor": "#374151", "borderWidth": 1 }, { "label": "Successful", "data": [ 9, 8 ], "backgroundColor": [ "rgba(175, 40, 60, 0.8)", "rgba(73, 133, 207, 0.8)" ], "borderColor": "#374151", "borderWidth": 1 }, { "label": "Other catches", "data": [ 8, 4 ], "backgroundColor": [ "rgba(245, 229, 233, 0.8)", "rgba(234, 241, 251, 0.8)" ], "borderColor": "#374151", "borderWidth": 1 }, { "label": "Incompletes", "data": [ 16, 20 ], "backgroundColor": "#FFFFFF", "borderColor": "#374151", "borderWidth": 1 }, { "label": "Interceptions", "data": [ 0, 1 ], "backgroundColor": "#4B5563", "borderColor": "#374151", "borderWidth": 1 } ], "currentParams": { "year": 2025, "week": 14, "seasonType": "regular", "team": "Alabama", "gameId": "401752784" }, "teamFilter": "both" }; // Chart options (WordPress-safe) const chartOptions = { responsive: true, maintainAspectRatio: false, animation: { duration: 1 // Minimal animation to trigger layout calculation (fixes label positioning) }, elements: 'bar' === 'line' ? 'top-passers'.includes('play-map') ? { line: { tension: 0, borderWidth: 0 } } : 'top-passers' === 'win-probability' ? { line: { tension: 0.15, borderWidth: 2.2, fill: false }, point: { pointRadius: 0, pointHoverRadius: 4 } } : { line: { tension: 0.25, borderWidth: 2.2 }, point: { pointRadius: 'top-passers'.includes('team-lines') ? 0 : undefined } } : {}, plugins: { datalabels: { display: function(context) { // Suppress data labels on line charts if ('bar' === 'line') { return false; } return context.dataset.datalabels && context.dataset.datalabels.display === true; }, formatter: function(value, context) { // Special handling for Overall Team Performance chart if ('top-passers' === 'overall-team-performance' && context.dataset.label === 'Success Rate (SR)') { // Use the stored play count data if (context.dataset.playCountData && context.dataset.playCountData[context.dataIndex]) { return context.dataset.playCountData[context.dataIndex]; } // Fallback to percentage if play count data not available return Math.round(value * 100) + '%'; } // Handle bar charts with count data (play-type, quarter, down, etc.) if (context.dataset.label && context.dataset.label.includes(' SR') && (chartData.teamCounts || chartData.oppCounts)) { // Find the first team SR dataset in the chart to determine team order const allDatasets = context.chart.data.datasets; const teamSRDataset = allDatasets.find(d => d.label && d.label.includes(' SR') && !d.label.includes('NCAA')); // If this is the first team's SR dataset, use teamCounts if (teamSRDataset && context.dataset.label === teamSRDataset.label && chartData.teamCounts) { return chartData.teamCounts[context.dataIndex] || 0; } // Otherwise, use oppCounts for the second team else if (chartData.oppCounts) { return chartData.oppCounts[context.dataIndex] || 0; } } // For player charts, show value only if > 0 (matches non-embedded behavior) if ('top-passers'.includes('top-rushers') || 'top-passers'.includes('top-passers') || 'top-passers'.includes('top-receivers')) { // Hide data labels for zero or negative values, show actual value for positive values return value > 0 ? value : null; } // For other charts, show values based on type if (typeof value === 'number') { // If value is between 0 and 1, treat as percentage if (value >= 0 && value 0 ? '#26262660' : 'transparent'; }, borderColor: function(context) { const value = context.dataset.data[context.dataIndex]; return value > 0 ? 'rgba(255, 255, 255, 0.2)' : 'transparent'; }, borderRadius: 4, align: 'center', anchor: 'center' }, legend: 'top-passers' === 'win-probability' ? { display: false } : 'bar' === 'line' ? { position: 'top', align: 'start', labels: 'top-passers'.includes('play-map') ? { usePointStyle: true, generateLabels: function(chart) { // Call the original generateLabels to get default styling const original = Chart.defaults.plugins.legend.labels.generateLabels; const labels = original.call(this, chart); // Filter and customize each label const filteredLabels = labels.filter(label => { return !label.text.includes(' { const dataset = chart.data.datasets[label.datasetIndex]; if (dataset && dataset.label) { if (dataset.label.includes('Rush')) { label.pointStyle = 'circle'; label.pointStyleWidth = 4; label.fillStyle = 'white'; } else if (dataset.label.includes('Pass')) { label.pointStyle = 'triangle'; label.pointStyleWidth = 4; label.fillStyle = 'white'; } else { label.pointStyle = 'rect'; label.pointStyleWidth = 4; label.fillStyle = 'white'; } } }); return filteredLabels; }, boxWidth: 20, padding: 12 } : { usePointStyle: false, boxWidth: 12, boxHeight: 12, padding: 12, generateLabels: function(chart) { const original = Chart.defaults.plugins.legend.labels.generateLabels; const labels = original.call(this, chart); // Filter out reference areas and ensure white fill const filteredLabels = labels.filter(label => { return !label.text.includes('NCAA Avg SR') && !label.text.includes('50/50') && !label.text.includes('Quarters'); }); // Ensure white fill for all line chart legend boxes filteredLabels.forEach((label) => { label.fillStyle = 'white'; }); return filteredLabels; } } } : { position: 'top', align: 'start', labels: { usePointStyle: false, boxWidth: 12, boxHeight: 12, padding: 12, filter: function(legendItem, chartData) { return !legendItem.text.includes('NCAA Avg SR') && !legendItem.text.includes('Quarters') && !legendItem.text.includes('50/50'); }, generateLabels: function(chart) { const data = chart.data; if (data.datasets.length) { return data.datasets.map((dataset, i) => { // Handle backgroundColor arrays (like in Overall Team Performance chart) let fillColor = dataset.backgroundColor; if (dataset.label === '# Plays') { fillColor = 'white'; } else if (Array.isArray(dataset.backgroundColor)) { // For datasets with backgroundColor arrays, use the first color for legend fillColor = dataset.backgroundColor[0]; } return { text: dataset.label, fillStyle: fillColor, strokeStyle: dataset.label === '# Plays' ? '#666' : dataset.borderColor, lineWidth: dataset.label === '# Plays' ? 1 : dataset.borderWidth, hidden: !chart.isDatasetVisible(i), datasetIndex: i }; }).filter((item, index) => { // Apply the same filter logic as above const dataset = chart.data.datasets[index]; if (!dataset || !dataset.data) return false; if (dataset.label === '# Plays') return true; // Always show # Plays if (dataset.label && (dataset.label.includes('NCAA Avg SR') || dataset.label.includes('Quarters') || dataset.label.includes('50/50'))) return false; return dataset.data.some((value) => value > 0); }); } return []; } } }, tooltip: 'top-passers' === 'win-probability' ? { mode: 'index', intersect: false, callbacks: { title: function(tooltipItems) { if (tooltipItems && tooltipItems[0]) { return 'Play ' + (tooltipItems[0].dataIndex + 1); } return ''; }, label: function(context) { const selectedTeamWinProb = context.parsed.y; const opponentWinProb = 100 - selectedTeamWinProb; const selectedTeam = context.dataset.selectedTeam || 'Team'; const opponentTeam = context.dataset.opponentTeam || 'Opponent'; return [ selectedTeam + ': ' + selectedTeamWinProb.toFixed(1) + '%', opponentTeam + ': ' + opponentWinProb.toFixed(1) + '%' ]; }, afterLabel: function(context) { if (context.dataset.playTexts && context.dataset.playTexts[context.dataIndex]) { return '\n' + context.dataset.playTexts[context.dataIndex]; } return ''; } } } : { filter: function(tooltipItem) { if ('top-passers'.includes('play-map')) { return !tooltipItem.dataset.label.includes('< 0') && !tooltipItem.dataset.label.includes('Quarters') && !tooltipItem.dataset.label.includes('Drive'); } return !tooltipItem.dataset.label.includes('NCAA Avg SR') && !tooltipItem.dataset.label.includes('50/50') && !tooltipItem.dataset.label.includes(' ds.label === 'Win Probability'); if (wpDataset && wpDataset.segmentColors) { wpDataset.segment = { borderColor: function(ctx) { // Use p1DataIndex (ending point) so the line inherits the destination color // This makes momentum shifts more visually intuitive const index = ctx.p1DataIndex; if (index !== undefined && wpDataset.segmentColors[index]) { return wpDataset.segmentColors[index]; } return wpDataset.borderColor || '#8B0000'; } }; } } // Initialize the chart const ctx = canvas.getContext('2d'); const chart = new Chart(ctx, { type: 'bar', data: chartData, options: chartOptions }); // Store reference to prevent re-initialization canvas.chartInstance = chart; console.log('CFB Chart initialized successfully'); } catch (error) { console.error('Error initializing CFB chart:', error); // Fallback: show error message in canvas container const container = document.getElementById('cfb-chart-1764544289987-h28yvfpwp').parentNode; if (container) { container.innerHTML = '

Chart failed to load. Please refresh the page.

'; } } } // Start loading scripts sequentially function startLoading() { // First, check if scripts are already loaded (multiple embeds on same page) if (typeof Chart !== 'undefined' && typeof ChartDataLabels !== 'undefined') { initChart(); return; } // Load Chart.js first if (typeof Chart === 'undefined') { loadScript('https://cdn.jsdelivr.net/npm/[email protected]/dist/chart.min.js', function() { // Then load ChartDataLabels if (typeof ChartDataLabels === 'undefined') { loadScript('https://cdn.jsdelivr.net/npm/[email protected]', function() { initChart(); }); } else { initChart(); } }); } else if (typeof ChartDataLabels === 'undefined') { // Chart.js loaded but not ChartDataLabels loadScript('https://cdn.jsdelivr.net/npm/[email protected]', function() { initChart(); }); } else { initChart(); } } // Initialize when DOM is ready if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', startLoading); } else { startLoading(); } })();

Ty was … well, Ty was on average about as good as the opposing QB; and given Auburn’s QB rotation in 2025, that’s not a compliment. On the plus side, Simpson had a higher completion rate and no interceptions, but Daniels had a few back-breaking explosive completions.

Let’s move on …

.cfb-chart-embed-cfb-chart-1764544390798-x0xavh8hf { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', sans-serif; margin: 0; padding: 0; } .cfb-chart-embed-cfb-chart-1764544390798-x0xavh8hf .chart-container { background: white; border-radius: 12px; border: 1px solid #e5e5e5; box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); overflow: hidden; } .cfb-chart-embed-cfb-chart-1764544390798-x0xavh8hf .chart-header { padding: 18px 24px 14px; border-bottom: 1px solid #e5e5e5; background: white; } .cfb-chart-embed-cfb-chart-1764544390798-x0xavh8hf .chart-title { font-size: 18px; font-weight: 600; color: #171717; margin: 0; } .cfb-chart-embed-cfb-chart-1764544390798-x0xavh8hf .chart-subtitle { font-size: 11px; font-weight: 400; color: #737373; margin: 4px 0 0 0; } .cfb-chart-embed-cfb-chart-1764544390798-x0xavh8hf .chart-content { padding: 20px 24px 24px !important; } .cfb-chart-embed-cfb-chart-1764544390798-x0xavh8hf .chart-content.top-receivers { height: 400px; } @media (max-width: 640px) { .cfb-chart-embed-cfb-chart-1764544390798-x0xavh8hf .chart-content { padding: 12px 16px 20px !important; } .cfb-chart-embed-cfb-chart-1764544390798-x0xavh8hf .chart-header { padding: 12px 16px 12px !important; } .cfb-chart-embed-cfb-chart-1764544390798-x0xavh8hf .embed-footer-top { padding: 8px 12px !important; } .cfb-chart-embed-cfb-chart-1764544390798-x0xavh8hf .data-definitions { padding: 12px !important; } } .cfb-chart-embed-cfb-chart-1764544390798-x0xavh8hf .embed-footer { border-top: 1px solid #e5e5e5; font-size: 12px; color: #737373; } .cfb-chart-embed-cfb-chart-1764544390798-x0xavh8hf .embed-footer-top { display: flex; justify-content: space-between; align-items: center; padding: 12px 16px; } .cfb-chart-embed-cfb-chart-1764544390798-x0xavh8hf .embed-footer-link { color: #737373; text-decoration: none; font-weight: 500; } .cfb-chart-embed-cfb-chart-1764544390798-x0xavh8hf .embed-footer-link:hover { color: #525252; text-decoration: underline; } .cfb-chart-embed-cfb-chart-1764544390798-x0xavh8hf .data-definitions-toggle { background: none; border: none; color: #737373; font-size: 12px; font-weight: 500; cursor: pointer; display: flex; align-items: center; gap: 4px; padding: 0; } .cfb-chart-embed-cfb-chart-1764544390798-x0xavh8hf .data-definitions-toggle:hover { color: #525252; } .cfb-chart-embed-cfb-chart-1764544390798-x0xavh8hf .caret { transition: transform 0.2s ease; font-size: 10px; } .cfb-chart-embed-cfb-chart-1764544390798-x0xavh8hf .caret.expanded { transform: rotate(180deg); } .cfb-chart-embed-cfb-chart-1764544390798-x0xavh8hf .data-definitions { display: none; padding: 16px; background: #fafafa; border-top: 1px solid #e5e5e5; font-size: 12px; line-height: 1.4; } .cfb-chart-embed-cfb-chart-1764544390798-x0xavh8hf .data-definitions.expanded { display: block; } .cfb-chart-embed-cfb-chart-1764544390798-x0xavh8hf .data-definitions ul { margin: 0; padding-left: 0; list-style: none; } .cfb-chart-embed-cfb-chart-1764544390798-x0xavh8hf .data-definitions li { margin-bottom: 4px; }

Top receivers

Alabama vs. Auburn • Nov 29, 2025

See all charts Data definitions ▼

  • Based roughly on the SP+ analytic system

  • Successful play: Gains enough needed yards (50% 1st down, 70% on 2nd, 100% on 3rd/4th)

  • Success Rate (SR): Percentage of plays that were successful

  • Explosiveness Rate (XR): Percentage of plays gaining 15+ yards

// Toggle data definitions accordion - unique function per embed function toggleDefinitions_cfb_chart_1764544390798_x0xavh8hf() { const definitions = document.getElementById('dataDefinitions_cfb-chart-1764544390798-x0xavh8hf'); const caret = document.getElementById('caret_cfb-chart-1764544390798-x0xavh8hf'); if (definitions.classList.contains('expanded')) { definitions.classList.remove('expanded'); caret.classList.remove('expanded'); } else { definitions.classList.add('expanded'); caret.classList.add('expanded'); } } // Sequential script loading for better reliability (function() { 'use strict'; let retryCount = 0; const maxRetries = 50; // 5 seconds total // Load scripts sequentially function loadScript(url, callback) { const script = document.createElement('script'); script.src = url; script.onload = callback; script.onerror = function() { console.error('Failed to load script:', url); showError('Failed to load required chart library'); }; document.head.appendChild(script); } function showError(message) { const canvas = document.getElementById('cfb-chart-1764544390798-x0xavh8hf'); if (canvas && canvas.parentNode) { canvas.parentNode.innerHTML = '

' + message + '

'; } } function initChart() { retryCount++; // Check if Chart.js is available if (typeof Chart === 'undefined') { if (retryCount >= maxRetries) { showError('Chart library failed to load. Please refresh the page.'); return; } setTimeout(initChart, 100); return; } // Check if datalabels plugin is available if (typeof ChartDataLabels === 'undefined') { if (retryCount >= maxRetries) { showError('Chart plugin failed to load. Please refresh the page.'); return; } setTimeout(initChart, 100); return; } // Check if canvas element exists const canvas = document.getElementById('cfb-chart-1764544390798-x0xavh8hf'); if (!canvas) { console.warn('Canvas element not found yet, retrying...'); setTimeout(initChart, 100); return; } // Prevent multiple chart instances if (canvas.chartInstance) { console.log('Chart already initialized'); return; } try { // Register the datalabels plugin Chart.register(ChartDataLabels); // Embed actual chart data directly const chartData = { "labels": [ "I.Horton", "G.Bernard", "J.Miller", "D.Hill", "L.Brooks", "K.Edwards", "J.Lindsey", "A.Dear" ], "datasets": [ { "label": "Explosive catches", "data": [ 0, 0, 0, 0, 0, 0, 0, 0 ], "backgroundColor": [ "#3c000cCC", "#3c000cCC", "#3c000cCC", "#3c000cCC", "#3c000cCC", "#3c000cCC", "#3c000cCC", "#3c000cCC" ], "borderColor": "#374151", "borderWidth": 1 }, { "label": "Successful catches", "data": [ 3, 2, 1, 0, 1, 1, 0, 1 ], "backgroundColor": [ "rgba(175, 40, 60, 0.8)", "rgba(175, 40, 60, 0.8)", "rgba(175, 40, 60, 0.8)", "rgba(175, 40, 60, 0.8)", "rgba(175, 40, 60, 0.8)", "rgba(175, 40, 60, 0.8)", "rgba(175, 40, 60, 0.8)", "rgba(175, 40, 60, 0.8)" ], "borderColor": "#374151", "borderWidth": 1 }, { "label": "Other catches", "data": [ 1, 1, 1, 2, 1, 1, 1, 0 ], "backgroundColor": [ "rgba(245, 229, 233, 0.8)", "rgba(245, 229, 233, 0.8)", "rgba(245, 229, 233, 0.8)", "rgba(245, 229, 233, 0.8)", "rgba(245, 229, 233, 0.8)", "rgba(245, 229, 233, 0.8)", "rgba(245, 229, 233, 0.8)", "rgba(245, 229, 233, 0.8)" ], "borderColor": "#374151", "borderWidth": 1 } ], "currentParams": { "year": 2025, "week": 14, "seasonType": "regular", "team": "Alabama", "gameId": "401752784" }, "teamFilter": "Alabama" }; // Chart options (WordPress-safe) const chartOptions = { responsive: true, maintainAspectRatio: false, animation: { duration: 1 // Minimal animation to trigger layout calculation (fixes label positioning) }, elements: 'bar' === 'line' ? 'top-receivers'.includes('play-map') ? { line: { tension: 0, borderWidth: 0 } } : 'top-receivers' === 'win-probability' ? { line: { tension: 0.15, borderWidth: 2.2, fill: false }, point: { pointRadius: 0, pointHoverRadius: 4 } } : { line: { tension: 0.25, borderWidth: 2.2 }, point: { pointRadius: 'top-receivers'.includes('team-lines') ? 0 : undefined } } : {}, plugins: { datalabels: { display: function(context) { // Suppress data labels on line charts if ('bar' === 'line') { return false; } return context.dataset.datalabels && context.dataset.datalabels.display === true; }, formatter: function(value, context) { // Special handling for Overall Team Performance chart if ('top-receivers' === 'overall-team-performance' && context.dataset.label === 'Success Rate (SR)') { // Use the stored play count data if (context.dataset.playCountData && context.dataset.playCountData[context.dataIndex]) { return context.dataset.playCountData[context.dataIndex]; } // Fallback to percentage if play count data not available return Math.round(value * 100) + '%'; } // Handle bar charts with count data (play-type, quarter, down, etc.) if (context.dataset.label && context.dataset.label.includes(' SR') && (chartData.teamCounts || chartData.oppCounts)) { // Find the first team SR dataset in the chart to determine team order const allDatasets = context.chart.data.datasets; const teamSRDataset = allDatasets.find(d => d.label && d.label.includes(' SR') && !d.label.includes('NCAA')); // If this is the first team's SR dataset, use teamCounts if (teamSRDataset && context.dataset.label === teamSRDataset.label && chartData.teamCounts) { return chartData.teamCounts[context.dataIndex] || 0; } // Otherwise, use oppCounts for the second team else if (chartData.oppCounts) { return chartData.oppCounts[context.dataIndex] || 0; } } // For player charts, show value only if > 0 (matches non-embedded behavior) if ('top-receivers'.includes('top-rushers') || 'top-receivers'.includes('top-passers') || 'top-receivers'.includes('top-receivers')) { // Hide data labels for zero or negative values, show actual value for positive values return value > 0 ? value : null; } // For other charts, show values based on type if (typeof value === 'number') { // If value is between 0 and 1, treat as percentage if (value >= 0 && value 0 ? '#26262660' : 'transparent'; }, borderColor: function(context) { const value = context.dataset.data[context.dataIndex]; return value > 0 ? 'rgba(255, 255, 255, 0.2)' : 'transparent'; }, borderRadius: 4, align: 'center', anchor: 'center' }, legend: 'top-receivers' === 'win-probability' ? { display: false } : 'bar' === 'line' ? { position: 'top', align: 'start', labels: 'top-receivers'.includes('play-map') ? { usePointStyle: true, generateLabels: function(chart) { // Call the original generateLabels to get default styling const original = Chart.defaults.plugins.legend.labels.generateLabels; const labels = original.call(this, chart); // Filter and customize each label const filteredLabels = labels.filter(label => { return !label.text.includes(' { const dataset = chart.data.datasets[label.datasetIndex]; if (dataset && dataset.label) { if (dataset.label.includes('Rush')) { label.pointStyle = 'circle'; label.pointStyleWidth = 4; label.fillStyle = 'white'; } else if (dataset.label.includes('Pass')) { label.pointStyle = 'triangle'; label.pointStyleWidth = 4; label.fillStyle = 'white'; } else { label.pointStyle = 'rect'; label.pointStyleWidth = 4; label.fillStyle = 'white'; } } }); return filteredLabels; }, boxWidth: 20, padding: 12 } : { usePointStyle: false, boxWidth: 12, boxHeight: 12, padding: 12, generateLabels: function(chart) { const original = Chart.defaults.plugins.legend.labels.generateLabels; const labels = original.call(this, chart); // Filter out reference areas and ensure white fill const filteredLabels = labels.filter(label => { return !label.text.includes('NCAA Avg SR') && !label.text.includes('50/50') && !label.text.includes('Quarters'); }); // Ensure white fill for all line chart legend boxes filteredLabels.forEach((label) => { label.fillStyle = 'white'; }); return filteredLabels; } } } : { position: 'top', align: 'start', labels: { usePointStyle: false, boxWidth: 12, boxHeight: 12, padding: 12, filter: function(legendItem, chartData) { return !legendItem.text.includes('NCAA Avg SR') && !legendItem.text.includes('Quarters') && !legendItem.text.includes('50/50'); }, generateLabels: function(chart) { const data = chart.data; if (data.datasets.length) { return data.datasets.map((dataset, i) => { // Handle backgroundColor arrays (like in Overall Team Performance chart) let fillColor = dataset.backgroundColor; if (dataset.label === '# Plays') { fillColor = 'white'; } else if (Array.isArray(dataset.backgroundColor)) { // For datasets with backgroundColor arrays, use the first color for legend fillColor = dataset.backgroundColor[0]; } return { text: dataset.label, fillStyle: fillColor, strokeStyle: dataset.label === '# Plays' ? '#666' : dataset.borderColor, lineWidth: dataset.label === '# Plays' ? 1 : dataset.borderWidth, hidden: !chart.isDatasetVisible(i), datasetIndex: i }; }).filter((item, index) => { // Apply the same filter logic as above const dataset = chart.data.datasets[index]; if (!dataset || !dataset.data) return false; if (dataset.label === '# Plays') return true; // Always show # Plays if (dataset.label && (dataset.label.includes('NCAA Avg SR') || dataset.label.includes('Quarters') || dataset.label.includes('50/50'))) return false; return dataset.data.some((value) => value > 0); }); } return []; } } }, tooltip: 'top-receivers' === 'win-probability' ? { mode: 'index', intersect: false, callbacks: { title: function(tooltipItems) { if (tooltipItems && tooltipItems[0]) { return 'Play ' + (tooltipItems[0].dataIndex + 1); } return ''; }, label: function(context) { const selectedTeamWinProb = context.parsed.y; const opponentWinProb = 100 - selectedTeamWinProb; const selectedTeam = context.dataset.selectedTeam || 'Team'; const opponentTeam = context.dataset.opponentTeam || 'Opponent'; return [ selectedTeam + ': ' + selectedTeamWinProb.toFixed(1) + '%', opponentTeam + ': ' + opponentWinProb.toFixed(1) + '%' ]; }, afterLabel: function(context) { if (context.dataset.playTexts && context.dataset.playTexts[context.dataIndex]) { return '\n' + context.dataset.playTexts[context.dataIndex]; } return ''; } } } : { filter: function(tooltipItem) { if ('top-receivers'.includes('play-map')) { return !tooltipItem.dataset.label.includes('< 0') && !tooltipItem.dataset.label.includes('Quarters') && !tooltipItem.dataset.label.includes('Drive'); } return !tooltipItem.dataset.label.includes('NCAA Avg SR') && !tooltipItem.dataset.label.includes('50/50') && !tooltipItem.dataset.label.includes(' ds.label === 'Win Probability'); if (wpDataset && wpDataset.segmentColors) { wpDataset.segment = { borderColor: function(ctx) { // Use p1DataIndex (ending point) so the line inherits the destination color // This makes momentum shifts more visually intuitive const index = ctx.p1DataIndex; if (index !== undefined && wpDataset.segmentColors[index]) { return wpDataset.segmentColors[index]; } return wpDataset.borderColor || '#8B0000'; } }; } } // Initialize the chart const ctx = canvas.getContext('2d'); const chart = new Chart(ctx, { type: 'bar', data: chartData, options: chartOptions }); // Store reference to prevent re-initialization canvas.chartInstance = chart; console.log('CFB Chart initialized successfully'); } catch (error) { console.error('Error initializing CFB chart:', error); // Fallback: show error message in canvas container const container = document.getElementById('cfb-chart-1764544390798-x0xavh8hf').parentNode; if (container) { container.innerHTML = '

Chart failed to load. Please refresh the page.

'; } } } // Start loading scripts sequentially function startLoading() { // First, check if scripts are already loaded (multiple embeds on same page) if (typeof Chart !== 'undefined' && typeof ChartDataLabels !== 'undefined') { initChart(); return; } // Load Chart.js first if (typeof Chart === 'undefined') { loadScript('https://cdn.jsdelivr.net/npm/[email protected]/dist/chart.min.js', function() { // Then load ChartDataLabels if (typeof ChartDataLabels === 'undefined') { loadScript('https://cdn.jsdelivr.net/npm/[email protected]', function() { initChart(); }); } else { initChart(); } }); } else if (typeof ChartDataLabels === 'undefined') { // Chart.js loaded but not ChartDataLabels loadScript('https://cdn.jsdelivr.net/npm/[email protected]', function() { initChart(); }); } else { initChart(); } } // Initialize when DOM is ready if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', startLoading); } else { startLoading(); } })();

Isaiah Horton was the hero of the day. Is it too late to claim that I’ve been rooting extra hard for him this year in a crowded WR room? What, you don’t believe me!?

Usually this line — 4 catches, with only 3 successful, and none explosive — wouldn’t be much of a celebration for a lead WR in a game. But all 3 of those successful catches were touchdowns, so apparently he had the magic touch this this game (where the passing game was otherwise cursed).

Of course Germie Bernard made his presence known per usual; then Lotty Brooks was actually WR3 (in the notable absence of targets for Ryan Williams), where he had an early drop but then a good contribution late.

Daniel Hill didn’t do his usual “aha! I’m actually a giant wide receiver in disguise” routine in this one, being targeted only twice and not getting successful yardage on either. (It does seem like his presence did pull defenders off of Ty on a few of those scrambles, including a late 4th down, though).

Jam had one successful reception, but another unsuccessful one (in addition to a drop). Then AK Dear didn’t get any rushes in this game, but caught a successful screen (during one of the rare moments where Grubb seemed to want to do something about the blitz).

The backup TE’s tried their best — I hope? — but it wasn’t a strong TE’s day. Kaleb Edwards was 1/2 for successful catches, and Jay Lindsey’s sole catch didn’t gain successful yardage.

A tale of two halves

Finally, let’s loop back around to revisit those overall SR’s and XR’s:

.cfb-chart-embed-cfb-chart-1764545748116-zplvab4ug { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', sans-serif; margin: 0; padding: 0; } .cfb-chart-embed-cfb-chart-1764545748116-zplvab4ug .chart-container { background: white; border-radius: 12px; border: 1px solid #e5e5e5; box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); overflow: hidden; } .cfb-chart-embed-cfb-chart-1764545748116-zplvab4ug .chart-header { padding: 18px 24px 14px; border-bottom: 1px solid #e5e5e5; background: white; } .cfb-chart-embed-cfb-chart-1764545748116-zplvab4ug .chart-title { font-size: 18px; font-weight: 600; color: #171717; margin: 0; } .cfb-chart-embed-cfb-chart-1764545748116-zplvab4ug .chart-subtitle { font-size: 11px; font-weight: 400; color: #737373; margin: 4px 0 0 0; } .cfb-chart-embed-cfb-chart-1764545748116-zplvab4ug .chart-content { padding: 20px 24px 24px !important; } .cfb-chart-embed-cfb-chart-1764545748116-zplvab4ug .chart-content { height: 325px; } @media (max-width: 640px) { .cfb-chart-embed-cfb-chart-1764545748116-zplvab4ug .chart-content { padding: 12px 16px 20px !important; height: 280px !important; } .cfb-chart-embed-cfb-chart-1764545748116-zplvab4ug .chart-header { padding: 12px 16px 12px !important; } .cfb-chart-embed-cfb-chart-1764545748116-zplvab4ug .embed-footer-top { padding: 8px 12px !important; } .cfb-chart-embed-cfb-chart-1764545748116-zplvab4ug .data-definitions { padding: 12px !important; } } .cfb-chart-embed-cfb-chart-1764545748116-zplvab4ug .embed-footer { border-top: 1px solid #e5e5e5; font-size: 12px; color: #737373; } .cfb-chart-embed-cfb-chart-1764545748116-zplvab4ug .embed-footer-top { display: flex; justify-content: space-between; align-items: center; padding: 12px 16px; } .cfb-chart-embed-cfb-chart-1764545748116-zplvab4ug .embed-footer-link { color: #737373; text-decoration: none; font-weight: 500; } .cfb-chart-embed-cfb-chart-1764545748116-zplvab4ug .embed-footer-link:hover { color: #525252; text-decoration: underline; } .cfb-chart-embed-cfb-chart-1764545748116-zplvab4ug .data-definitions-toggle { background: none; border: none; color: #737373; font-size: 12px; font-weight: 500; cursor: pointer; display: flex; align-items: center; gap: 4px; padding: 0; } .cfb-chart-embed-cfb-chart-1764545748116-zplvab4ug .data-definitions-toggle:hover { color: #525252; } .cfb-chart-embed-cfb-chart-1764545748116-zplvab4ug .caret { transition: transform 0.2s ease; font-size: 10px; } .cfb-chart-embed-cfb-chart-1764545748116-zplvab4ug .caret.expanded { transform: rotate(180deg); } .cfb-chart-embed-cfb-chart-1764545748116-zplvab4ug .data-definitions { display: none; padding: 16px; background: #fafafa; border-top: 1px solid #e5e5e5; font-size: 12px; line-height: 1.4; } .cfb-chart-embed-cfb-chart-1764545748116-zplvab4ug .data-definitions.expanded { display: block; } .cfb-chart-embed-cfb-chart-1764545748116-zplvab4ug .data-definitions ul { margin: 0; padding-left: 0; list-style: none; } .cfb-chart-embed-cfb-chart-1764545748116-zplvab4ug .data-definitions li { margin-bottom: 4px; }

SR and XR by Team

Alabama vs. Auburn • Nov 29, 2025

See all charts Data definitions ▼

  • Based roughly on the SP+ analytic system

  • Successful play: Gains enough needed yards (50% 1st down, 70% on 2nd, 100% on 3rd/4th)

  • Success Rate (SR): Percentage of plays that were successful

  • Explosiveness Rate (XR): Percentage of plays gaining 15+ yards

  • Gray area: Represents 42% (roughly NCAA average) success rate

// Toggle data definitions accordion - unique function per embed function toggleDefinitions_cfb_chart_1764545748116_zplvab4ug() { const definitions = document.getElementById('dataDefinitions_cfb-chart-1764545748116-zplvab4ug'); const caret = document.getElementById('caret_cfb-chart-1764545748116-zplvab4ug'); if (definitions.classList.contains('expanded')) { definitions.classList.remove('expanded'); caret.classList.remove('expanded'); } else { definitions.classList.add('expanded'); caret.classList.add('expanded'); } } // Sequential script loading for better reliability (function() { 'use strict'; let retryCount = 0; const maxRetries = 50; // 5 seconds total // Load scripts sequentially function loadScript(url, callback) { const script = document.createElement('script'); script.src = url; script.onload = callback; script.onerror = function() { console.error('Failed to load script:', url); showError('Failed to load required chart library'); }; document.head.appendChild(script); } function showError(message) { const canvas = document.getElementById('cfb-chart-1764545748116-zplvab4ug'); if (canvas && canvas.parentNode) { canvas.parentNode.innerHTML = '

' + message + '

'; } } function initChart() { retryCount++; // Check if Chart.js is available if (typeof Chart === 'undefined') { if (retryCount >= maxRetries) { showError('Chart library failed to load. Please refresh the page.'); return; } setTimeout(initChart, 100); return; } // Check if datalabels plugin is available if (typeof ChartDataLabels === 'undefined') { if (retryCount >= maxRetries) { showError('Chart plugin failed to load. Please refresh the page.'); return; } setTimeout(initChart, 100); return; } // Check if canvas element exists const canvas = document.getElementById('cfb-chart-1764545748116-zplvab4ug'); if (!canvas) { console.warn('Canvas element not found yet, retrying...'); setTimeout(initChart, 100); return; } // Prevent multiple chart instances if (canvas.chartInstance) { console.log('Chart already initialized'); return; } try { // Register the datalabels plugin Chart.register(ChartDataLabels); // Embed actual chart data directly const chartData = { "datasets": [ { "label": "NCAA Avg SR", "data": [ { "x": 1, "y": 0 }, { "x": 1, "y": 0.42 }, { "x": 144, "y": 0.42 }, { "x": 144, "y": 0 } ], "backgroundColor": "rgba(0,0,0,0.03)", "borderColor": "transparent", "pointRadius": 0, "fill": true, "tension": 0, "showLine": true, "datalabels": { "display": false } }, { "data": [ { "x": 1, "y": 0, "text": "T.Simpson pass incomplete deep middle to #5 G.Bernard thrown to AUB50" }, { "x": 2, "y": 0, "text": "T.Simpson pass complete short right to #26 J.Miller caught at ALA15, for 4 yards to the ALA25 (#4 K.Lee), out of bounds PENALTY AUB Face Mask (#4 K.Lee) 15 yards from ALA25 to ALA40, 1ST DOWN" }, { "x": 3, "y": 0, "text": "T.Simpson pass incomplete short left to #5 G.Bernard thrown to AUB44" }, { "x": 4, "y": 0, "text": "T.Simpson pass complete short left to #5 G.Bernard caught at ALA45, for 7 yards to the ALA47 (#28 K.Louidor-Faustin; #25 E.Winters)" }, { "x": 5, "y": 0, "text": "T.Simpson pass incomplete deep middle to #5 G.Bernard thrown to AUB15" }, { "x": 9, "y": 0, "text": "D.Hill rush right for 1 yard gain to the AUB48 (#15 K.Faulk)" }, { "x": 10, "y": 0, "text": "T.Simpson pass incomplete short middle to #17 L.Brooks thrown to AUB34" }, { "x": 11, "y": 0, "text": "T.Simpson pass complete short left to #4 D.Hill caught at AUB45, for 3 yards to the AUB45 (#23 J.Crawford)" }, { "x": 12, "y": 0, "text": "T.Simpson rush middle for 2 yards gain to the AUB43 (#47 M.Blocton), 1ST DOWN" }, { "x": 13, "y": 0, "text": "J.Miller rush left for 7 yards gain to the AUB36 (#24 K.Crawford)" }, { "x": 14, "y": 0, "text": "J.Miller rush middle for 4 yards gain to the AUB32 (#91 Z.Walker; #9 E.Melendez), 1ST DOWN" }, { "x": 15, "y": 0, "text": "J.Miller rush middle for 5 yards gain to the AUB27 (#91 Z.Walker)" }, { "x": 16, "y": 0, "text": "T.Simpson pass incomplete short right thrown to AUB25 QB hurried by #24 K.Crawford" }, { "x": 17, "y": 0, "text": "T.Simpson pass incomplete short left to #1 I.Horton thrown to AUB10 QB hurried by #24 K.Crawford" }, { "x": 21, "y": 0, "text": "T.Simpson pass incomplete short right to #88 J.Lindsey thrown to ALA34 broken up by #16 B.Deas" }, { "x": 22, "y": 0, "text": "J.Miller rush right for 1 yard gain to the ALA36 (#16 B.Deas)" }, { "x": 23, "y": 0, "text": "T.Simpson pass incomplete short right to #5 G.Bernard thrown to ALA45 QB hurried by #24 K.Crawford" }, { "x": 27, "y": 0.05555555555555555, "text": "T.Simpson pass complete short left to #17 L.Brooks caught at AUB45, for 15 yards to the AUB45, out of bounds at AUB45, 1ST DOWN. The previous play is under automatic review - \"Pass completion\". CALL OVERTURNED. (Original Play: (04:54) #15 T.Simpson pass incomplete short left to #17 L.Brooks thrown to AUB44)" }, { "x": 28, "y": 0.05263157894736842, "text": "G.Bernard rush left for 4 yards gain to the AUB41 (#24 K.Crawford), out of bounds" }, { "x": 29, "y": 0.05, "text": "D.Hill rush left for 3 yards gain to the AUB38 (#15 K.Faulk)" }, { "x": 30, "y": 0.09523809523809523, "text": "T.Simpson rush left for 26 yards gain to the AUB12 (#25 E.Winters), out of bounds, 1ST DOWN" }, { "x": 31, "y": 0.09090909090909091, "text": "D.Hill rush middle for 7 yards gain to the AUB05 (#8 K.Harris)" }, { "x": 32, "y": 0.08695652173913043, "text": "T.Simpson sacked for loss of 1 yard to the AUB06 (#8 K.Harris)" }, { "x": 33, "y": 0.08333333333333333, "text": "Isaiah Horton 6 Yd pass from Ty Simpson (Conor Talty Kick)" }, { "x": 41, "y": 0.08, "text": "T.Simpson pass complete short left to #26 J.Miller caught at ALA33, for 8 yards to the ALA44 (#14 R.Pleasant), out of bounds" }, { "x": 42, "y": 0.11538461538461539, "text": "J.Miller rush middle for 20 yards gain to the AUB36 (#5 J.Robinson), out of bounds, 1ST DOWN" }, { "x": 43, "y": 0.14814814814814814, "text": "J.Miller rush middle for 17 yards gain to the AUB19 (#8 K.Harris), 1ST DOWN" }, { "x": 44, "y": 0.14285714285714285, "text": "J.Miller rush middle for 3 yards gain to the AUB16 (#97 B.Jamison-Travis)" }, { "x": 45, "y": 0.13793103448275862, "text": "T.Simpson pass complete short right to #17 L.Brooks caught at AUB12, for 13 yards to the AUB03 (#23 J.Crawford), 1ST DOWN" }, { "x": 46, "y": 0.13333333333333333, "text": "Isaiah Horton 3 Yd pass from Ty Simpson (Conor Talty Kick)" }, { "x": 50, "y": 0.12903225806451613, "text": "T.Simpson pass incomplete deep middle to #11 R.Scott thrown to AUB45 QB hurried by #0 R.Woodyard Jr." }, { "x": 51, "y": 0.125, "text": "J.Miller rush middle for 3 yards gain to the ALA36 (#91 Z.Walker)" }, { "x": 52, "y": 0.12121212121212122, "text": "T.Simpson sacked for loss of 9 yards to the ALA27 (#17 X.Atkins, #47 M.Blocton)" }, { "x": 62, "y": 0.11764705882352941, "text": "J.Miller rush left for 2 yards gain to the ALA27 (#17 X.Atkins)" }, { "x": 63, "y": 0.11428571428571428, "text": "J.Miller rush middle for 2 yards gain to the ALA29 (#92 J.Hardy)" }, { "x": 64, "y": 0.1111111111111111, "text": "T.Simpson pass incomplete deep left to #5 G.Bernard thrown to AUB40 QB hurried by #17 X.Atkins and #24 K.Crawford" }, { "x": 78, "y": 0.10810810810810811, "text": "T.Simpson pass complete short right to #17 L.Brooks caught at ALA25, for 1 yard to the ALA26 (#25 E.Winters; #0 R.Woodyard Jr.)" }, { "x": 79, "y": 0.10526315789473684, "text": "D.Hill rush right for 3 yards gain to the ALA29 (#24 K.Crawford)" }, { "x": 80, "y": 0.1282051282051282, "text": "Ty Simpson pass to I. Horton for 16 yds for a 1ST down" }, { "x": 81, "y": 0.125, "text": "J.Miller rush left for 3 yards gain to the AUB37 (#19 S.Smith)" }, { "x": 82, "y": 0.12195121951219512, "text": "J.Miller rush left for 4 yards gain to the AUB33 (#19 S.Smith)" }, { "x": 83, "y": 0.11904761904761904, "text": "T.Simpson pass incomplete deep middle to #5 G.Bernard thrown to AUB12 broken up by #19 S.Smith" }, { "x": 84, "y": 0.11627906976744186, "text": "T.Simpson pass incomplete short left to #14 M.Pritchett thrown to AUB23" }, { "x": 85, "y": 0.11363636363636363, "text": "T.Simpson pass complete short left to #81 K.Edwards caught at AUB28, for 3 yards to the AUB25 (#24 K.Crawford)" }, { "x": 86, "y": 0.1111111111111111, "text": "T.Simpson rush right for 8 yards gain to the AUB17 (#14 R.Pleasant), 1ST DOWN" }, { "x": 87, "y": 0.10869565217391304, "text": "J.Miller rush middle for 7 yards gain to the AUB10 (#0 R.Woodyard Jr.)" }, { "x": 88, "y": 0.10638297872340426, "text": "T.Simpson pass complete short right to #88 J.Lindsey caught at AUB11, for 1 yard loss to the AUB11, out of bounds at AUB11" }, { "x": 89, "y": 0.10416666666666667, "text": "T.Simpson pass incomplete short left to #5 G.Bernard thrown to AUB00 broken up by #19 S.Smith" }, { "x": 93, "y": 0.10204081632653061, "text": "T.Simpson pass complete short middle to #81 K.Edwards caught at ALA40, for 5 yards to the ALA40 (#4 K.Lee)" }, { "x": 94, "y": 0.1, "text": "J.Miller rush middle for 3 yards gain to the ALA43 (#35 D.Walker)" }, { "x": 95, "y": 0.09803921568627451, "text": "T.Simpson pass incomplete short left to #26 J.Miller thrown to ALA47" }, { "x": 105, "y": 0.09615384615384616, "text": "T.Simpson sacked for loss of 9 yards to the ALA40 (#17 X.Atkins)" }, { "x": 106, "y": 0.09433962264150944, "text": "T.Simpson pass complete short right to #5 G.Bernard caught at ALA35, for 8 yards to the ALA48 (#0 R.Woodyard Jr.)" }, { "x": 107, "y": 0.09259259259259259, "text": "T.Simpson pass complete short left to #4 D.Hill caught at ALA47, for 6 yards to the AUB46 (#24 K.Crawford; #16 B.Deas)" }, { "x": 116, "y": 0.09090909090909091, "text": "J.Miller rush middle for 2 yards gain to the ALA27 (#97 B.Jamison-Travis)" }, { "x": 117, "y": 0.08928571428571429, "text": "T.Simpson pass complete short right to #1 I.Horton caught at ALA30, for 4 yards to the ALA31 (#19 S.Smith)" }, { "x": 118, "y": 0.08771929824561403, "text": "D.Hill rush middle for 3 yards gain to the ALA44 (#97 B.Jamison-Travis)" }, { "x": 119, "y": 0.08620689655172414, "text": "T.Simpson pass complete short middle to #0 A.Dear caught at ALA44, for 6 yards to the ALA50 (#97 B.Jamison-Travis)" }, { "x": 120, "y": 0.0847457627118644, "text": "T.Simpson pass incomplete deep left to #14 M.Pritchett thrown to AUB30 QB hurried by #3 C.Murray and #24 K.Crawford" }, { "x": 121, "y": 0.08333333333333333, "text": "T.Simpson rush middle for 2 yards gain to the AUB48, End Of Play, 1ST DOWN" }, { "x": 122, "y": 0.08196721311475409, "text": "D.Hill rush middle for 9 yards gain to the AUB39 (#8 K.Harris)" }, { "x": 123, "y": 0.08064516129032258, "text": "D.Hill rush middle for 8 yards gain to the AUB31 (#8 K.Harris), 1ST DOWN" }, { "x": 124, "y": 0.07936507936507936, "text": "D.Hill rush middle for 3 yards gain to the AUB28 (#35 D.Walker)" }, { "x": 125, "y": 0.078125, "text": "D.Hill rush right for 0 yards to the AUB28 (#3 C.Murray)" }, { "x": 126, "y": 0.07692307692307693, "text": "T.Simpson rush left for 14 yards gain (10) to the AUB00 TOUCHDOWN nullified by penalty, clock 05:31 PENALTY ALA Holding (#1 I.Horton) 10 yards from AUB04 to AUB14" }, { "x": 127, "y": 0.07575757575757576, "text": "D.Hill rush left for 1 yard loss to the AUB15 (#92 J.Hardy)" }, { "x": 128, "y": 0.07462686567164178, "text": "T.Simpson pass complete short right to #5 G.Bernard caught at AUB05, for 9 yards to the AUB06 (#4 K.Lee), out of bounds" }, { "x": 129, "y": 0.07352941176470588, "text": "T.Simpson pass incomplete short middle to #14 M.Pritchett thrown to AUB00 broken up by #15 K.Faulk" }, { "x": 130, "y": 0.07246376811594203, "text": "Isaiah Horton 6 Yd pass from Ty Simpson (Conor Talty Kick)" }, { "x": 142, "y": 0.07142857142857142, "text": "T.Simpson rush right for 1 yard gain to the ALA21, End Of Play" }, { "x": 143, "y": 0.07042253521126761, "text": "D.Hill rush middle for 3 yards gain to the ALA24 (#15 K.Faulk)" }, { "x": 144, "y": 0.06944444444444445, "text": "T.Simpson rush right for 1 yard gain to the ALA25 (#97 B.Jamison-Travis)" } ], "label": "Alabama XR", "borderColor": "rgba(101, 0, 20, 0.8)", "borderWidth": 2.2, "fill": false }, { "data": [ { "x": 1, "y": 0, "text": "T.Simpson pass incomplete deep middle to #5 G.Bernard thrown to AUB50" }, { "x": 2, "y": 0, "text": "T.Simpson pass complete short right to #26 J.Miller caught at ALA15, for 4 yards to the ALA25 (#4 K.Lee), out of bounds PENALTY AUB Face Mask (#4 K.Lee) 15 yards from ALA25 to ALA40, 1ST DOWN" }, { "x": 3, "y": 0, "text": "T.Simpson pass incomplete short left to #5 G.Bernard thrown to AUB44" }, { "x": 4, "y": 0.25, "text": "T.Simpson pass complete short left to #5 G.Bernard caught at ALA45, for 7 yards to the ALA47 (#28 K.Louidor-Faustin; #25 E.Winters)" }, { "x": 5, "y": 0.2, "text": "T.Simpson pass incomplete deep middle to #5 G.Bernard thrown to AUB15" }, { "x": 9, "y": 0.16666666666666666, "text": "D.Hill rush right for 1 yard gain to the AUB48 (#15 K.Faulk)" }, { "x": 10, "y": 0.14285714285714285, "text": "T.Simpson pass incomplete short middle to #17 L.Brooks thrown to AUB34" }, { "x": 11, "y": 0.125, "text": "T.Simpson pass complete short left to #4 D.Hill caught at AUB45, for 3 yards to the AUB45 (#23 J.Crawford)" }, { "x": 12, "y": 0.2222222222222222, "text": "T.Simpson rush middle for 2 yards gain to the AUB43 (#47 M.Blocton), 1ST DOWN" }, { "x": 13, "y": 0.3, "text": "J.Miller rush left for 7 yards gain to the AUB36 (#24 K.Crawford)" }, { "x": 14, "y": 0.36363636363636365, "text": "J.Miller rush middle for 4 yards gain to the AUB32 (#91 Z.Walker; #9 E.Melendez), 1ST DOWN" }, { "x": 15, "y": 0.4166666666666667, "text": "J.Miller rush middle for 5 yards gain to the AUB27 (#91 Z.Walker)" }, { "x": 16, "y": 0.38461538461538464, "text": "T.Simpson pass incomplete short right thrown to AUB25 QB hurried by #24 K.Crawford" }, { "x": 17, "y": 0.35714285714285715, "text": "T.Simpson pass incomplete short left to #1 I.Horton thrown to AUB10 QB hurried by #24 K.Crawford" }, { "x": 21, "y": 0.3333333333333333, "text": "T.Simpson pass incomplete short right to #88 J.Lindsey thrown to ALA34 broken up by #16 B.Deas" }, { "x": 22, "y": 0.3125, "text": "J.Miller rush right for 1 yard gain to the ALA36 (#16 B.Deas)" }, { "x": 23, "y": 0.29411764705882354, "text": "T.Simpson pass incomplete short right to #5 G.Bernard thrown to ALA45 QB hurried by #24 K.Crawford" }, { "x": 27, "y": 0.3333333333333333, "text": "T.Simpson pass complete short left to #17 L.Brooks caught at AUB45, for 15 yards to the AUB45, out of bounds at AUB45, 1ST DOWN. The previous play is under automatic review - \"Pass completion\". CALL OVERTURNED. (Original Play: (04:54) #15 T.Simpson pass incomplete short left to #17 L.Brooks thrown to AUB44)" }, { "x": 28, "y": 0.3157894736842105, "text": "G.Bernard rush left for 4 yards gain to the AUB41 (#24 K.Crawford), out of bounds" }, { "x": 29, "y": 0.3, "text": "D.Hill rush left for 3 yards gain to the AUB38 (#15 K.Faulk)" }, { "x": 30, "y": 0.3333333333333333, "text": "T.Simpson rush left for 26 yards gain to the AUB12 (#25 E.Winters), out of bounds, 1ST DOWN" }, { "x": 31, "y": 0.36363636363636365, "text": "D.Hill rush middle for 7 yards gain to the AUB05 (#8 K.Harris)" }, { "x": 32, "y": 0.34782608695652173, "text": "T.Simpson sacked for loss of 1 yard to the AUB06 (#8 K.Harris)" }, { "x": 33, "y": 0.375, "text": "Isaiah Horton 6 Yd pass from Ty Simpson (Conor Talty Kick)" }, { "x": 41, "y": 0.4, "text": "T.Simpson pass complete short left to #26 J.Miller caught at ALA33, for 8 yards to the ALA44 (#14 R.Pleasant), out of bounds" }, { "x": 42, "y": 0.4230769230769231, "text": "J.Miller rush middle for 20 yards gain to the AUB36 (#5 J.Robinson), out of bounds, 1ST DOWN" }, { "x": 43, "y": 0.4444444444444444, "text": "J.Miller rush middle for 17 yards gain to the AUB19 (#8 K.Harris), 1ST DOWN" }, { "x": 44, "y": 0.42857142857142855, "text": "J.Miller rush middle for 3 yards gain to the AUB16 (#97 B.Jamison-Travis)" }, { "x": 45, "y": 0.4482758620689655, "text": "T.Simpson pass complete short right to #17 L.Brooks caught at AUB12, for 13 yards to the AUB03 (#23 J.Crawford), 1ST DOWN" }, { "x": 46, "y": 0.4666666666666667, "text": "Isaiah Horton 3 Yd pass from Ty Simpson (Conor Talty Kick)" }, { "x": 50, "y": 0.45161290322580644, "text": "T.Simpson pass incomplete deep middle to #11 R.Scott thrown to AUB45 QB hurried by #0 R.Woodyard Jr." }, { "x": 51, "y": 0.4375, "text": "J.Miller rush middle for 3 yards gain to the ALA36 (#91 Z.Walker)" }, { "x": 52, "y": 0.42424242424242425, "text": "T.Simpson sacked for loss of 9 yards to the ALA27 (#17 X.Atkins, #47 M.Blocton)" }, { "x": 62, "y": 0.4117647058823529, "text": "J.Miller rush left for 2 yards gain to the ALA27 (#17 X.Atkins)" }, { "x": 63, "y": 0.4, "text": "J.Miller rush middle for 2 yards gain to the ALA29 (#92 J.Hardy)" }, { "x": 64, "y": 0.3888888888888889, "text": "T.Simpson pass incomplete deep left to #5 G.Bernard thrown to AUB40 QB hurried by #17 X.Atkins and #24 K.Crawford" }, { "x": 78, "y": 0.3783783783783784, "text": "T.Simpson pass complete short right to #17 L.Brooks caught at ALA25, for 1 yard to the ALA26 (#25 E.Winters; #0 R.Woodyard Jr.)" }, { "x": 79, "y": 0.3684210526315789, "text": "D.Hill rush right for 3 yards gain to the ALA29 (#24 K.Crawford)" }, { "x": 80, "y": 0.38461538461538464, "text": "Ty Simpson pass to I. Horton for 16 yds for a 1ST down" }, { "x": 81, "y": 0.375, "text": "J.Miller rush left for 3 yards gain to the AUB37 (#19 S.Smith)" }, { "x": 82, "y": 0.36585365853658536, "text": "J.Miller rush left for 4 yards gain to the AUB33 (#19 S.Smith)" }, { "x": 83, "y": 0.35714285714285715, "text": "T.Simpson pass incomplete deep middle to #5 G.Bernard thrown to AUB12 broken up by #19 S.Smith" }, { "x": 84, "y": 0.3488372093023256, "text": "T.Simpson pass incomplete short left to #14 M.Pritchett thrown to AUB23" }, { "x": 85, "y": 0.3409090909090909, "text": "T.Simpson pass complete short left to #81 K.Edwards caught at AUB28, for 3 yards to the AUB25 (#24 K.Crawford)" }, { "x": 86, "y": 0.35555555555555557, "text": "T.Simpson rush right for 8 yards gain to the AUB17 (#14 R.Pleasant), 1ST DOWN" }, { "x": 87, "y": 0.3695652173913043, "text": "J.Miller rush middle for 7 yards gain to the AUB10 (#0 R.Woodyard Jr.)" }, { "x": 88, "y": 0.3617021276595745, "text": "T.Simpson pass complete short right to #88 J.Lindsey caught at AUB11, for 1 yard loss to the AUB11, out of bounds at AUB11" }, { "x": 89, "y": 0.3541666666666667, "text": "T.Simpson pass incomplete short left to #5 G.Bernard thrown to AUB00 broken up by #19 S.Smith" }, { "x": 93, "y": 0.3673469387755102, "text": "T.Simpson pass complete short middle to #81 K.Edwards caught at ALA40, for 5 yards to the ALA40 (#4 K.Lee)" }, { "x": 94, "y": 0.36, "text": "J.Miller rush middle for 3 yards gain to the ALA43 (#35 D.Walker)" }, { "x": 95, "y": 0.35294117647058826, "text": "T.Simpson pass incomplete short left to #26 J.Miller thrown to ALA47" }, { "x": 105, "y": 0.34615384615384615, "text": "T.Simpson sacked for loss of 9 yards to the ALA40 (#17 X.Atkins)" }, { "x": 106, "y": 0.33962264150943394, "text": "T.Simpson pass complete short right to #5 G.Bernard caught at ALA35, for 8 yards to the ALA48 (#0 R.Woodyard Jr.)" }, { "x": 107, "y": 0.3333333333333333, "text": "T.Simpson pass complete short left to #4 D.Hill caught at ALA47, for 6 yards to the AUB46 (#24 K.Crawford; #16 B.Deas)" }, { "x": 116, "y": 0.32727272727272727, "text": "J.Miller rush middle for 2 yards gain to the ALA27 (#97 B.Jamison-Travis)" }, { "x": 117, "y": 0.32142857142857145, "text": "T.Simpson pass complete short right to #1 I.Horton caught at ALA30, for 4 yards to the ALA31 (#19 S.Smith)" }, { "x": 118, "y": 0.3157894736842105, "text": "D.Hill rush middle for 3 yards gain to the ALA44 (#97 B.Jamison-Travis)" }, { "x": 119, "y": 0.3275862068965517, "text": "T.Simpson pass complete short middle to #0 A.Dear caught at ALA44, for 6 yards to the ALA50 (#97 B.Jamison-Travis)" }, { "x": 120, "y": 0.3220338983050847, "text": "T.Simpson pass incomplete deep left to #14 M.Pritchett thrown to AUB30 QB hurried by #3 C.Murray and #24 K.Crawford" }, { "x": 121, "y": 0.3333333333333333, "text": "T.Simpson rush middle for 2 yards gain to the AUB48, End Of Play, 1ST DOWN" }, { "x": 122, "y": 0.3442622950819672, "text": "D.Hill rush middle for 9 yards gain to the AUB39 (#8 K.Harris)" }, { "x": 123, "y": 0.3548387096774194, "text": "D.Hill rush middle for 8 yards gain to the AUB31 (#8 K.Harris), 1ST DOWN" }, { "x": 124, "y": 0.3492063492063492, "text": "D.Hill rush middle for 3 yards gain to the AUB28 (#35 D.Walker)" }, { "x": 125, "y": 0.34375, "text": "D.Hill rush right for 0 yards to the AUB28 (#3 C.Murray)" }, { "x": 126, "y": 0.35384615384615387, "text": "T.Simpson rush left for 14 yards gain (10) to the AUB00 TOUCHDOWN nullified by penalty, clock 05:31 PENALTY ALA Holding (#1 I.Horton) 10 yards from AUB04 to AUB14" }, { "x": 127, "y": 0.3484848484848485, "text": "D.Hill rush left for 1 yard loss to the AUB15 (#92 J.Hardy)" }, { "x": 128, "y": 0.3582089552238806, "text": "T.Simpson pass complete short right to #5 G.Bernard caught at AUB05, for 9 yards to the AUB06 (#4 K.Lee), out of bounds" }, { "x": 129, "y": 0.35294117647058826, "text": "T.Simpson pass incomplete short middle to #14 M.Pritchett thrown to AUB00 broken up by #15 K.Faulk" }, { "x": 130, "y": 0.36231884057971014, "text": "Isaiah Horton 6 Yd pass from Ty Simpson (Conor Talty Kick)" }, { "x": 142, "y": 0.35714285714285715, "text": "T.Simpson rush right for 1 yard gain to the ALA21, End Of Play" }, { "x": 143, "y": 0.352112676056338, "text": "D.Hill rush middle for 3 yards gain to the ALA24 (#15 K.Faulk)" }, { "x": 144, "y": 0.3472222222222222, "text": "T.Simpson rush right for 1 yard gain to the ALA25 (#97 B.Jamison-Travis)" } ], "label": "Alabama SR", "borderColor": "rgba(175, 40, 60, 0.8)", "borderWidth": 2.2, "fill": false }, { "data": [ { "x": 6, "y": 0, "text": "A.Daniels rush middle for 5 yards gain to the AUB20 (#3 K.Sabb)" }, { "x": 7, "y": 0, "text": "A.Daniels sacked for loss of 6 yards to the AUB14 (#23 J.Smith)" }, { "x": 8, "y": 0, "text": "A.Daniels pass incomplete short right to #1 E.Singleton Jr. thrown to AUB10 broken up by #3 K.Sabb" }, { "x": 18, "y": 0, "text": "A.Daniels pass incomplete short left to #8 C.Coleman thrown to AUB37" }, { "x": 19, "y": 0, "text": "A.Daniels pass incomplete short left to #23 J.Cobb thrown to AUB30" }, { "x": 20, "y": 0, "text": "A.Daniels pass incomplete short left to #3 P.Thompson thrown to AUB35" }, { "x": 24, "y": 0, "text": "A.Daniels rush middle for 5 yards gain to the AUB18 (#23 J.Smith)" }, { "x": 25, "y": 0, "text": "A.Daniels pass complete short right to #6 B.Cain caught at AUB17, for 2 yards to the AUB20 (#3 K.Sabb)" }, { "x": 26, "y": 0, "text": "A.Daniels pass incomplete short middle to #87 B.Frazier thrown to AUB30" }, { "x": 34, "y": 0, "text": "J.Cobb rush middle for 1 yard gain to the AUB48 (#41 N.Hill-Green)" }, { "x": 35, "y": 0, "text": "A.Daniels pass complete short middle to #1 E.Singleton Jr. caught at AUB50, for 6 yards to the ALA46 (#16 R.Morgan)" }, { "x": 36, "y": 0, "text": "A.Daniels pass complete short middle to #1 E.Singleton Jr. caught at ALA42, for 4 yards to the ALA42 (#3 K.Sabb), 1ST DOWN" }, { "x": 37, "y": 0, "text": "J.Cobb rush middle for 3 yards gain to the ALA39 (#11 J.Renaud)" }, { "x": 38, "y": 0, "text": "A.Daniels rush middle for 3 yards gain to the ALA36 (#3 K.Sabb)" }, { "x": 39, "y": 0, "text": "A.Daniels pass incomplete short middle to #1 E.Singleton Jr. thrown to ALA30 broken up by #10 J.Jefferson" }, { "x": 40, "y": 0, "text": "A.Daniels pass incomplete short middle to #1 E.Singleton Jr. thrown to ALA30 broken up by #5 D.Lee Jr., TURNOVER ON DOWNS" }, { "x": 47, "y": 0, "text": "A.Daniels pass complete short left to #23 J.Cobb caught at AUB19, for 5 yards to the AUB25 (#4 Q.Russaw), out of bounds" }, { "x": 48, "y": 0, "text": "J.Cobb rush middle for 4 yards gain to the AUB29 (#22 L.Overton)" }, { "x": 49, "y": 0, "text": "J.Cobb rush middle for 1 yard loss to the AUB28 (#0 D.Lawson)" }, { "x": 53, "y": 0, "text": "A.Daniels pass incomplete deep left to #8 C.Coleman thrown to ALA07" }, { "x": 54, "y": 0, "text": "J.Cobb rush middle for 2 yards gain to the ALA49 (#2 Z.Brown)" }, { "x": 55, "y": 0, "text": "A.Daniels pass complete short left to #8 C.Coleman caught at ALA45, for 4 yards to the ALA45 (#2 Z.Brown)" }, { "x": 56, "y": 0.043478260869565216, "text": "A.Daniels rush right for 20 yards gain to the ALA25 (#23 J.Smith), out of bounds, 1ST DOWN" }, { "x": 57, "y": 0.041666666666666664, "text": "J.Cobb rush left for 12 yards gain to the ALA13 (#2 Z.Brown), 1ST DOWN" }, { "x": 58, "y": 0.04, "text": "A.Daniels rush middle for 3 yards gain to the ALA10 (#0 D.Lawson; #9 C.Calhoun) PENALTY ALA Targeting (#9 C.Calhoun) 5 yards from ALA10 to ALA05, 1ST DOWN. The previous play is under automatic review - \"Targeting\". CALL OVERTURNED. (Original Play: (06:24) No Huddle-Shotgun #12 A.Daniels rush middle for 4 yards gain to the ALA09 (#0 D.Lawson; #9 C.Calhoun))" }, { "x": 59, "y": 0.038461538461538464, "text": "A.Daniels pass incomplete short left to #8 C.Coleman thrown to ALA00" }, { "x": 60, "y": 0.037037037037037035, "text": "A.Daniels rush middle for 1 yard gain to the ALA04 (#16 R.Morgan)" }, { "x": 61, "y": 0.03571428571428571, "text": "A.Daniels rush right for 1 yard gain to the ALA03 (#23 J.Smith), out of bounds" }, { "x": 65, "y": 0.034482758620689655, "text": "A.Daniels pass incomplete short middle to #1 E.Singleton Jr. thrown to AUB28 broken up by #3 K.Sabb" }, { "x": 66, "y": 0.03333333333333333, "text": "A.Daniels rush left for 8 yards gain to the AUB35, out of bounds at AUB35" }, { "x": 67, "y": 0.06451612903225806, "text": "A.Daniels pass complete short right to #87 B.Frazier caught at AUB35, for 19 yards to the ALA46 (#10 J.Jefferson), out of bounds, 1ST DOWN" }, { "x": 68, "y": 0.0625, "text": "A.Daniels pass incomplete deep left to #1 E.Singleton Jr. thrown to ALA23" }, { "x": 69, "y": 0.06060606060606061, "text": "A.Daniels rush middle for 7 yards gain to the ALA39 (#18 B.Hubbard)" }, { "x": 70, "y": 0.058823529411764705, "text": "A.Daniels rush middle for 6 yards gain to the ALA33 (#16 R.Morgan), 1ST DOWN" }, { "x": 71, "y": 0.05714285714285714, "text": "A.Daniels pass incomplete short left to #1 E.Singleton Jr. thrown to ALA16" }, { "x": 72, "y": 0.05555555555555555, "text": "A.Daniels rush middle for 5 yards gain to the ALA33 (#94 E.Hill)" }, { "x": 73, "y": 0.05405405405405406, "text": "A.Daniels rush left for 8 yards gain to the ALA25 (#0 D.Lawson)" }, { "x": 74, "y": 0.05263157894736842, "text": "A.Daniels pass complete short middle to #4 M.Simmons caught at AUB35, for 13 yards to the AUB37 (#5 D.Lee Jr.), 1ST DOWN" }, { "x": 75, "y": 0.05128205128205128, "text": "J.Cobb rush middle for 1 yard loss to the AUB36 (#10 J.Jefferson)" }, { "x": 76, "y": 0.05, "text": "A.Daniels pass incomplete deep left to #8 C.Coleman thrown to ALA30" }, { "x": 77, "y": 0.07317073170731707, "text": "Malcolm Simmons 64 Yd pass from Ashton Daniels (Alex McPherson Kick)" }, { "x": 90, "y": 0.07142857142857142, "text": "A.Daniels rush middle for 2 yards gain to the AUB27 (#4 Q.Russaw)" }, { "x": 91, "y": 0.06976744186046512, "text": "A.Daniels pass incomplete deep left to #8 C.Coleman thrown to ALA40" }, { "x": 92, "y": 0.06818181818181818, "text": "A.Daniels pass incomplete short middle to #23 J.Cobb thrown to AUB41" }, { "x": 96, "y": 0.06666666666666667, "text": "A.Daniels rush middle for 3 yards gain to the AUB24 (#41 N.Hill-Green)" }, { "x": 97, "y": 0.06521739130434782, "text": "A.Daniels rush left for 3 yards gain to the AUB27, out of bounds at AUB27" }, { "x": 98, "y": 0.06382978723404255, "text": "A.Daniels pass complete short middle to #8 C.Coleman caught at AUB31, for 4 yards to the AUB31, End Of Play, 1ST DOWN" }, { "x": 99, "y": 0.0625, "text": "J.Jones rush middle for 7 yards gain to the AUB38 (#3 K.Sabb)" }, { "x": 100, "y": 0.061224489795918366, "text": "A.Daniels pass incomplete short middle to #15 P.Howard thrown to AUB42 broken up by #10 J.Jefferson. The previous play is under automatic review - \"Incomplete pass\". CALL UPHELD" }, { "x": 101, "y": 0.06, "text": "A.Daniels pass complete short left to #35 J.Jones caught at AUB34, for 3 yards to the AUB41 (#24 N.Carter), 1ST DOWN" }, { "x": 102, "y": 0.058823529411764705, "text": "E.Singleton Jr. rush left for 0 yards to the ALA43 (#0 D.Lawson)" }, { "x": 103, "y": 0.057692307692307696, "text": "A.Daniels pass complete short middle to #8 C.Coleman caught at ALA27, for 11 yards to the ALA28, End Of Play, 1ST DOWN" }, { "x": 104, "y": 0.05660377358490566, "text": "A.Daniels pass intercepted by #18 B.Hubbard at ALA15 #18 B.Hubbard return 34 yards to the ALA49 (#52 D.Wade)" }, { "x": 108, "y": 0.07407407407407407, "text": "A.Daniels pass complete short left to #8 C.Coleman caught at AUB45, for 17 yards to the AUB48, End Of Play, 1ST DOWN" }, { "x": 109, "y": 0.07272727272727272, "text": "A.Daniels pass complete short right to #6 B.Cain caught at AUB50, for 9 yards to the ALA43 (#42 Y.Pierre)" }, { "x": 110, "y": 0.07142857142857142, "text": "J.Cobb rush middle for 6 yards gain to the AUB18 (#10 J.Jefferson)" }, { "x": 111, "y": 0.07017543859649122, "text": "A.Daniels pass incomplete short middle to #4 M.Simmons thrown to AUB45 broken up by #12 Z.Mincey" }, { "x": 112, "y": 0.06896551724137931, "text": "A.Daniels rush middle for 1 yard gain to the AUB30 (#42 Y.Pierre)" }, { "x": 113, "y": 0.0847457627118644, "text": "A.Daniels pass complete short middle to #4 M.Simmons caught at AUB35, for 66 yards to the ALA04 (#1 D.Jackson), out of bounds, 1ST DOWN" }, { "x": 114, "y": 0.08333333333333333, "text": "A.Daniels rush middle for 2 yards gain to the ALA02 (#42 Y.Pierre)" }, { "x": 115, "y": 0.08196721311475409, "text": "Jeremiah Cobb 2 Yd Run (Alex McPherson Kick)" }, { "x": 131, "y": 0.08064516129032258, "text": "A.Daniels pass complete short right to #23 J.Cobb caught at AUB20, for 4 yards to the AUB26 (#42 Y.Pierre), out of bounds" }, { "x": 132, "y": 0.07936507936507936, "text": "A.Daniels rush middle for 8 yards gain to the AUB34 (#0 D.Lawson), 1ST DOWN" }, { "x": 133, "y": 0.078125, "text": "A.Daniels rush left for 5 yards gain to the AUB39 (#42 Y.Pierre), out of bounds" }, { "x": 134, "y": 0.07692307692307693, "text": "A.Daniels pass incomplete short left to #23 J.Cobb thrown to AUB42 broken up by #2 Z.Brown" }, { "x": 135, "y": 0.07575757575757576, "text": "A.Daniels pass incomplete short right to #4 M.Simmons thrown to AUB45" }, { "x": 136, "y": 0.07462686567164178, "text": "A.Daniels pass complete short middle to #15 P.Howard caught at AUB50, for 5 yards to the AUB50 (#0 D.Lawson)" }, { "x": 137, "y": 0.07352941176470588, "text": "A.Daniels rush middle for 3 yards gain to the ALA47 (#0 D.Lawson; #10 J.Jefferson)" }, { "x": 138, "y": 0.07246376811594203, "text": "A.Daniels pass incomplete short middle thrown to AUB50 QB hurried by #16 R.Morgan" }, { "x": 139, "y": 0.07142857142857142, "text": "A.Daniels rush middle for 2 yards gain to the ALA45 (#22 L.Overton), 1ST DOWN" }, { "x": 140, "y": 0.07042253521126761, "text": "J.Cobb rush middle for 5 yards gain to the ALA40 (#23 J.Smith)" }, { "x": 141, "y": 0.06944444444444445, "text": "A.Daniels rush left for 13 yards gain to the ALA27, out of bounds at ALA27, 1ST DOWN" } ], "label": "Auburn XR", "borderColor": "rgba(20, 59, 107, 0.8)", "borderWidth": 2.2, "borderDash": [ 4, 4 ], "fill": false }, { "data": [ { "x": 6, "y": 1, "text": "A.Daniels rush middle for 5 yards gain to the AUB20 (#3 K.Sabb)" }, { "x": 7, "y": 0.5, "text": "A.Daniels sacked for loss of 6 yards to the AUB14 (#23 J.Smith)" }, { "x": 8, "y": 0.3333333333333333, "text": "A.Daniels pass incomplete short right to #1 E.Singleton Jr. thrown to AUB10 broken up by #3 K.Sabb" }, { "x": 18, "y": 0.25, "text": "A.Daniels pass incomplete short left to #8 C.Coleman thrown to AUB37" }, { "x": 19, "y": 0.2, "text": "A.Daniels pass incomplete short left to #23 J.Cobb thrown to AUB30" }, { "x": 20, "y": 0.16666666666666666, "text": "A.Daniels pass incomplete short left to #3 P.Thompson thrown to AUB35" }, { "x": 24, "y": 0.14285714285714285, "text": "A.Daniels rush middle for 5 yards gain to the AUB18 (#23 J.Smith)" }, { "x": 25, "y": 0.125, "text": "A.Daniels pass complete short right to #6 B.Cain caught at AUB17, for 2 yards to the AUB20 (#3 K.Sabb)" }, { "x": 26, "y": 0.1111111111111111, "text": "A.Daniels pass incomplete short middle to #87 B.Frazier thrown to AUB30" }, { "x": 34, "y": 0.1, "text": "J.Cobb rush middle for 1 yard gain to the AUB48 (#41 N.Hill-Green)" }, { "x": 35, "y": 0.09090909090909091, "text": "A.Daniels pass complete short middle to #1 E.Singleton Jr. caught at AUB50, for 6 yards to the ALA46 (#16 R.Morgan)" }, { "x": 36, "y": 0.16666666666666666, "text": "A.Daniels pass complete short middle to #1 E.Singleton Jr. caught at ALA42, for 4 yards to the ALA42 (#3 K.Sabb), 1ST DOWN" }, { "x": 37, "y": 0.15384615384615385, "text": "J.Cobb rush middle for 3 yards gain to the ALA39 (#11 J.Renaud)" }, { "x": 38, "y": 0.14285714285714285, "text": "A.Daniels rush middle for 3 yards gain to the ALA36 (#3 K.Sabb)" }, { "x": 39, "y": 0.13333333333333333, "text": "A.Daniels pass incomplete short middle to #1 E.Singleton Jr. thrown to ALA30 broken up by #10 J.Jefferson" }, { "x": 40, "y": 0.125, "text": "A.Daniels pass incomplete short middle to #1 E.Singleton Jr. thrown to ALA30 broken up by #5 D.Lee Jr., TURNOVER ON DOWNS" }, { "x": 47, "y": 0.17647058823529413, "text": "A.Daniels pass complete short left to #23 J.Cobb caught at AUB19, for 5 yards to the AUB25 (#4 Q.Russaw), out of bounds" }, { "x": 48, "y": 0.2222222222222222, "text": "J.Cobb rush middle for 4 yards gain to the AUB29 (#22 L.Overton)" }, { "x": 49, "y": 0.21052631578947367, "text": "J.Cobb rush middle for 1 yard loss to the AUB28 (#0 D.Lawson)" }, { "x": 53, "y": 0.2, "text": "A.Daniels pass incomplete deep left to #8 C.Coleman thrown to ALA07" }, { "x": 54, "y": 0.19047619047619047, "text": "J.Cobb rush middle for 2 yards gain to the ALA49 (#2 Z.Brown)" }, { "x": 55, "y": 0.18181818181818182, "text": "A.Daniels pass complete short left to #8 C.Coleman caught at ALA45, for 4 yards to the ALA45 (#2 Z.Brown)" }, { "x": 56, "y": 0.21739130434782608, "text": "A.Daniels rush right for 20 yards gain to the ALA25 (#23 J.Smith), out of bounds, 1ST DOWN" }, { "x": 57, "y": 0.25, "text": "J.Cobb rush left for 12 yards gain to the ALA13 (#2 Z.Brown), 1ST DOWN" }, { "x": 58, "y": 0.24, "text": "A.Daniels rush middle for 3 yards gain to the ALA10 (#0 D.Lawson; #9 C.Calhoun) PENALTY ALA Targeting (#9 C.Calhoun) 5 yards from ALA10 to ALA05, 1ST DOWN. The previous play is under automatic review - \"Targeting\". CALL OVERTURNED. (Original Play: (06:24) No Huddle-Shotgun #12 A.Daniels rush middle for 4 yards gain to the ALA09 (#0 D.Lawson; #9 C.Calhoun))" }, { "x": 59, "y": 0.23076923076923078, "text": "A.Daniels pass incomplete short left to #8 C.Coleman thrown to ALA00" }, { "x": 60, "y": 0.2222222222222222, "text": "A.Daniels rush middle for 1 yard gain to the ALA04 (#16 R.Morgan)" }, { "x": 61, "y": 0.21428571428571427, "text": "A.Daniels rush right for 1 yard gain to the ALA03 (#23 J.Smith), out of bounds" }, { "x": 65, "y": 0.20689655172413793, "text": "A.Daniels pass incomplete short middle to #1 E.Singleton Jr. thrown to AUB28 broken up by #3 K.Sabb" }, { "x": 66, "y": 0.23333333333333334, "text": "A.Daniels rush left for 8 yards gain to the AUB35, out of bounds at AUB35" }, { "x": 67, "y": 0.25806451612903225, "text": "A.Daniels pass complete short right to #87 B.Frazier caught at AUB35, for 19 yards to the ALA46 (#10 J.Jefferson), out of bounds, 1ST DOWN" }, { "x": 68, "y": 0.25, "text": "A.Daniels pass incomplete deep left to #1 E.Singleton Jr. thrown to ALA23" }, { "x": 69, "y": 0.2727272727272727, "text": "A.Daniels rush middle for 7 yards gain to the ALA39 (#18 B.Hubbard)" }, { "x": 70, "y": 0.29411764705882354, "text": "A.Daniels rush middle for 6 yards gain to the ALA33 (#16 R.Morgan), 1ST DOWN" }, { "x": 71, "y": 0.2857142857142857, "text": "A.Daniels pass incomplete short left to #1 E.Singleton Jr. thrown to ALA16" }, { "x": 72, "y": 0.2777777777777778, "text": "A.Daniels rush middle for 5 yards gain to the ALA33 (#94 E.Hill)" }, { "x": 73, "y": 0.2702702702702703, "text": "A.Daniels rush left for 8 yards gain to the ALA25 (#0 D.Lawson)" }, { "x": 74, "y": 0.2894736842105263, "text": "A.Daniels pass complete short middle to #4 M.Simmons caught at AUB35, for 13 yards to the AUB37 (#5 D.Lee Jr.), 1ST DOWN" }, { "x": 75, "y": 0.28205128205128205, "text": "J.Cobb rush middle for 1 yard loss to the AUB36 (#10 J.Jefferson)" }, { "x": 76, "y": 0.275, "text": "A.Daniels pass incomplete deep left to #8 C.Coleman thrown to ALA30" }, { "x": 77, "y": 0.2926829268292683, "text": "Malcolm Simmons 64 Yd pass from Ashton Daniels (Alex McPherson Kick)" }, { "x": 90, "y": 0.2857142857142857, "text": "A.Daniels rush middle for 2 yards gain to the AUB27 (#4 Q.Russaw)" }, { "x": 91, "y": 0.27906976744186046, "text": "A.Daniels pass incomplete deep left to #8 C.Coleman thrown to ALA40" }, { "x": 92, "y": 0.2727272727272727, "text": "A.Daniels pass incomplete short middle to #23 J.Cobb thrown to AUB41" }, { "x": 96, "y": 0.26666666666666666, "text": "A.Daniels rush middle for 3 yards gain to the AUB24 (#41 N.Hill-Green)" }, { "x": 97, "y": 0.2608695652173913, "text": "A.Daniels rush left for 3 yards gain to the AUB27, out of bounds at AUB27" }, { "x": 98, "y": 0.2765957446808511, "text": "A.Daniels pass complete short middle to #8 C.Coleman caught at AUB31, for 4 yards to the AUB31, End Of Play, 1ST DOWN" }, { "x": 99, "y": 0.2916666666666667, "text": "J.Jones rush middle for 7 yards gain to the AUB38 (#3 K.Sabb)" }, { "x": 100, "y": 0.2857142857142857, "text": "A.Daniels pass incomplete short middle to #15 P.Howard thrown to AUB42 broken up by #10 J.Jefferson. The previous play is under automatic review - \"Incomplete pass\". CALL UPHELD" }, { "x": 101, "y": 0.3, "text": "A.Daniels pass complete short left to #35 J.Jones caught at AUB34, for 3 yards to the AUB41 (#24 N.Carter), 1ST DOWN" }, { "x": 102, "y": 0.29411764705882354, "text": "E.Singleton Jr. rush left for 0 yards to the ALA43 (#0 D.Lawson)" }, { "x": 103, "y": 0.3076923076923077, "text": "A.Daniels pass complete short middle to #8 C.Coleman caught at ALA27, for 11 yards to the ALA28, End Of Play, 1ST DOWN" }, { "x": 104, "y": 0.3018867924528302, "text": "A.Daniels pass intercepted by #18 B.Hubbard at ALA15 #18 B.Hubbard return 34 yards to the ALA49 (#52 D.Wade)" }, { "x": 108, "y": 0.3148148148148148, "text": "A.Daniels pass complete short left to #8 C.Coleman caught at AUB45, for 17 yards to the AUB48, End Of Play, 1ST DOWN" }, { "x": 109, "y": 0.32727272727272727, "text": "A.Daniels pass complete short right to #6 B.Cain caught at AUB50, for 9 yards to the ALA43 (#42 Y.Pierre)" }, { "x": 110, "y": 0.3392857142857143, "text": "J.Cobb rush middle for 6 yards gain to the AUB18 (#10 J.Jefferson)" }, { "x": 111, "y": 0.3333333333333333, "text": "A.Daniels pass incomplete short middle to #4 M.Simmons thrown to AUB45 broken up by #12 Z.Mincey" }, { "x": 112, "y": 0.3275862068965517, "text": "A.Daniels rush middle for 1 yard gain to the AUB30 (#42 Y.Pierre)" }, { "x": 113, "y": 0.3389830508474576, "text": "A.Daniels pass complete short middle to #4 M.Simmons caught at AUB35, for 66 yards to the ALA04 (#1 D.Jackson), out of bounds, 1ST DOWN" }, { "x": 114, "y": 0.35, "text": "A.Daniels rush middle for 2 yards gain to the ALA02 (#42 Y.Pierre)" }, { "x": 115, "y": 0.36065573770491804, "text": "Jeremiah Cobb 2 Yd Run (Alex McPherson Kick)" }, { "x": 131, "y": 0.3548387096774194, "text": "A.Daniels pass complete short right to #23 J.Cobb caught at AUB20, for 4 yards to the AUB26 (#42 Y.Pierre), out of bounds" }, { "x": 132, "y": 0.36507936507936506, "text": "A.Daniels rush middle for 8 yards gain to the AUB34 (#0 D.Lawson), 1ST DOWN" }, { "x": 133, "y": 0.375, "text": "A.Daniels rush left for 5 yards gain to the AUB39 (#42 Y.Pierre), out of bounds" }, { "x": 134, "y": 0.36923076923076925, "text": "A.Daniels pass incomplete short left to #23 J.Cobb thrown to AUB42 broken up by #2 Z.Brown" }, { "x": 135, "y": 0.36363636363636365, "text": "A.Daniels pass incomplete short right to #4 M.Simmons thrown to AUB45" }, { "x": 136, "y": 0.373134328358209, "text": "A.Daniels pass complete short middle to #15 P.Howard caught at AUB50, for 5 yards to the AUB50 (#0 D.Lawson)" }, { "x": 137, "y": 0.36764705882352944, "text": "A.Daniels rush middle for 3 yards gain to the ALA47 (#0 D.Lawson; #10 J.Jefferson)" }, { "x": 138, "y": 0.36231884057971014, "text": "A.Daniels pass incomplete short middle thrown to AUB50 QB hurried by #16 R.Morgan" }, { "x": 139, "y": 0.37142857142857144, "text": "A.Daniels rush middle for 2 yards gain to the ALA45 (#22 L.Overton), 1ST DOWN" }, { "x": 140, "y": 0.38028169014084506, "text": "J.Cobb rush middle for 5 yards gain to the ALA40 (#23 J.Smith)" }, { "x": 141, "y": 0.3888888888888889, "text": "A.Daniels rush left for 13 yards gain to the ALA27, out of bounds at ALA27, 1ST DOWN" } ], "label": "Auburn SR", "borderColor": "rgba(73, 133, 207, 0.8)", "borderWidth": 2.2, "borderDash": [ 4, 4 ], "fill": false }, { "label": "Quarters", "data": [ { "x": 1, "y": 0 }, { "x": 1, "y": 1 }, { "x": 144, "y": 1 }, { "x": 144, "y": 0 }, { "x": 38, "y": 0 }, { "x": 38, "y": 1 }, { "x": 144, "y": 1 }, { "x": 144, "y": 0 }, { "x": 74, "y": 0 }, { "x": 74, "y": 1 }, { "x": 144, "y": 1 }, { "x": 144, "y": 0 }, { "x": 107, "y": 0 }, { "x": 107, "y": 1 }, { "x": 144, "y": 1 }, { "x": 144, "y": 0 } ], "borderColor": "rgba(0,0,0,0.1)", "borderWidth": 1, "tension": 0, "fill": false, "pointRadius": 0, "showLine": true, "datalabels": { "display": false } } ], "currentParams": { "year": 2025, "week": 14, "seasonType": "regular", "team": "Alabama", "gameId": "401752784" } }; // Chart options (WordPress-safe) const chartOptions = { responsive: true, maintainAspectRatio: false, animation: { duration: 1 // Minimal animation to trigger layout calculation (fixes label positioning) }, elements: 'line' === 'line' ? 'team-lines'.includes('play-map') ? { line: { tension: 0, borderWidth: 0 } } : 'team-lines' === 'win-probability' ? { line: { tension: 0.15, borderWidth: 2.2, fill: false }, point: { pointRadius: 0, pointHoverRadius: 4 } } : { line: { tension: 0.25, borderWidth: 2.2 }, point: { pointRadius: 'team-lines'.includes('team-lines') ? 0 : undefined } } : {}, plugins: { datalabels: { display: function(context) { // Suppress data labels on line charts if ('line' === 'line') { return false; } return context.dataset.datalabels && context.dataset.datalabels.display === true; }, formatter: function(value, context) { // Special handling for Overall Team Performance chart if ('team-lines' === 'overall-team-performance' && context.dataset.label === 'Success Rate (SR)') { // Use the stored play count data if (context.dataset.playCountData && context.dataset.playCountData[context.dataIndex]) { return context.dataset.playCountData[context.dataIndex]; } // Fallback to percentage if play count data not available return Math.round(value * 100) + '%'; } // Handle bar charts with count data (play-type, quarter, down, etc.) if (context.dataset.label && context.dataset.label.includes(' SR') && (chartData.teamCounts || chartData.oppCounts)) { // Find the first team SR dataset in the chart to determine team order const allDatasets = context.chart.data.datasets; const teamSRDataset = allDatasets.find(d => d.label && d.label.includes(' SR') && !d.label.includes('NCAA')); // If this is the first team's SR dataset, use teamCounts if (teamSRDataset && context.dataset.label === teamSRDataset.label && chartData.teamCounts) { return chartData.teamCounts[context.dataIndex] || 0; } // Otherwise, use oppCounts for the second team else if (chartData.oppCounts) { return chartData.oppCounts[context.dataIndex] || 0; } } // For player charts, show value only if > 0 (matches non-embedded behavior) if ('team-lines'.includes('top-rushers') || 'team-lines'.includes('top-passers') || 'team-lines'.includes('top-receivers')) { // Hide data labels for zero or negative values, show actual value for positive values return value > 0 ? value : null; } // For other charts, show values based on type if (typeof value === 'number') { // If value is between 0 and 1, treat as percentage if (value >= 0 && value 0 ? '#26262660' : 'transparent'; }, borderColor: function(context) { const value = context.dataset.data[context.dataIndex]; return value > 0 ? 'rgba(255, 255, 255, 0.2)' : 'transparent'; }, borderRadius: 4, align: 'center', anchor: 'center' }, legend: 'team-lines' === 'win-probability' ? { display: false } : 'line' === 'line' ? { position: 'top', align: 'start', labels: 'team-lines'.includes('play-map') ? { usePointStyle: true, generateLabels: function(chart) { // Call the original generateLabels to get default styling const original = Chart.defaults.plugins.legend.labels.generateLabels; const labels = original.call(this, chart); // Filter and customize each label const filteredLabels = labels.filter(label => { return !label.text.includes(' { const dataset = chart.data.datasets[label.datasetIndex]; if (dataset && dataset.label) { if (dataset.label.includes('Rush')) { label.pointStyle = 'circle'; label.pointStyleWidth = 4; label.fillStyle = 'white'; } else if (dataset.label.includes('Pass')) { label.pointStyle = 'triangle'; label.pointStyleWidth = 4; label.fillStyle = 'white'; } else { label.pointStyle = 'rect'; label.pointStyleWidth = 4; label.fillStyle = 'white'; } } }); return filteredLabels; }, boxWidth: 20, padding: 12 } : { usePointStyle: false, boxWidth: 12, boxHeight: 12, padding: 12, generateLabels: function(chart) { const original = Chart.defaults.plugins.legend.labels.generateLabels; const labels = original.call(this, chart); // Filter out reference areas and ensure white fill const filteredLabels = labels.filter(label => { return !label.text.includes('NCAA Avg SR') && !label.text.includes('50/50') && !label.text.includes('Quarters'); }); // Ensure white fill for all line chart legend boxes filteredLabels.forEach((label) => { label.fillStyle = 'white'; }); return filteredLabels; } } } : { position: 'top', align: 'start', labels: { usePointStyle: false, boxWidth: 12, boxHeight: 12, padding: 12, filter: function(legendItem, chartData) { return !legendItem.text.includes('NCAA Avg SR') && !legendItem.text.includes('Quarters') && !legendItem.text.includes('50/50'); }, generateLabels: function(chart) { const data = chart.data; if (data.datasets.length) { return data.datasets.map((dataset, i) => { // Handle backgroundColor arrays (like in Overall Team Performance chart) let fillColor = dataset.backgroundColor; if (dataset.label === '# Plays') { fillColor = 'white'; } else if (Array.isArray(dataset.backgroundColor)) { // For datasets with backgroundColor arrays, use the first color for legend fillColor = dataset.backgroundColor[0]; } return { text: dataset.label, fillStyle: fillColor, strokeStyle: dataset.label === '# Plays' ? '#666' : dataset.borderColor, lineWidth: dataset.label === '# Plays' ? 1 : dataset.borderWidth, hidden: !chart.isDatasetVisible(i), datasetIndex: i }; }).filter((item, index) => { // Apply the same filter logic as above const dataset = chart.data.datasets[index]; if (!dataset || !dataset.data) return false; if (dataset.label === '# Plays') return true; // Always show # Plays if (dataset.label && (dataset.label.includes('NCAA Avg SR') || dataset.label.includes('Quarters') || dataset.label.includes('50/50'))) return false; return dataset.data.some((value) => value > 0); }); } return []; } } }, tooltip: 'team-lines' === 'win-probability' ? { mode: 'index', intersect: false, callbacks: { title: function(tooltipItems) { if (tooltipItems && tooltipItems[0]) { return 'Play ' + (tooltipItems[0].dataIndex + 1); } return ''; }, label: function(context) { const selectedTeamWinProb = context.parsed.y; const opponentWinProb = 100 - selectedTeamWinProb; const selectedTeam = context.dataset.selectedTeam || 'Team'; const opponentTeam = context.dataset.opponentTeam || 'Opponent'; return [ selectedTeam + ': ' + selectedTeamWinProb.toFixed(1) + '%', opponentTeam + ': ' + opponentWinProb.toFixed(1) + '%' ]; }, afterLabel: function(context) { if (context.dataset.playTexts && context.dataset.playTexts[context.dataIndex]) { return '\n' + context.dataset.playTexts[context.dataIndex]; } return ''; } } } : { filter: function(tooltipItem) { if ('team-lines'.includes('play-map')) { return !tooltipItem.dataset.label.includes('< 0') && !tooltipItem.dataset.label.includes('Quarters') && !tooltipItem.dataset.label.includes('Drive'); } return !tooltipItem.dataset.label.includes('NCAA Avg SR') && !tooltipItem.dataset.label.includes('50/50') && !tooltipItem.dataset.label.includes(' ds.label === 'Win Probability'); if (wpDataset && wpDataset.segmentColors) { wpDataset.segment = { borderColor: function(ctx) { // Use p1DataIndex (ending point) so the line inherits the destination color // This makes momentum shifts more visually intuitive const index = ctx.p1DataIndex; if (index !== undefined && wpDataset.segmentColors[index]) { return wpDataset.segmentColors[index]; } return wpDataset.borderColor || '#8B0000'; } }; } } // Initialize the chart const ctx = canvas.getContext('2d'); const chart = new Chart(ctx, { type: 'line', data: chartData, options: chartOptions }); // Store reference to prevent re-initialization canvas.chartInstance = chart; console.log('CFB Chart initialized successfully'); } catch (error) { console.error('Error initializing CFB chart:', error); // Fallback: show error message in canvas container const container = document.getElementById('cfb-chart-1764545748116-zplvab4ug').parentNode; if (container) { container.innerHTML = '

Chart failed to load. Please refresh the page.

'; } } } // Start loading scripts sequentially function startLoading() { // First, check if scripts are already loaded (multiple embeds on same page) if (typeof Chart !== 'undefined' && typeof ChartDataLabels !== 'undefined') { initChart(); return; } // Load Chart.js first if (typeof Chart === 'undefined') { loadScript('https://cdn.jsdelivr.net/npm/[email protected]/dist/chart.min.js', function() { // Then load ChartDataLabels if (typeof ChartDataLabels === 'undefined') { loadScript('https://cdn.jsdelivr.net/npm/[email protected]', function() { initChart(); }); } else { initChart(); } }); } else if (typeof ChartDataLabels === 'undefined') { // Chart.js loaded but not ChartDataLabels loadScript('https://cdn.jsdelivr.net/npm/[email protected]', function() { initChart(); }); } else { initChart(); } } // Initialize when DOM is ready if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', startLoading); } else { startLoading(); } })();

Yeah, despite the “bad” topline numbers, it really was a tale of two halves. The Alabama offense was indeed outperforming Auburn for much of this game (and especially early in the 2nd quarter). But Auburn got better from there, and Alabama got worse … eventually, the lines all converged and we were in yet another close game that came down to the last drive. Sigh.

I’m not an X’s-and-O’s person enough to know if this is an “adjustments” issue from the coaching staff, but it seems to be intuitively so. Which is only fitting that we’re about to play a rematch with arguably the best adjustment-makers in college ball in Kirby Smart’s staff. And, yep, the game against them in September had the same dynamics across the 1st and 2nd halves.

But life’s short: who’s got time to be cranky? Alabama has won the Iron Bowl six times in a row, with an opportunity to win the SEC and to get to the 12-team Playoff in DeBoer’s second year.

That’s pretty good stuff, especially considering where we were after the opening loss to Florida State. (Ahem, I was one of the few voices saying that it wasn’t that bad and that we still had reason to expect success in 2025)

Roll Tide, all.

📊 All the charts from this game are here.

AdvertisementAdvertisement