Whew, what a game. I feel like I’ve written that coming out of several games this season, but I suppose that’s just the nature of this particular team and schedule.
And by “what a game,” I mean that some mix of all of these emotions were experienced:
- Shock into disgust
- Frustrating into something like numbness
- Slight, heavily measured encouragement
- Shocking whiplash, even a whiff of hope
- My goodness, the hope has set in! Be wary.
- Maniacal laughter, perverse and poisoned Joy.
- Roll Tide. We
haveget to keep playing games.
About that “mirror image”
Coming out of this game, I saw a lot of commentary around these parts about the role of [luck, bounces, turnovers, whatever you want to call it) in this somehow-surprising win. There’s especially the notion that this was the “mirror image” of the odd loss to Oklahoma in Tuscaloosa on 11/15, where the Sooners won on the back of highly pivotal (and dramatically imbalanced) turnovers rather than conventional, ahem, “football performance.”
Was the Tide on the other end of that one here? Let’s pull some graphs for and against.
The case for the “mirror image”
Welp, this is the big one. You heard me complain at the time and ad nauseam since about how Oklahoma massively underperformed Alabama in both conventional and advanced metrics in the November game, including delivering roughly half the efficiency (Success Rate) that Alabama’s offense put up. Plus, they lagged on Explosiveness Rate too (though slightly outperformed the Tide in overall Explosiveness Index).
This was why Oklahoma came out of that kind-of-shocking win with a ~5% Win Expectancy on SP+ style metrics. Frustrating, to say the least!
.cfb-chart-embed-cfb-chart-1766345830316-ok8g9adfl {
font-family: -apple-system, BlinkMacSystemFont, ‘Segoe UI’, ‘Roboto’, sans-serif;
margin: 0;
padding: 0;
}
.cfb-chart-embed-cfb-chart-1766345830316-ok8g9adfl .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-1766345830316-ok8g9adfl .chart-header {
padding: 18px 24px 14px;
border-bottom: 1px solid #e5e5e5;
background: white;
}
.cfb-chart-embed-cfb-chart-1766345830316-ok8g9adfl .chart-title {
font-size: 18px;
font-weight: 600;
color: #171717;
margin: 0;
}
.cfb-chart-embed-cfb-chart-1766345830316-ok8g9adfl .chart-subtitle {
font-size: 11px;
font-weight: 400;
color: #737373;
margin: 4px 0 0 0;
}
.cfb-chart-embed-cfb-chart-1766345830316-ok8g9adfl .chart-content {
padding: 20px 24px 24px !important;
}
.cfb-chart-embed-cfb-chart-1766345830316-ok8g9adfl .chart-content { height: 325px; }
@media (max-width: 640px) {
.cfb-chart-embed-cfb-chart-1766345830316-ok8g9adfl .chart-content {
padding: 12px 16px 20px !important;
height: 280px !important;
}
.cfb-chart-embed-cfb-chart-1766345830316-ok8g9adfl .chart-header {
padding: 12px 16px 12px !important;
}
.cfb-chart-embed-cfb-chart-1766345830316-ok8g9adfl .embed-footer-top {
padding: 8px 12px !important;
}
.cfb-chart-embed-cfb-chart-1766345830316-ok8g9adfl .data-definitions {
padding: 12px !important;
}
}
.cfb-chart-embed-cfb-chart-1766345830316-ok8g9adfl .embed-footer {
border-top: 1px solid #e5e5e5;
font-size: 12px;
color: #737373;
}
.cfb-chart-embed-cfb-chart-1766345830316-ok8g9adfl .embed-footer-top {
display: flex;
justify-content: space-between;
align-items: center;
padding: 12px 16px;
}
.cfb-chart-embed-cfb-chart-1766345830316-ok8g9adfl .embed-footer-link {
color: #737373;
text-decoration: none;
font-weight: 500;
}
.cfb-chart-embed-cfb-chart-1766345830316-ok8g9adfl .embed-footer-link:hover {
color: #525252;
text-decoration: underline;
}
.cfb-chart-embed-cfb-chart-1766345830316-ok8g9adfl .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-1766345830316-ok8g9adfl .data-definitions-toggle:hover {
color: #525252;
}
.cfb-chart-embed-cfb-chart-1766345830316-ok8g9adfl .caret {
transition: transform 0.2s ease;
font-size: 10px;
}
.cfb-chart-embed-cfb-chart-1766345830316-ok8g9adfl .caret.expanded {
transform: rotate(180deg);
}
.cfb-chart-embed-cfb-chart-1766345830316-ok8g9adfl .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-1766345830316-ok8g9adfl .data-definitions.expanded {
display: block;
}
.cfb-chart-embed-cfb-chart-1766345830316-ok8g9adfl .data-definitions ul {
margin: 0;
padding-left: 0;
list-style: none;
}
.cfb-chart-embed-cfb-chart-1766345830316-ok8g9adfl .data-definitions li {
margin-bottom: 4px;
}
Overall Team Performance
Alabama vs. Oklahoma • Dec 19, 2025
- 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_1766345830316_ok8g9adfl() {
const definitions = document.getElementById(‘dataDefinitions_cfb-chart-1766345830316-ok8g9adfl’);
const caret = document.getElementById(‘caret_cfb-chart-1766345830316-ok8g9adfl’);
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-1766345830316-ok8g9adfl’);
if (canvas && canvas.parentNode) {
canvas.parentNode.innerHTML = ‘
‘;
}
}
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-1766345830316-ok8g9adfl’);
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”,
“Oklahoma”
],
“datasets”: [
{
“label”: “Explosiveness Rate (XR)”,
“data”: [
0.1111111111111111,
0.12
],
“backgroundColor”: [
“rgba(101, 0, 20, 0.8)”,
“#5e0a33CC”
],
“stack”: “SRXR”,
“datalabels”: {
“display”: false
}
},
{
“label”: “Success Rate (SR)”,
“data”: [
0.25925925925925924,
0.32
],
“backgroundColor”: [
“rgba(175, 40, 60, 0.8)”,
“#EC4899CC”
],
“stack”: “SRXR”,
“datalabels”: {
“display”: true
},
“playCountData”: [
54,
75
]
},
{
“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”: “#EC4899CC”,
“explosive”: “#5e0a33CC”,
“light”: “#FCE7F3CC”,
“color”: “#EC4899”,
“colorDark”: “#5e0a33”
},
“teamPlayCount”: 54,
“opponentPlayCount”: 75,
“currentParams”: {
“year”: 2025,
“week”: 1,
“seasonType”: “postseason”,
“team”: “Alabama”,
“gameId”: “401779840”
}
};
// 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-1766345830316-ok8g9adfl’).parentNode;
if (container) {
container.innerHTML = ‘
‘;
}
}
}
// 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/chart.js@3.9.1/dist/chart.min.js’, function() {
// Then load ChartDataLabels
if (typeof ChartDataLabels === ‘undefined’) {
loadScript(‘https://cdn.jsdelivr.net/npm/chartjs-plugin-datalabels@2.2.0’, function() {
initChart();
});
} else {
initChart();
}
});
} else if (typeof ChartDataLabels === ‘undefined’) {
// Chart.js loaded but not ChartDataLabels
loadScript(‘https://cdn.jsdelivr.net/npm/chartjs-plugin-datalabels@2.2.0’, function() {
initChart();
});
} else {
initChart();
}
}
// Initialize when DOM is ready
if (document.readyState === ‘loading’) {
document.addEventListener(‘DOMContentLoaded’, startLoading);
} else {
startLoading();
}
})();
But, heyo, Alabama was on the other end of all three of those metrics this time around:
- A notably lower SR than the Sooners (26% to their 32%). I’ll caveat that the gap isn’t as bad as the flipside in the prior game, but both teams are just worse in this one, with Alabama’s 26% SR being about as low as I’ve seen from a victor (and even lower than Okie’s 28% against us in the Nov. game).
- A slightly lagging XR than them, too (11% to 12%). Again, neither team was exactly lighting it up here, but Oklahoma created slightly more explosiveness slightly more often than Alabama (and then lost)
- But, the Tide pulled a higher explosiveness index (1.83 to 1.45). It’s actually funny how high these numbers are: this is perhaps the Tide’s highest Explosiveness number this year, but this metric can have an inverse relationship with efficiency: sure, Alabama was real explosive when it made gains (the long Lotty Brooks touchdown catch, Daniel Hill’s 30-yard rumble, Cuevas on a few plays), but they didn’t have many successful plays otherwise. Not exactly a badge of honor.
I’d call this all a definite point in favor of the “mirror image” theory.
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. Oklahoma • Dec 19, 2025
| Stats | Alabama | Oklahoma |
|---|---|---|
| Points | 34 | 24 |
| Game Excitement | 5.4 | 5.4 |
| Total yards | 260 | 362 |
| Rush yards | 28 | 55 |
| Rush attempts | 25 | 33 |
| Yards per rush | 1.1 | 1.7 |
| Pass yards | 232 | 307 |
| Pass attempts | 18-29 | 26-42 |
| Yards per pass | 8.0 | 7.3 |
| 1st downs | 12 | 18 |
| 3rd down eff | 2-12 | 7-17 |
| 4th down eff | 1-1 | 1-1 |
| Explosiveness | 1.83 | 1.45 |
| Turnovers | 0 | 1 |
| Tackles | 36 | 30 |
| Sacks | 5 | 4 |
| Penalties-Yds | 4-46 | 5-50 |
| Possession | 26:52 | 33:08 |
And the box score contains a few other hints at a mirror image effect. In both matchups, the victor …
- Got more points (Roll Tide!)
- Got considerably fewer yards (and across both rush and pass)
- Had a much lower TOP
- Had fewer 1st downs
- Had horrible 3rd down efficiency
- BUT, they got more sacks (though closer in the second matchup)
- AND, they “forced”* more turnovers (if less dramatically in December)
Several of those signal a pretty ugly game for the Tide.
* I’ll talk about “forcing turnovers” shortly on the other side of the coin.
.cfb-chart-embed-cfb-chart-1766345866451-c875tzps6 {
font-family: -apple-system, BlinkMacSystemFont, ‘Segoe UI’, ‘Roboto’, sans-serif;
margin: 0;
padding: 0;
}
.cfb-chart-embed-cfb-chart-1766345866451-c875tzps6 .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-1766345866451-c875tzps6 .chart-header {
padding: 18px 24px 14px;
border-bottom: 1px solid #e5e5e5;
background: white;
}
.cfb-chart-embed-cfb-chart-1766345866451-c875tzps6 .chart-title {
font-size: 18px;
font-weight: 600;
color: #171717;
margin: 0;
}
.cfb-chart-embed-cfb-chart-1766345866451-c875tzps6 .chart-subtitle {
font-size: 11px;
font-weight: 400;
color: #737373;
margin: 4px 0 0 0;
}
.cfb-chart-embed-cfb-chart-1766345866451-c875tzps6 .chart-content {
padding: 20px 24px 24px !important;
}
.cfb-chart-embed-cfb-chart-1766345866451-c875tzps6 .chart-content { height: 325px; }
@media (max-width: 640px) {
.cfb-chart-embed-cfb-chart-1766345866451-c875tzps6 .chart-content {
padding: 12px 16px 20px !important;
height: 280px !important;
}
.cfb-chart-embed-cfb-chart-1766345866451-c875tzps6 .chart-header {
padding: 12px 16px 12px !important;
}
.cfb-chart-embed-cfb-chart-1766345866451-c875tzps6 .embed-footer-top {
padding: 8px 12px !important;
}
.cfb-chart-embed-cfb-chart-1766345866451-c875tzps6 .data-definitions {
padding: 12px !important;
}
}
.cfb-chart-embed-cfb-chart-1766345866451-c875tzps6 .embed-footer {
border-top: 1px solid #e5e5e5;
font-size: 12px;
color: #737373;
}
.cfb-chart-embed-cfb-chart-1766345866451-c875tzps6 .embed-footer-top {
display: flex;
justify-content: space-between;
align-items: center;
padding: 12px 16px;
}
.cfb-chart-embed-cfb-chart-1766345866451-c875tzps6 .embed-footer-link {
color: #737373;
text-decoration: none;
font-weight: 500;
}
.cfb-chart-embed-cfb-chart-1766345866451-c875tzps6 .embed-footer-link:hover {
color: #525252;
text-decoration: underline;
}
.cfb-chart-embed-cfb-chart-1766345866451-c875tzps6 .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-1766345866451-c875tzps6 .data-definitions-toggle:hover {
color: #525252;
}
.cfb-chart-embed-cfb-chart-1766345866451-c875tzps6 .caret {
transition: transform 0.2s ease;
font-size: 10px;
}
.cfb-chart-embed-cfb-chart-1766345866451-c875tzps6 .caret.expanded {
transform: rotate(180deg);
}
.cfb-chart-embed-cfb-chart-1766345866451-c875tzps6 .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-1766345866451-c875tzps6 .data-definitions.expanded {
display: block;
}
.cfb-chart-embed-cfb-chart-1766345866451-c875tzps6 .data-definitions ul {
margin: 0;
padding-left: 0;
list-style: none;
}
.cfb-chart-embed-cfb-chart-1766345866451-c875tzps6 .data-definitions li {
margin-bottom: 4px;
}
Play Map: Alabama
Alabama vs. Oklahoma • Dec 19, 2025
- 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_1766345866451_c875tzps6() {
const definitions = document.getElementById(‘dataDefinitions_cfb-chart-1766345866451-c875tzps6’);
const caret = document.getElementById(‘caret_cfb-chart-1766345866451-c875tzps6’);
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-1766345866451-c875tzps6’);
if (canvas && canvas.parentNode) {
canvas.parentNode.innerHTML = ‘
‘;
}
}
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-1766345866451-c875tzps6’);
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-1766345866451-c875tzps6’).parentNode;
if (container) {
container.innerHTML = ‘
‘;
}
}
}
// 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/chart.js@3.9.1/dist/chart.min.js’, function() {
// Then load ChartDataLabels
if (typeof ChartDataLabels === ‘undefined’) {
loadScript(‘https://cdn.jsdelivr.net/npm/chartjs-plugin-datalabels@2.2.0’, function() {
initChart();
});
} else {
initChart();
}
});
} else if (typeof ChartDataLabels === ‘undefined’) {
// Chart.js loaded but not ChartDataLabels
loadScript(‘https://cdn.jsdelivr.net/npm/chartjs-plugin-datalabels@2.2.0’, function() {
initChart();
});
} else {
initChart();
}
}
// Initialize when DOM is ready
if (document.readyState === ‘loading’) {
document.addEventListener(‘DOMContentLoaded’, startLoading);
} else {
startLoading();
}
})();
Alabama’s Play Map also gives some whiff of them “winning despite some serious leakage.” You can count only six total explosive Alabama plays here: that’s three fewer than Oklahoma, and matches the six that the Sooners scraped together in the first matchup (vs. the Tide’s 11 in that one).
And then it’s pathetically easy to count the other successful plays: just eight more on the whole day. Sorry, how did we win this one by 10 again? Was it just Zabien Brown + a Sooners Special teams meltdown?
.cfb-chart-embed-cfb-chart-1766345876596-xq96bun92 {
font-family: -apple-system, BlinkMacSystemFont, ‘Segoe UI’, ‘Roboto’, sans-serif;
margin: 0;
padding: 0;
}
.cfb-chart-embed-cfb-chart-1766345876596-xq96bun92 .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-1766345876596-xq96bun92 .chart-header {
padding: 18px 24px 14px;
border-bottom: 1px solid #e5e5e5;
background: white;
}
.cfb-chart-embed-cfb-chart-1766345876596-xq96bun92 .chart-title {
font-size: 18px;
font-weight: 600;
color: #171717;
margin: 0;
}
.cfb-chart-embed-cfb-chart-1766345876596-xq96bun92 .chart-subtitle {
font-size: 11px;
font-weight: 400;
color: #737373;
margin: 4px 0 0 0;
}
.cfb-chart-embed-cfb-chart-1766345876596-xq96bun92 .chart-content {
padding: 20px 24px 24px !important;
}
.cfb-chart-embed-cfb-chart-1766345876596-xq96bun92 .chart-content { height: 325px; }
@media (max-width: 640px) {
.cfb-chart-embed-cfb-chart-1766345876596-xq96bun92 .chart-content {
padding: 12px 16px 20px !important;
height: 280px !important;
}
.cfb-chart-embed-cfb-chart-1766345876596-xq96bun92 .chart-header {
padding: 12px 16px 12px !important;
}
.cfb-chart-embed-cfb-chart-1766345876596-xq96bun92 .embed-footer-top {
padding: 8px 12px !important;
}
.cfb-chart-embed-cfb-chart-1766345876596-xq96bun92 .data-definitions {
padding: 12px !important;
}
}
.cfb-chart-embed-cfb-chart-1766345876596-xq96bun92 .embed-footer {
border-top: 1px solid #e5e5e5;
font-size: 12px;
color: #737373;
}
.cfb-chart-embed-cfb-chart-1766345876596-xq96bun92 .embed-footer-top {
display: flex;
justify-content: space-between;
align-items: center;
padding: 12px 16px;
}
.cfb-chart-embed-cfb-chart-1766345876596-xq96bun92 .embed-footer-link {
color: #737373;
text-decoration: none;
font-weight: 500;
}
.cfb-chart-embed-cfb-chart-1766345876596-xq96bun92 .embed-footer-link:hover {
color: #525252;
text-decoration: underline;
}
.cfb-chart-embed-cfb-chart-1766345876596-xq96bun92 .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-1766345876596-xq96bun92 .data-definitions-toggle:hover {
color: #525252;
}
.cfb-chart-embed-cfb-chart-1766345876596-xq96bun92 .caret {
transition: transform 0.2s ease;
font-size: 10px;
}
.cfb-chart-embed-cfb-chart-1766345876596-xq96bun92 .caret.expanded {
transform: rotate(180deg);
}
.cfb-chart-embed-cfb-chart-1766345876596-xq96bun92 .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-1766345876596-xq96bun92 .data-definitions.expanded {
display: block;
}
.cfb-chart-embed-cfb-chart-1766345876596-xq96bun92 .data-definitions ul {
margin: 0;
padding-left: 0;
list-style: none;
}
.cfb-chart-embed-cfb-chart-1766345876596-xq96bun92 .data-definitions li {
margin-bottom: 4px;
}
SR, XR, and Play Count by Drive: Alabama
Alabama vs. Oklahoma • Dec 19, 2025
- 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_1766345876596_xq96bun92() {
const definitions = document.getElementById(‘dataDefinitions_cfb-chart-1766345876596-xq96bun92’);
const caret = document.getElementById(‘caret_cfb-chart-1766345876596-xq96bun92’);
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-1766345876596-xq96bun92’);
if (canvas && canvas.parentNode) {
canvas.parentNode.innerHTML = ‘
‘;
}
}
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-1766345876596-xq96bun92’);
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 2”,
“Drive 4”,
“Drive 6”,
“Drive 8”,
“Drive 10”,
“Drive 13”,
“Drive 15”,
“Drive 17”,
“Drive 19”,
“Drive 21”,
“Drive 23”,
“Drive 25”,
“Drive 27”
],
“datasets”: [
{
“label”: “Alabama XR”,
“data”: [
0,
0,
0,
0.2222222222222222,
0,
0,
0.6666666666666666,
0,
0.25,
0.25,
0,
0,
0
],
“backgroundColor”: “rgba(101, 0, 20, 0.8)”,
“stack”: “SRXR”,
“yAxisID”: “y”,
“datalabels”: {
“display”: false
}
},
{
“label”: “Alabama SR”,
“data”: [
0,
0,
0.3333333333333333,
0.3333333333333333,
0.25,
0.25,
0.6666666666666666,
0.25,
0.25,
0.75,
0,
0,
0
],
“backgroundColor”: “rgba(175, 40, 60, 0.8)”,
“stack”: “SRXR”,
“yAxisID”: “y”,
“datalabels”: {
“display”: false
}
},
{
“label”: “Plays in drive”,
“data”: [
3,
3,
3,
9,
4,
4,
3,
8,
4,
4,
3,
3,
3
],
“backgroundColor”: “rgba(148, 148, 148, 0.8)”,
“stack”: “Plays”,
“yAxisID”: “y1”,
“datalabels”: {
“display”: true
}
}
],
“currentParams”: {
“year”: 2025,
“week”: 1,
“seasonType”: “postseason”,
“team”: “Alabama”,
“gameId”: “401779840”
}
};
// 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-1766345876596-xq96bun92’).parentNode;
if (container) {
container.innerHTML = ‘
‘;
}
}
}
// 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/chart.js@3.9.1/dist/chart.min.js’, function() {
// Then load ChartDataLabels
if (typeof ChartDataLabels === ‘undefined’) {
loadScript(‘https://cdn.jsdelivr.net/npm/chartjs-plugin-datalabels@2.2.0’, function() {
initChart();
});
} else {
initChart();
}
});
} else if (typeof ChartDataLabels === ‘undefined’) {
// Chart.js loaded but not ChartDataLabels
loadScript(‘https://cdn.jsdelivr.net/npm/chartjs-plugin-datalabels@2.2.0’, function() {
initChart();
});
} else {
initChart();
}
}
// Initialize when DOM is ready
if (document.readyState === ‘loading’) {
document.addEventListener(‘DOMContentLoaded’, startLoading);
} else {
startLoading();
}
})();
And the drives chart tells a vaguely similar story: it’s three-and-outs for days, especially bookending this game for the offense, but with a few long-ish scoring drives sprinkled in, and a few more scores from shorter fields (the fumble-punt, then the shanked punt to a surprise Germie return).
I mean, that this drives chart has only two drives of more than 4 plays is remarkable. This is like Iowa ball or something, I don’t get it.
.cfb-chart-embed-cfb-chart-1766345890170-82z30xpu8 {
font-family: -apple-system, BlinkMacSystemFont, ‘Segoe UI’, ‘Roboto’, sans-serif;
margin: 0;
padding: 0;
}
.cfb-chart-embed-cfb-chart-1766345890170-82z30xpu8 .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-1766345890170-82z30xpu8 .chart-header {
padding: 18px 24px 14px;
border-bottom: 1px solid #e5e5e5;
background: white;
}
.cfb-chart-embed-cfb-chart-1766345890170-82z30xpu8 .chart-title {
font-size: 18px;
font-weight: 600;
color: #171717;
margin: 0;
}
.cfb-chart-embed-cfb-chart-1766345890170-82z30xpu8 .chart-subtitle {
font-size: 11px;
font-weight: 400;
color: #737373;
margin: 4px 0 0 0;
}
.cfb-chart-embed-cfb-chart-1766345890170-82z30xpu8 .chart-content {
padding: 20px 24px 24px !important;
}
.cfb-chart-embed-cfb-chart-1766345890170-82z30xpu8 .chart-content.top-passers { height: 280px !important; }
@media (max-width: 640px) {
.cfb-chart-embed-cfb-chart-1766345890170-82z30xpu8 .chart-content {
padding: 12px 16px 20px !important;
}
.cfb-chart-embed-cfb-chart-1766345890170-82z30xpu8 .chart-header {
padding: 12px 16px 12px !important;
}
.cfb-chart-embed-cfb-chart-1766345890170-82z30xpu8 .embed-footer-top {
padding: 8px 12px !important;
}
.cfb-chart-embed-cfb-chart-1766345890170-82z30xpu8 .data-definitions {
padding: 12px !important;
}
}
.cfb-chart-embed-cfb-chart-1766345890170-82z30xpu8 .embed-footer {
border-top: 1px solid #e5e5e5;
font-size: 12px;
color: #737373;
}
.cfb-chart-embed-cfb-chart-1766345890170-82z30xpu8 .embed-footer-top {
display: flex;
justify-content: space-between;
align-items: center;
padding: 12px 16px;
}
.cfb-chart-embed-cfb-chart-1766345890170-82z30xpu8 .embed-footer-link {
color: #737373;
text-decoration: none;
font-weight: 500;
}
.cfb-chart-embed-cfb-chart-1766345890170-82z30xpu8 .embed-footer-link:hover {
color: #525252;
text-decoration: underline;
}
.cfb-chart-embed-cfb-chart-1766345890170-82z30xpu8 .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-1766345890170-82z30xpu8 .data-definitions-toggle:hover {
color: #525252;
}
.cfb-chart-embed-cfb-chart-1766345890170-82z30xpu8 .caret {
transition: transform 0.2s ease;
font-size: 10px;
}
.cfb-chart-embed-cfb-chart-1766345890170-82z30xpu8 .caret.expanded {
transform: rotate(180deg);
}
.cfb-chart-embed-cfb-chart-1766345890170-82z30xpu8 .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-1766345890170-82z30xpu8 .data-definitions.expanded {
display: block;
}
.cfb-chart-embed-cfb-chart-1766345890170-82z30xpu8 .data-definitions ul {
margin: 0;
padding-left: 0;
list-style: none;
}
.cfb-chart-embed-cfb-chart-1766345890170-82z30xpu8 .data-definitions li {
margin-bottom: 4px;
}
Top passers
Alabama vs. Oklahoma • Dec 19, 2025
- 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_1766345890170_82z30xpu8() {
const definitions = document.getElementById(‘dataDefinitions_cfb-chart-1766345890170-82z30xpu8’);
const caret = document.getElementById(‘caret_cfb-chart-1766345890170-82z30xpu8’);
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-1766345890170-82z30xpu8’);
if (canvas && canvas.parentNode) {
canvas.parentNode.innerHTML = ‘
‘;
}
}
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-1766345890170-82z30xpu8’);
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”,
“J.Mateer”
],
“datasets”: [
{
“label”: “Explosive”,
“data”: [
5,
9
],
“backgroundColor”: [
“#3c000cCC”,
“#3c031fCC”
],
“borderColor”: “#374151”,
“borderWidth”: 1
},
{
“label”: “Successful”,
“data”: [
4,
6
],
“backgroundColor”: [
“rgba(175, 40, 60, 0.8)”,
“#EC4899CC”
],
“borderColor”: “#374151”,
“borderWidth”: 1
},
{
“label”: “Other catches”,
“data”: [
9,
11
],
“backgroundColor”: [
“rgba(245, 229, 233, 0.8)”,
“#FCE7F3CC”
],
“borderColor”: “#374151”,
“borderWidth”: 1
},
{
“label”: “Incompletes”,
“data”: [
11,
15
],
“backgroundColor”: “#FFFFFF”,
“borderColor”: “#374151”,
“borderWidth”: 1
},
{
“label”: “Interceptions”,
“data”: [
0,
1
],
“backgroundColor”: “#4B5563”,
“borderColor”: “#374151”,
“borderWidth”: 1
}
],
“currentParams”: {
“year”: 2025,
“week”: 1,
“seasonType”: “postseason”,
“team”: “Alabama”,
“gameId”: “401779840”
},
“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-1766345890170-82z30xpu8’).parentNode;
if (container) {
container.innerHTML = ‘
‘;
}
}
}
// 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/chart.js@3.9.1/dist/chart.min.js’, function() {
// Then load ChartDataLabels
if (typeof ChartDataLabels === ‘undefined’) {
loadScript(‘https://cdn.jsdelivr.net/npm/chartjs-plugin-datalabels@2.2.0’, function() {
initChart();
});
} else {
initChart();
}
});
} else if (typeof ChartDataLabels === ‘undefined’) {
// Chart.js loaded but not ChartDataLabels
loadScript(‘https://cdn.jsdelivr.net/npm/chartjs-plugin-datalabels@2.2.0’, function() {
initChart();
});
} else {
initChart();
}
}
// Initialize when DOM is ready
if (document.readyState === ‘loading’) {
document.addEventListener(‘DOMContentLoaded’, startLoading);
} else {
startLoading();
}
})();
I’m not going to dwell here in this article, but Ty Simpson’s line here looks remarkably similar to Mateer’s line out of the first game. That is to say: pretty bad! A surprising line for the victorious QB to ride in on!
.cfb-chart-embed-cfb-chart-1766345901305-1j5z0cii7 {
font-family: -apple-system, BlinkMacSystemFont, ‘Segoe UI’, ‘Roboto’, sans-serif;
margin: 0;
padding: 0;
}
.cfb-chart-embed-cfb-chart-1766345901305-1j5z0cii7 .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-1766345901305-1j5z0cii7 .chart-header {
padding: 18px 24px 14px;
border-bottom: 1px solid #e5e5e5;
background: white;
}
.cfb-chart-embed-cfb-chart-1766345901305-1j5z0cii7 .chart-title {
font-size: 18px;
font-weight: 600;
color: #171717;
margin: 0;
}
.cfb-chart-embed-cfb-chart-1766345901305-1j5z0cii7 .chart-subtitle {
font-size: 11px;
font-weight: 400;
color: #737373;
margin: 4px 0 0 0;
}
.cfb-chart-embed-cfb-chart-1766345901305-1j5z0cii7 .chart-content {
padding: 20px 24px 24px !important;
}
.cfb-chart-embed-cfb-chart-1766345901305-1j5z0cii7 .chart-content { height: 325px; }
@media (max-width: 640px) {
.cfb-chart-embed-cfb-chart-1766345901305-1j5z0cii7 .chart-content {
padding: 12px 16px 20px !important;
height: 280px !important;
}
.cfb-chart-embed-cfb-chart-1766345901305-1j5z0cii7 .chart-header {
padding: 12px 16px 12px !important;
}
.cfb-chart-embed-cfb-chart-1766345901305-1j5z0cii7 .embed-footer-top {
padding: 8px 12px !important;
}
.cfb-chart-embed-cfb-chart-1766345901305-1j5z0cii7 .data-definitions {
padding: 12px !important;
}
}
.cfb-chart-embed-cfb-chart-1766345901305-1j5z0cii7 .embed-footer {
border-top: 1px solid #e5e5e5;
font-size: 12px;
color: #737373;
}
.cfb-chart-embed-cfb-chart-1766345901305-1j5z0cii7 .embed-footer-top {
display: flex;
justify-content: space-between;
align-items: center;
padding: 12px 16px;
}
.cfb-chart-embed-cfb-chart-1766345901305-1j5z0cii7 .embed-footer-link {
color: #737373;
text-decoration: none;
font-weight: 500;
}
.cfb-chart-embed-cfb-chart-1766345901305-1j5z0cii7 .embed-footer-link:hover {
color: #525252;
text-decoration: underline;
}
.cfb-chart-embed-cfb-chart-1766345901305-1j5z0cii7 .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-1766345901305-1j5z0cii7 .data-definitions-toggle:hover {
color: #525252;
}
.cfb-chart-embed-cfb-chart-1766345901305-1j5z0cii7 .caret {
transition: transform 0.2s ease;
font-size: 10px;
}
.cfb-chart-embed-cfb-chart-1766345901305-1j5z0cii7 .caret.expanded {
transform: rotate(180deg);
}
.cfb-chart-embed-cfb-chart-1766345901305-1j5z0cii7 .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-1766345901305-1j5z0cii7 .data-definitions.expanded {
display: block;
}
.cfb-chart-embed-cfb-chart-1766345901305-1j5z0cii7 .data-definitions ul {
margin: 0;
padding-left: 0;
list-style: none;
}
.cfb-chart-embed-cfb-chart-1766345901305-1j5z0cii7 .data-definitions li {
margin-bottom: 4px;
}
SR and XR by Red Zone
Alabama vs. Oklahoma • Dec 19, 2025
- 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_1766345901305_1j5z0cii7() {
const definitions = document.getElementById(‘dataDefinitions_cfb-chart-1766345901305-1j5z0cii7’);
const caret = document.getElementById(‘caret_cfb-chart-1766345901305-1j5z0cii7’);
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-1766345901305-1j5z0cii7’);
if (canvas && canvas.parentNode) {
canvas.parentNode.innerHTML = ‘
‘;
}
}
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-1766345901305-1j5z0cii7’);
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.13043478260869565
],
“stack”: “Team”,
“label”: “Alabama XR”,
“backgroundColor”: “rgba(101, 0, 20, 0.8)”,
“datalabels”: {
“display”: false
}
},
{
“data”: [
0.25,
0.2608695652173913
],
“stack”: “Team”,
“label”: “Alabama SR”,
“backgroundColor”: “rgba(175, 40, 60, 0.8)”,
“datalabels”: {
“display”: true
}
},
{
“data”: [
0,
0.12857142857142856
],
“stack”: “Opponent”,
“label”: “Oklahoma XR”,
“backgroundColor”: “#5e0a33CC”,
“datalabels”: {
“display”: false
}
},
{
“data”: [
0.4,
0.3142857142857143
],
“stack”: “Opponent”,
“label”: “Oklahoma SR”,
“backgroundColor”: “#EC4899CC”,
“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”: [
8,
46
],
“oppCounts”: [
5,
70
],
“currentParams”: {
“year”: 2025,
“week”: 1,
“seasonType”: “postseason”,
“team”: “Alabama”,
“gameId”: “401779840”
}
};
// 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-1766345901305-1j5z0cii7’).parentNode;
if (container) {
container.innerHTML = ‘
‘;
}
}
}
// 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/chart.js@3.9.1/dist/chart.min.js’, function() {
// Then load ChartDataLabels
if (typeof ChartDataLabels === ‘undefined’) {
loadScript(‘https://cdn.jsdelivr.net/npm/chartjs-plugin-datalabels@2.2.0’, function() {
initChart();
});
} else {
initChart();
}
});
} else if (typeof ChartDataLabels === ‘undefined’) {
// Chart.js loaded but not ChartDataLabels
loadScript(‘https://cdn.jsdelivr.net/npm/chartjs-plugin-datalabels@2.2.0’, function() {
initChart();
});
} else {
initChart();
}
}
// Initialize when DOM is ready
if (document.readyState === ‘loading’) {
document.addEventListener(‘DOMContentLoaded’, startLoading);
} else {
startLoading();
}
})();
Finally, I’m showing this chart because of the relative non-story: sometimes the Red Zone stuff is what tells upsets, but in this one the Sooners were more efficient inside and outside the Red Zone (just like Alabama was in the first one).
The case against the “mirror image”
Ok, let’s get into the turnovers. On turnovers in general, I use the word “forced” with caution: some defenses do have skills and tendencies that on average lead to more turnovers, but TO’s — especially fumble recoveries — are one of the most variance/luck oriented parts of the game.
Good teams can push past bad luck, and vice versa, and it’s still “football,” but I’m always skeptical when commentators give a team (like Oklahoma in November) credit for “forcing turnovers” in a single game. It’s like … yeah, kinda. That same logic applies to Mateer’s pass to Zabien Brown in this game, and their weird fumble-punt. Their odd kicking issues, too. I’d argue that that was all lucky for the Tide in a way that majorly contributed to victory.
But, tendency does color those comparisons a bit. For one, Alabama went into the November matchup as one of the best teams in the SEC on turnover margin. Again, some of that is luck, but once you see ~10 games you start to expect tendency. Meanwhile, Oklahoma was close to the bottom of the conference in that metric. And yet, Oklahoma manages a 3 to zero turnover margin against Alabama. Sure, one of those was a strip sack, which Ty has been good for ~1 per SEC game, so I’ll give the Sooners that. But otherwise, that turnover line (and the resulting loss for Alabama), was waaay against tendency for both teams. Very, very frustrating.
So, in this Playoff rematch, I do give the Tide a little more grace. So you’re telling me that QB John Mateer threw a bad pick six in this one? Well, sure, he threw three picks against LSU in his prior game, and has been known to be a little fast and loose with the ball. That’s much more “on tendency,” and that he didn’t manage to throw one in the first matchup (despite his efforts) is more remarkable.
(Now, the story doesn’t hold the same for Special Teams: I have no explanation for why Oklahoma’s highly-rated special teams unit melted down in several ways on Friday. Maybe some cruel reversion to the mean or something, but it was definitely against tendency).
And finally, Alabama netted what I would call a 2-to-0 turnover margin in this one (counting the fumble-punt, which doesn’t count as an official TO in the box score … but it essentially was), which I’d call both less dramatic than the reverse margin from November, and not terribly off tendency for Alabama.
.cfb-chart-embed-cfb-chart-1766345919405-650evlgcw {
font-family: -apple-system, BlinkMacSystemFont, ‘Segoe UI’, ‘Roboto’, sans-serif;
margin: 0;
padding: 0;
}
.cfb-chart-embed-cfb-chart-1766345919405-650evlgcw .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-1766345919405-650evlgcw .chart-header {
padding: 18px 24px 14px;
border-bottom: 1px solid #e5e5e5;
background: white;
}
.cfb-chart-embed-cfb-chart-1766345919405-650evlgcw .chart-title {
font-size: 18px;
font-weight: 600;
color: #171717;
margin: 0;
}
.cfb-chart-embed-cfb-chart-1766345919405-650evlgcw .chart-subtitle {
font-size: 11px;
font-weight: 400;
color: #737373;
margin: 4px 0 0 0;
}
.cfb-chart-embed-cfb-chart-1766345919405-650evlgcw .chart-content {
padding: 20px 24px 24px !important;
}
.cfb-chart-embed-cfb-chart-1766345919405-650evlgcw .chart-content { height: 325px; }
@media (max-width: 640px) {
.cfb-chart-embed-cfb-chart-1766345919405-650evlgcw .chart-content {
padding: 12px 16px 20px !important;
height: 280px !important;
}
.cfb-chart-embed-cfb-chart-1766345919405-650evlgcw .chart-header {
padding: 12px 16px 12px !important;
}
.cfb-chart-embed-cfb-chart-1766345919405-650evlgcw .embed-footer-top {
padding: 8px 12px !important;
}
.cfb-chart-embed-cfb-chart-1766345919405-650evlgcw .data-definitions {
padding: 12px !important;
}
}
.cfb-chart-embed-cfb-chart-1766345919405-650evlgcw .embed-footer {
border-top: 1px solid #e5e5e5;
font-size: 12px;
color: #737373;
}
.cfb-chart-embed-cfb-chart-1766345919405-650evlgcw .embed-footer-top {
display: flex;
justify-content: space-between;
align-items: center;
padding: 12px 16px;
}
.cfb-chart-embed-cfb-chart-1766345919405-650evlgcw .embed-footer-link {
color: #737373;
text-decoration: none;
font-weight: 500;
}
.cfb-chart-embed-cfb-chart-1766345919405-650evlgcw .embed-footer-link:hover {
color: #525252;
text-decoration: underline;
}
.cfb-chart-embed-cfb-chart-1766345919405-650evlgcw .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-1766345919405-650evlgcw .data-definitions-toggle:hover {
color: #525252;
}
.cfb-chart-embed-cfb-chart-1766345919405-650evlgcw .caret {
transition: transform 0.2s ease;
font-size: 10px;
}
.cfb-chart-embed-cfb-chart-1766345919405-650evlgcw .caret.expanded {
transform: rotate(180deg);
}
.cfb-chart-embed-cfb-chart-1766345919405-650evlgcw .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-1766345919405-650evlgcw .data-definitions.expanded {
display: block;
}
.cfb-chart-embed-cfb-chart-1766345919405-650evlgcw .data-definitions ul {
margin: 0;
padding-left: 0;
list-style: none;
}
.cfb-chart-embed-cfb-chart-1766345919405-650evlgcw .data-definitions li {
margin-bottom: 4px;
}
SR and XR by Quarter
Alabama vs. Oklahoma • Dec 19, 2025
- 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_1766345919405_650evlgcw() {
const definitions = document.getElementById(‘dataDefinitions_cfb-chart-1766345919405-650evlgcw’);
const caret = document.getElementById(‘caret_cfb-chart-1766345919405-650evlgcw’);
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-1766345919405-650evlgcw’);
if (canvas && canvas.parentNode) {
canvas.parentNode.innerHTML = ‘
‘;
}
}
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-1766345919405-650evlgcw’);
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”: [
“Q1”,
“Q2”,
“Q3”,
“Q4”
],
“datasets”: [
{
“data”: [
0,
0.14285714285714285,
0.13333333333333333,
0.11764705882352941
],
“stack”: “Team”,
“label”: “Alabama XR”,
“backgroundColor”: “rgba(101, 0, 20, 0.8)”,
“datalabels”: {
“display”: false
}
},
{
“data”: [
0.125,
0.2857142857142857,
0.3333333333333333,
0.23529411764705882
],
“stack”: “Team”,
“label”: “Alabama SR”,
“backgroundColor”: “rgba(175, 40, 60, 0.8)”,
“datalabels”: {
“display”: true
}
},
{
“data”: [
0.09090909090909091,
0.22727272727272727,
0,
0.1111111111111111
],
“stack”: “Opponent”,
“label”: “Oklahoma XR”,
“backgroundColor”: “#5e0a33CC”,
“datalabels”: {
“display”: false
}
},
{
“data”: [
0.45454545454545453,
0.2727272727272727,
0.3076923076923077,
0.2222222222222222
],
“stack”: “Opponent”,
“label”: “Oklahoma SR”,
“backgroundColor”: “#EC4899CC”,
“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”: [
8,
14,
15,
17
],
“oppCounts”: [
22,
22,
13,
18
],
“currentParams”: {
“year”: 2025,
“week”: 1,
“seasonType”: “postseason”,
“team”: “Alabama”,
“gameId”: “401779840”
}
};
// 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’ ? ‘quarter-bars’.includes(‘play-map’) ? {
line: {
tension: 0,
borderWidth: 0
}
} : ‘quarter-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: ‘quarter-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 (‘quarter-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 (‘quarter-bars’.includes(‘top-rushers’) || ‘quarter-bars’.includes(‘top-passers’) || ‘quarter-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: ‘quarter-bars’ === ‘win-probability’ ? {
display: false
} : ‘bar’ === ‘line’ ? {
position: ‘top’,
align: ‘start’,
labels: ‘quarter-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: ‘quarter-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 (‘quarter-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-1766345919405-650evlgcw’).parentNode;
if (container) {
container.innerHTML = ‘
‘;
}
}
}
// 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/chart.js@3.9.1/dist/chart.min.js’, function() {
// Then load ChartDataLabels
if (typeof ChartDataLabels === ‘undefined’) {
loadScript(‘https://cdn.jsdelivr.net/npm/chartjs-plugin-datalabels@2.2.0’, function() {
initChart();
});
} else {
initChart();
}
});
} else if (typeof ChartDataLabels === ‘undefined’) {
// Chart.js loaded but not ChartDataLabels
loadScript(‘https://cdn.jsdelivr.net/npm/chartjs-plugin-datalabels@2.2.0’, function() {
initChart();
});
} else {
initChart();
}
}
// Initialize when DOM is ready
if (document.readyState === ‘loading’) {
document.addEventListener(‘DOMContentLoaded’, startLoading);
} else {
startLoading();
}
})();
Plus, Alabama actually did look at least slightly better for this entire game after that 1st quarter: an opening quarter that I can best describe as “I wish we’d just played in the Pop Tarts Bowl.” Sure, edging out a generally-bad Oklahoma offense for three quarters isn’t exactly something to write Mother about, but it shows that there was more to the Tide comeback than random Sooner meltdowns.
Here’s the sequence as I see it:
- Sooners have both a pretty excellent first quarter, but it’s more fragile than it looks: several unlikely diving sideline catches, other catches from not-that-accurate Mateer passes, and then lots of 3rd downs converted (including on amazing sideline catches); all while Alabama was bitten by untimely drops. That 3rd downs perfection-into-lapse might remind you of a certain Alabama team in Athens, by the way. Basically, the Sooners looked great, but not, like, 17-to-0 great.
- Alabama’s offense started showing some life, and Oklahoma’s Magical Mystery Tour started coming back to Earth.
- But some piece of the universe chose this moment to more dramatically balance things out: Oklahoma made huge mistakes to let Alabama score a quick 10 points (amidst another solid drive from the Tide, albeit one that required its own 4th down risk). Very suddenly, the score was tied.
- I’d call it a “close game” in the second half, with Alabama slightly outperforming the Sooners, and likely “deserving” something like a 3-4 point win. Instead, the Sooners kept missing kicks they’d usually make, and the Tide won by 10.
And, simply, 10 points is not a mirror image of the 2-point squeaker that the Sooners managed the first time.
.cfb-chart-embed-cfb-chart-1766345933069-20pt4ndz2 {
font-family: -apple-system, BlinkMacSystemFont, ‘Segoe UI’, ‘Roboto’, sans-serif;
margin: 0;
padding: 0;
}
.cfb-chart-embed-cfb-chart-1766345933069-20pt4ndz2 .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-1766345933069-20pt4ndz2 .chart-header {
padding: 18px 24px 14px;
border-bottom: 1px solid #e5e5e5;
background: white;
}
.cfb-chart-embed-cfb-chart-1766345933069-20pt4ndz2 .chart-title {
font-size: 18px;
font-weight: 600;
color: #171717;
margin: 0;
}
.cfb-chart-embed-cfb-chart-1766345933069-20pt4ndz2 .chart-subtitle {
font-size: 11px;
font-weight: 400;
color: #737373;
margin: 4px 0 0 0;
}
.cfb-chart-embed-cfb-chart-1766345933069-20pt4ndz2 .chart-content {
padding: 20px 24px 24px !important;
}
.cfb-chart-embed-cfb-chart-1766345933069-20pt4ndz2 .chart-content { height: 325px; }
@media (max-width: 640px) {
.cfb-chart-embed-cfb-chart-1766345933069-20pt4ndz2 .chart-content {
padding: 12px 16px 20px !important;
height: 280px !important;
}
.cfb-chart-embed-cfb-chart-1766345933069-20pt4ndz2 .chart-header {
padding: 12px 16px 12px !important;
}
.cfb-chart-embed-cfb-chart-1766345933069-20pt4ndz2 .embed-footer-top {
padding: 8px 12px !important;
}
.cfb-chart-embed-cfb-chart-1766345933069-20pt4ndz2 .data-definitions {
padding: 12px !important;
}
}
.cfb-chart-embed-cfb-chart-1766345933069-20pt4ndz2 .embed-footer {
border-top: 1px solid #e5e5e5;
font-size: 12px;
color: #737373;
}
.cfb-chart-embed-cfb-chart-1766345933069-20pt4ndz2 .embed-footer-top {
display: flex;
justify-content: space-between;
align-items: center;
padding: 12px 16px;
}
.cfb-chart-embed-cfb-chart-1766345933069-20pt4ndz2 .embed-footer-link {
color: #737373;
text-decoration: none;
font-weight: 500;
}
.cfb-chart-embed-cfb-chart-1766345933069-20pt4ndz2 .embed-footer-link:hover {
color: #525252;
text-decoration: underline;
}
.cfb-chart-embed-cfb-chart-1766345933069-20pt4ndz2 .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-1766345933069-20pt4ndz2 .data-definitions-toggle:hover {
color: #525252;
}
.cfb-chart-embed-cfb-chart-1766345933069-20pt4ndz2 .caret {
transition: transform 0.2s ease;
font-size: 10px;
}
.cfb-chart-embed-cfb-chart-1766345933069-20pt4ndz2 .caret.expanded {
transform: rotate(180deg);
}
.cfb-chart-embed-cfb-chart-1766345933069-20pt4ndz2 .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-1766345933069-20pt4ndz2 .data-definitions.expanded {
display: block;
}
.cfb-chart-embed-cfb-chart-1766345933069-20pt4ndz2 .data-definitions ul {
margin: 0;
padding-left: 0;
list-style: none;
}
.cfb-chart-embed-cfb-chart-1766345933069-20pt4ndz2 .data-definitions li {
margin-bottom: 4px;
}
SR and XR by Team
Alabama vs. Oklahoma • Dec 19, 2025
- 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_1766345933069_20pt4ndz2() {
const definitions = document.getElementById(‘dataDefinitions_cfb-chart-1766345933069-20pt4ndz2’);
const caret = document.getElementById(‘caret_cfb-chart-1766345933069-20pt4ndz2’);
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-1766345933069-20pt4ndz2’);
if (canvas && canvas.parentNode) {
canvas.parentNode.innerHTML = ‘
‘;
}
}
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-1766345933069-20pt4ndz2’);
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”: 129,
“y”: 0.42
},
{
“x”: 129,
“y”: 0
}
],
“backgroundColor”: “rgba(0,0,0,0.03)”,
“borderColor”: “transparent”,
“pointRadius”: 0,
“fill”: true,
“tension”: 0,
“showLine”: true,
“datalabels”: {
“display”: false
}
},
{
“data”: [
{
“x”: 10,
“y”: 0,
“text”: “D.Hill rush middle for 1 yard gain to the UA13 (#32 R.Thomas)”
},
{
“x”: 11,
“y”: 0,
“text”: “T.Simpson pass complete short left to #1 I.Horton caught at UA17, for 4 yards to the UA17 (#5 K.Daniels)”
},
{
“x”: 12,
“y”: 0,
“text”: “T.Simpson pass incomplete short left to #1 I.Horton thrown to UA24 broken up by #4 C.Guillory”
},
{
“x”: 21,
“y”: 0,
“text”: “T.Simpson sacked for loss of 8 yards to the UA06 (#10 K.Lewis)”
},
{
“x”: 22,
“y”: 0,
“text”: “T.Simpson pass complete short middle to #80 J.Cuevas caught at UA10, for 8 yards to the UA14 (#3 R.Spears-Jennings; #38 O.Heinecke)”
},
{
“x”: 23,
“y”: 0,
“text”: “T.Simpson pass incomplete short left to #17 L.Brooks thrown to UA33 broken up by #23 E.Bowen QB hurried by #38 O.Heinecke”
},
{
“x”: 29,
“y”: 0,
“text”: “J.Miller rush left for 7 yards gain to the UA32 (#25 M.Boganowski)”
},
{
“x”: 30,
“y”: 0,
“text”: “J.Miller rush middle for 0 yards to the UA32 (#4 C.Guillory)”
},
{
“x”: 31,
“y”: 0,
“text”: “T.Simpson pass incomplete short left to #1 I.Horton thrown to UA40”
},
{
“x”: 40,
“y”: 0,
“text”: “T.Simpson pass incomplete short left to #2 R.Williams thrown to UA36 QB hurried by #0 D.Stone”
},
{
“x”: 41,
“y”: 0,
“text”: “T.Simpson pass complete short right to #17 L.Brooks caught at UA29, for 5 yards to the UA30 (#5 K.Daniels; #38 O.Heinecke)”
},
{
“x”: 42,
“y”: 0.08333333333333333,
“text”: “T.Simpson pass complete deep left to #17 L.Brooks caught at OU45, for 29 yards to the OU41, End Of Play, 1ST DOWN”
},
{
“x”: 43,
“y”: 0.07692307692307693,
“text”: “T.Simpson pass incomplete short left to #80 J.Cuevas thrown to OU44 QB hurried by #32 R.Thomas”
},
{
“x”: 44,
“y”: 0.14285714285714285,
“text”: “T.Simpson pass complete short middle to #80 J.Cuevas caught at OU24, for 23 yards to the OU18 (#22 P.Bowen), 1ST DOWN”
},
{
“x”: 45,
“y”: 0.13333333333333333,
“text”: “T.Simpson pass incomplete short left to #80 J.Cuevas thrown to OU12”
},
{
“x”: 46,
“y”: 0.125,
“text”: “J.Miller rush left for 4 yards gain to the OU14 (#7 S.Omosigho), out of bounds”
},
{
“x”: 47,
“y”: 0.11764705882352941,
“text”: “T.Simpson pass complete short right to #5 G.Bernard caught at OU10, for 4 yards to the OU10, End Of Play”
},
{
“x”: 48,
“y”: 0.1111111111111111,
“text”: “T.Simpson pass complete short left to #17 L.Brooks caught at OU06, for 10 yards to the OU00 TOUCHDOWN, clock 06:52, 1ST DOWN #31 C.Talty kick attempt good (H: #38 B.Doud, LS: #45 D.Bird) PENALTY OU Holding declined”
},
{
“x”: 53,
“y”: 0.10526315789473684,
“text”: “T.Simpson pass complete short middle to #1 I.Horton caught at OU16, for 14 yards to the OU16 (#23 E.Bowen), 1ST DOWN”
},
{
“x”: 54,
“y”: 0.1,
“text”: “T.Simpson sacked for loss of 7 yards to the OU23 (#97 M.Jones Jr.)”
},
{
“x”: 55,
“y”: 0.09523809523809523,
“text”: “T.Simpson pass complete short right to #1 I.Horton caught at OU18, for 6 yards to the OU17 (#22 P.Bowen; #23 E.Bowen)”
},
{
“x”: 56,
“y”: 0.09090909090909091,
“text”: “T.Simpson pass incomplete short middle to #20 D.Washington thrown to OU17 QB hurried by #56 G.Halton and #0 D.Stone”
},
{
“x”: 67,
“y”: 0.08695652173913043,
“text”: “T.Simpson pass complete short right to #5 G.Bernard caught at UA25, for 12 yards to the UA37 (#44 T.Wein), 1ST DOWN”
},
{
“x”: 68,
“y”: 0.08333333333333333,
“text”: “T.Simpson pass complete short right to #1 I.Horton caught at UA40, for 4 yards to the UA41 (#23 E.Bowen), out of bounds”
},
{
“x”: 69,
“y”: 0.08,
“text”: “T.Simpson pass incomplete short right to #1 I.Horton thrown to OU45”
},
{
“x”: 70,
“y”: 0.07692307692307693,
“text”: “T.Simpson pass incomplete short right to #2 R.Williams thrown to OU45”
},
{
“x”: 74,
“y”: 0.1111111111111111,
“text”: “D.Hill rush left for 30 yards gain to the OU30 (#3 R.Spears-Jennings; #23 E.Bowen), 1ST DOWN”
},
{
“x”: 75,
“y”: 0.10714285714285714,
“text”: “T.Simpson pass incomplete short right to #17 L.Brooks thrown to OU25”
},
{
“x”: 76,
“y”: 0.13793103448275862,
“text”: “T.Simpson pass complete deep left to #17 L.Brooks caught at OU00, for 30 yards to the OU00 TOUCHDOWN, clock 11:21, 1ST DOWN #31 C.Talty kick attempt good (H: #38 B.Doud, LS: #45 D.Bird)”
},
{
“x”: 80,
“y”: 0.13333333333333333,
“text”: “T.Simpson rush left for 0 yards to the UA38 (#65 J.Jackson; #7 S.Omosigho)”
},
{
“x”: 81,
“y”: 0.12903225806451613,
“text”: “T.Simpson pass complete short middle to #80 J.Cuevas caught at UA45, for 8 yards to the UA46 (#5 K.Daniels)”
},
{
“x”: 82,
“y”: 0.125,
“text”: “G.Bernard rush left for 0 yards to the OU44 (#56 G.Halton)”
},
{
“x”: 83,
“y”: 0.12121212121212122,
“text”: “T.Simpson pass complete short right to #17 L.Brooks caught at OU40, for 5 yards to the OU39 (#25 M.Boganowski; #13 R.Powers III)”
},
{
“x”: 84,
“y”: 0.11764705882352941,
“text”: “T.Simpson rush left for 13 yards gain to the OU26 (#13 R.Powers III), out of bounds, 1ST DOWN”
},
{
“x”: 85,
“y”: 0.11428571428571428,
“text”: “T.Simpson pass complete short left to #80 J.Cuevas caught at OU22, for 4 yards to the OU22 (#32 R.Thomas), out of bounds”
},
{
“x”: 86,
“y”: 0.1111111111111111,
“text”: “T.Simpson pass incomplete short left to #81 K.Edwards thrown to OU22”
},
{
“x”: 87,
“y”: 0.10810810810810811,
“text”: “J.Miller rush middle for 0 yards to the OU22 (#56 G.Halton; #10 K.Lewis)”
},
{
“x”: 96,
“y”: 0.10526315789473684,
“text”: “J.Miller rush middle for 1 yard gain to the UA26 (#65 J.Jackson; #52 D.Williams)”
},
{
“x”: 97,
“y”: 0.1282051282051282,
“text”: “T.Simpson pass complete deep right to #1 I.Horton caught at OU39, for 37 yards to the OU37 (#23 E.Bowen), out of bounds, 1ST DOWN”
},
{
“x”: 98,
“y”: 0.125,
“text”: “J.Miller rush left for 0 yards to the OU37 (#13 R.Powers III; #32 R.Thomas)”
},
{
“x”: 99,
“y”: 0.12195121951219512,
“text”: “T.Simpson sacked for loss of 9 yards to the OU47 (#38 O.Heinecke)”
},
{
“x”: 103,
“y”: 0.11904761904761904,
“text”: “D.Hill rush middle for 6 yards gain to the OU29 (#5 K.Daniels)”
},
{
“x”: 104,
“y”: 0.13953488372093023,
“text”: “T.Simpson pass complete short right to #5 G.Bernard caught at OU10, for 24 yards to the OU05 (#19 J.Johnson), 1ST DOWN”
},
{
“x”: 105,
“y”: 0.13636363636363635,
“text”: “Shotgun rush left for 1 yard loss to the OU06 (#65 J.Jackson)”
},
{
“x”: 106,
“y”: 0.13333333333333333,
“text”: “D.Hill rush middle for 6 yards gain to the OU00 TOUCHDOWN, clock 07:24 Timeout Alabama, clock 07:30 #31 C.Talty kick attempt good (H: #38 B.Doud, LS: #45 D.Bird)”
},
{
“x”: 110,
“y”: 0.13043478260869565,
“text”: “D.Hill rush right for 2 yards gain to the UA32 (#38 O.Heinecke)”
},
{
“x”: 111,
“y”: 0.1276595744680851,
“text”: “D.Hill rush middle for 3 yards gain to the UA35 (#10 K.Lewis)”
},
{
“x”: 112,
“y”: 0.125,
“text”: “T.Simpson sacked for loss of 11 yards to the UA24 (#44 T.Wein)”
},
{
“x”: 120,
“y”: 0.12244897959183673,
“text”: “D.Hill rush middle for 0 yards to the UA20 (#38 O.Heinecke; #4 C.Guillory)”
},
{
“x”: 121,
“y”: 0.12,
“text”: “D.Hill rush left for 4 yards loss to the UA16 (#38 O.Heinecke)”
},
{
“x”: 122,
“y”: 0.11764705882352941,
“text”: “T.Simpson pass complete short right to #2 R.Williams caught at UA15, for 5 yards to the UA21 (#22 P.Bowen)”
},
{
“x”: 127,
“y”: 0.11538461538461539,
“text”: “Kneel down by Alabama at UA31 for loss of 3 yards”
},
{
“x”: 128,
“y”: 0.11320754716981132,
“text”: “Kneel down by Alabama at UA32 for loss of 2 yards”
},
{
“x”: 129,
“y”: 0.1111111111111111,
“text”: “Kneel down by Alabama at UA30 for loss of 2 yards”
}
],
“label”: “Alabama XR”,
“borderColor”: “rgba(101, 0, 20, 0.8)”,
“borderWidth”: 2.2,
“fill”: false
},
{
“data”: [
{
“x”: 10,
“y”: 0,
“text”: “D.Hill rush middle for 1 yard gain to the UA13 (#32 R.Thomas)”
},
{
“x”: 11,
“y”: 0,
“text”: “T.Simpson pass complete short left to #1 I.Horton caught at UA17, for 4 yards to the UA17 (#5 K.Daniels)”
},
{
“x”: 12,
“y”: 0,
“text”: “T.Simpson pass incomplete short left to #1 I.Horton thrown to UA24 broken up by #4 C.Guillory”
},
{
“x”: 21,
“y”: 0,
“text”: “T.Simpson sacked for loss of 8 yards to the UA06 (#10 K.Lewis)”
},
{
“x”: 22,
“y”: 0,
“text”: “T.Simpson pass complete short middle to #80 J.Cuevas caught at UA10, for 8 yards to the UA14 (#3 R.Spears-Jennings; #38 O.Heinecke)”
},
{
“x”: 23,
“y”: 0,
“text”: “T.Simpson pass incomplete short left to #17 L.Brooks thrown to UA33 broken up by #23 E.Bowen QB hurried by #38 O.Heinecke”
},
{
“x”: 29,
“y”: 0.14285714285714285,
“text”: “J.Miller rush left for 7 yards gain to the UA32 (#25 M.Boganowski)”
},
{
“x”: 30,
“y”: 0.125,
“text”: “J.Miller rush middle for 0 yards to the UA32 (#4 C.Guillory)”
},
{
“x”: 31,
“y”: 0.1111111111111111,
“text”: “T.Simpson pass incomplete short left to #1 I.Horton thrown to UA40”
},
{
“x”: 40,
“y”: 0.1,
“text”: “T.Simpson pass incomplete short left to #2 R.Williams thrown to UA36 QB hurried by #0 D.Stone”
},
{
“x”: 41,
“y”: 0.09090909090909091,
“text”: “T.Simpson pass complete short right to #17 L.Brooks caught at UA29, for 5 yards to the UA30 (#5 K.Daniels; #38 O.Heinecke)”
},
{
“x”: 42,
“y”: 0.16666666666666666,
“text”: “T.Simpson pass complete deep left to #17 L.Brooks caught at OU45, for 29 yards to the OU41, End Of Play, 1ST DOWN”
},
{
“x”: 43,
“y”: 0.15384615384615385,
“text”: “T.Simpson pass incomplete short left to #80 J.Cuevas thrown to OU44 QB hurried by #32 R.Thomas”
},
{
“x”: 44,
“y”: 0.21428571428571427,
“text”: “T.Simpson pass complete short middle to #80 J.Cuevas caught at OU24, for 23 yards to the OU18 (#22 P.Bowen), 1ST DOWN”
},
{
“x”: 45,
“y”: 0.2,
“text”: “T.Simpson pass incomplete short left to #80 J.Cuevas thrown to OU12”
},
{
“x”: 46,
“y”: 0.1875,
“text”: “J.Miller rush left for 4 yards gain to the OU14 (#7 S.Omosigho), out of bounds”
},
{
“x”: 47,
“y”: 0.17647058823529413,
“text”: “T.Simpson pass complete short right to #5 G.Bernard caught at OU10, for 4 yards to the OU10, End Of Play”
},
{
“x”: 48,
“y”: 0.2222222222222222,
“text”: “T.Simpson pass complete short left to #17 L.Brooks caught at OU06, for 10 yards to the OU00 TOUCHDOWN, clock 06:52, 1ST DOWN #31 C.Talty kick attempt good (H: #38 B.Doud, LS: #45 D.Bird) PENALTY OU Holding declined”
},
{
“x”: 53,
“y”: 0.2631578947368421,
“text”: “T.Simpson pass complete short middle to #1 I.Horton caught at OU16, for 14 yards to the OU16 (#23 E.Bowen), 1ST DOWN”
},
{
“x”: 54,
“y”: 0.25,
“text”: “T.Simpson sacked for loss of 7 yards to the OU23 (#97 M.Jones Jr.)”
},
{
“x”: 55,
“y”: 0.23809523809523808,
“text”: “T.Simpson pass complete short right to #1 I.Horton caught at OU18, for 6 yards to the OU17 (#22 P.Bowen; #23 E.Bowen)”
},
{
“x”: 56,
“y”: 0.22727272727272727,
“text”: “T.Simpson pass incomplete short middle to #20 D.Washington thrown to OU17 QB hurried by #56 G.Halton and #0 D.Stone”
},
{
“x”: 67,
“y”: 0.2608695652173913,
“text”: “T.Simpson pass complete short right to #5 G.Bernard caught at UA25, for 12 yards to the UA37 (#44 T.Wein), 1ST DOWN”
},
{
“x”: 68,
“y”: 0.25,
“text”: “T.Simpson pass complete short right to #1 I.Horton caught at UA40, for 4 yards to the UA41 (#23 E.Bowen), out of bounds”
},
{
“x”: 69,
“y”: 0.24,
“text”: “T.Simpson pass incomplete short right to #1 I.Horton thrown to OU45”
},
{
“x”: 70,
“y”: 0.23076923076923078,
“text”: “T.Simpson pass incomplete short right to #2 R.Williams thrown to OU45”
},
{
“x”: 74,
“y”: 0.25925925925925924,
“text”: “D.Hill rush left for 30 yards gain to the OU30 (#3 R.Spears-Jennings; #23 E.Bowen), 1ST DOWN”
},
{
“x”: 75,
“y”: 0.25,
“text”: “T.Simpson pass incomplete short right to #17 L.Brooks thrown to OU25”
},
{
“x”: 76,
“y”: 0.27586206896551724,
“text”: “T.Simpson pass complete deep left to #17 L.Brooks caught at OU00, for 30 yards to the OU00 TOUCHDOWN, clock 11:21, 1ST DOWN #31 C.Talty kick attempt good (H: #38 B.Doud, LS: #45 D.Bird)”
},
{
“x”: 80,
“y”: 0.26666666666666666,
“text”: “T.Simpson rush left for 0 yards to the UA38 (#65 J.Jackson; #7 S.Omosigho)”
},
{
“x”: 81,
“y”: 0.2903225806451613,
“text”: “T.Simpson pass complete short middle to #80 J.Cuevas caught at UA45, for 8 yards to the UA46 (#5 K.Daniels)”
},
{
“x”: 82,
“y”: 0.28125,
“text”: “G.Bernard rush left for 0 yards to the OU44 (#56 G.Halton)”
},
{
“x”: 83,
“y”: 0.2727272727272727,
“text”: “T.Simpson pass complete short right to #17 L.Brooks caught at OU40, for 5 yards to the OU39 (#25 M.Boganowski; #13 R.Powers III)”
},
{
“x”: 84,
“y”: 0.29411764705882354,
“text”: “T.Simpson rush left for 13 yards gain to the OU26 (#13 R.Powers III), out of bounds, 1ST DOWN”
},
{
“x”: 85,
“y”: 0.2857142857142857,
“text”: “T.Simpson pass complete short left to #80 J.Cuevas caught at OU22, for 4 yards to the OU22 (#32 R.Thomas), out of bounds”
},
{
“x”: 86,
“y”: 0.2777777777777778,
“text”: “T.Simpson pass incomplete short left to #81 K.Edwards thrown to OU22”
},
{
“x”: 87,
“y”: 0.2702702702702703,
“text”: “J.Miller rush middle for 0 yards to the OU22 (#56 G.Halton; #10 K.Lewis)”
},
{
“x”: 96,
“y”: 0.2631578947368421,
“text”: “J.Miller rush middle for 1 yard gain to the UA26 (#65 J.Jackson; #52 D.Williams)”
},
{
“x”: 97,
“y”: 0.28205128205128205,
“text”: “T.Simpson pass complete deep right to #1 I.Horton caught at OU39, for 37 yards to the OU37 (#23 E.Bowen), out of bounds, 1ST DOWN”
},
{
“x”: 98,
“y”: 0.275,
“text”: “J.Miller rush left for 0 yards to the OU37 (#13 R.Powers III; #32 R.Thomas)”
},
{
“x”: 99,
“y”: 0.2682926829268293,
“text”: “T.Simpson sacked for loss of 9 yards to the OU47 (#38 O.Heinecke)”
},
{
“x”: 103,
“y”: 0.2857142857142857,
“text”: “D.Hill rush middle for 6 yards gain to the OU29 (#5 K.Daniels)”
},
{
“x”: 104,
“y”: 0.3023255813953488,
“text”: “T.Simpson pass complete short right to #5 G.Bernard caught at OU10, for 24 yards to the OU05 (#19 J.Johnson), 1ST DOWN”
},
{
“x”: 105,
“y”: 0.29545454545454547,
“text”: “Shotgun rush left for 1 yard loss to the OU06 (#65 J.Jackson)”
},
{
“x”: 106,
“y”: 0.3111111111111111,
“text”: “D.Hill rush middle for 6 yards gain to the OU00 TOUCHDOWN, clock 07:24 Timeout Alabama, clock 07:30 #31 C.Talty kick attempt good (H: #38 B.Doud, LS: #45 D.Bird)”
},
{
“x”: 110,
“y”: 0.30434782608695654,
“text”: “D.Hill rush right for 2 yards gain to the UA32 (#38 O.Heinecke)”
},
{
“x”: 111,
“y”: 0.2978723404255319,
“text”: “D.Hill rush middle for 3 yards gain to the UA35 (#10 K.Lewis)”
},
{
“x”: 112,
“y”: 0.2916666666666667,
“text”: “T.Simpson sacked for loss of 11 yards to the UA24 (#44 T.Wein)”
},
{
“x”: 120,
“y”: 0.2857142857142857,
“text”: “D.Hill rush middle for 0 yards to the UA20 (#38 O.Heinecke; #4 C.Guillory)”
},
{
“x”: 121,
“y”: 0.28,
“text”: “D.Hill rush left for 4 yards loss to the UA16 (#38 O.Heinecke)”
},
{
“x”: 122,
“y”: 0.27450980392156865,
“text”: “T.Simpson pass complete short right to #2 R.Williams caught at UA15, for 5 yards to the UA21 (#22 P.Bowen)”
},
{
“x”: 127,
“y”: 0.2692307692307692,
“text”: “Kneel down by Alabama at UA31 for loss of 3 yards”
},
{
“x”: 128,
“y”: 0.2641509433962264,
“text”: “Kneel down by Alabama at UA32 for loss of 2 yards”
},
{
“x”: 129,
“y”: 0.25925925925925924,
“text”: “Kneel down by Alabama at UA30 for loss of 2 yards”
}
],
“label”: “Alabama SR”,
“borderColor”: “rgba(175, 40, 60, 0.8)”,
“borderWidth”: 2.2,
“fill”: false
},
{
“data”: [
{
“x”: 1,
“y”: 0,
“text”: “J.Mateer rush right for 0 yards to the OU25 (#2 Z.Brown)”
},
{
“x”: 2,
“y”: 0,
“text”: “T.Blaylock rush left for 4 yards gain to the OU29 (#10 J.Jefferson)”
},
{
“x”: 3,
“y”: 0,
“text”: “J.Mateer pass complete short right to #4 D.Burks caught at OU42, for 14 yards to the OU43, End Of Play, 1ST DOWN”
},
{
“x”: 4,
“y”: 0,
“text”: “T.Blaylock rush right for 6 yards gain to the OU49 (#10 J.Jefferson)”
},
{
“x”: 5,
“y”: 0,
“text”: “J.Mateer rush left for 2 yards gain to the UA49 (#0 D.Lawson)”
},
{
“x”: 6,
“y”: 0,
“text”: “J.Mateer rush for 5 yards gain to the UA44 (#3 K.Sabb; #1 D.Jackson), 1ST DOWN”
},
{
“x”: 7,
“y”: 0,
“text”: “J.Mateer pass incomplete short right to #4 D.Burks thrown to UA33 broken up by #2 Z.Brown”
},
{
“x”: 8,
“y”: 0,
“text”: “T.Blaylock rush middle for 0 yards to the UA44 (#90 L.Simmons)”
},
{
“x”: 9,
“y”: 0,
“text”: “J.Mateer pass incomplete short right to #6 T.Blaylock thrown to UA46”
},
{
“x”: 13,
“y”: 0,
“text”: “T.Blaylock rush right for 2 yards gain to the OU43 (#41 N.Hill-Green)”
},
{
“x”: 14,
“y”: 0.09090909090909091,
“text”: “J.Mateer pass complete short middle to #84 J.Carter caught at UA38, for 21 yards to the UA36 (#3 K.Sabb), 1ST DOWN”
},
{
“x”: 15,
“y”: 0.08333333333333333,
“text”: “J.Mateer pass incomplete deep left to #11 J.Gibson thrown to UA16”
},
{
“x”: 16,
“y”: 0.07692307692307693,
“text”: “J.Mateer rush left for 11 yards gain to the UA25 (#3 K.Sabb), 1ST DOWN”
},
{
“x”: 17,
“y”: 0.07142857142857142,
“text”: “T.Blaylock rush middle for 0 yards to the UA25 (#31 K.Keeley; #0 D.Lawson)”
},
{
“x”: 18,
“y”: 0.06666666666666667,
“text”: “J.Mateer pass incomplete short right thrown to UA15 QB hurried by #16 R.Morgan”
},
{
“x”: 19,
“y”: 0.125,
“text”: “J.Mateer pass complete short middle to #24 X.Robinson caught at UA23, for 17 yards to the UA08 (#0 D.Lawson), out of bounds, 1ST DOWN”
},
{
“x”: 20,
“y”: 0.11764705882352941,
“text”: “J.Mateer rush middle for 8 yards gain to the UA00 TOUCHDOWN, clock 05:29 #29 T.Sandell kick attempt good (H: #87 J.Ulrich, LS: #49 B.Anderson)”
},
{
“x”: 24,
“y”: 0.1111111111111111,
“text”: “J.Mateer pass complete short left to #12 J.Kanak caught at UA40, for 8 yards to the UA38 (#13 I.Taylor)”
},
{
“x”: 25,
“y”: 0.10526315789473684,
“text”: “T.Blaylock rush middle for 3 yards gain to the UA35 (#10 J.Jefferson; #13 I.Taylor), 1ST DOWN”
},
{
“x”: 26,
“y”: 0.1,
“text”: “T.Blaylock rush right for 6 yards gain to the UA29 (#41 N.Hill-Green)”
},
{
“x”: 27,
“y”: 0.09523809523809523,
“text”: “T.Blaylock rush right for 1 yard gain to the UA28 (#5 D.Lee Jr.) PENALTY OU UNS: Unsportsmanlike Conduct (#55 E.Pierre-Louis) 15 yards from UA28 to UA43”
},
{
“x”: 28,
“y”: 0.09090909090909091,
“text”: “J.Mateer pass complete short left to #5 I.Sategna III caught at UA41, for 10 yards to the UA33 (#4 Q.Russaw; #10 J.Jefferson)”
},
{
“x”: 32,
“y”: 0.08695652173913043,
“text”: “J.Mateer pass incomplete short middle to #5 I.Sategna III thrown to OU44 broken up by #7 D.Jones”
},
{
“x”: 33,
“y”: 0.08333333333333333,
“text”: “X.Robinson rush right for 2 yards gain to the OU39 (#11 J.Renaud; #8 J.Hill)”
},
{
“x”: 34,
“y”: 0.12,
“text”: “J.Mateer pass complete short right to #4 D.Burks caught at UA45, for 16 yards to the UA45, out of bounds at UA45, 1ST DOWN”
},
{
“x”: 35,
“y”: 0.15384615384615385,
“text”: “J.Mateer pass complete short middle to #4 D.Burks caught at UA28, for 18 yards to the UA28, End Of Play, 1ST DOWN”
},
{
“x”: 36,
“y”: 0.14814814814814814,
“text”: “X.Robinson rush left for 1 yard loss to the UA29 (#10 J.Jefferson)”
},
{
“x”: 37,
“y”: 0.14285714285714285,
“text”: “J.Mateer pass complete short right to #4 D.Burks caught at UA26, for 6 yards to the UA23 (#2 Z.Brown)”
},
{
“x”: 38,
“y”: 0.1724137931034483,
“text”: “J.Mateer pass complete short middle to #88 J.Jordan caught at UA11, for 16 yards to the UA07 (#7 D.Jones), 1ST DOWN”
},
{
“x”: 39,
“y”: 0.16666666666666666,
“text”: “J.Mateer pass complete short middle to #5 I.Sategna III caught at UA00, for 7 yards to the UA00 TOUCHDOWN, clock 10:51 #29 T.Sandell kick attempt good (H: #87 J.Ulrich, LS: #49 B.Anderson)”
},
{
“x”: 49,
“y”: 0.1935483870967742,
“text”: “J.Mateer pass complete short left to #4 D.Burks for 15 yards to the OU40 (#3 K.Sabb; #18 B.Hubbard), 1ST DOWN”
},
{
“x”: 50,
“y”: 0.1875,
“text”: “J.Mateer rush right for 4 yards gain to the OU44 (#18 B.Hubbard)”
},
{
“x”: 51,
“y”: 0.18181818181818182,
“text”: “J.Mateer pass complete short right to #11 J.Gibson caught at OU47, for 3 yards to the OU47 (#1 D.Jackson)”
},
{
“x”: 52,
“y”: 0.17647058823529413,
“text”: “J.Mateer pass incomplete deep left to #24 X.Robinson thrown to UA20”
},
{
“x”: 57,
“y”: 0.17142857142857143,
“text”: “J.Mateer rush middle for 2 yards gain to the OU27 (#4 Q.Russaw; #11 J.Renaud)”
},
{
“x”: 58,
“y”: 0.19444444444444445,
“text”: “J.Mateer pass complete deep middle to #84 J.Carter caught at OU48, for 22 yards to the OU49, End Of Play, 1ST DOWN”
},
{
“x”: 59,
“y”: 0.1891891891891892,
“text”: “J.Mateer sacked for loss of 3 yards to the OU46 (#10 J.Jefferson)”
},
{
“x”: 60,
“y”: 0.18421052631578946,
“text”: “J.Mateer pass intercepted by #2 Z.Brown at UA50 #2 Z.Brown return 50 yards to the OU00 TOUCHDOWN, clock 01:18 Timeout Alabama, clock 01:26 #31 C.Talty kick attempt good (H: #38 B.Doud, LS: #45 D.Bird)”
},
{
“x”: 61,
“y”: 0.1794871794871795,
“text”: “J.Mateer pass incomplete short left to #5 I.Sategna III thrown to OU23 broken up by #23 J.Smith”
},
{
“x”: 62,
“y”: 0.175,
“text”: “J.Mateer pass complete short left to #9 K.Lewis caught at OU29, for 5 yards to the OU30 (#1 D.Jackson)”
},
{
“x”: 63,
“y”: 0.17073170731707318,
“text”: “J.Mateer rush middle for 1 yard gain to the OU31 (#24 N.Carter; #42 Y.Pierre) PENALTY UA Sideline Inteference 16 yards from OU31 to OU47, 1ST DOWN”
},
{
“x”: 64,
“y”: 0.16666666666666666,
“text”: “J.Mateer pass complete short right to #84 J.Carter caught at UA50, for 3 yards to the OU50, out of bounds at UA50”
},
{
“x”: 65,
“y”: 0.16279069767441862,
“text”: “J.Mateer rush middle for 3 yards loss to the OU47 (#42 Y.Pierre)”
},
{
“x”: 66,
“y”: 0.1590909090909091,
“text”: “J.Mateer pass complete short right to #6 T.Blaylock caught at OU48, for 6 yards to the UA47 (#5 D.Lee Jr.; #0 D.Lawson)”
},
{
“x”: 71,
“y”: 0.15555555555555556,
“text”: “T.Blaylock rush middle for 4 yards gain to the OU29 (#0 D.Lawson; #41 N.Hill-Green)”
},
{
“x”: 72,
“y”: 0.15217391304347827,
“text”: “J.Mateer pass incomplete short middle to #4 D.Burks thrown to OU35”
},
{
“x”: 73,
“y”: 0.14893617021276595,
“text”: “J.Mateer pass incomplete short middle to #5 I.Sategna III thrown to OU34”
},
{
“x”: 77,
“y”: 0.14583333333333334,
“text”: “J.Mateer sacked for loss of 5 yards to the OU20 (#31 K.Keeley)”
},
{
“x”: 78,
“y”: 0.14285714285714285,
“text”: “J.Mateer sacked for loss of 7 yards to the OU13 (#42 Y.Pierre, #90 L.Simmons)”
},
{
“x”: 79,
“y”: 0.14,
“text”: “J.Mateer pass complete short middle to #6 T.Blaylock caught at OU14, for 12 yards to the OU25 (#0 D.Lawson)”
},
{
“x”: 88,
“y”: 0.13725490196078433,
“text”: “J.Mateer rush left for 7 yards gain to the OU32 (#10 J.Jefferson)”
},
{
“x”: 89,
“y”: 0.1346153846153846,
“text”: “J.Mateer rush left for 2 yards gain to the OU34 (#88 I.Faga)”
},
{
“x”: 90,
“y”: 0.1320754716981132,
“text”: “J.Mateer rush middle for 1 yard gain to the OU35 (#96 T.Keenan III), 1ST DOWN”
},
{
“x”: 91,
“y”: 0.12962962962962962,
“text”: “X.Robinson rush right for 3 yards gain to the OU38 (#0 D.Lawson)”
},
{
“x”: 92,
“y”: 0.12727272727272726,
“text”: “T.Blaylock rush middle for 5 yards gain to the OU43 (#18 B.Hubbard; #0 D.Lawson)”
},
{
“x”: 93,
“y”: 0.125,
“text”: “J.Mateer pass complete short right to #6 T.Blaylock caught at OU45, for 5 yards to the OU48 (#2 Z.Brown), 1ST DOWN”
},
{
“x”: 94,
“y”: 0.12280701754385964,
“text”: “J.Mateer rush left for 0 yards to the OU48 (#10 J.Jefferson)”
},
{
“x”: 95,
“y”: 0.13793103448275862,
“text”: “J.Mateer pass complete short middle to #4 D.Burks caught at UA18, for 37 yards to the UA00 TOUCHDOWN, clock 14:45, 1ST DOWN #29 T.Sandell kick attempt good (H: #87 J.Ulrich, LS: #49 B.Anderson)”
},
{
“x”: 100,
“y”: 0.13559322033898305,
“text”: “J.Mateer rush right for 1 yard gain to the OU08 (#42 Y.Pierre)”
},
{
“x”: 101,
“y”: 0.13333333333333333,
“text”: “T.Blaylock rush left for 5 yards gain to the OU13 (#3 K.Sabb; #18 B.Hubbard)”
},
{
“x”: 102,
“y”: 0.13114754098360656,
“text”: “J.Mateer pass incomplete short middle to #6 T.Blaylock thrown to OU10 broken up by #0 D.Lawson”
},
{
“x”: 107,
“y”: 0.12903225806451613,
“text”: “J.Mateer pass incomplete short left to #5 I.Sategna III thrown to OU35 broken up by #31 K.Keeley”
},
{
“x”: 108,
“y”: 0.12698412698412698,
“text”: “J.Mateer pass complete short left to #4 D.Burks caught at OU21, for 2 yards to the OU27 (#1 D.Jackson)”
},
{
“x”: 109,
“y”: 0.125,
“text”: “J.Mateer sacked for loss of 8 yards to the OU19 (#17 K.Collins)”
},
{
“x”: 113,
“y”: 0.12307692307692308,
“text”: “J.Mateer pass incomplete short right thrown to OU50 QB hurried by #24 N.Carter and #96 T.Keenan III”
},
{
“x”: 114,
“y”: 0.12121212121212122,
“text”: “J.Mateer pass complete short middle to #12 J.Kanak caught at OU43, for 5 yards to the OU43 (#18 B.Hubbard)”
},
{
“x”: 115,
“y”: 0.11940298507462686,
“text”: “J.Mateer pass incomplete short middle to #10 K.Lewis thrown to OU46”
},
{
“x”: 116,
“y”: 0.1323529411764706,
“text”: “J.Mateer pass complete deep left to #11 J.Gibson caught at UA37, for 38 yards to the UA19 (#7 D.Jones), 1ST DOWN”
},
{
“x”: 117,
“y”: 0.13043478260869565,
“text”: “J.Mateer pass complete short middle to #6 T.Blaylock caught at UA15, for 4 yards to the UA15 (#10 J.Jefferson)”
},
{
“x”: 118,
“y”: 0.12857142857142856,
“text”: “J.Mateer sacked for loss of 3 yards to the UA18 (#0 D.Lawson)”
},
{
“x”: 119,
“y”: 0.1267605633802817,
“text”: “J.Mateer pass incomplete short right thrown to UA10 QB hurried by #41 N.Hill-Green”
},
{
“x”: 123,
“y”: 0.125,
“text”: “J.Mateer pass complete short left to #12 J.Kanak caught at OU48, for 4 yards to the UA48 (#0 D.Lawson), out of bounds”
},
{
“x”: 124,
“y”: 0.1232876712328767,
“text”: “J.Mateer pass complete short middle to #6 T.Blaylock caught at UA42, for 9 yards to the UA39 (#1 D.Jackson), out of bounds, 1ST DOWN”
},
{
“x”: 125,
“y”: 0.12162162162162163,
“text”: “J.Mateer pass complete short middle to #12 J.Kanak caught at UA35, for 5 yards to the UA34 (#31 K.Keeley)”
},
{
“x”: 126,
“y”: 0.12,
“text”: “J.Mateer pass incomplete, Spike”
}
],
“label”: “Oklahoma XR”,
“borderColor”: “#5e0a33CC”,
“borderWidth”: 2.2,
“borderDash”: [
4,
4
],
“fill”: false
},
{
“data”: [
{
“x”: 1,
“y”: 0,
“text”: “J.Mateer rush right for 0 yards to the OU25 (#2 Z.Brown)”
},
{
“x”: 2,
“y”: 0,
“text”: “T.Blaylock rush left for 4 yards gain to the OU29 (#10 J.Jefferson)”
},
{
“x”: 3,
“y”: 0.3333333333333333,
“text”: “J.Mateer pass complete short right to #4 D.Burks caught at OU42, for 14 yards to the OU43, End Of Play, 1ST DOWN”
},
{
“x”: 4,
“y”: 0.5,
“text”: “T.Blaylock rush right for 6 yards gain to the OU49 (#10 J.Jefferson)”
},
{
“x”: 5,
“y”: 0.4,
“text”: “J.Mateer rush left for 2 yards gain to the UA49 (#0 D.Lawson)”
},
{
“x”: 6,
“y”: 0.5,
“text”: “J.Mateer rush for 5 yards gain to the UA44 (#3 K.Sabb; #1 D.Jackson), 1ST DOWN”
},
{
“x”: 7,
“y”: 0.42857142857142855,
“text”: “J.Mateer pass incomplete short right to #4 D.Burks thrown to UA33 broken up by #2 Z.Brown”
},
{
“x”: 8,
“y”: 0.375,
“text”: “T.Blaylock rush middle for 0 yards to the UA44 (#90 L.Simmons)”
},
{
“x”: 9,
“y”: 0.3333333333333333,
“text”: “J.Mateer pass incomplete short right to #6 T.Blaylock thrown to UA46”
},
{
“x”: 13,
“y”: 0.3,
“text”: “T.Blaylock rush right for 2 yards gain to the OU43 (#41 N.Hill-Green)”
},
{
“x”: 14,
“y”: 0.36363636363636365,
“text”: “J.Mateer pass complete short middle to #84 J.Carter caught at UA38, for 21 yards to the UA36 (#3 K.Sabb), 1ST DOWN”
},
{
“x”: 15,
“y”: 0.3333333333333333,
“text”: “J.Mateer pass incomplete deep left to #11 J.Gibson thrown to UA16”
},
{
“x”: 16,
“y”: 0.38461538461538464,
“text”: “J.Mateer rush left for 11 yards gain to the UA25 (#3 K.Sabb), 1ST DOWN”
},
{
“x”: 17,
“y”: 0.35714285714285715,
“text”: “T.Blaylock rush middle for 0 yards to the UA25 (#31 K.Keeley; #0 D.Lawson)”
},
{
“x”: 18,
“y”: 0.3333333333333333,
“text”: “J.Mateer pass incomplete short right thrown to UA15 QB hurried by #16 R.Morgan”
},
{
“x”: 19,
“y”: 0.375,
“text”: “J.Mateer pass complete short middle to #24 X.Robinson caught at UA23, for 17 yards to the UA08 (#0 D.Lawson), out of bounds, 1ST DOWN”
},
{
“x”: 20,
“y”: 0.4117647058823529,
“text”: “J.Mateer rush middle for 8 yards gain to the UA00 TOUCHDOWN, clock 05:29 #29 T.Sandell kick attempt good (H: #87 J.Ulrich, LS: #49 B.Anderson)”
},
{
“x”: 24,
“y”: 0.4444444444444444,
“text”: “J.Mateer pass complete short left to #12 J.Kanak caught at UA40, for 8 yards to the UA38 (#13 I.Taylor)”
},
{
“x”: 25,
“y”: 0.47368421052631576,
“text”: “T.Blaylock rush middle for 3 yards gain to the UA35 (#10 J.Jefferson; #13 I.Taylor), 1ST DOWN”
},
{
“x”: 26,
“y”: 0.5,
“text”: “T.Blaylock rush right for 6 yards gain to the UA29 (#41 N.Hill-Green)”
},
{
“x”: 27,
“y”: 0.47619047619047616,
“text”: “T.Blaylock rush right for 1 yard gain to the UA28 (#5 D.Lee Jr.) PENALTY OU UNS: Unsportsmanlike Conduct (#55 E.Pierre-Louis) 15 yards from UA28 to UA43”
},
{
“x”: 28,
“y”: 0.45454545454545453,
“text”: “J.Mateer pass complete short left to #5 I.Sategna III caught at UA41, for 10 yards to the UA33 (#4 Q.Russaw; #10 J.Jefferson)”
},
{
“x”: 32,
“y”: 0.43478260869565216,
“text”: “J.Mateer pass incomplete short middle to #5 I.Sategna III thrown to OU44 broken up by #7 D.Jones”
},
{
“x”: 33,
“y”: 0.4166666666666667,
“text”: “X.Robinson rush right for 2 yards gain to the OU39 (#11 J.Renaud; #8 J.Hill)”
},
{
“x”: 34,
“y”: 0.44,
“text”: “J.Mateer pass complete short right to #4 D.Burks caught at UA45, for 16 yards to the UA45, out of bounds at UA45, 1ST DOWN”
},
{
“x”: 35,
“y”: 0.46153846153846156,
“text”: “J.Mateer pass complete short middle to #4 D.Burks caught at UA28, for 18 yards to the UA28, End Of Play, 1ST DOWN”
},
{
“x”: 36,
“y”: 0.4444444444444444,
“text”: “X.Robinson rush left for 1 yard loss to the UA29 (#10 J.Jefferson)”
},
{
“x”: 37,
“y”: 0.42857142857142855,
“text”: “J.Mateer pass complete short right to #4 D.Burks caught at UA26, for 6 yards to the UA23 (#2 Z.Brown)”
},
{
“x”: 38,
“y”: 0.4482758620689655,
“text”: “J.Mateer pass complete short middle to #88 J.Jordan caught at UA11, for 16 yards to the UA07 (#7 D.Jones), 1ST DOWN”
},
{
“x”: 39,
“y”: 0.4666666666666667,
“text”: “J.Mateer pass complete short middle to #5 I.Sategna III caught at UA00, for 7 yards to the UA00 TOUCHDOWN, clock 10:51 #29 T.Sandell kick attempt good (H: #87 J.Ulrich, LS: #49 B.Anderson)”
},
{
“x”: 49,
“y”: 0.4838709677419355,
“text”: “J.Mateer pass complete short left to #4 D.Burks for 15 yards to the OU40 (#3 K.Sabb; #18 B.Hubbard), 1ST DOWN”
},
{
“x”: 50,
“y”: 0.46875,
“text”: “J.Mateer rush right for 4 yards gain to the OU44 (#18 B.Hubbard)”
},
{
“x”: 51,
“y”: 0.45454545454545453,
“text”: “J.Mateer pass complete short right to #11 J.Gibson caught at OU47, for 3 yards to the OU47 (#1 D.Jackson)”
},
{
“x”: 52,
“y”: 0.4411764705882353,
“text”: “J.Mateer pass incomplete deep left to #24 X.Robinson thrown to UA20”
},
{
“x”: 57,
“y”: 0.42857142857142855,
“text”: “J.Mateer rush middle for 2 yards gain to the OU27 (#4 Q.Russaw; #11 J.Renaud)”
},
{
“x”: 58,
“y”: 0.4444444444444444,
“text”: “J.Mateer pass complete deep middle to #84 J.Carter caught at OU48, for 22 yards to the OU49, End Of Play, 1ST DOWN”
},
{
“x”: 59,
“y”: 0.43243243243243246,
“text”: “J.Mateer sacked for loss of 3 yards to the OU46 (#10 J.Jefferson)”
},
{
“x”: 60,
“y”: 0.42105263157894735,
“text”: “J.Mateer pass intercepted by #2 Z.Brown at UA50 #2 Z.Brown return 50 yards to the OU00 TOUCHDOWN, clock 01:18 Timeout Alabama, clock 01:26 #31 C.Talty kick attempt good (H: #38 B.Doud, LS: #45 D.Bird)”
},
{
“x”: 61,
“y”: 0.41025641025641024,
“text”: “J.Mateer pass incomplete short left to #5 I.Sategna III thrown to OU23 broken up by #23 J.Smith”
},
{
“x”: 62,
“y”: 0.4,
“text”: “J.Mateer pass complete short left to #9 K.Lewis caught at OU29, for 5 yards to the OU30 (#1 D.Jackson)”
},
{
“x”: 63,
“y”: 0.3902439024390244,
“text”: “J.Mateer rush middle for 1 yard gain to the OU31 (#24 N.Carter; #42 Y.Pierre) PENALTY UA Sideline Inteference 16 yards from OU31 to OU47, 1ST DOWN”
},
{
“x”: 64,
“y”: 0.38095238095238093,
“text”: “J.Mateer pass complete short right to #84 J.Carter caught at UA50, for 3 yards to the OU50, out of bounds at UA50”
},
{
“x”: 65,
“y”: 0.37209302325581395,
“text”: “J.Mateer rush middle for 3 yards loss to the OU47 (#42 Y.Pierre)”
},
{
“x”: 66,
“y”: 0.36363636363636365,
“text”: “J.Mateer pass complete short right to #6 T.Blaylock caught at OU48, for 6 yards to the UA47 (#5 D.Lee Jr.; #0 D.Lawson)”
},
{
“x”: 71,
“y”: 0.35555555555555557,
“text”: “T.Blaylock rush middle for 4 yards gain to the OU29 (#0 D.Lawson; #41 N.Hill-Green)”
},
{
“x”: 72,
“y”: 0.34782608695652173,
“text”: “J.Mateer pass incomplete short middle to #4 D.Burks thrown to OU35”
},
{
“x”: 73,
“y”: 0.3404255319148936,
“text”: “J.Mateer pass incomplete short middle to #5 I.Sategna III thrown to OU34”
},
{
“x”: 77,
“y”: 0.3333333333333333,
“text”: “J.Mateer sacked for loss of 5 yards to the OU20 (#31 K.Keeley)”
},
{
“x”: 78,
“y”: 0.32653061224489793,
“text”: “J.Mateer sacked for loss of 7 yards to the OU13 (#42 Y.Pierre, #90 L.Simmons)”
},
{
“x”: 79,
“y”: 0.32,
“text”: “J.Mateer pass complete short middle to #6 T.Blaylock caught at OU14, for 12 yards to the OU25 (#0 D.Lawson)”
},
{
“x”: 88,
“y”: 0.3333333333333333,
“text”: “J.Mateer rush left for 7 yards gain to the OU32 (#10 J.Jefferson)”
},
{
“x”: 89,
“y”: 0.3269230769230769,
“text”: “J.Mateer rush left for 2 yards gain to the OU34 (#88 I.Faga)”
},
{
“x”: 90,
“y”: 0.33962264150943394,
“text”: “J.Mateer rush middle for 1 yard gain to the OU35 (#96 T.Keenan III), 1ST DOWN”
},
{
“x”: 91,
“y”: 0.3333333333333333,
“text”: “X.Robinson rush right for 3 yards gain to the OU38 (#0 D.Lawson)”
},
{
“x”: 92,
“y”: 0.34545454545454546,
“text”: “T.Blaylock rush middle for 5 yards gain to the OU43 (#18 B.Hubbard; #0 D.Lawson)”
},
{
“x”: 93,
“y”: 0.35714285714285715,
“text”: “J.Mateer pass complete short right to #6 T.Blaylock caught at OU45, for 5 yards to the OU48 (#2 Z.Brown), 1ST DOWN”
},
{
“x”: 94,
“y”: 0.3508771929824561,
“text”: “J.Mateer rush left for 0 yards to the OU48 (#10 J.Jefferson)”
},
{
“x”: 95,
“y”: 0.3620689655172414,
“text”: “J.Mateer pass complete short middle to #4 D.Burks caught at UA18, for 37 yards to the UA00 TOUCHDOWN, clock 14:45, 1ST DOWN #29 T.Sandell kick attempt good (H: #87 J.Ulrich, LS: #49 B.Anderson)”
},
{
“x”: 100,
“y”: 0.3559322033898305,
“text”: “J.Mateer rush right for 1 yard gain to the OU08 (#42 Y.Pierre)”
},
{
“x”: 101,
“y”: 0.35,
“text”: “T.Blaylock rush left for 5 yards gain to the OU13 (#3 K.Sabb; #18 B.Hubbard)”
},
{
“x”: 102,
“y”: 0.3442622950819672,
“text”: “J.Mateer pass incomplete short middle to #6 T.Blaylock thrown to OU10 broken up by #0 D.Lawson”
},
{
“x”: 107,
“y”: 0.3387096774193548,
“text”: “J.Mateer pass incomplete short left to #5 I.Sategna III thrown to OU35 broken up by #31 K.Keeley”
},
{
“x”: 108,
“y”: 0.3333333333333333,
“text”: “J.Mateer pass complete short left to #4 D.Burks caught at OU21, for 2 yards to the OU27 (#1 D.Jackson)”
},
{
“x”: 109,
“y”: 0.328125,
“text”: “J.Mateer sacked for loss of 8 yards to the OU19 (#17 K.Collins)”
},
{
“x”: 113,
“y”: 0.3230769230769231,
“text”: “J.Mateer pass incomplete short right thrown to OU50 QB hurried by #24 N.Carter and #96 T.Keenan III”
},
{
“x”: 114,
“y”: 0.3181818181818182,
“text”: “J.Mateer pass complete short middle to #12 J.Kanak caught at OU43, for 5 yards to the OU43 (#18 B.Hubbard)”
},
{
“x”: 115,
“y”: 0.31343283582089554,
“text”: “J.Mateer pass incomplete short middle to #10 K.Lewis thrown to OU46”
},
{
“x”: 116,
“y”: 0.3235294117647059,
“text”: “J.Mateer pass complete deep left to #11 J.Gibson caught at UA37, for 38 yards to the UA19 (#7 D.Jones), 1ST DOWN”
},
{
“x”: 117,
“y”: 0.3188405797101449,
“text”: “J.Mateer pass complete short middle to #6 T.Blaylock caught at UA15, for 4 yards to the UA15 (#10 J.Jefferson)”
},
{
“x”: 118,
“y”: 0.3142857142857143,
“text”: “J.Mateer sacked for loss of 3 yards to the UA18 (#0 D.Lawson)”
},
{
“x”: 119,
“y”: 0.30985915492957744,
“text”: “J.Mateer pass incomplete short right thrown to UA10 QB hurried by #41 N.Hill-Green”
},
{
“x”: 123,
“y”: 0.3055555555555556,
“text”: “J.Mateer pass complete short left to #12 J.Kanak caught at OU48, for 4 yards to the UA48 (#0 D.Lawson), out of bounds”
},
{
“x”: 124,
“y”: 0.3150684931506849,
“text”: “J.Mateer pass complete short middle to #6 T.Blaylock caught at UA42, for 9 yards to the UA39 (#1 D.Jackson), out of bounds, 1ST DOWN”
},
{
“x”: 125,
“y”: 0.32432432432432434,
“text”: “J.Mateer pass complete short middle to #12 J.Kanak caught at UA35, for 5 yards to the UA34 (#31 K.Keeley)”
},
{
“x”: 126,
“y”: 0.32,
“text”: “J.Mateer pass incomplete, Spike”
}
],
“label”: “Oklahoma SR”,
“borderColor”: “#EC4899CC”,
“borderWidth”: 2.2,
“borderDash”: [
4,
4
],
“fill”: false
},
{
“label”: “Quarters”,
“data”: [
{
“x”: 1,
“y”: 0
},
{
“x”: 1,
“y”: 1
},
{
“x”: 129,
“y”: 1
},
{
“x”: 129,
“y”: 0
},
{
“x”: 31,
“y”: 0
},
{
“x”: 31,
“y”: 1
},
{
“x”: 129,
“y”: 1
},
{
“x”: 129,
“y”: 0
},
{
“x”: 67,
“y”: 0
},
{
“x”: 67,
“y”: 1
},
{
“x”: 129,
“y”: 1
},
{
“x”: 129,
“y”: 0
},
{
“x”: 95,
“y”: 0
},
{
“x”: 95,
“y”: 1
},
{
“x”: 129,
“y”: 1
},
{
“x”: 129,
“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”: 1,
“seasonType”: “postseason”,
“team”: “Alabama”,
“gameId”: “401779840”
}
};
// 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-1766345933069-20pt4ndz2’).parentNode;
if (container) {
container.innerHTML = ‘
‘;
}
}
}
// 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/chart.js@3.9.1/dist/chart.min.js’, function() {
// Then load ChartDataLabels
if (typeof ChartDataLabels === ‘undefined’) {
loadScript(‘https://cdn.jsdelivr.net/npm/chartjs-plugin-datalabels@2.2.0’, function() {
initChart();
});
} else {
initChart();
}
});
} else if (typeof ChartDataLabels === ‘undefined’) {
// Chart.js loaded but not ChartDataLabels
loadScript(‘https://cdn.jsdelivr.net/npm/chartjs-plugin-datalabels@2.2.0’, function() {
initChart();
});
} else {
initChart();
}
}
// Initialize when DOM is ready
if (document.readyState === ‘loading’) {
document.addEventListener(‘DOMContentLoaded’, startLoading);
} else {
startLoading();
}
})();
Plus, if we break it down by more than quarters, you see some funny business right at the end of this game. Alabama’s cumulative Success Rate climbed out of the cellar over the course of the 2nd, 3rd, and the first part of the 4th quarters; these teams were pretty evenly matched at that point in the 4th. But then Alabama’s offense nose-dived at the end (remember those final three 3-and-outs).
Part of that was a desperate and talented Oklahoma defense trying to drag their team back from the brink: I mean, if Alabama could’ve managed a 1st down to essentially ice the game, they would’ve taken that all day! But at least part of this was on strategy, with Alabama burning clock doing what it does worst: RTDB. Maybe they would’ve been 3-and-outs anyway, but letting Ty pass the thing was surely the likelier (if also riskier) way of getting a 1st down there.
At the same time, Oklahoma had this “dead cat bounce” in their efficiencies right at the end that contributed yardage without points (and even if they’d made those field goals, Bama still very likely wins). So I’d consider the sudden departure of these teams’ SR’s at the end of the game as at least something of a phantom. Peering at that mid-late 4th quarter here, I’d call the “practical” difference more like 28% overall SR for Alabama vs. 30% for the Sooners (with XR tied at 11%).
.cfb-chart-embed-cfb-chart-1766345942253-v551sojnl {
font-family: -apple-system, BlinkMacSystemFont, ‘Segoe UI’, ‘Roboto’, sans-serif;
margin: 0;
padding: 0;
}
.cfb-chart-embed-cfb-chart-1766345942253-v551sojnl .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-1766345942253-v551sojnl .chart-header {
padding: 18px 24px 14px;
border-bottom: 1px solid #e5e5e5;
background: white;
}
.cfb-chart-embed-cfb-chart-1766345942253-v551sojnl .chart-title {
font-size: 18px;
font-weight: 600;
color: #171717;
margin: 0;
}
.cfb-chart-embed-cfb-chart-1766345942253-v551sojnl .chart-subtitle {
font-size: 11px;
font-weight: 400;
color: #737373;
margin: 4px 0 0 0;
}
.cfb-chart-embed-cfb-chart-1766345942253-v551sojnl .chart-content {
padding: 20px 24px 24px !important;
}
.cfb-chart-embed-cfb-chart-1766345942253-v551sojnl .chart-content { height: 325px; }
@media (max-width: 640px) {
.cfb-chart-embed-cfb-chart-1766345942253-v551sojnl .chart-content {
padding: 12px 16px 20px !important;
height: 280px !important;
}
.cfb-chart-embed-cfb-chart-1766345942253-v551sojnl .chart-header {
padding: 12px 16px 12px !important;
}
.cfb-chart-embed-cfb-chart-1766345942253-v551sojnl .embed-footer-top {
padding: 8px 12px !important;
}
.cfb-chart-embed-cfb-chart-1766345942253-v551sojnl .data-definitions {
padding: 12px !important;
}
}
.cfb-chart-embed-cfb-chart-1766345942253-v551sojnl .embed-footer {
border-top: 1px solid #e5e5e5;
font-size: 12px;
color: #737373;
}
.cfb-chart-embed-cfb-chart-1766345942253-v551sojnl .embed-footer-top {
display: flex;
justify-content: space-between;
align-items: center;
padding: 12px 16px;
}
.cfb-chart-embed-cfb-chart-1766345942253-v551sojnl .embed-footer-link {
color: #737373;
text-decoration: none;
font-weight: 500;
}
.cfb-chart-embed-cfb-chart-1766345942253-v551sojnl .embed-footer-link:hover {
color: #525252;
text-decoration: underline;
}
.cfb-chart-embed-cfb-chart-1766345942253-v551sojnl .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-1766345942253-v551sojnl .data-definitions-toggle:hover {
color: #525252;
}
.cfb-chart-embed-cfb-chart-1766345942253-v551sojnl .caret {
transition: transform 0.2s ease;
font-size: 10px;
}
.cfb-chart-embed-cfb-chart-1766345942253-v551sojnl .caret.expanded {
transform: rotate(180deg);
}
.cfb-chart-embed-cfb-chart-1766345942253-v551sojnl .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-1766345942253-v551sojnl .data-definitions.expanded {
display: block;
}
.cfb-chart-embed-cfb-chart-1766345942253-v551sojnl .data-definitions ul {
margin: 0;
padding-left: 0;
list-style: none;
}
.cfb-chart-embed-cfb-chart-1766345942253-v551sojnl .data-definitions li {
margin-bottom: 4px;
}
Win Probability
Alabama vs. Oklahoma • Dec 19, 2025
- Win Probability: Likelihood of winning based on game situation
- Line Color: Gradient reflects which team is favored
- 50% Line: Dashed line indicates even odds
- Data Source: CollegeFootballData.com win probability models
// Toggle data definitions accordion – unique function per embed
function toggleDefinitions_cfb_chart_1766345942253_v551sojnl() {
const definitions = document.getElementById(‘dataDefinitions_cfb-chart-1766345942253-v551sojnl’);
const caret = document.getElementById(‘caret_cfb-chart-1766345942253-v551sojnl’);
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-1766345942253-v551sojnl’);
if (canvas && canvas.parentNode) {
canvas.parentNode.innerHTML = ‘
‘;
}
}
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-1766345942253-v551sojnl’);
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”: [
0,
1,
2,
3,
4,
5,
6,
7,
8,
9,
10,
11,
12,
13,
14,
15,
16,
17,
18,
19,
20,
21,
22,
23,
24,
25,
26,
27,
28,
29,
30,
31,
32,
33,
34,
35,
36,
37,
38,
39,
40,
41,
42,
43,
44,
45,
46,
47,
48,
49,
50,
51,
52,
53,
54,
55,
56,
57,
58,
59,
60,
61,
62,
63,
64,
65,
66,
67,
68,
69,
70,
71,
72,
73,
74,
75,
76,
77,
78,
79,
80,
81,
82,
83,
84,
85,
86,
87,
88,
89,
90,
91,
92,
93,
94,
95,
96,
97,
98,
99,
100,
101,
102,
103,
104,
105,
106,
107,
108,
109,
110,
111,
112,
113,
114,
115,
116,
117,
118,
119,
120,
121,
122,
123,
124,
125,
126,
127,
128,
129,
130,
131,
132,
133,
134,
135,
136,
137,
138,
139,
140,
141,
142,
143,
144,
145,
146,
147,
148,
149,
150,
151,
152,
153,
154,
155,
156
],
“datasets”: [
{
“label”: “Win Probability”,
“data”: [
{
“x”: 0,
“y”: 41.40433073043823
},
{
“x”: 1,
“y”: 43.198162317276
},
{
“x”: 2,
“y”: 43.15360188484192
},
{
“x”: 3,
“y”: 36.45033836364746
},
{
“x”: 4,
“y”: 36.24013066291809
},
{
“x”: 5,
“y”: 36.845892667770386
},
{
“x”: 6,
“y”: 33.03343653678894
},
{
“x”: 7,
“y”: 34.483569860458374
},
{
“x”: 8,
“y”: 37.88743615150452
},
{
“x”: 9,
“y”: 39.485424757003784
},
{
“x”: 10,
“y”: 45.929914712905884
},
{
“x”: 11,
“y”: 45.043933391571045
},
{
“x”: 12,
“y”: 44.10061836242676
},
{
“x”: 13,
“y”: 43.19269061088562
},
{
“x”: 14,
“y”: 36.68861985206604
},
{
“x”: 15,
“y”: 38.919514417648315
},
{
“x”: 16,
“y”: 35.304194688797
},
{
“x”: 17,
“y”: 36.88279986381531
},
{
“x”: 18,
“y”: 34.173768758773804
},
{
“x”: 19,
“y”: 35.61708927154541
},
{
“x”: 20,
“y”: 38.43637704849243
},
{
“x”: 21,
“y”: 18.12819242477417
},
{
“x”: 22,
“y”: 23.772424459457397
},
{
“x”: 23,
“y”: 19.90920901298523
},
{
“x”: 24,
“y”: 23.1070876121521
},
{
“x”: 25,
“y”: 22.262543439865112
},
{
“x”: 26,
“y”: 15.938496589660645
},
{
“x”: 27,
“y”: 16.774529218673706
},
{
“x”: 28,
“y”: 16.753411293029785
},
{
“x”: 29,
“y”: 16.731232404708862
},
{
“x”: 30,
“y”: 19.874417781829834
},
{
“x”: 31,
“y”: 15.63493013381958
},
{
“x”: 32,
“y”: 19.144517183303833
},
{
“x”: 33,
“y”: 20.272350311279297
},
{
“x”: 34,
“y”: 20.272350311279297
},
{
“x”: 35,
“y”: 18.7383770942688
},
{
“x”: 36,
“y”: 18.004417419433594
},
{
“x”: 37,
“y”: 13.241183757781982
},
{
“x”: 38,
“y”: 13.479959964752197
},
{
“x”: 39,
“y”: 14.403623342514038
},
{
“x”: 40,
“y”: 12.348109483718872
},
{
“x”: 41,
“y”: 12.454813718795776
},
{
“x”: 42,
“y”: 12.070256471633911
},
{
“x”: 43,
“y”: 11.914831399917603
},
{
“x”: 44,
“y”: 2.6637792587280273
},
{
“x”: 45,
“y”: 5.420339107513428
},
{
“x”: 46,
“y”: 4.809218645095825
},
{
“x”: 47,
“y”: 5.034929513931274
},
{
“x”: 48,
“y”: 8.016550540924072
},
{
“x”: 49,
“y”: 7.62324333190918
},
{
“x”: 50,
“y”: 10.011845827102661
},
{
“x”: 51,
“y”: 9.534180164337158
},
{
“x”: 52,
“y”: 8.731108903884888
},
{
“x”: 53,
“y”: 23.594391345977783
},
{
“x”: 54,
“y”: 13.965928554534912
},
{
“x”: 55,
“y”: 12.931853532791138
},
{
“x”: 56,
“y”: 12.858331203460693
},
{
“x”: 57,
“y”: 13.48617672920227
},
{
“x”: 58,
“y”: 15.233314037322998
},
{
“x”: 59,
“y”: 15.788251161575317
},
{
“x”: 60,
“y”: 24.973905086517334
},
{
“x”: 61,
“y”: 26.127725839614868
},
{
“x”: 62,
“y”: 23.831379413604736
},
{
“x”: 63,
“y”: 23.535937070846558
},
{
“x”: 64,
“y”: 27.93022394180298
},
{
“x”: 65,
“y”: 20.883184671401978
},
{
“x”: 66,
“y”: 22.483617067337036
},
{
“x”: 67,
“y”: 19.998812675476074
},
{
“x”: 68,
“y”: 29.52200174331665
},
{
“x”: 69,
“y”: 36.413103342056274
},
{
“x”: 70,
“y”: 37.88509964942932
},
{
“x”: 71,
“y”: 37.724196910858154
},
{
“x”: 72,
“y”: 32.321566343307495
},
{
“x”: 73,
“y”: 32.095569372177124
},
{
“x”: 74,
“y”: 34.83315706253052
},
{
“x”: 75,
“y”: 33.17931890487671
},
{
“x”: 76,
“y”: 48.63305687904358
},
{
“x”: 77,
“y”: 50.55730640888214
},
{
“x”: 78,
“y”: 50.99307298660278
},
{
“x”: 79,
“y”: 48.24386239051819
},
{
“x”: 80,
“y”: 44.465917348861694
},
{
“x”: 81,
“y”: 42.73597002029419
},
{
“x”: 82,
“y”: 43.83966326713562
},
{
“x”: 83,
“y”: 43.68525147438049
},
{
“x”: 84,
“y”: 46.10047936439514
},
{
“x”: 85,
“y”: 48.478901386260986
},
{
“x”: 86,
“y”: 51.76839530467987
},
{
“x”: 87,
“y”: 56.58321976661682
},
{
“x”: 88,
“y”: 82.35462605953217
},
{
“x”: 89,
“y”: 72.85456359386444
},
{
“x”: 90,
“y”: 77.8680369257927
},
{
“x”: 91,
“y”: 81.0665026307106
},
{
“x”: 92,
“y”: 76.10519677400589
},
{
“x”: 93,
“y”: 79.54839020967484
},
{
“x”: 94,
“y”: 78.51493954658508
},
{
“x”: 95,
“y”: 77.85634398460388
},
{
“x”: 96,
“y”: 82.25884139537811
},
{
“x”: 97,
“y”: 81.63531571626663
},
{
“x”: 98,
“y”: 81.22482150793076
},
{
“x”: 99,
“y”: 83.0020159482956
},
{
“x”: 100,
“y”: 84.42970365285873
},
{
“x”: 101,
“y”: 82.40797817707062
},
{
“x”: 102,
“y”: 80.69057911634445
},
{
“x”: 103,
“y”: 81.389319896698
},
{
“x”: 104,
“y”: 81.66439384222033
},
{
“x”: 105,
“y”: 82.64621496200574
},
{
“x”: 106,
“y”: 80.56020140647908
},
{
“x”: 107,
“y”: 80.94565272331296
},
{
“x”: 108,
“y”: 81.69316798449053
},
{
“x”: 109,
“y”: 79.57637906075502
},
{
“x”: 110,
“y”: 79.65946197513306
},
{
“x”: 111,
“y”: 82.34973847868345
},
{
“x”: 112,
“y”: 48.63931536671341
},
{
“x”: 113,
“y”: 65.84018170858663
},
{
“x”: 114,
“y”: 65.7150298367908
},
{
“x”: 115,
“y”: 72.93271124580123
},
{
“x”: 116,
“y”: 72.89572360824823
},
{
“x”: 117,
“y”: 69.03813786277844
},
{
“x”: 118,
“y”: 66.51406327236333
},
{
“x”: 119,
“y”: 57.98237342326691
},
{
“x”: 120,
“y”: 58.79834967369615
},
{
“x”: 121,
“y”: 60.2407777315991
},
{
“x”: 122,
“y”: 61.53347140615135
},
{
“x”: 123,
“y”: 62.794689324414364
},
{
“x”: 124,
“y”: 79.69539430595648
},
{
“x”: 125,
“y”: 78.98211393557737
},
{
“x”: 126,
“y”: 79.46663744361078
},
{
“x”: 127,
“y”: 95.32369045526448
},
{
“x”: 128,
“y”: 91.21508595380045
},
{
“x”: 129,
“y”: 91.93507773271207
},
{
“x”: 130,
“y”: 94.57138101551891
},
{
“x”: 131,
“y”: 99.42994501103193
},
{
“x”: 132,
“y”: 96.40440288917806
},
{
“x”: 133,
“y”: 95.6443037639565
},
{
“x”: 134,
“y”: 96.08746290494501
},
{
“x”: 135,
“y”: 90.68923122928257
},
{
“x”: 136,
“y”: 93.40751618172143
},
{
“x”: 137,
“y”: 93.8601419990308
},
{
“x”: 138,
“y”: 95.50816967674307
},
{
“x”: 139,
“y”: 97.79548874628739
},
{
“x”: 140,
“y”: 92.25208520402268
},
{
“x”: 141,
“y”: 92.59875564547475
},
{
“x”: 142,
“y”: 92.44969094774675
},
{
“x”: 143,
“y”: 93.01151273843904
},
{
“x”: 144,
“y”: 98.58201870327532
},
{
“x”: 145,
“y”: 91.9362130452609
},
{
“x”: 146,
“y”: 91.11854003452373
},
{
“x”: 147,
“y”: 85.30103618096085
},
{
“x”: 148,
“y”: 87.85539708240289
},
{
“x”: 149,
“y”: 89.73976863641668
},
{
“x”: 150,
“y”: 93.77089588142562
},
{
“x”: 151,
“y”: 97.09874024596726
},
{
“x”: 152,
“y”: 98.7189990772817
},
{
“x”: 153,
“y”: 92.45085837096717
},
{
“x”: 154,
“y”: 88.03312063791428
},
{
“x”: 155,
“y”: 90.03164817709501
},
{
“x”: 156,
“y”: 100
}
],
“borderColor”: “#af283c”,
“backgroundColor”: “transparent”,
“pointBackgroundColor”: [
“rgb(236, 72, 153)”,
“rgb(233, 71, 149)”,
“rgb(233, 71, 149)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(222, 65, 132)”,
“rgb(226, 67, 137)”,
“rgb(229, 69, 143)”,
“rgb(233, 71, 149)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(211, 59, 115)”,
“rgb(203, 55, 103)”,
“rgb(201, 54, 100)”,
“rgb(213, 60, 117)”,
“rgb(228, 68, 141)”,
“rgb(235, 71, 152)”,
“rgb(231, 69, 145)”,
“rgb(231, 69, 146)”,
“rgb(221, 64, 131)”,
“rgb(212, 59, 116)”,
“rgb(198, 52, 96)”,
“rgb(179, 42, 66)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(211, 59, 115)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”
],
“pointBorderColor”: [
“rgb(236, 72, 153)”,
“rgb(233, 71, 149)”,
“rgb(233, 71, 149)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(222, 65, 132)”,
“rgb(226, 67, 137)”,
“rgb(229, 69, 143)”,
“rgb(233, 71, 149)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(211, 59, 115)”,
“rgb(203, 55, 103)”,
“rgb(201, 54, 100)”,
“rgb(213, 60, 117)”,
“rgb(228, 68, 141)”,
“rgb(235, 71, 152)”,
“rgb(231, 69, 145)”,
“rgb(231, 69, 146)”,
“rgb(221, 64, 131)”,
“rgb(212, 59, 116)”,
“rgb(198, 52, 96)”,
“rgb(179, 42, 66)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(211, 59, 115)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”
],
“pointRadius”: 0,
“pointHoverRadius”: 4,
“tension”: 0.15,
“borderWidth”: 2.2,
“fill”: false,
“selectedTeam”: “Alabama”,
“opponentTeam”: “Oklahoma”,
“isSelectedTeamHome”: false,
“playTexts”: [
“(15:00) No Huddle-Shotgun #10 J.Mateer rush right for 0 yards to the OU25 (#2 Z.Brown)”,
“(14:23) No Huddle-Shotgun #6 T.Blaylock rush left for 4 yards gain to the OU29 (#10 J.Jefferson)”,
“(13:45) No Huddle-Shotgun #10 J.Mateer pass complete short right to #4 D.Burks caught at OU42, for 14 yards to the OU43, End Of Play, 1ST DOWN”,
“(13:05) No Huddle-Shotgun #6 T.Blaylock rush right for 6 yards gain to the OU49 (#10 J.Jefferson)”,
“(12:47) No Huddle-Shotgun #10 J.Mateer rush left for 2 yards gain to the UA49 (#0 D.Lawson)”,
“(12:00) No Huddle-Shotgun #10 J.Mateer rush for 5 yards gain to the UA44 (#3 K.Sabb; #1 D.Jackson), 1ST DOWN”,
“(11:21) No Huddle-Shotgun #10 J.Mateer pass incomplete short right to #4 D.Burks thrown to UA33 broken up by #2 Z.Brown”,
“(11:17) No Huddle-Shotgun #6 T.Blaylock rush middle for 0 yards to the UA44 (#90 L.Simmons)”,
“(10:41) No Huddle-Shotgun #10 J.Mateer pass incomplete short right to #6 T.Blaylock thrown to UA46”,
“(10:36) #43 G.Miller punt 32 yards to the UA12 fair catch by #7 C.Adams at UA12”,
“(10:30) Shotgun #4 D.Hill rush middle for 1 yard gain to the UA13 (#32 R.Thomas)”,
“(09:51) Shotgun #15 T.Simpson pass complete short left to #1 I.Horton caught at UA17, for 4 yards to the UA17 (#5 K.Daniels)”,
“(09:17) No Huddle-Shotgun #15 T.Simpson pass incomplete short left to #1 I.Horton thrown to UA24 broken up by #4 C.Guillory”,
“(09:13) #38 B.Doud punt 42 yards to the OU41”,
“(09:03) Shotgun #6 T.Blaylock rush right for 2 yards gain to the OU43 (#41 N.Hill-Green)”,
“(08:27) No Huddle-Shotgun #10 J.Mateer pass complete short middle to #84 J.Carter caught at UA38, for 21 yards to the UA36 (#3 K.Sabb), 1ST DOWN”,
“(07:44) No Huddle-Shotgun #10 J.Mateer pass incomplete deep left to #11 J.Gibson thrown to UA16”,
“(07:39) No Huddle-Shotgun #10 J.Mateer rush left for 11 yards gain to the UA25 (#3 K.Sabb), 1ST DOWN”,
“(06:57) No Huddle-Shotgun #6 T.Blaylock rush middle for 0 yards to the UA25 (#31 K.Keeley; #0 D.Lawson)”,
“(06:25) No Huddle-Shotgun #10 J.Mateer pass incomplete short right thrown to UA15 QB hurried by #16 R.Morgan”,
“(06:20) No Huddle-Shotgun #10 J.Mateer pass complete short middle to #24 X.Robinson caught at UA23, for 17 yards to the UA08 (#0 D.Lawson), out of bounds, 1ST DOWN”,
“(05:34) No Huddle-Shotgun #10 J.Mateer rush middle for 8 yards gain to the UA00 TOUCHDOWN, clock 05:29 #29 T.Sandell kick attempt good (H: #87 J.Ulrich, LS: #49 B.Anderson)”,
“(05:21) No Huddle-Shotgun #15 T.Simpson sacked for loss of 8 yards to the UA06 (#10 K.Lewis)”,
“(04:47) No Huddle-Shotgun #15 T.Simpson pass complete short middle to #80 J.Cuevas caught at UA10, for 8 yards to the UA14 (#3 R.Spears-Jennings; #38 O.Heinecke)”,
“(04:00) Shotgun #15 T.Simpson pass incomplete short left to #17 L.Brooks thrown to UA33 broken up by #23 E.Bowen QB hurried by #38 O.Heinecke”,
“(03:52) #38 B.Doud punt 32 yards to the UA46 fair catch by #5 I.Sategna III at UA46”,
“(03:44) Shotgun #10 J.Mateer pass complete short left to #12 J.Kanak caught at UA40, for 8 yards to the UA38 (#13 I.Taylor)”,
“(03:09) No Huddle-Shotgun #6 T.Blaylock rush middle for 3 yards gain to the UA35 (#10 J.Jefferson; #13 I.Taylor), 1ST DOWN”,
“(02:36) No Huddle-Shotgun #6 T.Blaylock rush right for 6 yards gain to the UA29 (#41 N.Hill-Green)”,
“(01:55) No Huddle-Shotgun #6 T.Blaylock rush right for 1 yard gain to the UA28 (#5 D.Lee Jr.) PENALTY OU UNS: Unsportsmanlike Conduct (#55 E.Pierre-Louis) 15 yards from UA28 to UA43”,
“(01:32) No Huddle-Shotgun #10 J.Mateer pass complete short left to #5 I.Sategna III caught at UA41, for 10 yards to the UA33 (#4 Q.Russaw; #10 J.Jefferson)”,
“(00:48) #29 T.Sandell field goal attempt from 51 yards GOOD (H: #87 J.Ulrich, LS: #49 B.Anderson), clock 00:45”,
“(00:44) Shotgun #26 J.Miller rush left for 7 yards gain to the UA32 (#25 M.Boganowski)”,
“(00:02) Shotgun #26 J.Miller rush middle for 0 yards to the UA32 (#4 C.Guillory)”,
“End of 1st quarter.”,
“(15:00) Shotgun #15 T.Simpson pass incomplete short left to #1 I.Horton thrown to UA40”,
“(14:55) #38 B.Doud punt 31 yards to the OU37, out of bounds at OU37”,
“(14:48) Shotgun #10 J.Mateer pass incomplete short middle to #5 I.Sategna III thrown to OU44 broken up by #7 D.Jones”,
“(14:44) No Huddle-Shotgun #24 X.Robinson rush right for 2 yards gain to the OU39 (#11 J.Renaud; #8 J.Hill)”,
“(14:03) No Huddle-Shotgun #10 J.Mateer pass complete short right to #4 D.Burks caught at UA45, for 16 yards to the UA45, out of bounds at UA45, 1ST DOWN”,
“(13:25) Shotgun #10 J.Mateer pass complete short middle to #4 D.Burks caught at UA28, for 18 yards to the UA28, End Of Play, 1ST DOWN”,
“(12:59) No Huddle-Shotgun #24 X.Robinson rush left for 1 yard loss to the UA29 (#10 J.Jefferson)”,
“(12:22) Shotgun #10 J.Mateer pass complete short right to #4 D.Burks caught at UA26, for 6 yards to the UA23 (#2 Z.Brown)”,
“(11:38) No Huddle-Shotgun #10 J.Mateer pass complete short middle to #88 J.Jordan caught at UA11, for 16 yards to the UA07 (#7 D.Jones), 1ST DOWN”,
“(10:51) No Huddle-Shotgun #10 J.Mateer pass complete short middle to #5 I.Sategna III caught at UA00, for 7 yards to the UA00 TOUCHDOWN, clock 10:51 #29 T.Sandell kick attempt good (H: #87 J.Ulrich, LS: #49 B.Anderson)”,
“(10:51) Shotgun #15 T.Simpson pass incomplete short left to #2 R.Williams thrown to UA36 QB hurried by #0 D.Stone”,
“(10:42) No Huddle-Shotgun #15 T.Simpson pass complete short right to #17 L.Brooks caught at UA29, for 5 yards to the UA30 (#5 K.Daniels; #38 O.Heinecke)”,
“(09:58) Shotgun #15 T.Simpson pass complete deep left to #17 L.Brooks caught at OU45, for 29 yards to the OU41, End Of Play, 1ST DOWN”,
“(09:13) Shotgun #15 T.Simpson pass incomplete short left to #80 J.Cuevas thrown to OU44 QB hurried by #32 R.Thomas”,
“(09:06) Shotgun #15 T.Simpson pass complete short middle to #80 J.Cuevas caught at OU24, for 23 yards to the OU18 (#22 P.Bowen), 1ST DOWN”,
“(08:33) Shotgun #15 T.Simpson pass incomplete short left to #80 J.Cuevas thrown to OU12”,
“(08:29) Shotgun #26 J.Miller rush left for 4 yards gain to the OU14 (#7 S.Omosigho), out of bounds”,
“(07:46) Shotgun #15 T.Simpson pass complete short right to #5 G.Bernard caught at OU10, for 4 yards to the OU10, End Of Play”,
“(07:01) Shotgun #15 T.Simpson pass complete short left to #17 L.Brooks caught at OU06, for 10 yards to the OU00 TOUCHDOWN, clock 06:52, 1ST DOWN #31 C.Talty kick attempt good (H: #38 B.Doud, LS: #45 D.Bird) PENALTY OU Holding declined”,
“(06:51) Shotgun #10 J.Mateer pass complete short left to #4 D.Burks for 15 yards to the OU40 (#3 K.Sabb; #18 B.Hubbard), 1ST DOWN”,
“(06:06) No Huddle-Shotgun #10 J.Mateer rush right for 4 yards gain to the OU44 (#18 B.Hubbard)”,
“(05:24) Shotgun #10 J.Mateer pass complete short right to #11 J.Gibson caught at OU47, for 3 yards to the OU47 (#1 D.Jackson)”,
“(04:39) No Huddle-Shotgun #10 J.Mateer pass incomplete deep left to #24 X.Robinson thrown to UA20”,
“PENALTY OU Delay Of Game 5 yards from OU47 to OU42. NO PLAY”,
“(04:27) #43 G.Miller punt 0 yards to the OU42 blocked by #96 T.Keenan III recovered by UA #96 T.Keenan III at OU30, End Of Play”,
“(04:21) No Huddle #15 T.Simpson pass complete short middle to #1 I.Horton caught at OU16, for 14 yards to the OU16 (#23 E.Bowen), 1ST DOWN”,
“(03:47) No Huddle-Shotgun #15 T.Simpson sacked for loss of 7 yards to the OU23 (#97 M.Jones Jr.)”,
“(03:02) Shotgun #15 T.Simpson pass complete short right to #1 I.Horton caught at OU18, for 6 yards to the OU17 (#22 P.Bowen; #23 E.Bowen)”,
“(02:15) Shotgun #15 T.Simpson pass incomplete short middle to #20 D.Washington thrown to OU17 QB hurried by #56 G.Halton and #0 D.Stone”,
“(02:10) #31 C.Talty field goal attempt from 35 yards GOOD (H: #38 B.Doud, LS: #45 D.Bird), clock 02:08”,
“(02:07) Shotgun #10 J.Mateer rush middle for 2 yards gain to the OU27 (#4 Q.Russaw; #11 J.Renaud)”,
“(01:59) Shotgun #10 J.Mateer pass complete deep middle to #84 J.Carter caught at OU48, for 22 yards to the OU49, End Of Play, 1ST DOWN”,
“(01:36) No Huddle-Shotgun #10 J.Mateer sacked for loss of 3 yards to the OU46 (#10 J.Jefferson)”,
“(01:26) No Huddle-Shotgun #10 J.Mateer pass intercepted by #2 Z.Brown at UA50 #2 Z.Brown return 50 yards to the OU00 TOUCHDOWN, clock 01:18 Timeout Alabama, clock 01:26 #31 C.Talty kick attempt good (H: #38 B.Doud, LS: #45 D.Bird)”,
“(01:17) No Huddle-Shotgun #10 J.Mateer pass incomplete short left to #5 I.Sategna III thrown to OU23 broken up by #23 J.Smith”,
“(01:14) No Huddle-Shotgun #10 J.Mateer pass complete short left to #9 K.Lewis caught at OU29, for 5 yards to the OU30 (#1 D.Jackson)”,
“(00:28) Shotgun #10 J.Mateer rush middle for 1 yard gain to the OU31 (#24 N.Carter; #42 Y.Pierre) PENALTY UA Sideline Inteference 16 yards from OU31 to OU47, 1ST DOWN”,
“(00:19) No Huddle-Shotgun #10 J.Mateer pass complete short right to #84 J.Carter caught at UA50, for 3 yards to the OU50, out of bounds at UA50”,
“(00:18) No Huddle-Shotgun #10 J.Mateer rush middle for 3 yards loss to the OU47 (#42 Y.Pierre)”,
“(00:14) No Huddle-Shotgun #10 J.Mateer pass complete short right to #6 T.Blaylock caught at OU48, for 6 yards to the UA47 (#5 D.Lee Jr.; #0 D.Lawson)”,
“End of 2nd quarter.”,
“(15:00) #15 T.Simpson pass complete short right to #5 G.Bernard caught at UA25, for 12 yards to the UA37 (#44 T.Wein), 1ST DOWN”,
“(14:16) No Huddle-Shotgun #15 T.Simpson pass complete short right to #1 I.Horton caught at UA40, for 4 yards to the UA41 (#23 E.Bowen), out of bounds”,
“(13:41) No Huddle-Shotgun #15 T.Simpson pass incomplete short right to #1 I.Horton thrown to OU45”,
“PENALTY UA False Start (#74 K.Proctor) 5 yards from UA41 to UA36. NO PLAY”,
“(13:37) Shotgun #15 T.Simpson pass incomplete short right to #2 R.Williams thrown to OU45”,
“(13:27) #38 B.Doud punt 39 yards to the OU25 fair catch by #5 I.Sategna III at OU25”,
“(13:21) Shotgun #6 T.Blaylock rush middle for 4 yards gain to the OU29 (#0 D.Lawson; #41 N.Hill-Green)”,
“(12:38) Shotgun #10 J.Mateer pass incomplete short middle to #4 D.Burks thrown to OU35”,
“(12:32) Shotgun #10 J.Mateer pass incomplete short middle to #5 I.Sategna III thrown to OU34”,
“(12:28) #43 G.Miller punt 54 yards to the UA17 #7 C.Adams return 8 yards to the UA25 (#38 O.Heinecke) PENALTY OU Personal Foul (#44 T.Wein) 15 yards from UA25 to UA40, 1ST DOWN”,
“(12:18) Shotgun #4 D.Hill rush left for 30 yards gain to the OU30 (#3 R.Spears-Jennings; #23 E.Bowen), 1ST DOWN”,
“(11:31) No Huddle-Shotgun #15 T.Simpson pass incomplete short right to #17 L.Brooks thrown to OU25”,
“(11:28) No Huddle-Shotgun #15 T.Simpson pass complete deep left to #17 L.Brooks caught at OU00, for 30 yards to the OU00 TOUCHDOWN, clock 11:21, 1ST DOWN #31 C.Talty kick attempt good (H: #38 B.Doud, LS: #45 D.Bird)”,
“(11:19) Shotgun #10 J.Mateer sacked for loss of 5 yards to the OU20 (#31 K.Keeley)”,
“(10:47) No Huddle-Shotgun #10 J.Mateer sacked for loss of 7 yards to the OU13 (#42 Y.Pierre, #90 L.Simmons)”,
“(10:12) No Huddle-Shotgun #10 J.Mateer pass complete short middle to #6 T.Blaylock caught at OU14, for 12 yards to the OU25 (#0 D.Lawson)”,
“(09:35) #43 G.Miller punt 47 yards to the UA28 #7 C.Adams return 10 yards to the UA38 (#12 D.Jordan)”,
“(09:25) Shotgun #15 T.Simpson rush left for 0 yards to the UA38 (#65 J.Jackson; #7 S.Omosigho)”,
“(08:47) Shotgun #15 T.Simpson pass complete short middle to #80 J.Cuevas caught at UA45, for 8 yards to the UA46 (#5 K.Daniels)”,
“(08:06) Shotgun #15 T.Simpson pass incomplete deep left to #5 G.Bernard thrown to OU25 PENALTY OU Holding (#4 C.Guillory) 10 yards from UA46 to OU44, 1ST DOWN. NO PLAY”,
“(07:59) Shotgun #5 G.Bernard rush left for 0 yards to the OU44 (#56 G.Halton)”,
“(07:19) Shotgun #15 T.Simpson pass complete short right to #17 L.Brooks caught at OU40, for 5 yards to the OU39 (#25 M.Boganowski; #13 R.Powers III)”,
“(06:37) Shotgun #15 T.Simpson rush left for 13 yards gain to the OU26 (#13 R.Powers III), out of bounds, 1ST DOWN”,
“(05:53) Shotgun #15 T.Simpson pass complete short left to #80 J.Cuevas caught at OU22, for 4 yards to the OU22 (#32 R.Thomas), out of bounds”,
“(05:19) Shotgun #15 T.Simpson pass incomplete short left to #81 K.Edwards thrown to OU22”,
“(05:14) No Huddle-Shotgun #26 J.Miller rush middle for 0 yards to the OU22 (#56 G.Halton; #10 K.Lewis)”,
“(04:33) #31 C.Talty field goal attempt from 40 yards GOOD (H: #38 B.Doud, LS: #45 D.Bird), clock 04:30”,
“(04:29) Shotgun #10 J.Mateer rush left for 7 yards gain to the OU32 (#10 J.Jefferson)”,
“(03:50) No Huddle-Shotgun #10 J.Mateer rush left for 2 yards gain to the OU34 (#88 I.Faga)”,
“(03:12) No Huddle-Shotgun #10 J.Mateer rush middle for 1 yard gain to the OU35 (#96 T.Keenan III), 1ST DOWN”,
“(02:36) No Huddle-Shotgun #24 X.Robinson rush right for 3 yards gain to the OU38 (#0 D.Lawson)”,
“(01:58) No Huddle-Shotgun #6 T.Blaylock rush middle for 5 yards gain to the OU43 (#18 B.Hubbard; #0 D.Lawson)”,
“(01:18) No Huddle-Shotgun #10 J.Mateer pass complete short right to #6 T.Blaylock caught at OU45, for 5 yards to the OU48 (#2 Z.Brown), 1ST DOWN”,
“(00:39) No Huddle-Shotgun #10 J.Mateer rush left for 0 yards to the OU48 (#10 J.Jefferson)”,
“End of 3rd quarter.”,
“(15:00) Shotgun #10 J.Mateer pass incomplete deep right to #12 J.Kanak thrown to UA30 PENALTY UA Pass Interference (#18 B.Hubbard) 15 yards from OU48 to UA37, 1ST DOWN. NO PLAY”,
“(14:53) No Huddle-Shotgun #10 J.Mateer pass complete short middle to #4 D.Burks caught at UA18, for 37 yards to the UA00 TOUCHDOWN, clock 14:45, 1ST DOWN #29 T.Sandell kick attempt good (H: #87 J.Ulrich, LS: #49 B.Anderson)”,
“(14:41) Shotgun #26 J.Miller rush middle for 1 yard gain to the UA26 (#65 J.Jackson; #52 D.Williams)”,
“(14:01) No Huddle-Shotgun #15 T.Simpson pass complete deep right to #1 I.Horton caught at OU39, for 37 yards to the OU37 (#23 E.Bowen), out of bounds, 1ST DOWN”,
“(13:30) No Huddle-Shotgun #26 J.Miller rush left for 0 yards to the OU37 (#13 R.Powers III; #32 R.Thomas)”,
“(12:51) No Huddle-Shotgun #26 J.Miller rush left for 1 yard loss to the OU38 fumbled by #26 J.Miller at OU37 forced by #10 K.Lewis recovered by UA at OU38, End Of Play”,
“(11:51) No Huddle-Shotgun #15 T.Simpson sacked for loss of 9 yards to the OU47 (#38 O.Heinecke)”,
“(10:57) #38 B.Doud punt 40 yards to the OU07, out of bounds at OU07”,
“(10:55) Shotgun #10 J.Mateer rush right for 1 yard gain to the OU08 (#42 Y.Pierre)”,
“(10:17) No Huddle-Shotgun #6 T.Blaylock rush left for 5 yards gain to the OU13 (#3 K.Sabb; #18 B.Hubbard)”,
“PENALTY OU False Start (#70 R.Fodje) 5 yards from OU13 to OU08. NO PLAY”,
“(09:33) No Huddle-Shotgun #10 J.Mateer pass incomplete short middle to #6 T.Blaylock thrown to OU10 broken up by #0 D.Lawson”,
“(09:27) #43 G.Miller punt 32 yards to the OU40 #5 D.Lee Jr. return 5 yards to the OU35 (#7 S.Omosigho)”,
“(09:19) #4 D.Hill rush middle for 6 yards gain to the OU29 (#5 K.Daniels)”,
“(08:44) Shotgun #15 T.Simpson pass complete short right to #5 G.Bernard caught at OU10, for 24 yards to the OU05 (#19 J.Johnson), 1ST DOWN”,
“(08:05) Shotgun rush left for 1 yard loss to the OU06 (#65 J.Jackson)”,
“(07:29) Shotgun #4 D.Hill rush middle for 6 yards gain to the OU00 TOUCHDOWN, clock 07:24 Timeout Alabama, clock 07:30 #31 C.Talty kick attempt good (H: #38 B.Doud, LS: #45 D.Bird)”,
“(07:23) No Huddle-Shotgun #10 J.Mateer pass incomplete short left to #5 I.Sategna III thrown to OU35 broken up by #31 K.Keeley”,
“(07:19) No Huddle-Shotgun #10 J.Mateer pass complete short left to #4 D.Burks caught at OU21, for 2 yards to the OU27 (#1 D.Jackson)”,
“(06:36) No Huddle-Shotgun #10 J.Mateer sacked for loss of 8 yards to the OU19 (#17 K.Collins)”,
“(06:01) #43 G.Miller punt 46 yards to the UA35 #7 C.Adams return 7 yards to the UA42 (#14 E.Thomas) PENALTY UA Holding (#13 I.Taylor) 10 yards from UA40 to UA30”,
“(05:55) No Huddle-Shotgun #4 D.Hill rush right for 2 yards gain to the UA32 (#38 O.Heinecke)”,
“(05:47) Shotgun #4 D.Hill rush middle for 3 yards gain to the UA35 (#10 K.Lewis)”,
“(05:40) Shotgun #15 T.Simpson sacked for loss of 11 yards to the UA24 (#44 T.Wein)”,
“(05:02) #38 B.Doud punt 38 yards to the OU38 fair catch by #5 I.Sategna III at OU38”,
“(04:59) Shotgun #10 J.Mateer pass incomplete short right thrown to OU50 QB hurried by #24 N.Carter and #96 T.Keenan III”,
“(04:48) No Huddle-Shotgun #10 J.Mateer pass complete short middle to #12 J.Kanak caught at OU43, for 5 yards to the OU43 (#18 B.Hubbard)”,
“(04:33) No Huddle-Shotgun #10 J.Mateer pass incomplete short middle to #10 K.Lewis thrown to OU46”,
“(04:24) Shotgun #10 J.Mateer pass complete deep left to #11 J.Gibson caught at UA37, for 38 yards to the UA19 (#7 D.Jones), 1ST DOWN”,
“(03:55) No Huddle-Shotgun #10 J.Mateer pass complete short middle to #6 T.Blaylock caught at UA15, for 4 yards to the UA15 (#10 J.Jefferson)”,
“(03:37) No Huddle-Shotgun #10 J.Mateer sacked for loss of 3 yards to the UA18 (#0 D.Lawson)”,
“(03:00) No Huddle-Shotgun #10 J.Mateer pass incomplete short right thrown to UA10 QB hurried by #41 N.Hill-Green”,
“(02:57) #29 T.Sandell field goal attempt from 36 yards NO GOOD (H: #87 J.Ulrich, LS: #49 B.Anderson), clock 02:53”,
“(02:53) #4 D.Hill rush middle for 0 yards to the UA20 (#38 O.Heinecke; #4 C.Guillory)”,
“(02:45) #4 D.Hill rush left for 4 yards loss to the UA16 (#38 O.Heinecke)”,
“(02:02) Shotgun #15 T.Simpson pass complete short right to #2 R.Williams caught at UA15, for 5 yards to the UA21 (#22 P.Bowen)”,
“(01:51) #38 B.Doud punt 48 yards to the OU31 #5 I.Sategna III return 17 yards to the OU48 (#3 K.Sabb; #88 I.Faga)”,
“(01:47) Shotgun #10 J.Mateer pass complete short left to #12 J.Kanak caught at OU48, for 4 yards to the UA48 (#0 D.Lawson), out of bounds”,
“(01:41) No Huddle-Shotgun #10 J.Mateer pass complete short middle to #6 T.Blaylock caught at UA42, for 9 yards to the UA39 (#1 D.Jackson), out of bounds, 1ST DOWN”,
“(01:33) No Huddle-Shotgun #10 J.Mateer pass complete short middle to #12 J.Kanak caught at UA35, for 5 yards to the UA34 (#31 K.Keeley)”,
“(01:18) No Huddle-Shotgun #10 J.Mateer pass incomplete, Spike”,
“(01:17) #29 T.Sandell field goal attempt from 51 yards NO GOOD (H: #87 J.Ulrich, LS: #49 B.Anderson), clock 01:13, End Of Play”,
“(01:11) Kneel down by Alabama at UA31 for loss of 3 yards”,
“(00:11) Kneel down by Alabama at UA32 for loss of 2 yards”,
“(00:00) Kneel down by Alabama at UA30 for loss of 2 yards”,
“Game ended”
],
“segmentColors”: [
“rgb(236, 72, 153)”,
“rgb(233, 71, 149)”,
“rgb(233, 71, 149)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(222, 65, 132)”,
“rgb(226, 67, 137)”,
“rgb(229, 69, 143)”,
“rgb(233, 71, 149)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(236, 72, 153)”,
“rgb(211, 59, 115)”,
“rgb(203, 55, 103)”,
“rgb(201, 54, 100)”,
“rgb(213, 60, 117)”,
“rgb(228, 68, 141)”,
“rgb(235, 71, 152)”,
“rgb(231, 69, 145)”,
“rgb(231, 69, 146)”,
“rgb(221, 64, 131)”,
“rgb(212, 59, 116)”,
“rgb(198, 52, 96)”,
“rgb(179, 42, 66)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(211, 59, 115)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”,
“rgb(175, 40, 60)”
]
},
{
“label”: “50% Line”,
“data”: [
{
“x”: 0,
“y”: 50
},
{
“x”: 156,
“y”: 50
}
],
“borderColor”: “rgba(0,0,0,0.3)”,
“borderWidth”: 1.5,
“borderDash”: [
5,
5
],
“backgroundColor”: “transparent”,
“pointRadius”: 0,
“showLine”: true,
“fill”: false,
“tension”: 0,
“order”: 90,
“datalabels”: {
“display”: false
}
},
{
“label”: “Quarters”,
“data”: [
{
“x”: 35,
“y”: 0
},
{
“x”: 35,
“y”: 100
},
{
“x”: 156,
“y”: 100
},
{
“x”: 156,
“y”: 0
},
{
“x”: 76,
“y”: 0
},
{
“x”: 76,
“y”: 100
},
{
“x”: 156,
“y”: 100
},
{
“x”: 156,
“y”: 0
},
{
“x”: 111,
“y”: 0
},
{
“x”: 111,
“y”: 100
},
{
“x”: 156,
“y”: 100
},
{
“x”: 156,
“y”: 0
}
],
“borderColor”: “rgba(0,0,0,0.1)”,
“borderWidth”: 1,
“pointRadius”: 0,
“showLine”: true,
“fill”: false,
“tension”: 0,
“order”: 100,
“datalabels”: {
“display”: false
}
}
],
“currentParams”: {
“year”: 2025,
“week”: 1,
“seasonType”: “postseason”,
“team”: “Alabama”,
“gameId”: “401779840”
}
};
// 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’ ? ‘win-probability’.includes(‘play-map’) ? {
line: {
tension: 0,
borderWidth: 0
}
} : ‘win-probability’ === ‘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: ‘win-probability’.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 (‘win-probability’ === ‘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 (‘win-probability’.includes(‘top-rushers’) || ‘win-probability’.includes(‘top-passers’) || ‘win-probability’.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: ‘win-probability’ === ‘win-probability’ ? {
display: false
} : ‘line’ === ‘line’ ? {
position: ‘top’,
align: ‘start’,
labels: ‘win-probability’.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: ‘win-probability’ === ‘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 (‘win-probability’.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-1766345942253-v551sojnl’).parentNode;
if (container) {
container.innerHTML = ‘
‘;
}
}
}
// 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/chart.js@3.9.1/dist/chart.min.js’, function() {
// Then load ChartDataLabels
if (typeof ChartDataLabels === ‘undefined’) {
loadScript(‘https://cdn.jsdelivr.net/npm/chartjs-plugin-datalabels@2.2.0’, function() {
initChart();
});
} else {
initChart();
}
});
} else if (typeof ChartDataLabels === ‘undefined’) {
// Chart.js loaded but not ChartDataLabels
loadScript(‘https://cdn.jsdelivr.net/npm/chartjs-plugin-datalabels@2.2.0’, function() {
initChart();
});
} else {
initChart();
}
}
// Initialize when DOM is ready
if (document.readyState === ‘loading’) {
document.addEventListener(‘DOMContentLoaded’, startLoading);
} else {
startLoading();
}
})();
And look … this win probability metric can be pretty funky at times — we should all salt this to taste — but Win Probability had a lot more confidence in Alabama than I did during most of this second half (especially after the defense forced another Sooner punt early in the 4th quarter).
Compare that to the chart from the November matchup; it does bear some passing resemblance at times, but it waffles so much more. I mean, within the last 10 play of that game the odds were still sitting near 50/50, vs. the >90% rate the Tide carried through most of the 4th quarter on Friday.
Plus, I trust Bill Connelly’s numbers more on this one and will cite them again for this game: his SP+ derived Postgame Win Expectancy (PWE) numbers had Alabama at 84.5%, which is high, but is hilariously lower than the 95% Alabama delivered in the first game in a loss. The Sooners had absolutely no business winning that first game. The second time around brought some weird dynamics, but Alabama ended that game with a strong case for its win.
Whew. Even thinking about that game makes me exhausted, but after that comeback I was finally again experiencing some guarded gratitude to the mystical football powers in the sky. This Playoff game was a gift (and only partially deserved, in my opinion), but one with emotional complexity given the storylines against this particular (and frustrating) opponent. The losing streak against OU and Venables; the coaches; the rematch; the in-conference implications.
But getting that particular Skeletor out of our closet feels good! And now I truly feel like we’re playing with found money. And at the Rose Bowl again! I’ve been surprised at some of my fellow Gumps’ confidence going into this next matchup — sure, storylines and context abounds, but the advanced metrics love the Hoosiers and they’ve beaten a few great teams — but the -6.5 line doesn’t entirely disagree with you.
Still, I’ll be going into this one with low expectations and high hopes. It’ll all upside from here, folks. Roll Tide.