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 • Nov 15, 2025
| Stats | Alabama | Oklahoma |
|---|---|---|
| Points | 21 | 23 |
| Game Excitement | 6.7 | 6.7 |
| Total yards | 406 | 212 |
| Rush yards | 80 | 74 |
| Rush attempts | 33 | 28 |
| Yards per rush | 2.4 | 2.6 |
| Pass yards | 326 | 138 |
| Pass attempts | 28-42 | 15-23 |
| Yards per pass | 7.8 | 6.0 |
| 1st downs | 23 | 12 |
| 3rd down eff | 5-13 | 3-13 |
| 4th down eff | 2-3 | 0-0 |
| Explosiveness | 1.21 | 1.41 |
| Turnovers | 3 | 0 |
| Tackles | 26 | 49 |
| Sacks | 2 | 4 |
| Penalties-Yds | 2-25 | 5-37 |
| Possession | 34:28 | 25:32 |
Well, if you’ve been even vaguely paying attention to this loss to Oklahoma—or even glancing at the box score—I think you already understand the basic story I’m going to tell: Alabama was statistically a lot better in this one in basically everything but turnovers. The Tide actually had one of their better, most efficient games in a few weeks, decisively outmatching Oklahoma’s Success Rates (and even the Tide’s own SR’s against LSU last week!). They ended up with around double first downs, a lot more yards, higher YPP (with similar YPR given sacks), fewer penalties, and high TOP.
The only thing here that broke that trend were the three turnovers that the Tide managed to cough up vs. zero forced on their end (despite some close calls).
But we can dig around a bit to see if anything stands out statistically in this loss—or if there are any silver linings to notice. Though, you’ll see pretty quickly why I’m calling these charts “useless” this week in the face of a -3 turnover margin.
Bama was pretty dang efficient
.cfb-chart-embed-cfb-chart-1763259260441-hklg6nunx {
font-family: -apple-system, BlinkMacSystemFont, ‘Segoe UI’, ‘Roboto’, sans-serif;
margin: 0;
padding: 0;
}
.cfb-chart-embed-cfb-chart-1763259260441-hklg6nunx .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-1763259260441-hklg6nunx .chart-header {
padding: 18px 24px 14px;
border-bottom: 1px solid #e5e5e5;
background: white;
}
.cfb-chart-embed-cfb-chart-1763259260441-hklg6nunx .chart-title {
font-size: 18px;
font-weight: 600;
color: #171717;
margin: 0;
}
.cfb-chart-embed-cfb-chart-1763259260441-hklg6nunx .chart-subtitle {
font-size: 11px;
font-weight: 400;
color: #737373;
margin: 4px 0 0 0;
}
.cfb-chart-embed-cfb-chart-1763259260441-hklg6nunx .chart-content {
padding: 20px 24px 24px !important;
}
.cfb-chart-embed-cfb-chart-1763259260441-hklg6nunx .chart-content { height: 325px; }
@media (max-width: 640px) {
.cfb-chart-embed-cfb-chart-1763259260441-hklg6nunx .chart-content {
padding: 12px 16px 20px !important;
height: 280px !important;
}
.cfb-chart-embed-cfb-chart-1763259260441-hklg6nunx .chart-header {
padding: 12px 16px 12px !important;
}
.cfb-chart-embed-cfb-chart-1763259260441-hklg6nunx .embed-footer-top {
padding: 8px 12px !important;
}
.cfb-chart-embed-cfb-chart-1763259260441-hklg6nunx .data-definitions {
padding: 12px !important;
}
}
.cfb-chart-embed-cfb-chart-1763259260441-hklg6nunx .embed-footer {
border-top: 1px solid #e5e5e5;
font-size: 12px;
color: #737373;
}
.cfb-chart-embed-cfb-chart-1763259260441-hklg6nunx .embed-footer-top {
display: flex;
justify-content: space-between;
align-items: center;
padding: 12px 16px;
}
.cfb-chart-embed-cfb-chart-1763259260441-hklg6nunx .embed-footer-link {
color: #737373;
text-decoration: none;
font-weight: 500;
}
.cfb-chart-embed-cfb-chart-1763259260441-hklg6nunx .embed-footer-link:hover {
color: #525252;
text-decoration: underline;
}
.cfb-chart-embed-cfb-chart-1763259260441-hklg6nunx .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-1763259260441-hklg6nunx .data-definitions-toggle:hover {
color: #525252;
}
.cfb-chart-embed-cfb-chart-1763259260441-hklg6nunx .caret {
transition: transform 0.2s ease;
font-size: 10px;
}
.cfb-chart-embed-cfb-chart-1763259260441-hklg6nunx .caret.expanded {
transform: rotate(180deg);
}
.cfb-chart-embed-cfb-chart-1763259260441-hklg6nunx .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-1763259260441-hklg6nunx .data-definitions.expanded {
display: block;
}
.cfb-chart-embed-cfb-chart-1763259260441-hklg6nunx .data-definitions ul {
margin: 0;
padding-left: 0;
list-style: none;
}
.cfb-chart-embed-cfb-chart-1763259260441-hklg6nunx .data-definitions li {
margin-bottom: 4px;
}
Overall Team Performance
Alabama vs. Oklahoma • Nov 15, 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_1763259260441_hklg6nunx() {
const definitions = document.getElementById(‘dataDefinitions_cfb-chart-1763259260441-hklg6nunx’);
const caret = document.getElementById(‘caret_cfb-chart-1763259260441-hklg6nunx’);
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-1763259260441-hklg6nunx’);
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-1763259260441-hklg6nunx’);
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.1506849315068493,
0.12
],
“backgroundColor”: [
“rgba(101, 0, 20, 0.8)”,
“#4c2d00CC”
],
“stack”: “SRXR”,
“datalabels”: {
“display”: false
}
},
{
“label”: “Success Rate (SR)”,
“data”: [
0.4657534246575342,
0.28
],
“backgroundColor”: [
“rgba(175, 40, 60, 0.8)”,
“#A16207CC”
],
“stack”: “SRXR”,
“datalabels”: {
“display”: true
},
“playCountData”: [
73,
50
]
},
{
“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”: “#A16207CC”,
“explosive”: “#4c2d00CC”,
“light”: “#FEF3C7CC”,
“color”: “#A16207”,
“colorDark”: “#4c2d00”
},
“teamPlayCount”: 73,
“opponentPlayCount”: 50,
“currentParams”: {
“year”: 2025,
“week”: 12,
“seasonType”: “regular”,
“team”: “Alabama”,
“gameId”: “401752765”
}
};
// 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-1763259260441-hklg6nunx’).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();
}
})();
Yeah, without looking at the scoreboard, you would be really pleased with this chart coming out of any SEC game! This looks like it should have resulted in something like the Wisconsin victory, not a 2-point loss in a low-scoring affair. Alabama had one of its most efficient games this season, albeit in a year where we really haven’t had very high SR’s.
This solid 47% Success Rate is impressive compared to that of the victorious Oklahoma Sooners, who delivered a whopping 28% success rate on the day—which would, I believe, be the worst success rate that Alabama had delivered all season, or maybe even in several seasons. Oklahoma’s down-by-down performance was bad. They just had a few breaks go their way and delivered in a few key moments (including getting close enough for their skilled kicker to score the deciding points in a way that Alabama could not).
.cfb-chart-embed-cfb-chart-1763259277502-j2dpsrbg2 {
font-family: -apple-system, BlinkMacSystemFont, ‘Segoe UI’, ‘Roboto’, sans-serif;
margin: 0;
padding: 0;
}
.cfb-chart-embed-cfb-chart-1763259277502-j2dpsrbg2 .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-1763259277502-j2dpsrbg2 .chart-header {
padding: 18px 24px 14px;
border-bottom: 1px solid #e5e5e5;
background: white;
}
.cfb-chart-embed-cfb-chart-1763259277502-j2dpsrbg2 .chart-title {
font-size: 18px;
font-weight: 600;
color: #171717;
margin: 0;
}
.cfb-chart-embed-cfb-chart-1763259277502-j2dpsrbg2 .chart-subtitle {
font-size: 11px;
font-weight: 400;
color: #737373;
margin: 4px 0 0 0;
}
.cfb-chart-embed-cfb-chart-1763259277502-j2dpsrbg2 .chart-content {
padding: 20px 24px 24px !important;
}
.cfb-chart-embed-cfb-chart-1763259277502-j2dpsrbg2 .chart-content { height: 325px; }
@media (max-width: 640px) {
.cfb-chart-embed-cfb-chart-1763259277502-j2dpsrbg2 .chart-content {
padding: 12px 16px 20px !important;
height: 280px !important;
}
.cfb-chart-embed-cfb-chart-1763259277502-j2dpsrbg2 .chart-header {
padding: 12px 16px 12px !important;
}
.cfb-chart-embed-cfb-chart-1763259277502-j2dpsrbg2 .embed-footer-top {
padding: 8px 12px !important;
}
.cfb-chart-embed-cfb-chart-1763259277502-j2dpsrbg2 .data-definitions {
padding: 12px !important;
}
}
.cfb-chart-embed-cfb-chart-1763259277502-j2dpsrbg2 .embed-footer {
border-top: 1px solid #e5e5e5;
font-size: 12px;
color: #737373;
}
.cfb-chart-embed-cfb-chart-1763259277502-j2dpsrbg2 .embed-footer-top {
display: flex;
justify-content: space-between;
align-items: center;
padding: 12px 16px;
}
.cfb-chart-embed-cfb-chart-1763259277502-j2dpsrbg2 .embed-footer-link {
color: #737373;
text-decoration: none;
font-weight: 500;
}
.cfb-chart-embed-cfb-chart-1763259277502-j2dpsrbg2 .embed-footer-link:hover {
color: #525252;
text-decoration: underline;
}
.cfb-chart-embed-cfb-chart-1763259277502-j2dpsrbg2 .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-1763259277502-j2dpsrbg2 .data-definitions-toggle:hover {
color: #525252;
}
.cfb-chart-embed-cfb-chart-1763259277502-j2dpsrbg2 .caret {
transition: transform 0.2s ease;
font-size: 10px;
}
.cfb-chart-embed-cfb-chart-1763259277502-j2dpsrbg2 .caret.expanded {
transform: rotate(180deg);
}
.cfb-chart-embed-cfb-chart-1763259277502-j2dpsrbg2 .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-1763259277502-j2dpsrbg2 .data-definitions.expanded {
display: block;
}
.cfb-chart-embed-cfb-chart-1763259277502-j2dpsrbg2 .data-definitions ul {
margin: 0;
padding-left: 0;
list-style: none;
}
.cfb-chart-embed-cfb-chart-1763259277502-j2dpsrbg2 .data-definitions li {
margin-bottom: 4px;
}
SR and XR by Team
Alabama vs. Oklahoma • Nov 15, 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_1763259277502_j2dpsrbg2() {
const definitions = document.getElementById(‘dataDefinitions_cfb-chart-1763259277502-j2dpsrbg2’);
const caret = document.getElementById(‘caret_cfb-chart-1763259277502-j2dpsrbg2’);
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-1763259277502-j2dpsrbg2’);
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-1763259277502-j2dpsrbg2’);
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”: 123,
“y”: 0.42
},
{
“x”: 123,
“y”: 0
}
],
“backgroundColor”: “rgba(0,0,0,0.03)”,
“borderColor”: “transparent”,
“pointRadius”: 0,
“fill”: true,
“tension”: 0,
“showLine”: true,
“datalabels”: {
“display”: false
}
},
{
“data”: [
{
“x”: 1,
“y”: 0,
“text”: “T.Simpson pass incomplete short left to #80 J.Cuevas thrown to ALA25”
},
{
“x”: 2,
“y”: 0,
“text”: “J.Miller rush middle for 3 yards gain to the ALA23 (#10 K.Lewis)”
},
{
“x”: 3,
“y”: 0,
“text”: “T.Simpson rush right for 0 yards to the ALA23 (#97 M.Jones Jr.)”
},
{
“x”: 8,
“y”: 0,
“text”: “T.Simpson sacked for loss of 7 yards to the ALA18 (#10 K.Lewis)”
},
{
“x”: 9,
“y”: 0,
“text”: “T.Simpson pass complete short right to #2 R.Williams caught at ALA15, for 1 yard loss to the ALA17 (#38 O.Heinecke)”
},
{
“x”: 10,
“y”: 0,
“text”: “T.Simpson pass incomplete deep left to #2 R.Williams thrown to OU 41”
},
{
“x”: 17,
“y”: 0.14285714285714285,
“text”: “T.Simpson pass complete short middle to #5 G.Bernard caught at ALA34, for 17 yards to the ALA37 (#25 M.Boganowski), 1ST DOWN”
},
{
“x”: 18,
“y”: 0.125,
“text”: “T.Simpson pass complete short left to #4 D.Hill caught at ALA38, for 8 yards to the ALA45 (#5 K.Daniels; #25 M.Boganowski)”
},
{
“x”: 19,
“y”: 0.1111111111111111,
“text”: “D.Hill rush left for 1 yard gain to the ALA46 (#11 K.McKinzie)”
},
{
“x”: 20,
“y”: 0.1,
“text”: “D.Hill rush middle for 2 yards gain to the ALA48 (#22 P.Bowen), 1ST DOWN”
},
{
“x”: 21,
“y”: 0.18181818181818182,
“text”: “T.Simpson pass complete short left to #5 G.Bernard caught at OU 37, for 15 yards to the OU 37 (#4 C.Guillory), 1ST DOWN”
},
{
“x”: 22,
“y”: 0.16666666666666666,
“text”: “D.Hill rush right for 7 yards gain to the OU 30 (#13 R.Powers III; #99 M.Strong)”
},
{
“x”: 23,
“y”: 0.15384615384615385,
“text”: “T.Simpson pass intercepted by #23 E.Bowen at OU 13 QB hurried by #10 K.Lewis #23 E.Bowen return 87 yards to the ALA00 TOUCHDOWN, clock 02:03 #29 T.Sandell kick attempt good (H: #87 J.Ulrich, LS: #49 B.Anderson)”
},
{
“x”: 24,
“y”: 0.14285714285714285,
“text”: “T.Simpson pass complete short middle to #80 J.Cuevas caught at ALA27, for 3 yards to the ALA31 (#10 K.Lewis)”
},
{
“x”: 25,
“y”: 0.13333333333333333,
“text”: “T.Simpson pass complete short middle to #5 G.Bernard caught at ALA43, for 11 yards to the ALA42 (#3 R.Spears-Jennings), 1ST DOWN”
},
{
“x”: 26,
“y”: 0.125,
“text”: “J.Miller rush right for 2 yards gain to the ALA44 (#0 D.Stone)”
},
{
“x”: 27,
“y”: 0.11764705882352941,
“text”: “T.Simpson pass complete short left to #5 G.Bernard caught at ALA40, for 8 yards to the OU 48 (#1 J.Hardy; #97 M.Jones Jr.), 1ST DOWN”
},
{
“x”: 28,
“y”: 0.1111111111111111,
“text”: “T.Simpson rush left for 9 yards gain to the OU 39 (#4 C.Guillory)”
},
{
“x”: 29,
“y”: 0.10526315789473684,
“text”: “T.Simpson pass incomplete short right to #5 G.Bernard thrown to OU 25”
},
{
“x”: 30,
“y”: 0.1,
“text”: “D.Hill rush middle for 3 yards gain to the OU 36 (#52 D.Williams; #0 D.Stone), 1ST DOWN”
},
{
“x”: 31,
“y”: 0.14285714285714285,
“text”: “T.Simpson pass complete short left to #81 K.Edwards caught at OU 20, for 25 yards to the OU 11 (#7 S.Omosigho), 1ST DOWN”
},
{
“x”: 32,
“y”: 0.13636363636363635,
“text”: “T.Simpson pass incomplete short middle to #1 I.Horton thrown to OU 01”
},
{
“x”: 33,
“y”: 0.13043478260869565,
“text”: “J.Miller rush left for 2 yards gain to the OU 09 (#7 S.Omosigho; #44 T.Wein)”
},
{
“x”: 34,
“y”: 0.125,
“text”: “D.Hill rush middle for 1 yard gain to the OU 01 (#52 D.Williams)”
},
{
“x”: 35,
“y”: 0.12,
“text”: “D.Hill rush middle for 1 yard gain to the OU 00 TOUCHDOWN, clock 10:36 #31 C.Talty kick attempt good (H: #38 B.Doud, LS: #45 D.Bird)”
},
{
“x”: 41,
“y”: 0.15384615384615385,
“text”: “T.Simpson pass complete deep right to #2 R.Williams caught at OU 48, for 38 yards to the OU 40 (#23 E.Bowen), 1ST DOWN”
},
{
“x”: 42,
“y”: 0.14814814814814814,
“text”: “T.Simpson pass complete short right to #5 G.Bernard caught at OU 36, for 5 yards to the OU 35 (#23 E.Bowen)”
},
{
“x”: 43,
“y”: 0.14285714285714285,
“text”: “T.Simpson pass complete short right to #17 L.Brooks caught at OU 38, for 6 yards to the OU 29 (#23 E.Bowen), 1ST DOWN”
},
{
“x”: 44,
“y”: 0.13793103448275862,
“text”: “T.Simpson pass incomplete short middle to #5 G.Bernard thrown to OU 13”
},
{
“x”: 45,
“y”: 0.13333333333333333,
“text”: “D.Hill rush left for 4 yards gain to the OU 25 (#25 M.Boganowski; #52 D.Williams)”
},
{
“x”: 46,
“y”: 0.16129032258064516,
“text”: “T.Simpson pass complete short right to #80 J.Cuevas caught at OU 20, for 25 yards to the OU 00 TOUCHDOWN, clock 06:13, 1ST DOWN #31 C.Talty kick attempt good (H: #38 B.Doud, LS: #45 D.Bird)”
},
{
“x”: 53,
“y”: 0.15625,
“text”: “T.Simpson pass complete short right to #26 J.Miller caught at ALA13, for 0 yards to the ALA13 (#13 R.Powers III)”
},
{
“x”: 54,
“y”: 0.15151515151515152,
“text”: “T.Simpson pass complete short right to #80 J.Cuevas caught at ALA18, for 14 yards to the ALA27 (#38 O.Heinecke; #1 J.Hardy), 1ST DOWN”
},
{
“x”: 55,
“y”: 0.14705882352941177,
“text”: “T.Simpson pass complete short right to #2 R.Williams caught at ALA31, for 8 yards to the ALA35 (#10 K.Lewis)”
},
{
“x”: 56,
“y”: 0.14285714285714285,
“text”: “T.Simpson pass complete short middle to #80 J.Cuevas caught at ALA40, for 14 yards to the ALA49 (#34 A.Adebawore; #3 R.Spears-Jennings), 1ST DOWN”
},
{
“x”: 57,
“y”: 0.1388888888888889,
“text”: “T.Simpson pass complete short left to #4 D.Hill caught at OU 49, for 2 yards to the OU 49 (#38 O.Heinecke)”
},
{
“x”: 58,
“y”: 0.16216216216216217,
“text”: “T.Simpson pass complete short middle to #4 D.Hill caught at ALA45, for 16 yards to the OU 43 (#23 E.Bowen)”
},
{
“x”: 59,
“y”: 0.15789473684210525,
“text”: “T.Simpson pass complete short right to #80 J.Cuevas caught at OU 40, for 4 yards to the OU 39 (#44 T.Wein), out of bounds, 1ST DOWN”
},
{
“x”: 60,
“y”: 0.15384615384615385,
“text”: “T.Simpson pass incomplete short middle to #26 J.Miller thrown to OU 35”
},
{
“x”: 61,
“y”: 0.15,
“text”: “T.Simpson pass incomplete deep left to #5 G.Bernard thrown to OU 15 QB hurried by #44 T.Wein”
},
{
“x”: 62,
“y”: 0.14634146341463414,
“text”: “T.Simpson pass incomplete short left to #5 G.Bernard thrown to OU 20 broken up by #23 E.Bowen”
},
{
“x”: 63,
“y”: 0.16666666666666666,
“text”: “T.Simpson pass complete short left to #1 I.Horton caught at OU 29, for 15 yards to the OU 24 (#22 P.Bowen), 1ST DOWN”
},
{
“x”: 64,
“y”: 0.16279069767441862,
“text”: “T.Simpson pass complete short left to #5 G.Bernard caught at OU 18, for 6 yards to the OU 18, out of bounds at OU 18”
},
{
“x”: 71,
“y”: 0.1590909090909091,
“text”: “T.Simpson pass incomplete short right to #5 G.Bernard thrown to ALA41”
},
{
“x”: 72,
“y”: 0.17777777777777778,
“text”: “D.Hill rush right for 28 yards gain to the OU 47 (#23 E.Bowen), out of bounds, 1ST DOWN”
},
{
“x”: 73,
“y”: 0.17391304347826086,
“text”: “D.Hill rush left for 0 yards to the OU 47 (#13 R.Powers III)”
},
{
“x”: 74,
“y”: 0.19148936170212766,
“text”: “T.Simpson pass complete short right to #80 J.Cuevas caught at OU 48, for 20 yards to the OU 27 (#3 R.Spears-Jennings), 1ST DOWN”
},
{
“x”: 75,
“y”: 0.20833333333333334,
“text”: “T.Simpson pass complete deep right to #1 I.Horton caught at OU 03, for 26 yards to the OU 01 (#3 R.Spears-Jennings), out of bounds, 1ST DOWN”
},
{
“x”: 76,
“y”: 0.20408163265306123,
“text”: “J.Miller rush middle for 0 yards to the OU 01 (#56 G.Halton)”
},
{
“x”: 77,
“y”: 0.2,
“text”: “D.Hill rush middle for 1 yard gain to the OU 00 TOUCHDOWN, clock 07:27 #31 C.Talty kick attempt good (H: #38 B.Doud, LS: #52 A.Rozier)”
},
{
“x”: 83,
“y”: 0.19607843137254902,
“text”: “D.Hill pass complete short left to #4 D.Hill caught at ALA22, for 4 yards to the ALA24, End Of Play”
},
{
“x”: 84,
“y”: 0.19230769230769232,
“text”: “D.Hill rush right for 3 yards gain to the ALA27 (#7 S.Omosigho; #11 K.McKinzie)”
},
{
“x”: 85,
“y”: 0.18867924528301888,
“text”: “T.Simpson pass incomplete short middle to #5 G.Bernard thrown to ALA38”
},
{
“x”: 89,
“y”: 0.18518518518518517,
“text”: “J.Miller rush left for 4 yards gain to the ALA22 (#52 D.Williams; #0 D.Stone)”
},
{
“x”: 90,
“y”: 0.18181818181818182,
“text”: “T.Simpson rush right for 8 yards gain to the ALA30 (#22 P.Bowen; #0 D.Stone), 1ST DOWN”
},
{
“x”: 91,
“y”: 0.17857142857142858,
“text”: “J.Miller rush left for 1 yard gain to the ALA31 (#19 J.Johnson)”
},
{
“x”: 92,
“y”: 0.17543859649122806,
“text”: “T.Simpson pass incomplete short left to #5 G.Bernard thrown to ALA30 QB hurried by #44 T.Wein and #34 A.Adebawore”
},
{
“x”: 97,
“y”: 0.1724137931034483,
“text”: “D.Hill rush left for 5 yards gain to the ALA30 (#7 S.Omosigho)”
},
{
“x”: 98,
“y”: 0.1694915254237288,
“text”: “D.Hill rush right for 0 yards to the ALA30 (#11 K.McKinzie)”
},
{
“x”: 99,
“y”: 0.16666666666666666,
“text”: “T.Simpson sacked for loss of 7 yards to the ALA23 (#12 D.Jordan)”
},
{
“x”: 108,
“y”: 0.16393442622950818,
“text”: “D.Hill rush right for 3 yards gain to the ALA09 (#12 D.Jordan)”
},
{
“x”: 109,
“y”: 0.16129032258064516,
“text”: “T.Simpson rush right for 2 yards gain to the ALA11 (#10 K.Lewis), out of bounds”
},
{
“x”: 110,
“y”: 0.15873015873015872,
“text”: “T.Simpson pass complete short left to #5 G.Bernard caught at ALA20, for 9 yards to the ALA20 (#4 C.Guillory), out of bounds, 1ST DOWN”
},
{
“x”: 111,
“y”: 0.15625,
“text”: “J.Miller rush left for 8 yards gain to the ALA28 (#38 O.Heinecke)”
},
{
“x”: 112,
“y”: 0.15384615384615385,
“text”: “J.Miller rush middle for 5 yards gain to the ALA33 (#4 C.Guillory), 1ST DOWN”
},
{
“x”: 113,
“y”: 0.15151515151515152,
“text”: “J.Miller rush right for 2 yards gain to the ALA35 (#22 P.Bowen)”
},
{
“x”: 114,
“y”: 0.14925373134328357,
“text”: “T.Simpson pass complete short left to #17 L.Brooks caught at ALA40, for 6 yards to the ALA41 (#22 P.Bowen; #99 M.Strong). #17 L.Brooks injured on the play”
},
{
“x”: 115,
“y”: 0.14705882352941177,
“text”: “D.Hill rush middle for 1 yard gain to the ALA42 (#11 K.McKinzie; #56 G.Halton)”
},
{
“x”: 116,
“y”: 0.14492753623188406,
“text”: “L.Brooks rush right for 2 yards gain to the ALA44 (#3 R.Spears-Jennings), 1ST DOWN”
},
{
“x”: 117,
“y”: 0.14285714285714285,
“text”: “T.Simpson sacked for loss of 11 yards to the ALA33 (#10 K.Lewis)”
},
{
“x”: 118,
“y”: 0.14084507042253522,
“text”: “T.Simpson pass incomplete deep right to #1 I.Horton thrown to OU 43”
},
{
“x”: 119,
“y”: 0.1527777777777778,
“text”: “T.Simpson pass complete short right to #1 I.Horton caught at ALA48, for 15 yards to the ALA48 (#10 K.Lewis)”
},
{
“x”: 120,
“y”: 0.1506849315068493,
“text”: “T.Simpson pass incomplete short left to #2 R.Williams thrown to OU 46 broken up by #22 P.Bowen, TURNOVER ON DOWNS”
}
],
“label”: “Alabama XR”,
“borderColor”: “rgba(101, 0, 20, 0.8)”,
“borderWidth”: 2.2,
“fill”: false
},
{
“data”: [
{
“x”: 1,
“y”: 0,
“text”: “T.Simpson pass incomplete short left to #80 J.Cuevas thrown to ALA25”
},
{
“x”: 2,
“y”: 0,
“text”: “J.Miller rush middle for 3 yards gain to the ALA23 (#10 K.Lewis)”
},
{
“x”: 3,
“y”: 0,
“text”: “T.Simpson rush right for 0 yards to the ALA23 (#97 M.Jones Jr.)”
},
{
“x”: 8,
“y”: 0,
“text”: “T.Simpson sacked for loss of 7 yards to the ALA18 (#10 K.Lewis)”
},
{
“x”: 9,
“y”: 0,
“text”: “T.Simpson pass complete short right to #2 R.Williams caught at ALA15, for 1 yard loss to the ALA17 (#38 O.Heinecke)”
},
{
“x”: 10,
“y”: 0,
“text”: “T.Simpson pass incomplete deep left to #2 R.Williams thrown to OU 41”
},
{
“x”: 17,
“y”: 0.14285714285714285,
“text”: “T.Simpson pass complete short middle to #5 G.Bernard caught at ALA34, for 17 yards to the ALA37 (#25 M.Boganowski), 1ST DOWN”
},
{
“x”: 18,
“y”: 0.25,
“text”: “T.Simpson pass complete short left to #4 D.Hill caught at ALA38, for 8 yards to the ALA45 (#5 K.Daniels; #25 M.Boganowski)”
},
{
“x”: 19,
“y”: 0.2222222222222222,
“text”: “D.Hill rush left for 1 yard gain to the ALA46 (#11 K.McKinzie)”
},
{
“x”: 20,
“y”: 0.3,
“text”: “D.Hill rush middle for 2 yards gain to the ALA48 (#22 P.Bowen), 1ST DOWN”
},
{
“x”: 21,
“y”: 0.36363636363636365,
“text”: “T.Simpson pass complete short left to #5 G.Bernard caught at OU 37, for 15 yards to the OU 37 (#4 C.Guillory), 1ST DOWN”
},
{
“x”: 22,
“y”: 0.4166666666666667,
“text”: “D.Hill rush right for 7 yards gain to the OU 30 (#13 R.Powers III; #99 M.Strong)”
},
{
“x”: 23,
“y”: 0.38461538461538464,
“text”: “T.Simpson pass intercepted by #23 E.Bowen at OU 13 QB hurried by #10 K.Lewis #23 E.Bowen return 87 yards to the ALA00 TOUCHDOWN, clock 02:03 #29 T.Sandell kick attempt good (H: #87 J.Ulrich, LS: #49 B.Anderson)”
},
{
“x”: 24,
“y”: 0.35714285714285715,
“text”: “T.Simpson pass complete short middle to #80 J.Cuevas caught at ALA27, for 3 yards to the ALA31 (#10 K.Lewis)”
},
{
“x”: 25,
“y”: 0.4,
“text”: “T.Simpson pass complete short middle to #5 G.Bernard caught at ALA43, for 11 yards to the ALA42 (#3 R.Spears-Jennings), 1ST DOWN”
},
{
“x”: 26,
“y”: 0.375,
“text”: “J.Miller rush right for 2 yards gain to the ALA44 (#0 D.Stone)”
},
{
“x”: 27,
“y”: 0.4117647058823529,
“text”: “T.Simpson pass complete short left to #5 G.Bernard caught at ALA40, for 8 yards to the OU 48 (#1 J.Hardy; #97 M.Jones Jr.), 1ST DOWN”
},
{
“x”: 28,
“y”: 0.4444444444444444,
“text”: “T.Simpson rush left for 9 yards gain to the OU 39 (#4 C.Guillory)”
},
{
“x”: 29,
“y”: 0.42105263157894735,
“text”: “T.Simpson pass incomplete short right to #5 G.Bernard thrown to OU 25”
},
{
“x”: 30,
“y”: 0.45,
“text”: “D.Hill rush middle for 3 yards gain to the OU 36 (#52 D.Williams; #0 D.Stone), 1ST DOWN”
},
{
“x”: 31,
“y”: 0.47619047619047616,
“text”: “T.Simpson pass complete short left to #81 K.Edwards caught at OU 20, for 25 yards to the OU 11 (#7 S.Omosigho), 1ST DOWN”
},
{
“x”: 32,
“y”: 0.45454545454545453,
“text”: “T.Simpson pass incomplete short middle to #1 I.Horton thrown to OU 01”
},
{
“x”: 33,
“y”: 0.43478260869565216,
“text”: “J.Miller rush left for 2 yards gain to the OU 09 (#7 S.Omosigho; #44 T.Wein)”
},
{
“x”: 34,
“y”: 0.4583333333333333,
“text”: “D.Hill rush middle for 1 yard gain to the OU 01 (#52 D.Williams)”
},
{
“x”: 35,
“y”: 0.48,
“text”: “D.Hill rush middle for 1 yard gain to the OU 00 TOUCHDOWN, clock 10:36 #31 C.Talty kick attempt good (H: #38 B.Doud, LS: #45 D.Bird)”
},
{
“x”: 41,
“y”: 0.5,
“text”: “T.Simpson pass complete deep right to #2 R.Williams caught at OU 48, for 38 yards to the OU 40 (#23 E.Bowen), 1ST DOWN”
},
{
“x”: 42,
“y”: 0.5185185185185185,
“text”: “T.Simpson pass complete short right to #5 G.Bernard caught at OU 36, for 5 yards to the OU 35 (#23 E.Bowen)”
},
{
“x”: 43,
“y”: 0.5357142857142857,
“text”: “T.Simpson pass complete short right to #17 L.Brooks caught at OU 38, for 6 yards to the OU 29 (#23 E.Bowen), 1ST DOWN”
},
{
“x”: 44,
“y”: 0.5172413793103449,
“text”: “T.Simpson pass incomplete short middle to #5 G.Bernard thrown to OU 13”
},
{
“x”: 45,
“y”: 0.5,
“text”: “D.Hill rush left for 4 yards gain to the OU 25 (#25 M.Boganowski; #52 D.Williams)”
},
{
“x”: 46,
“y”: 0.5161290322580645,
“text”: “T.Simpson pass complete short right to #80 J.Cuevas caught at OU 20, for 25 yards to the OU 00 TOUCHDOWN, clock 06:13, 1ST DOWN #31 C.Talty kick attempt good (H: #38 B.Doud, LS: #45 D.Bird)”
},
{
“x”: 53,
“y”: 0.5,
“text”: “T.Simpson pass complete short right to #26 J.Miller caught at ALA13, for 0 yards to the ALA13 (#13 R.Powers III)”
},
{
“x”: 54,
“y”: 0.5151515151515151,
“text”: “T.Simpson pass complete short right to #80 J.Cuevas caught at ALA18, for 14 yards to the ALA27 (#38 O.Heinecke; #1 J.Hardy), 1ST DOWN”
},
{
“x”: 55,
“y”: 0.5294117647058824,
“text”: “T.Simpson pass complete short right to #2 R.Williams caught at ALA31, for 8 yards to the ALA35 (#10 K.Lewis)”
},
{
“x”: 56,
“y”: 0.5428571428571428,
“text”: “T.Simpson pass complete short middle to #80 J.Cuevas caught at ALA40, for 14 yards to the ALA49 (#34 A.Adebawore; #3 R.Spears-Jennings), 1ST DOWN”
},
{
“x”: 57,
“y”: 0.5277777777777778,
“text”: “T.Simpson pass complete short left to #4 D.Hill caught at OU 49, for 2 yards to the OU 49 (#38 O.Heinecke)”
},
{
“x”: 58,
“y”: 0.5405405405405406,
“text”: “T.Simpson pass complete short middle to #4 D.Hill caught at ALA45, for 16 yards to the OU 43 (#23 E.Bowen)”
},
{
“x”: 59,
“y”: 0.5526315789473685,
“text”: “T.Simpson pass complete short right to #80 J.Cuevas caught at OU 40, for 4 yards to the OU 39 (#44 T.Wein), out of bounds, 1ST DOWN”
},
{
“x”: 60,
“y”: 0.5384615384615384,
“text”: “T.Simpson pass incomplete short middle to #26 J.Miller thrown to OU 35”
},
{
“x”: 61,
“y”: 0.525,
“text”: “T.Simpson pass incomplete deep left to #5 G.Bernard thrown to OU 15 QB hurried by #44 T.Wein”
},
{
“x”: 62,
“y”: 0.5121951219512195,
“text”: “T.Simpson pass incomplete short left to #5 G.Bernard thrown to OU 20 broken up by #23 E.Bowen”
},
{
“x”: 63,
“y”: 0.5238095238095238,
“text”: “T.Simpson pass complete short left to #1 I.Horton caught at OU 29, for 15 yards to the OU 24 (#22 P.Bowen), 1ST DOWN”
},
{
“x”: 64,
“y”: 0.5348837209302325,
“text”: “T.Simpson pass complete short left to #5 G.Bernard caught at OU 18, for 6 yards to the OU 18, out of bounds at OU 18”
},
{
“x”: 71,
“y”: 0.5227272727272727,
“text”: “T.Simpson pass incomplete short right to #5 G.Bernard thrown to ALA41”
},
{
“x”: 72,
“y”: 0.5333333333333333,
“text”: “D.Hill rush right for 28 yards gain to the OU 47 (#23 E.Bowen), out of bounds, 1ST DOWN”
},
{
“x”: 73,
“y”: 0.5217391304347826,
“text”: “D.Hill rush left for 0 yards to the OU 47 (#13 R.Powers III)”
},
{
“x”: 74,
“y”: 0.5319148936170213,
“text”: “T.Simpson pass complete short right to #80 J.Cuevas caught at OU 48, for 20 yards to the OU 27 (#3 R.Spears-Jennings), 1ST DOWN”
},
{
“x”: 75,
“y”: 0.5416666666666666,
“text”: “T.Simpson pass complete deep right to #1 I.Horton caught at OU 03, for 26 yards to the OU 01 (#3 R.Spears-Jennings), out of bounds, 1ST DOWN”
},
{
“x”: 76,
“y”: 0.5306122448979592,
“text”: “J.Miller rush middle for 0 yards to the OU 01 (#56 G.Halton)”
},
{
“x”: 77,
“y”: 0.54,
“text”: “D.Hill rush middle for 1 yard gain to the OU 00 TOUCHDOWN, clock 07:27 #31 C.Talty kick attempt good (H: #38 B.Doud, LS: #52 A.Rozier)”
},
{
“x”: 83,
“y”: 0.5294117647058824,
“text”: “D.Hill pass complete short left to #4 D.Hill caught at ALA22, for 4 yards to the ALA24, End Of Play”
},
{
“x”: 84,
“y”: 0.5192307692307693,
“text”: “D.Hill rush right for 3 yards gain to the ALA27 (#7 S.Omosigho; #11 K.McKinzie)”
},
{
“x”: 85,
“y”: 0.5094339622641509,
“text”: “T.Simpson pass incomplete short middle to #5 G.Bernard thrown to ALA38”
},
{
“x”: 89,
“y”: 0.5,
“text”: “J.Miller rush left for 4 yards gain to the ALA22 (#52 D.Williams; #0 D.Stone)”
},
{
“x”: 90,
“y”: 0.509090909090909,
“text”: “T.Simpson rush right for 8 yards gain to the ALA30 (#22 P.Bowen; #0 D.Stone), 1ST DOWN”
},
{
“x”: 91,
“y”: 0.5,
“text”: “J.Miller rush left for 1 yard gain to the ALA31 (#19 J.Johnson)”
},
{
“x”: 92,
“y”: 0.49122807017543857,
“text”: “T.Simpson pass incomplete short left to #5 G.Bernard thrown to ALA30 QB hurried by #44 T.Wein and #34 A.Adebawore”
},
{
“x”: 97,
“y”: 0.5,
“text”: “D.Hill rush left for 5 yards gain to the ALA30 (#7 S.Omosigho)”
},
{
“x”: 98,
“y”: 0.4915254237288136,
“text”: “D.Hill rush right for 0 yards to the ALA30 (#11 K.McKinzie)”
},
{
“x”: 99,
“y”: 0.48333333333333334,
“text”: “T.Simpson sacked for loss of 7 yards to the ALA23 (#12 D.Jordan)”
},
{
“x”: 108,
“y”: 0.47540983606557374,
“text”: “D.Hill rush right for 3 yards gain to the ALA09 (#12 D.Jordan)”
},
{
“x”: 109,
“y”: 0.46774193548387094,
“text”: “T.Simpson rush right for 2 yards gain to the ALA11 (#10 K.Lewis), out of bounds”
},
{
“x”: 110,
“y”: 0.47619047619047616,
“text”: “T.Simpson pass complete short left to #5 G.Bernard caught at ALA20, for 9 yards to the ALA20 (#4 C.Guillory), out of bounds, 1ST DOWN”
},
{
“x”: 111,
“y”: 0.484375,
“text”: “J.Miller rush left for 8 yards gain to the ALA28 (#38 O.Heinecke)”
},
{
“x”: 112,
“y”: 0.49230769230769234,
“text”: “J.Miller rush middle for 5 yards gain to the ALA33 (#4 C.Guillory), 1ST DOWN”
},
{
“x”: 113,
“y”: 0.48484848484848486,
“text”: “J.Miller rush right for 2 yards gain to the ALA35 (#22 P.Bowen)”
},
{
“x”: 114,
“y”: 0.4925373134328358,
“text”: “T.Simpson pass complete short left to #17 L.Brooks caught at ALA40, for 6 yards to the ALA41 (#22 P.Bowen; #99 M.Strong). #17 L.Brooks injured on the play”
},
{
“x”: 115,
“y”: 0.4852941176470588,
“text”: “D.Hill rush middle for 1 yard gain to the ALA42 (#11 K.McKinzie; #56 G.Halton)”
},
{
“x”: 116,
“y”: 0.4927536231884058,
“text”: “L.Brooks rush right for 2 yards gain to the ALA44 (#3 R.Spears-Jennings), 1ST DOWN”
},
{
“x”: 117,
“y”: 0.4857142857142857,
“text”: “T.Simpson sacked for loss of 11 yards to the ALA33 (#10 K.Lewis)”
},
{
“x”: 118,
“y”: 0.4788732394366197,
“text”: “T.Simpson pass incomplete deep right to #1 I.Horton thrown to OU 43”
},
{
“x”: 119,
“y”: 0.4722222222222222,
“text”: “T.Simpson pass complete short right to #1 I.Horton caught at ALA48, for 15 yards to the ALA48 (#10 K.Lewis)”
},
{
“x”: 120,
“y”: 0.4657534246575342,
“text”: “T.Simpson pass incomplete short left to #2 R.Williams thrown to OU 46 broken up by #22 P.Bowen, TURNOVER ON DOWNS”
}
],
“label”: “Alabama SR”,
“borderColor”: “rgba(175, 40, 60, 0.8)”,
“borderWidth”: 2.2,
“fill”: false
},
{
“data”: [
{
“x”: 4,
“y”: 1,
“text”: “D.Burks caught at ALA20, for 18 yards to the ALA12 (#2 Z.Brown; #10 J.Jefferson), 1ST DOWN”
},
{
“x”: 5,
“y”: 0.5,
“text”: “X.Robinson rush left for 4 yards gain to the ALA08 (#0 D.Lawson; #5 D.Lee Jr.)”
},
{
“x”: 6,
“y”: 0.3333333333333333,
“text”: “D.Burks caught at ALA06, for 1 yard to the ALA07 (#23 J.Smith; #10 J.Jefferson)”
},
{
“x”: 7,
“y”: 0.25,
“text”: “J.Mateer pass incomplete short left to #11 J.Gibson thrown to ALA02”
},
{
“x”: 11,
“y”: 0.2,
“text”: “X.Robinson rush left for 4 yards gain to the OU 41 (#94 E.Hill)”
},
{
“x”: 12,
“y”: 0.16666666666666666,
“text”: “J.Mateer rush right for 4 yards gain to the OU 45 (#0 D.Lawson)”
},
{
“x”: 13,
“y”: 0.14285714285714285,
“text”: “X.Robinson rush middle for 3 yards gain to the OU 48 (#41 N.Hill-Green; #8 J.Hill), 1ST DOWN”
},
{
“x”: 14,
“y”: 0.125,
“text”: “X.Robinson rush middle for 1 yard gain to the OU 49 (#0 D.Lawson)”
},
{
“x”: 15,
“y”: 0.1111111111111111,
“text”: “J.Mateer rush right for 1 yard gain to the OU 35 (#41 N.Hill-Green), out of bounds”
},
{
“x”: 16,
“y”: 0.1,
“text”: “J.Mateer pass complete short left to #5 I.Sategna III caught at OU 32, for 6 yards to the OU 41 (#18 B.Hubbard; #3 K.Sabb)”
},
{
“x”: 36,
“y”: 0.09090909090909091,
“text”: “J.Mateer pass incomplete short right to #4 D.Burks thrown to OU 35 broken up by #10 J.Jefferson”
},
{
“x”: 37,
“y”: 0.08333333333333333,
“text”: “J.Mateer rush middle for 5 yards gain to the OU 30 (#22 L.Overton)”
},
{
“x”: 38,
“y”: 0.07692307692307693,
“text”: “J.Mateer pass incomplete short left to #5 I.Sategna III thrown to OU 35 QB hurried by #41 N.Hill-Green”
},
{
“x”: 39,
“y”: 0.07142857142857142,
“text”: “J.Mateer pass complete short right to #12 J.Kanak caught at ALA22, for 11 yards to the ALA20 (#2 Z.Brown), 1ST DOWN”
},
{
“x”: 40,
“y”: 0.13333333333333333,
“text”: “J.Mateer rush middle for 20 yards gain to the ALA00 TOUCHDOWN, clock 08:49, 1ST DOWN #29 T.Sandell kick attempt good (H: #87 J.Ulrich, LS: #49 B.Anderson)”
},
{
“x”: 47,
“y”: 0.125,
“text”: “J.Mateer pass complete short middle to #12 J.Kanak caught at OU 31, for 12 yards to the OU 37 (#10 J.Jefferson; #18 B.Hubbard), 1ST DOWN”
},
{
“x”: 48,
“y”: 0.11764705882352941,
“text”: “J.Mateer pass complete short left to #24 X.Robinson caught at OU 34, for 8 yards to the OU 45 (#18 B.Hubbard)”
},
{
“x”: 49,
“y”: 0.1111111111111111,
“text”: “X.Robinson rush middle for 6 yards gain to the ALA49 (#94 E.Hill; #1 D.Jackson), 1ST DOWN”
},
{
“x”: 50,
“y”: 0.10526315789473684,
“text”: “X.Robinson rush left for 1 yard gain to the ALA48 (#1 D.Jackson)”
},
{
“x”: 51,
“y”: 0.1,
“text”: “J.Mateer pass complete short right to #5 I.Sategna III caught at ALA49, for 2 yards to the ALA46 (#16 R.Morgan; #3 K.Sabb)”
},
{
“x”: 52,
“y”: 0.09523809523809523,
“text”: “J.Mateer pass incomplete short right to #6 T.Blaylock thrown to ALA49 QB hurried by #42 Y.Pierre”
},
{
“x”: 65,
“y”: 0.13636363636363635,
“text”: “I.Sategna III rush right for 21 yards gain to the OU 46 (#5 D.Lee Jr.), 1ST DOWN”
},
{
“x”: 66,
“y”: 0.13043478260869565,
“text”: “X.Robinson rush middle for 7 yards gain to the ALA47 (#18 B.Hubbard)”
},
{
“x”: 67,
“y”: 0.125,
“text”: “J.Mateer pass complete short right to #24 X.Robinson caught at OU 42, for 0 yards to the OU 43 (#16 R.Morgan)”
},
{
“x”: 68,
“y”: 0.16,
“text”: “J.Mateer pass complete short right to #5 I.Sategna III caught at ALA40, for 21 yards to the ALA36 (#5 D.Lee Jr.), 1ST DOWN”
},
{
“x”: 69,
“y”: 0.15384615384615385,
“text”: “J.Mateer sacked for loss of 2 yards to the ALA41 (#3 K.Sabb)”
},
{
“x”: 70,
“y”: 0.14814814814814814,
“text”: “J.Mateer pass complete short right to #84 J.Carter caught at ALA35, for 7 yards to the ALA34 (#18 B.Hubbard)”
},
{
“x”: 78,
“y”: 0.14285714285714285,
“text”: “J.Mateer pass incomplete short right to #4 D.Burks thrown to OU 30 broken up by #96 T.Keenan III”
},
{
“x”: 79,
“y”: 0.1724137931034483,
“text”: “J.Mateer pass complete short middle to #84 J.Carter caught at OU 41, for 22 yards to the OU 47 (#1 D.Jackson), 1ST DOWN”
},
{
“x”: 80,
“y”: 0.16666666666666666,
“text”: “J.Mateer pass complete short left to #84 J.Carter caught at ALA45, for 7 yards to the ALA46 (#1 D.Jackson)”
},
{
“x”: 81,
“y”: 0.16129032258064516,
“text”: “T.Blaylock rush left for 1 yard gain to the ALA45 (#16 R.Morgan; #0 D.Lawson)”
},
{
“x”: 82,
“y”: 0.15625,
“text”: “T.Blaylock rush left for 4 yards loss to the ALA49 (#42 Y.Pierre) PENALTY OU Illegal Formation declined”
},
{
“x”: 86,
“y”: 0.15151515151515152,
“text”: “X.Robinson rush middle for 1 yard gain to the OU 36 (#94 E.Hill)”
},
{
“x”: 87,
“y”: 0.14705882352941177,
“text”: “J.Mateer pass incomplete short right to #5 I.Sategna III thrown to OU 40”
},
{
“x”: 88,
“y”: 0.14285714285714285,
“text”: “J.Mateer pass incomplete short left to #84 J.Carter thrown to OU 50 PENALTY OU Chop Block declined”
},
{
“x”: 93,
“y”: 0.1388888888888889,
“text”: “J.Mateer rush left for 3 yards gain to the ALA25 (#10 J.Jefferson)”
},
{
“x”: 94,
“y”: 0.13513513513513514,
“text”: “T.Blaylock rush middle for 0 yards to the ALA10 (#42 Y.Pierre)”
},
{
“x”: 95,
“y”: 0.13157894736842105,
“text”: “T.Blaylock rush left for 4 yards gain to the ALA06 (#42 Y.Pierre)”
},
{
“x”: 96,
“y”: 0.1282051282051282,
“text”: “J.Mateer rush right for 0 yards to the ALA06 (#3 K.Sabb; #2 Z.Brown)”
},
{
“x”: 100,
“y”: 0.125,
“text”: “J.Mateer rush middle for 0 yards to the OU 30 (#11 J.Renaud; #24 N.Carter)”
},
{
“x”: 101,
“y”: 0.12195121951219512,
“text”: “J.Mateer pass complete short left to #11 J.Gibson caught at OU 38, for 11 yards to the OU 41 (#1 D.Jackson), 1ST DOWN”
},
{
“x”: 102,
“y”: 0.11904761904761904,
“text”: “X.Robinson rush right for 4 yards gain to the OU 45 (#0 D.Lawson; #11 J.Renaud)”
},
{
“x”: 103,
“y”: 0.11627906976744186,
“text”: “J.Mateer pass incomplete short middle to #12 J.Kanak thrown to OU 50 broken up by #41 N.Hill-Green”
},
{
“x”: 104,
“y”: 0.13636363636363635,
“text”: “J.Mateer pass complete short left to #11 J.Gibson caught at ALA49, for 15 yards to the ALA40 (#5 D.Lee Jr.; #12 Z.Mincey), 1ST DOWN”
},
{
“x”: 105,
“y”: 0.13333333333333333,
“text”: “X.Robinson rush left for 3 yards gain to the ALA37 (#17 K.Collins)”
},
{
“x”: 106,
“y”: 0.13043478260869565,
“text”: “J.Mateer rush middle for 4 yards gain to the ALA33 (#22 L.Overton)”
},
{
“x”: 107,
“y”: 0.1276595744680851,
“text”: “J.Mateer pass incomplete short middle thrown to ALA45 QB hurried by #17 K.Collins PENALTY OU Intentional Grounding (#10 J.Mateer)”
},
{
“x”: 121,
“y”: 0.125,
“text”: “J.Mateer at ALA49 for loss of 1 yard”
},
{
“x”: 122,
“y”: 0.12244897959183673,
“text”: “J.Mateer at ALA50 for loss of 1 yard”
},
{
“x”: 123,
“y”: 0.12,
“text”: “J.Mateer at OU 47 for loss of 3 yards”
}
],
“label”: “Oklahoma XR”,
“borderColor”: “#4c2d00CC”,
“borderWidth”: 2.2,
“borderDash”: [
4,
4
],
“fill”: false
},
{
“data”: [
{
“x”: 4,
“y”: 1,
“text”: “D.Burks caught at ALA20, for 18 yards to the ALA12 (#2 Z.Brown; #10 J.Jefferson), 1ST DOWN”
},
{
“x”: 5,
“y”: 0.5,
“text”: “X.Robinson rush left for 4 yards gain to the ALA08 (#0 D.Lawson; #5 D.Lee Jr.)”
},
{
“x”: 6,
“y”: 0.3333333333333333,
“text”: “D.Burks caught at ALA06, for 1 yard to the ALA07 (#23 J.Smith; #10 J.Jefferson)”
},
{
“x”: 7,
“y”: 0.25,
“text”: “J.Mateer pass incomplete short left to #11 J.Gibson thrown to ALA02”
},
{
“x”: 11,
“y”: 0.2,
“text”: “X.Robinson rush left for 4 yards gain to the OU 41 (#94 E.Hill)”
},
{
“x”: 12,
“y”: 0.16666666666666666,
“text”: “J.Mateer rush right for 4 yards gain to the OU 45 (#0 D.Lawson)”
},
{
“x”: 13,
“y”: 0.2857142857142857,
“text”: “X.Robinson rush middle for 3 yards gain to the OU 48 (#41 N.Hill-Green; #8 J.Hill), 1ST DOWN”
},
{
“x”: 14,
“y”: 0.25,
“text”: “X.Robinson rush middle for 1 yard gain to the OU 49 (#0 D.Lawson)”
},
{
“x”: 15,
“y”: 0.2222222222222222,
“text”: “J.Mateer rush right for 1 yard gain to the OU 35 (#41 N.Hill-Green), out of bounds”
},
{
“x”: 16,
“y”: 0.2,
“text”: “J.Mateer pass complete short left to #5 I.Sategna III caught at OU 32, for 6 yards to the OU 41 (#18 B.Hubbard; #3 K.Sabb)”
},
{
“x”: 36,
“y”: 0.18181818181818182,
“text”: “J.Mateer pass incomplete short right to #4 D.Burks thrown to OU 35 broken up by #10 J.Jefferson”
},
{
“x”: 37,
“y”: 0.16666666666666666,
“text”: “J.Mateer rush middle for 5 yards gain to the OU 30 (#22 L.Overton)”
},
{
“x”: 38,
“y”: 0.15384615384615385,
“text”: “J.Mateer pass incomplete short left to #5 I.Sategna III thrown to OU 35 QB hurried by #41 N.Hill-Green”
},
{
“x”: 39,
“y”: 0.21428571428571427,
“text”: “J.Mateer pass complete short right to #12 J.Kanak caught at ALA22, for 11 yards to the ALA20 (#2 Z.Brown), 1ST DOWN”
},
{
“x”: 40,
“y”: 0.26666666666666666,
“text”: “J.Mateer rush middle for 20 yards gain to the ALA00 TOUCHDOWN, clock 08:49, 1ST DOWN #29 T.Sandell kick attempt good (H: #87 J.Ulrich, LS: #49 B.Anderson)”
},
{
“x”: 47,
“y”: 0.3125,
“text”: “J.Mateer pass complete short middle to #12 J.Kanak caught at OU 31, for 12 yards to the OU 37 (#10 J.Jefferson; #18 B.Hubbard), 1ST DOWN”
},
{
“x”: 48,
“y”: 0.35294117647058826,
“text”: “J.Mateer pass complete short left to #24 X.Robinson caught at OU 34, for 8 yards to the OU 45 (#18 B.Hubbard)”
},
{
“x”: 49,
“y”: 0.3888888888888889,
“text”: “X.Robinson rush middle for 6 yards gain to the ALA49 (#94 E.Hill; #1 D.Jackson), 1ST DOWN”
},
{
“x”: 50,
“y”: 0.3684210526315789,
“text”: “X.Robinson rush left for 1 yard gain to the ALA48 (#1 D.Jackson)”
},
{
“x”: 51,
“y”: 0.35,
“text”: “J.Mateer pass complete short right to #5 I.Sategna III caught at ALA49, for 2 yards to the ALA46 (#16 R.Morgan; #3 K.Sabb)”
},
{
“x”: 52,
“y”: 0.3333333333333333,
“text”: “J.Mateer pass incomplete short right to #6 T.Blaylock thrown to ALA49 QB hurried by #42 Y.Pierre”
},
{
“x”: 65,
“y”: 0.36363636363636365,
“text”: “I.Sategna III rush right for 21 yards gain to the OU 46 (#5 D.Lee Jr.), 1ST DOWN”
},
{
“x”: 66,
“y”: 0.391304347826087,
“text”: “X.Robinson rush middle for 7 yards gain to the ALA47 (#18 B.Hubbard)”
},
{
“x”: 67,
“y”: 0.375,
“text”: “J.Mateer pass complete short right to #24 X.Robinson caught at OU 42, for 0 yards to the OU 43 (#16 R.Morgan)”
},
{
“x”: 68,
“y”: 0.4,
“text”: “J.Mateer pass complete short right to #5 I.Sategna III caught at ALA40, for 21 yards to the ALA36 (#5 D.Lee Jr.), 1ST DOWN”
},
{
“x”: 69,
“y”: 0.38461538461538464,
“text”: “J.Mateer sacked for loss of 2 yards to the ALA41 (#3 K.Sabb)”
},
{
“x”: 70,
“y”: 0.37037037037037035,
“text”: “J.Mateer pass complete short right to #84 J.Carter caught at ALA35, for 7 yards to the ALA34 (#18 B.Hubbard)”
},
{
“x”: 78,
“y”: 0.35714285714285715,
“text”: “J.Mateer pass incomplete short right to #4 D.Burks thrown to OU 30 broken up by #96 T.Keenan III”
},
{
“x”: 79,
“y”: 0.3793103448275862,
“text”: “J.Mateer pass complete short middle to #84 J.Carter caught at OU 41, for 22 yards to the OU 47 (#1 D.Jackson), 1ST DOWN”
},
{
“x”: 80,
“y”: 0.4,
“text”: “J.Mateer pass complete short left to #84 J.Carter caught at ALA45, for 7 yards to the ALA46 (#1 D.Jackson)”
},
{
“x”: 81,
“y”: 0.3870967741935484,
“text”: “T.Blaylock rush left for 1 yard gain to the ALA45 (#16 R.Morgan; #0 D.Lawson)”
},
{
“x”: 82,
“y”: 0.375,
“text”: “T.Blaylock rush left for 4 yards loss to the ALA49 (#42 Y.Pierre) PENALTY OU Illegal Formation declined”
},
{
“x”: 86,
“y”: 0.36363636363636365,
“text”: “X.Robinson rush middle for 1 yard gain to the OU 36 (#94 E.Hill)”
},
{
“x”: 87,
“y”: 0.35294117647058826,
“text”: “J.Mateer pass incomplete short right to #5 I.Sategna III thrown to OU 40”
},
{
“x”: 88,
“y”: 0.34285714285714286,
“text”: “J.Mateer pass incomplete short left to #84 J.Carter thrown to OU 50 PENALTY OU Chop Block declined”
},
{
“x”: 93,
“y”: 0.3333333333333333,
“text”: “J.Mateer rush left for 3 yards gain to the ALA25 (#10 J.Jefferson)”
},
{
“x”: 94,
“y”: 0.32432432432432434,
“text”: “T.Blaylock rush middle for 0 yards to the ALA10 (#42 Y.Pierre)”
},
{
“x”: 95,
“y”: 0.3157894736842105,
“text”: “T.Blaylock rush left for 4 yards gain to the ALA06 (#42 Y.Pierre)”
},
{
“x”: 96,
“y”: 0.3076923076923077,
“text”: “J.Mateer rush right for 0 yards to the ALA06 (#3 K.Sabb; #2 Z.Brown)”
},
{
“x”: 100,
“y”: 0.3,
“text”: “J.Mateer rush middle for 0 yards to the OU 30 (#11 J.Renaud; #24 N.Carter)”
},
{
“x”: 101,
“y”: 0.3170731707317073,
“text”: “J.Mateer pass complete short left to #11 J.Gibson caught at OU 38, for 11 yards to the OU 41 (#1 D.Jackson), 1ST DOWN”
},
{
“x”: 102,
“y”: 0.30952380952380953,
“text”: “X.Robinson rush right for 4 yards gain to the OU 45 (#0 D.Lawson; #11 J.Renaud)”
},
{
“x”: 103,
“y”: 0.3023255813953488,
“text”: “J.Mateer pass incomplete short middle to #12 J.Kanak thrown to OU 50 broken up by #41 N.Hill-Green”
},
{
“x”: 104,
“y”: 0.3181818181818182,
“text”: “J.Mateer pass complete short left to #11 J.Gibson caught at ALA49, for 15 yards to the ALA40 (#5 D.Lee Jr.; #12 Z.Mincey), 1ST DOWN”
},
{
“x”: 105,
“y”: 0.3111111111111111,
“text”: “X.Robinson rush left for 3 yards gain to the ALA37 (#17 K.Collins)”
},
{
“x”: 106,
“y”: 0.30434782608695654,
“text”: “J.Mateer rush middle for 4 yards gain to the ALA33 (#22 L.Overton)”
},
{
“x”: 107,
“y”: 0.2978723404255319,
“text”: “J.Mateer pass incomplete short middle thrown to ALA45 QB hurried by #17 K.Collins PENALTY OU Intentional Grounding (#10 J.Mateer)”
},
{
“x”: 121,
“y”: 0.2916666666666667,
“text”: “J.Mateer at ALA49 for loss of 1 yard”
},
{
“x”: 122,
“y”: 0.2857142857142857,
“text”: “J.Mateer at ALA50 for loss of 1 yard”
},
{
“x”: 123,
“y”: 0.28,
“text”: “J.Mateer at OU 47 for loss of 3 yards”
}
],
“label”: “Oklahoma SR”,
“borderColor”: “#A16207CC”,
“borderWidth”: 2.2,
“borderDash”: [
4,
4
],
“fill”: false
},
{
“label”: “Quarters”,
“data”: [
{
“x”: 1,
“y”: 0
},
{
“x”: 1,
“y”: 1
},
{
“x”: 123,
“y”: 1
},
{
“x”: 123,
“y”: 0
},
{
“x”: 27,
“y”: 0
},
{
“x”: 27,
“y”: 1
},
{
“x”: 123,
“y”: 1
},
{
“x”: 123,
“y”: 0
},
{
“x”: 65,
“y”: 0
},
{
“x”: 65,
“y”: 1
},
{
“x”: 123,
“y”: 1
},
{
“x”: 123,
“y”: 0
},
{
“x”: 95,
“y”: 0
},
{
“x”: 95,
“y”: 1
},
{
“x”: 123,
“y”: 1
},
{
“x”: 123,
“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”: 12,
“seasonType”: “regular”,
“team”: “Alabama”,
“gameId”: “401752765”
}
};
// 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-1763259277502-j2dpsrbg2’).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 mean, you can’t help but read this chart the same way. Alabama’s efficiency did not start out well in this game, delivering a 3-and-out right away. But things climbed into league-average territory at the end of the 1st quarter and sailed into definitively positive territory for the 2nd and 3rd quarters. Things drifted a little bit in the 4th; unfortunately, a few things didn’t break there and the comeback ended.
But at the same time, Oklahoma had even worse 1st and 4th quarters, with efficiencies easily 15-20 points below those of Alabama’s. Alabama’s explosiveness rate (XR) was also higher than Oklahoma’s for most of this game, if only by a few points. Ultimately, that didn’t really matter because when you look at the explosiveness index—which bakes in a bit more about how explosive plays were—then Oklahoma still wins out there with a 1.41 to Alabama’s 1.21.
.cfb-chart-embed-cfb-chart-1763259286363-u9c158e89 {
font-family: -apple-system, BlinkMacSystemFont, ‘Segoe UI’, ‘Roboto’, sans-serif;
margin: 0;
padding: 0;
}
.cfb-chart-embed-cfb-chart-1763259286363-u9c158e89 .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-1763259286363-u9c158e89 .chart-header {
padding: 18px 24px 14px;
border-bottom: 1px solid #e5e5e5;
background: white;
}
.cfb-chart-embed-cfb-chart-1763259286363-u9c158e89 .chart-title {
font-size: 18px;
font-weight: 600;
color: #171717;
margin: 0;
}
.cfb-chart-embed-cfb-chart-1763259286363-u9c158e89 .chart-subtitle {
font-size: 11px;
font-weight: 400;
color: #737373;
margin: 4px 0 0 0;
}
.cfb-chart-embed-cfb-chart-1763259286363-u9c158e89 .chart-content {
padding: 20px 24px 24px !important;
}
.cfb-chart-embed-cfb-chart-1763259286363-u9c158e89 .chart-content { height: 325px; }
@media (max-width: 640px) {
.cfb-chart-embed-cfb-chart-1763259286363-u9c158e89 .chart-content {
padding: 12px 16px 20px !important;
height: 280px !important;
}
.cfb-chart-embed-cfb-chart-1763259286363-u9c158e89 .chart-header {
padding: 12px 16px 12px !important;
}
.cfb-chart-embed-cfb-chart-1763259286363-u9c158e89 .embed-footer-top {
padding: 8px 12px !important;
}
.cfb-chart-embed-cfb-chart-1763259286363-u9c158e89 .data-definitions {
padding: 12px !important;
}
}
.cfb-chart-embed-cfb-chart-1763259286363-u9c158e89 .embed-footer {
border-top: 1px solid #e5e5e5;
font-size: 12px;
color: #737373;
}
.cfb-chart-embed-cfb-chart-1763259286363-u9c158e89 .embed-footer-top {
display: flex;
justify-content: space-between;
align-items: center;
padding: 12px 16px;
}
.cfb-chart-embed-cfb-chart-1763259286363-u9c158e89 .embed-footer-link {
color: #737373;
text-decoration: none;
font-weight: 500;
}
.cfb-chart-embed-cfb-chart-1763259286363-u9c158e89 .embed-footer-link:hover {
color: #525252;
text-decoration: underline;
}
.cfb-chart-embed-cfb-chart-1763259286363-u9c158e89 .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-1763259286363-u9c158e89 .data-definitions-toggle:hover {
color: #525252;
}
.cfb-chart-embed-cfb-chart-1763259286363-u9c158e89 .caret {
transition: transform 0.2s ease;
font-size: 10px;
}
.cfb-chart-embed-cfb-chart-1763259286363-u9c158e89 .caret.expanded {
transform: rotate(180deg);
}
.cfb-chart-embed-cfb-chart-1763259286363-u9c158e89 .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-1763259286363-u9c158e89 .data-definitions.expanded {
display: block;
}
.cfb-chart-embed-cfb-chart-1763259286363-u9c158e89 .data-definitions ul {
margin: 0;
padding-left: 0;
list-style: none;
}
.cfb-chart-embed-cfb-chart-1763259286363-u9c158e89 .data-definitions li {
margin-bottom: 4px;
}
SR by Play Type: Oklahoma
Alabama vs. Oklahoma • Nov 15, 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_1763259286363_u9c158e89() {
const definitions = document.getElementById(‘dataDefinitions_cfb-chart-1763259286363-u9c158e89’);
const caret = document.getElementById(‘caret_cfb-chart-1763259286363-u9c158e89’);
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-1763259286363-u9c158e89’);
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-1763259286363-u9c158e89’);
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”: 50,
“y”: 0.42
},
{
“x”: 50,
“y”: 0
}
],
“backgroundColor”: “rgba(0,0,0,0.03)”,
“borderColor”: “transparent”,
“pointRadius”: 0,
“fill”: true,
“tension”: 0,
“showLine”: true,
“datalabels”: {
“display”: false
}
},
{
“data”: [
{
“x”: 1,
“y”: 0,
“text”: “D.Burks caught at ALA20, for 18 yards to the ALA12 (#2 Z.Brown; #10 J.Jefferson), 1ST DOWN”
},
{
“x”: 2,
“y”: 0,
“text”: “X.Robinson rush left for 4 yards gain to the ALA08 (#0 D.Lawson; #5 D.Lee Jr.)”
},
{
“x”: 3,
“y”: 0,
“text”: “D.Burks caught at ALA06, for 1 yard to the ALA07 (#23 J.Smith; #10 J.Jefferson)”
},
{
“x”: 4,
“y”: 0,
“text”: “J.Mateer pass incomplete short left to #11 J.Gibson thrown to ALA02”
},
{
“x”: 5,
“y”: 0,
“text”: “X.Robinson rush left for 4 yards gain to the OU 41 (#94 E.Hill)”
},
{
“x”: 6,
“y”: 0,
“text”: “J.Mateer rush right for 4 yards gain to the OU 45 (#0 D.Lawson)”
},
{
“x”: 7,
“y”: 0.25,
“text”: “X.Robinson rush middle for 3 yards gain to the OU 48 (#41 N.Hill-Green; #8 J.Hill), 1ST DOWN”
},
{
“x”: 8,
“y”: 0.2,
“text”: “X.Robinson rush middle for 1 yard gain to the OU 49 (#0 D.Lawson)”
},
{
“x”: 9,
“y”: 0.16666666666666666,
“text”: “J.Mateer rush right for 1 yard gain to the OU 35 (#41 N.Hill-Green), out of bounds”
},
{
“x”: 10,
“y”: 0.16666666666666666,
“text”: “J.Mateer pass complete short left to #5 I.Sategna III caught at OU 32, for 6 yards to the OU 41 (#18 B.Hubbard; #3 K.Sabb)”
},
{
“x”: 11,
“y”: 0.16666666666666666,
“text”: “J.Mateer pass incomplete short right to #4 D.Burks thrown to OU 35 broken up by #10 J.Jefferson”
},
{
“x”: 12,
“y”: 0.14285714285714285,
“text”: “J.Mateer rush middle for 5 yards gain to the OU 30 (#22 L.Overton)”
},
{
“x”: 13,
“y”: 0.14285714285714285,
“text”: “J.Mateer pass incomplete short left to #5 I.Sategna III thrown to OU 35 QB hurried by #41 N.Hill-Green”
},
{
“x”: 14,
“y”: 0.14285714285714285,
“text”: “J.Mateer pass complete short right to #12 J.Kanak caught at ALA22, for 11 yards to the ALA20 (#2 Z.Brown), 1ST DOWN”
},
{
“x”: 15,
“y”: 0.25,
“text”: “J.Mateer rush middle for 20 yards gain to the ALA00 TOUCHDOWN, clock 08:49, 1ST DOWN #29 T.Sandell kick attempt good (H: #87 J.Ulrich, LS: #49 B.Anderson)”
},
{
“x”: 16,
“y”: 0.25,
“text”: “J.Mateer pass complete short middle to #12 J.Kanak caught at OU 31, for 12 yards to the OU 37 (#10 J.Jefferson; #18 B.Hubbard), 1ST DOWN”
},
{
“x”: 17,
“y”: 0.25,
“text”: “J.Mateer pass complete short left to #24 X.Robinson caught at OU 34, for 8 yards to the OU 45 (#18 B.Hubbard)”
},
{
“x”: 18,
“y”: 0.3333333333333333,
“text”: “X.Robinson rush middle for 6 yards gain to the ALA49 (#94 E.Hill; #1 D.Jackson), 1ST DOWN”
},
{
“x”: 19,
“y”: 0.3,
“text”: “X.Robinson rush left for 1 yard gain to the ALA48 (#1 D.Jackson)”
},
{
“x”: 20,
“y”: 0.3,
“text”: “J.Mateer pass complete short right to #5 I.Sategna III caught at ALA49, for 2 yards to the ALA46 (#16 R.Morgan; #3 K.Sabb)”
},
{
“x”: 21,
“y”: 0.3,
“text”: “J.Mateer pass incomplete short right to #6 T.Blaylock thrown to ALA49 QB hurried by #42 Y.Pierre”
},
{
“x”: 22,
“y”: 0.36363636363636365,
“text”: “I.Sategna III rush right for 21 yards gain to the OU 46 (#5 D.Lee Jr.), 1ST DOWN”
},
{
“x”: 23,
“y”: 0.4166666666666667,
“text”: “X.Robinson rush middle for 7 yards gain to the ALA47 (#18 B.Hubbard)”
},
{
“x”: 24,
“y”: 0.4166666666666667,
“text”: “J.Mateer pass complete short right to #24 X.Robinson caught at OU 42, for 0 yards to the OU 43 (#16 R.Morgan)”
},
{
“x”: 25,
“y”: 0.4166666666666667,
“text”: “J.Mateer pass complete short right to #5 I.Sategna III caught at ALA40, for 21 yards to the ALA36 (#5 D.Lee Jr.), 1ST DOWN”
},
{
“x”: 26,
“y”: 0.4166666666666667,
“text”: “J.Mateer sacked for loss of 2 yards to the ALA41 (#3 K.Sabb)”
},
{
“x”: 27,
“y”: 0.4166666666666667,
“text”: “J.Mateer pass complete short right to #84 J.Carter caught at ALA35, for 7 yards to the ALA34 (#18 B.Hubbard)”
},
{
“x”: 28,
“y”: 0.4166666666666667,
“text”: “J.Mateer pass incomplete short right to #4 D.Burks thrown to OU 30 broken up by #96 T.Keenan III”
},
{
“x”: 29,
“y”: 0.4166666666666667,
“text”: “J.Mateer pass complete short middle to #84 J.Carter caught at OU 41, for 22 yards to the OU 47 (#1 D.Jackson), 1ST DOWN”
},
{
“x”: 30,
“y”: 0.4166666666666667,
“text”: “J.Mateer pass complete short left to #84 J.Carter caught at ALA45, for 7 yards to the ALA46 (#1 D.Jackson)”
},
{
“x”: 31,
“y”: 0.38461538461538464,
“text”: “T.Blaylock rush left for 1 yard gain to the ALA45 (#16 R.Morgan; #0 D.Lawson)”
},
{
“x”: 32,
“y”: 0.35714285714285715,
“text”: “T.Blaylock rush left for 4 yards loss to the ALA49 (#42 Y.Pierre) PENALTY OU Illegal Formation declined”
},
{
“x”: 33,
“y”: 0.3333333333333333,
“text”: “X.Robinson rush middle for 1 yard gain to the OU 36 (#94 E.Hill)”
},
{
“x”: 34,
“y”: 0.3333333333333333,
“text”: “J.Mateer pass incomplete short right to #5 I.Sategna III thrown to OU 40”
},
{
“x”: 35,
“y”: 0.3333333333333333,
“text”: “J.Mateer pass incomplete short left to #84 J.Carter thrown to OU 50 PENALTY OU Chop Block declined”
},
{
“x”: 36,
“y”: 0.3125,
“text”: “J.Mateer rush left for 3 yards gain to the ALA25 (#10 J.Jefferson)”
},
{
“x”: 37,
“y”: 0.29411764705882354,
“text”: “T.Blaylock rush middle for 0 yards to the ALA10 (#42 Y.Pierre)”
},
{
“x”: 38,
“y”: 0.2777777777777778,
“text”: “T.Blaylock rush left for 4 yards gain to the ALA06 (#42 Y.Pierre)”
},
{
“x”: 39,
“y”: 0.2631578947368421,
“text”: “J.Mateer rush right for 0 yards to the ALA06 (#3 K.Sabb; #2 Z.Brown)”
},
{
“x”: 40,
“y”: 0.25,
“text”: “J.Mateer rush middle for 0 yards to the OU 30 (#11 J.Renaud; #24 N.Carter)”
},
{
“x”: 41,
“y”: 0.25,
“text”: “J.Mateer pass complete short left to #11 J.Gibson caught at OU 38, for 11 yards to the OU 41 (#1 D.Jackson), 1ST DOWN”
},
{
“x”: 42,
“y”: 0.23809523809523808,
“text”: “X.Robinson rush right for 4 yards gain to the OU 45 (#0 D.Lawson; #11 J.Renaud)”
},
{
“x”: 43,
“y”: 0.23809523809523808,
“text”: “J.Mateer pass incomplete short middle to #12 J.Kanak thrown to OU 50 broken up by #41 N.Hill-Green”
},
{
“x”: 44,
“y”: 0.23809523809523808,
“text”: “J.Mateer pass complete short left to #11 J.Gibson caught at ALA49, for 15 yards to the ALA40 (#5 D.Lee Jr.; #12 Z.Mincey), 1ST DOWN”
},
{
“x”: 45,
“y”: 0.22727272727272727,
“text”: “X.Robinson rush left for 3 yards gain to the ALA37 (#17 K.Collins)”
},
{
“x”: 46,
“y”: 0.21739130434782608,
“text”: “J.Mateer rush middle for 4 yards gain to the ALA33 (#22 L.Overton)”
},
{
“x”: 47,
“y”: 0.21739130434782608,
“text”: “J.Mateer pass incomplete short middle thrown to ALA45 QB hurried by #17 K.Collins PENALTY OU Intentional Grounding (#10 J.Mateer)”
},
{
“x”: 48,
“y”: 0.20833333333333334,
“text”: “J.Mateer at ALA49 for loss of 1 yard”
},
{
“x”: 49,
“y”: 0.2,
“text”: “J.Mateer at ALA50 for loss of 1 yard”
},
{
“x”: 50,
“y”: 0.19230769230769232,
“text”: “J.Mateer at OU 47 for loss of 3 yards”
}
],
“label”: “Oklahoma Rush SR”,
“borderColor”: “#4c2d00CC”,
“backgroundColor”: [
“rgba(255,255,255,0.9)”,
“rgba(255,255,255,0.9)”,
“rgba(255,255,255,0.9)”,
“rgba(255,255,255,0.9)”,
“rgba(255,255,255,0.9)”,
“rgba(255,255,255,0.9)”,
“#A16207CC”,
“rgba(255,255,255,0.9)”,
“rgba(255,255,255,0.9)”,
“rgba(255,255,255,0.9)”,
“rgba(255,255,255,0.9)”,
“rgba(255,255,255,0.9)”,
“rgba(255,255,255,0.9)”,
“rgba(255,255,255,0.9)”,
“#4c2d00CC”,
“rgba(255,255,255,0.9)”,
“rgba(255,255,255,0.9)”,
“#A16207CC”,
“rgba(255,255,255,0.9)”,
“rgba(255,255,255,0.9)”,
“rgba(255,255,255,0.9)”,
“#4c2d00CC”,
“#A16207CC”,
“rgba(255,255,255,0.9)”,
“rgba(255,255,255,0.9)”,
“rgba(255,255,255,0.9)”,
“rgba(255,255,255,0.9)”,
“rgba(255,255,255,0.9)”,
“rgba(255,255,255,0.9)”,
“rgba(255,255,255,0.9)”,
“rgba(255,255,255,0.9)”,
“rgba(255,255,255,0.9)”,
“rgba(255,255,255,0.9)”,
“rgba(255,255,255,0.9)”,
“rgba(255,255,255,0.9)”,
“rgba(255,255,255,0.9)”,
“rgba(255,255,255,0.9)”,
“rgba(255,255,255,0.9)”,
“rgba(255,255,255,0.9)”,
“rgba(255,255,255,0.9)”,
“rgba(255,255,255,0.9)”,
“rgba(255,255,255,0.9)”,
“rgba(255,255,255,0.9)”,
“rgba(255,255,255,0.9)”,
“rgba(255,255,255,0.9)”,
“rgba(255,255,255,0.9)”,
“rgba(255,255,255,0.9)”,
“rgba(255,255,255,0.9)”,
“rgba(255,255,255,0.9)”,
“rgba(255,255,255,0.9)”
],
“borderWidth”: 2,
“pointStyle”: “circle”,
“pointRadius”: [
0,
4,
0,
0,
4,
4,
4,
4,
4,
0,
0,
4,
0,
0,
4,
0,
0,
4,
4,
0,
0,
4,
4,
0,
0,
0,
0,
0,
0,
0,
4,
4,
4,
0,
0,
4,
4,
4,
4,
4,
0,
4,
0,
0,
4,
4,
0,
4,
4,
4
],
“pointBorderWidth”: 1,
“pointBorderColor”: “#4c2d00CC”,
“showLine”: true
},
{
“data”: [
{
“x”: 1,
“y”: 1,
“text”: “D.Burks caught at ALA20, for 18 yards to the ALA12 (#2 Z.Brown; #10 J.Jefferson), 1ST DOWN”
},
{
“x”: 2,
“y”: 1,
“text”: “X.Robinson rush left for 4 yards gain to the ALA08 (#0 D.Lawson; #5 D.Lee Jr.)”
},
{
“x”: 3,
“y”: 0.5,
“text”: “D.Burks caught at ALA06, for 1 yard to the ALA07 (#23 J.Smith; #10 J.Jefferson)”
},
{
“x”: 4,
“y”: 0.3333333333333333,
“text”: “J.Mateer pass incomplete short left to #11 J.Gibson thrown to ALA02”
},
{
“x”: 5,
“y”: 0.3333333333333333,
“text”: “X.Robinson rush left for 4 yards gain to the OU 41 (#94 E.Hill)”
},
{
“x”: 6,
“y”: 0.3333333333333333,
“text”: “J.Mateer rush right for 4 yards gain to the OU 45 (#0 D.Lawson)”
},
{
“x”: 7,
“y”: 0.3333333333333333,
“text”: “X.Robinson rush middle for 3 yards gain to the OU 48 (#41 N.Hill-Green; #8 J.Hill), 1ST DOWN”
},
{
“x”: 8,
“y”: 0.3333333333333333,
“text”: “X.Robinson rush middle for 1 yard gain to the OU 49 (#0 D.Lawson)”
},
{
“x”: 9,
“y”: 0.3333333333333333,
“text”: “J.Mateer rush right for 1 yard gain to the OU 35 (#41 N.Hill-Green), out of bounds”
},
{
“x”: 10,
“y”: 0.25,
“text”: “J.Mateer pass complete short left to #5 I.Sategna III caught at OU 32, for 6 yards to the OU 41 (#18 B.Hubbard; #3 K.Sabb)”
},
{
“x”: 11,
“y”: 0.2,
“text”: “J.Mateer pass incomplete short right to #4 D.Burks thrown to OU 35 broken up by #10 J.Jefferson”
},
{
“x”: 12,
“y”: 0.2,
“text”: “J.Mateer rush middle for 5 yards gain to the OU 30 (#22 L.Overton)”
},
{
“x”: 13,
“y”: 0.16666666666666666,
“text”: “J.Mateer pass incomplete short left to #5 I.Sategna III thrown to OU 35 QB hurried by #41 N.Hill-Green”
},
{
“x”: 14,
“y”: 0.2857142857142857,
“text”: “J.Mateer pass complete short right to #12 J.Kanak caught at ALA22, for 11 yards to the ALA20 (#2 Z.Brown), 1ST DOWN”
},
{
“x”: 15,
“y”: 0.2857142857142857,
“text”: “J.Mateer rush middle for 20 yards gain to the ALA00 TOUCHDOWN, clock 08:49, 1ST DOWN #29 T.Sandell kick attempt good (H: #87 J.Ulrich, LS: #49 B.Anderson)”
},
{
“x”: 16,
“y”: 0.375,
“text”: “J.Mateer pass complete short middle to #12 J.Kanak caught at OU 31, for 12 yards to the OU 37 (#10 J.Jefferson; #18 B.Hubbard), 1ST DOWN”
},
{
“x”: 17,
“y”: 0.4444444444444444,
“text”: “J.Mateer pass complete short left to #24 X.Robinson caught at OU 34, for 8 yards to the OU 45 (#18 B.Hubbard)”
},
{
“x”: 18,
“y”: 0.4444444444444444,
“text”: “X.Robinson rush middle for 6 yards gain to the ALA49 (#94 E.Hill; #1 D.Jackson), 1ST DOWN”
},
{
“x”: 19,
“y”: 0.4444444444444444,
“text”: “X.Robinson rush left for 1 yard gain to the ALA48 (#1 D.Jackson)”
},
{
“x”: 20,
“y”: 0.4,
“text”: “J.Mateer pass complete short right to #5 I.Sategna III caught at ALA49, for 2 yards to the ALA46 (#16 R.Morgan; #3 K.Sabb)”
},
{
“x”: 21,
“y”: 0.36363636363636365,
“text”: “J.Mateer pass incomplete short right to #6 T.Blaylock thrown to ALA49 QB hurried by #42 Y.Pierre”
},
{
“x”: 22,
“y”: 0.36363636363636365,
“text”: “I.Sategna III rush right for 21 yards gain to the OU 46 (#5 D.Lee Jr.), 1ST DOWN”
},
{
“x”: 23,
“y”: 0.36363636363636365,
“text”: “X.Robinson rush middle for 7 yards gain to the ALA47 (#18 B.Hubbard)”
},
{
“x”: 24,
“y”: 0.3333333333333333,
“text”: “J.Mateer pass complete short right to #24 X.Robinson caught at OU 42, for 0 yards to the OU 43 (#16 R.Morgan)”
},
{
“x”: 25,
“y”: 0.38461538461538464,
“text”: “J.Mateer pass complete short right to #5 I.Sategna III caught at ALA40, for 21 yards to the ALA36 (#5 D.Lee Jr.), 1ST DOWN”
},
{
“x”: 26,
“y”: 0.35714285714285715,
“text”: “J.Mateer sacked for loss of 2 yards to the ALA41 (#3 K.Sabb)”
},
{
“x”: 27,
“y”: 0.3333333333333333,
“text”: “J.Mateer pass complete short right to #84 J.Carter caught at ALA35, for 7 yards to the ALA34 (#18 B.Hubbard)”
},
{
“x”: 28,
“y”: 0.3125,
“text”: “J.Mateer pass incomplete short right to #4 D.Burks thrown to OU 30 broken up by #96 T.Keenan III”
},
{
“x”: 29,
“y”: 0.35294117647058826,
“text”: “J.Mateer pass complete short middle to #84 J.Carter caught at OU 41, for 22 yards to the OU 47 (#1 D.Jackson), 1ST DOWN”
},
{
“x”: 30,
“y”: 0.3888888888888889,
“text”: “J.Mateer pass complete short left to #84 J.Carter caught at ALA45, for 7 yards to the ALA46 (#1 D.Jackson)”
},
{
“x”: 31,
“y”: 0.3888888888888889,
“text”: “T.Blaylock rush left for 1 yard gain to the ALA45 (#16 R.Morgan; #0 D.Lawson)”
},
{
“x”: 32,
“y”: 0.3888888888888889,
“text”: “T.Blaylock rush left for 4 yards loss to the ALA49 (#42 Y.Pierre) PENALTY OU Illegal Formation declined”
},
{
“x”: 33,
“y”: 0.3888888888888889,
“text”: “X.Robinson rush middle for 1 yard gain to the OU 36 (#94 E.Hill)”
},
{
“x”: 34,
“y”: 0.3684210526315789,
“text”: “J.Mateer pass incomplete short right to #5 I.Sategna III thrown to OU 40”
},
{
“x”: 35,
“y”: 0.35,
“text”: “J.Mateer pass incomplete short left to #84 J.Carter thrown to OU 50 PENALTY OU Chop Block declined”
},
{
“x”: 36,
“y”: 0.35,
“text”: “J.Mateer rush left for 3 yards gain to the ALA25 (#10 J.Jefferson)”
},
{
“x”: 37,
“y”: 0.35,
“text”: “T.Blaylock rush middle for 0 yards to the ALA10 (#42 Y.Pierre)”
},
{
“x”: 38,
“y”: 0.35,
“text”: “T.Blaylock rush left for 4 yards gain to the ALA06 (#42 Y.Pierre)”
},
{
“x”: 39,
“y”: 0.35,
“text”: “J.Mateer rush right for 0 yards to the ALA06 (#3 K.Sabb; #2 Z.Brown)”
},
{
“x”: 40,
“y”: 0.35,
“text”: “J.Mateer rush middle for 0 yards to the OU 30 (#11 J.Renaud; #24 N.Carter)”
},
{
“x”: 41,
“y”: 0.38095238095238093,
“text”: “J.Mateer pass complete short left to #11 J.Gibson caught at OU 38, for 11 yards to the OU 41 (#1 D.Jackson), 1ST DOWN”
},
{
“x”: 42,
“y”: 0.38095238095238093,
“text”: “X.Robinson rush right for 4 yards gain to the OU 45 (#0 D.Lawson; #11 J.Renaud)”
},
{
“x”: 43,
“y”: 0.36363636363636365,
“text”: “J.Mateer pass incomplete short middle to #12 J.Kanak thrown to OU 50 broken up by #41 N.Hill-Green”
},
{
“x”: 44,
“y”: 0.391304347826087,
“text”: “J.Mateer pass complete short left to #11 J.Gibson caught at ALA49, for 15 yards to the ALA40 (#5 D.Lee Jr.; #12 Z.Mincey), 1ST DOWN”
},
{
“x”: 45,
“y”: 0.391304347826087,
“text”: “X.Robinson rush left for 3 yards gain to the ALA37 (#17 K.Collins)”
},
{
“x”: 46,
“y”: 0.391304347826087,
“text”: “J.Mateer rush middle for 4 yards gain to the ALA33 (#22 L.Overton)”
},
{
“x”: 47,
“y”: 0.375,
“text”: “J.Mateer pass incomplete short middle thrown to ALA45 QB hurried by #17 K.Collins PENALTY OU Intentional Grounding (#10 J.Mateer)”
},
{
“x”: 48,
“y”: 0.375,
“text”: “J.Mateer at ALA49 for loss of 1 yard”
},
{
“x”: 49,
“y”: 0.375,
“text”: “J.Mateer at ALA50 for loss of 1 yard”
},
{
“x”: 50,
“y”: 0.375,
“text”: “J.Mateer at OU 47 for loss of 3 yards”
}
],
“label”: “Oklahoma Pass SR”,
“borderColor”: “#4c2d00CC”,
“backgroundColor”: [
“#4c2d00CC”,
“rgba(255,255,255,0.9)”,
“rgba(255,255,255,0.9)”,
“rgba(255,255,255,0.9)”,
“rgba(255,255,255,0.9)”,
“rgba(255,255,255,0.9)”,
“rgba(255,255,255,0.9)”,
“rgba(255,255,255,0.9)”,
“rgba(255,255,255,0.9)”,
“rgba(255,255,255,0.9)”,
“rgba(255,255,255,0.9)”,
“rgba(255,255,255,0.9)”,
“rgba(255,255,255,0.9)”,
“#A16207CC”,
“rgba(255,255,255,0.9)”,
“#A16207CC”,
“#A16207CC”,
“rgba(255,255,255,0.9)”,
“rgba(255,255,255,0.9)”,
“rgba(255,255,255,0.9)”,
“rgba(255,255,255,0.9)”,
“rgba(255,255,255,0.9)”,
“rgba(255,255,255,0.9)”,
“rgba(255,255,255,0.9)”,
“#4c2d00CC”,
“rgba(255,255,255,0.9)”,
“rgba(255,255,255,0.9)”,
“rgba(255,255,255,0.9)”,
“#4c2d00CC”,
“#A16207CC”,
“rgba(255,255,255,0.9)”,
“rgba(255,255,255,0.9)”,
“rgba(255,255,255,0.9)”,
“rgba(255,255,255,0.9)”,
“rgba(255,255,255,0.9)”,
“rgba(255,255,255,0.9)”,
“rgba(255,255,255,0.9)”,
“rgba(255,255,255,0.9)”,
“rgba(255,255,255,0.9)”,
“rgba(255,255,255,0.9)”,
“#A16207CC”,
“rgba(255,255,255,0.9)”,
“rgba(255,255,255,0.9)”,
“#4c2d00CC”,
“rgba(255,255,255,0.9)”,
“rgba(255,255,255,0.9)”,
“rgba(255,255,255,0.9)”,
“rgba(255,255,255,0.9)”,
“rgba(255,255,255,0.9)”,
“rgba(255,255,255,0.9)”
],
“borderWidth”: 2,
“pointStyle”: “triangle”,
“pointRadius”: [
6,
0,
6,
6,
0,
0,
0,
0,
0,
6,
6,
0,
6,
6,
0,
6,
6,
0,
0,
6,
6,
0,
0,
6,
6,
6,
6,
6,
6,
6,
0,
0,
0,
6,
6,
0,
0,
0,
0,
0,
6,
0,
6,
6,
0,
0,
6,
0,
0,
0
],
“pointBorderWidth”: 1,
“pointBorderColor”: “#4c2d00CC”,
“borderDash”: [
4,
4
],
“showLine”: true
},
{
“label”: “Quarters”,
“data”: [
{
“x”: 1,
“y”: 0
},
{
“x”: 1,
“y”: 1
},
{
“x”: 50,
“y”: 1
},
{
“x”: 50,
“y”: 0
},
{
“x”: 11,
“y”: 0
},
{
“x”: 11,
“y”: 1
},
{
“x”: 50,
“y”: 1
},
{
“x”: 50,
“y”: 0
},
{
“x”: 22,
“y”: 0
},
{
“x”: 22,
“y”: 1
},
{
“x”: 50,
“y”: 1
},
{
“x”: 50,
“y”: 0
},
{
“x”: 38,
“y”: 0
},
{
“x”: 38,
“y”: 1
},
{
“x”: 50,
“y”: 1
},
{
“x”: 50,
“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”: 12,
“seasonType”: “regular”,
“team”: “Alabama”,
“gameId”: “401752765”
}
};
// 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’ ? ‘opponent-play-type-lines’.includes(‘play-map’) ? {
line: {
tension: 0,
borderWidth: 0
}
} : ‘opponent-play-type-lines’ === ‘win-probability’ ? {
line: {
tension: 0.15,
borderWidth: 2.2,
fill: false
},
point: {
pointRadius: 0,
pointHoverRadius: 4
}
} : {
line: {
tension: 0.25,
borderWidth: 2.2
},
point: {
pointRadius: ‘opponent-play-type-lines’.includes(‘team-lines’) ? 0 : undefined
}
} : {},
plugins: {
datalabels: {
display: function(context) {
// Suppress data labels on line charts
if (‘line’ === ‘line’) {
return false;
}
return context.dataset.datalabels && context.dataset.datalabels.display === true;
},
formatter: function(value, context) {
// Special handling for Overall Team Performance chart
if (‘opponent-play-type-lines’ === ‘overall-team-performance’ && context.dataset.label === ‘Success Rate (SR)’) {
// Use the stored play count data
if (context.dataset.playCountData && context.dataset.playCountData[context.dataIndex]) {
return context.dataset.playCountData[context.dataIndex];
}
// Fallback to percentage if play count data not available
return Math.round(value * 100) + ‘%’;
}
// Handle bar charts with count data (play-type, quarter, down, etc.)
if (context.dataset.label && context.dataset.label.includes(‘ SR’) &&
(chartData.teamCounts || chartData.oppCounts)) {
// Find the first team SR dataset in the chart to determine team order
const allDatasets = context.chart.data.datasets;
const teamSRDataset = allDatasets.find(d => d.label && d.label.includes(‘ SR’) && !d.label.includes(‘NCAA’));
// If this is the first team’s SR dataset, use teamCounts
if (teamSRDataset && context.dataset.label === teamSRDataset.label && chartData.teamCounts) {
return chartData.teamCounts[context.dataIndex] || 0;
}
// Otherwise, use oppCounts for the second team
else if (chartData.oppCounts) {
return chartData.oppCounts[context.dataIndex] || 0;
}
}
// For player charts, show value only if > 0 (matches non-embedded behavior)
if (‘opponent-play-type-lines’.includes(‘top-rushers’) || ‘opponent-play-type-lines’.includes(‘top-passers’) || ‘opponent-play-type-lines’.includes(‘top-receivers’)) {
// Hide data labels for zero or negative values, show actual value for positive values
return value > 0 ? value : null;
}
// For other charts, show values based on type
if (typeof value === ‘number’) {
// If value is between 0 and 1, treat as percentage
if (value >= 0 && value 0 ? ‘#26262660’ : ‘transparent’;
},
borderColor: function(context) {
const value = context.dataset.data[context.dataIndex];
return value > 0 ? ‘rgba(255, 255, 255, 0.2)’ : ‘transparent’;
},
borderRadius: 4,
align: ‘center’,
anchor: ‘center’
},
legend: ‘opponent-play-type-lines’ === ‘win-probability’ ? {
display: false
} : ‘line’ === ‘line’ ? {
position: ‘top’,
align: ‘start’,
labels: ‘opponent-play-type-lines’.includes(‘play-map’) ? {
usePointStyle: true,
generateLabels: function(chart) {
// Call the original generateLabels to get default styling
const original = Chart.defaults.plugins.legend.labels.generateLabels;
const labels = original.call(this, chart);
// Filter and customize each label
const filteredLabels = labels.filter(label => {
return !label.text.includes(‘ {
const dataset = chart.data.datasets[label.datasetIndex];
if (dataset && dataset.label) {
if (dataset.label.includes(‘Rush’)) {
label.pointStyle = ‘circle’;
label.pointStyleWidth = 4;
label.fillStyle = ‘white’;
} else if (dataset.label.includes(‘Pass’)) {
label.pointStyle = ‘triangle’;
label.pointStyleWidth = 4;
label.fillStyle = ‘white’;
} else {
label.pointStyle = ‘rect’;
label.pointStyleWidth = 4;
label.fillStyle = ‘white’;
}
}
});
return filteredLabels;
},
boxWidth: 20,
padding: 12
} : {
usePointStyle: false,
boxWidth: 12,
boxHeight: 12,
padding: 12,
generateLabels: function(chart) {
const original = Chart.defaults.plugins.legend.labels.generateLabels;
const labels = original.call(this, chart);
// Filter out reference areas and ensure white fill
const filteredLabels = labels.filter(label => {
return !label.text.includes(‘NCAA Avg SR’) &&
!label.text.includes(’50/50′) &&
!label.text.includes(‘Quarters’);
});
// Ensure white fill for all line chart legend boxes
filteredLabels.forEach((label) => {
label.fillStyle = ‘white’;
});
return filteredLabels;
}
}
} : {
position: ‘top’,
align: ‘start’,
labels: {
usePointStyle: false,
boxWidth: 12,
boxHeight: 12,
padding: 12,
filter: function(legendItem, chartData) {
return !legendItem.text.includes(‘NCAA Avg SR’) &&
!legendItem.text.includes(‘Quarters’) &&
!legendItem.text.includes(’50/50′);
},
generateLabels: function(chart) {
const data = chart.data;
if (data.datasets.length) {
return data.datasets.map((dataset, i) => {
// Handle backgroundColor arrays (like in Overall Team Performance chart)
let fillColor = dataset.backgroundColor;
if (dataset.label === ‘# Plays’) {
fillColor = ‘white’;
} else if (Array.isArray(dataset.backgroundColor)) {
// For datasets with backgroundColor arrays, use the first color for legend
fillColor = dataset.backgroundColor[0];
}
return {
text: dataset.label,
fillStyle: fillColor,
strokeStyle: dataset.label === ‘# Plays’ ? ‘#666’ : dataset.borderColor,
lineWidth: dataset.label === ‘# Plays’ ? 1 : dataset.borderWidth,
hidden: !chart.isDatasetVisible(i),
datasetIndex: i
};
}).filter((item, index) => {
// Apply the same filter logic as above
const dataset = chart.data.datasets[index];
if (!dataset || !dataset.data) return false;
if (dataset.label === ‘# Plays’) return true; // Always show # Plays
if (dataset.label && (dataset.label.includes(‘NCAA Avg SR’) ||
dataset.label.includes(‘Quarters’) ||
dataset.label.includes(’50/50′))) return false;
return dataset.data.some((value) => value > 0);
});
}
return [];
}
}
},
tooltip: ‘opponent-play-type-lines’ === ‘win-probability’ ? {
mode: ‘index’,
intersect: false,
callbacks: {
title: function(tooltipItems) {
if (tooltipItems && tooltipItems[0]) {
return ‘Play ‘ + (tooltipItems[0].dataIndex + 1);
}
return ”;
},
label: function(context) {
const selectedTeamWinProb = context.parsed.y;
const opponentWinProb = 100 – selectedTeamWinProb;
const selectedTeam = context.dataset.selectedTeam || ‘Team’;
const opponentTeam = context.dataset.opponentTeam || ‘Opponent’;
return [
selectedTeam + ‘: ‘ + selectedTeamWinProb.toFixed(1) + ‘%’,
opponentTeam + ‘: ‘ + opponentWinProb.toFixed(1) + ‘%’
];
},
afterLabel: function(context) {
if (context.dataset.playTexts && context.dataset.playTexts[context.dataIndex]) {
return ‘n’ + context.dataset.playTexts[context.dataIndex];
}
return ”;
}
}
} : {
filter: function(tooltipItem) {
if (‘opponent-play-type-lines’.includes(‘play-map’)) {
return !tooltipItem.dataset.label.includes(‘< 0’) &&
!tooltipItem.dataset.label.includes(‘Quarters’) &&
!tooltipItem.dataset.label.includes(‘Drive’);
}
return !tooltipItem.dataset.label.includes(‘NCAA Avg SR’) &&
!tooltipItem.dataset.label.includes(’50/50′) &&
!tooltipItem.dataset.label.includes(‘ ds.label === ‘Win Probability’);
if (wpDataset && wpDataset.segmentColors) {
wpDataset.segment = {
borderColor: function(ctx) {
// Use p1DataIndex (ending point) so the line inherits the destination color
// This makes momentum shifts more visually intuitive
const index = ctx.p1DataIndex;
if (index !== undefined && wpDataset.segmentColors[index]) {
return wpDataset.segmentColors[index];
}
return wpDataset.borderColor || ‘#8B0000’;
}
};
}
}
// Initialize the chart
const ctx = canvas.getContext(‘2d’);
const chart = new Chart(ctx, {
type: ‘line’,
data: chartData,
options: chartOptions
});
// Store reference to prevent re-initialization
canvas.chartInstance = chart;
console.log(‘CFB Chart initialized successfully’);
} catch (error) {
console.error(‘Error initializing CFB chart:’, error);
// Fallback: show error message in canvas container
const container = document.getElementById(‘cfb-chart-1763259286363-u9c158e89’).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 the funny thing about that explosiveness number from Oklahoma is that it was derived from so few plays. The Sooners ran 23 fewer plays than Alabama, and really only compiled a few handfuls of successful plays the entire day. You can see here that in the 1st quarter they had 2, in the 2nd and 3rd quarters they had 5 each, and in the 4th quarter they had 2. That is 14 total “successful plays” in a conference victory against a #4-ranked opponent. Absolutely nuts.
And looking at their rushing line in this chart: after midway through the 3rd quarter, Okie didn’t have a single successful rush from 14 attempts. (Unfortunately, Mateer did have a successful pass, then an explosive pass in the 4th quarter … which was enough to tip the balance in a close game.
Bama actually ran the ball pretty well
But I promised a few silver linings, didn’t I? There aren’t many, but despite the continued gripes around here, it looks like we actually did run the ball pretty well:
.cfb-chart-embed-cfb-chart-1763259340562-pqbowr3e8 {
font-family: -apple-system, BlinkMacSystemFont, ‘Segoe UI’, ‘Roboto’, sans-serif;
margin: 0;
padding: 0;
}
.cfb-chart-embed-cfb-chart-1763259340562-pqbowr3e8 .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-1763259340562-pqbowr3e8 .chart-header {
padding: 18px 24px 14px;
border-bottom: 1px solid #e5e5e5;
background: white;
}
.cfb-chart-embed-cfb-chart-1763259340562-pqbowr3e8 .chart-title {
font-size: 18px;
font-weight: 600;
color: #171717;
margin: 0;
}
.cfb-chart-embed-cfb-chart-1763259340562-pqbowr3e8 .chart-subtitle {
font-size: 11px;
font-weight: 400;
color: #737373;
margin: 4px 0 0 0;
}
.cfb-chart-embed-cfb-chart-1763259340562-pqbowr3e8 .chart-content {
padding: 20px 24px 24px !important;
}
.cfb-chart-embed-cfb-chart-1763259340562-pqbowr3e8 .chart-content { height: 325px; }
@media (max-width: 640px) {
.cfb-chart-embed-cfb-chart-1763259340562-pqbowr3e8 .chart-content {
padding: 12px 16px 20px !important;
height: 280px !important;
}
.cfb-chart-embed-cfb-chart-1763259340562-pqbowr3e8 .chart-header {
padding: 12px 16px 12px !important;
}
.cfb-chart-embed-cfb-chart-1763259340562-pqbowr3e8 .embed-footer-top {
padding: 8px 12px !important;
}
.cfb-chart-embed-cfb-chart-1763259340562-pqbowr3e8 .data-definitions {
padding: 12px !important;
}
}
.cfb-chart-embed-cfb-chart-1763259340562-pqbowr3e8 .embed-footer {
border-top: 1px solid #e5e5e5;
font-size: 12px;
color: #737373;
}
.cfb-chart-embed-cfb-chart-1763259340562-pqbowr3e8 .embed-footer-top {
display: flex;
justify-content: space-between;
align-items: center;
padding: 12px 16px;
}
.cfb-chart-embed-cfb-chart-1763259340562-pqbowr3e8 .embed-footer-link {
color: #737373;
text-decoration: none;
font-weight: 500;
}
.cfb-chart-embed-cfb-chart-1763259340562-pqbowr3e8 .embed-footer-link:hover {
color: #525252;
text-decoration: underline;
}
.cfb-chart-embed-cfb-chart-1763259340562-pqbowr3e8 .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-1763259340562-pqbowr3e8 .data-definitions-toggle:hover {
color: #525252;
}
.cfb-chart-embed-cfb-chart-1763259340562-pqbowr3e8 .caret {
transition: transform 0.2s ease;
font-size: 10px;
}
.cfb-chart-embed-cfb-chart-1763259340562-pqbowr3e8 .caret.expanded {
transform: rotate(180deg);
}
.cfb-chart-embed-cfb-chart-1763259340562-pqbowr3e8 .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-1763259340562-pqbowr3e8 .data-definitions.expanded {
display: block;
}
.cfb-chart-embed-cfb-chart-1763259340562-pqbowr3e8 .data-definitions ul {
margin: 0;
padding-left: 0;
list-style: none;
}
.cfb-chart-embed-cfb-chart-1763259340562-pqbowr3e8 .data-definitions li {
margin-bottom: 4px;
}
SR and XR by Play Type
Alabama vs. Oklahoma • Nov 15, 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_1763259340562_pqbowr3e8() {
const definitions = document.getElementById(‘dataDefinitions_cfb-chart-1763259340562-pqbowr3e8’);
const caret = document.getElementById(‘caret_cfb-chart-1763259340562-pqbowr3e8’);
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-1763259340562-pqbowr3e8’);
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-1763259340562-pqbowr3e8’);
if (!canvas) {
console.warn(‘Canvas element not found yet, retrying…’);
setTimeout(initChart, 100);
return;
}
// Prevent multiple chart instances
if (canvas.chartInstance) {
console.log(‘Chart already initialized’);
return;
}
try {
// Register the datalabels plugin
Chart.register(ChartDataLabels);
// Embed actual chart data directly
const chartData = {
“labels”: [
“Rush”,
“Pass”
],
“datasets”: [
{
“data”: [
0.034482758620689655,
0.22727272727272727
],
“stack”: “Team”,
“label”: “Alabama XR”,
“backgroundColor”: “rgba(101, 0, 20, 0.8)”,
“datalabels”: {
“display”: false
}
},
{
“data”: [
0.4482758620689655,
0.4772727272727273
],
“stack”: “Team”,
“label”: “Alabama SR”,
“backgroundColor”: “rgba(175, 40, 60, 0.8)”,
“datalabels”: {
“display”: true
}
},
{
“data”: [
0.07692307692307693,
0.16666666666666666
],
“stack”: “Opponent”,
“label”: “Oklahoma XR”,
“backgroundColor”: “#4c2d00CC”,
“datalabels”: {
“display”: false
}
},
{
“data”: [
0.19230769230769232,
0.375
],
“stack”: “Opponent”,
“label”: “Oklahoma SR”,
“backgroundColor”: “#A16207CC”,
“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”: [
29,
44
],
“oppCounts”: [
26,
24
],
“currentParams”: {
“year”: 2025,
“week”: 12,
“seasonType”: “regular”,
“team”: “Alabama”,
“gameId”: “401752765”
}
};
// Chart options (WordPress-safe)
const chartOptions = {
responsive: true,
maintainAspectRatio: false,
animation: {
duration: 1 // Minimal animation to trigger layout calculation (fixes label positioning)
},
elements: ‘bar’ === ‘line’ ? ‘play-type-bars’.includes(‘play-map’) ? {
line: {
tension: 0,
borderWidth: 0
}
} : ‘play-type-bars’ === ‘win-probability’ ? {
line: {
tension: 0.15,
borderWidth: 2.2,
fill: false
},
point: {
pointRadius: 0,
pointHoverRadius: 4
}
} : {
line: {
tension: 0.25,
borderWidth: 2.2
},
point: {
pointRadius: ‘play-type-bars’.includes(‘team-lines’) ? 0 : undefined
}
} : {},
plugins: {
datalabels: {
display: function(context) {
// Suppress data labels on line charts
if (‘bar’ === ‘line’) {
return false;
}
return context.dataset.datalabels && context.dataset.datalabels.display === true;
},
formatter: function(value, context) {
// Special handling for Overall Team Performance chart
if (‘play-type-bars’ === ‘overall-team-performance’ && context.dataset.label === ‘Success Rate (SR)’) {
// Use the stored play count data
if (context.dataset.playCountData && context.dataset.playCountData[context.dataIndex]) {
return context.dataset.playCountData[context.dataIndex];
}
// Fallback to percentage if play count data not available
return Math.round(value * 100) + ‘%’;
}
// Handle bar charts with count data (play-type, quarter, down, etc.)
if (context.dataset.label && context.dataset.label.includes(‘ SR’) &&
(chartData.teamCounts || chartData.oppCounts)) {
// Find the first team SR dataset in the chart to determine team order
const allDatasets = context.chart.data.datasets;
const teamSRDataset = allDatasets.find(d => d.label && d.label.includes(‘ SR’) && !d.label.includes(‘NCAA’));
// If this is the first team’s SR dataset, use teamCounts
if (teamSRDataset && context.dataset.label === teamSRDataset.label && chartData.teamCounts) {
return chartData.teamCounts[context.dataIndex] || 0;
}
// Otherwise, use oppCounts for the second team
else if (chartData.oppCounts) {
return chartData.oppCounts[context.dataIndex] || 0;
}
}
// For player charts, show value only if > 0 (matches non-embedded behavior)
if (‘play-type-bars’.includes(‘top-rushers’) || ‘play-type-bars’.includes(‘top-passers’) || ‘play-type-bars’.includes(‘top-receivers’)) {
// Hide data labels for zero or negative values, show actual value for positive values
return value > 0 ? value : null;
}
// For other charts, show values based on type
if (typeof value === ‘number’) {
// If value is between 0 and 1, treat as percentage
if (value >= 0 && value 0 ? ‘#26262660’ : ‘transparent’;
},
borderColor: function(context) {
const value = context.dataset.data[context.dataIndex];
return value > 0 ? ‘rgba(255, 255, 255, 0.2)’ : ‘transparent’;
},
borderRadius: 4,
align: ‘center’,
anchor: ‘center’
},
legend: ‘play-type-bars’ === ‘win-probability’ ? {
display: false
} : ‘bar’ === ‘line’ ? {
position: ‘top’,
align: ‘start’,
labels: ‘play-type-bars’.includes(‘play-map’) ? {
usePointStyle: true,
generateLabels: function(chart) {
// Call the original generateLabels to get default styling
const original = Chart.defaults.plugins.legend.labels.generateLabels;
const labels = original.call(this, chart);
// Filter and customize each label
const filteredLabels = labels.filter(label => {
return !label.text.includes(‘ {
const dataset = chart.data.datasets[label.datasetIndex];
if (dataset && dataset.label) {
if (dataset.label.includes(‘Rush’)) {
label.pointStyle = ‘circle’;
label.pointStyleWidth = 4;
label.fillStyle = ‘white’;
} else if (dataset.label.includes(‘Pass’)) {
label.pointStyle = ‘triangle’;
label.pointStyleWidth = 4;
label.fillStyle = ‘white’;
} else {
label.pointStyle = ‘rect’;
label.pointStyleWidth = 4;
label.fillStyle = ‘white’;
}
}
});
return filteredLabels;
},
boxWidth: 20,
padding: 12
} : {
usePointStyle: false,
boxWidth: 12,
boxHeight: 12,
padding: 12,
generateLabels: function(chart) {
const original = Chart.defaults.plugins.legend.labels.generateLabels;
const labels = original.call(this, chart);
// Filter out reference areas and ensure white fill
const filteredLabels = labels.filter(label => {
return !label.text.includes(‘NCAA Avg SR’) &&
!label.text.includes(’50/50′) &&
!label.text.includes(‘Quarters’);
});
// Ensure white fill for all line chart legend boxes
filteredLabels.forEach((label) => {
label.fillStyle = ‘white’;
});
return filteredLabels;
}
}
} : {
position: ‘top’,
align: ‘start’,
labels: {
usePointStyle: false,
boxWidth: 12,
boxHeight: 12,
padding: 12,
filter: function(legendItem, chartData) {
return !legendItem.text.includes(‘NCAA Avg SR’) &&
!legendItem.text.includes(‘Quarters’) &&
!legendItem.text.includes(’50/50′);
},
generateLabels: function(chart) {
const data = chart.data;
if (data.datasets.length) {
return data.datasets.map((dataset, i) => {
// Handle backgroundColor arrays (like in Overall Team Performance chart)
let fillColor = dataset.backgroundColor;
if (dataset.label === ‘# Plays’) {
fillColor = ‘white’;
} else if (Array.isArray(dataset.backgroundColor)) {
// For datasets with backgroundColor arrays, use the first color for legend
fillColor = dataset.backgroundColor[0];
}
return {
text: dataset.label,
fillStyle: fillColor,
strokeStyle: dataset.label === ‘# Plays’ ? ‘#666’ : dataset.borderColor,
lineWidth: dataset.label === ‘# Plays’ ? 1 : dataset.borderWidth,
hidden: !chart.isDatasetVisible(i),
datasetIndex: i
};
}).filter((item, index) => {
// Apply the same filter logic as above
const dataset = chart.data.datasets[index];
if (!dataset || !dataset.data) return false;
if (dataset.label === ‘# Plays’) return true; // Always show # Plays
if (dataset.label && (dataset.label.includes(‘NCAA Avg SR’) ||
dataset.label.includes(‘Quarters’) ||
dataset.label.includes(’50/50′))) return false;
return dataset.data.some((value) => value > 0);
});
}
return [];
}
}
},
tooltip: ‘play-type-bars’ === ‘win-probability’ ? {
mode: ‘index’,
intersect: false,
callbacks: {
title: function(tooltipItems) {
if (tooltipItems && tooltipItems[0]) {
return ‘Play ‘ + (tooltipItems[0].dataIndex + 1);
}
return ”;
},
label: function(context) {
const selectedTeamWinProb = context.parsed.y;
const opponentWinProb = 100 – selectedTeamWinProb;
const selectedTeam = context.dataset.selectedTeam || ‘Team’;
const opponentTeam = context.dataset.opponentTeam || ‘Opponent’;
return [
selectedTeam + ‘: ‘ + selectedTeamWinProb.toFixed(1) + ‘%’,
opponentTeam + ‘: ‘ + opponentWinProb.toFixed(1) + ‘%’
];
},
afterLabel: function(context) {
if (context.dataset.playTexts && context.dataset.playTexts[context.dataIndex]) {
return ‘n’ + context.dataset.playTexts[context.dataIndex];
}
return ”;
}
}
} : {
filter: function(tooltipItem) {
if (‘play-type-bars’.includes(‘play-map’)) {
return !tooltipItem.dataset.label.includes(‘< 0’) &&
!tooltipItem.dataset.label.includes(‘Quarters’) &&
!tooltipItem.dataset.label.includes(‘Drive’);
}
return !tooltipItem.dataset.label.includes(‘NCAA Avg SR’) &&
!tooltipItem.dataset.label.includes(’50/50′) &&
!tooltipItem.dataset.label.includes(‘ ds.label === ‘Win Probability’);
if (wpDataset && wpDataset.segmentColors) {
wpDataset.segment = {
borderColor: function(ctx) {
// Use p1DataIndex (ending point) so the line inherits the destination color
// This makes momentum shifts more visually intuitive
const index = ctx.p1DataIndex;
if (index !== undefined && wpDataset.segmentColors[index]) {
return wpDataset.segmentColors[index];
}
return wpDataset.borderColor || ‘#8B0000’;
}
};
}
}
// Initialize the chart
const ctx = canvas.getContext(‘2d’);
const chart = new Chart(ctx, {
type: ‘bar’,
data: chartData,
options: chartOptions
});
// Store reference to prevent re-initialization
canvas.chartInstance = chart;
console.log(‘CFB Chart initialized successfully’);
} catch (error) {
console.error(‘Error initializing CFB chart:’, error);
// Fallback: show error message in canvas container
const container = document.getElementById(‘cfb-chart-1763259340562-pqbowr3e8’).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 mean, we didn’t exactly expect Oklahoma to come in with a strong running game either, but Alabama’s running game absolutely pasted theirs, with an SR more than double the Sooners’. Sure, Oklahoma had a higher rushing explosiveness rate, but it was just a difference of one play, as they had two explosive rushes (The Mateer TD and another from WR Sategna) to the Tide’s 1 (the long Ty Simpson rush).
Alabama continued to pass a little bit better than it runs, but it was a relatively subtle difference this time—at least by SR and XR. Plus, Alabama’s passing game continued to be the only area where it really tends to drive explosiveness.
.cfb-chart-embed-cfb-chart-1763259432376-4152o88ey {
font-family: -apple-system, BlinkMacSystemFont, ‘Segoe UI’, ‘Roboto’, sans-serif;
margin: 0;
padding: 0;
}
.cfb-chart-embed-cfb-chart-1763259432376-4152o88ey .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-1763259432376-4152o88ey .chart-header {
padding: 18px 24px 14px;
border-bottom: 1px solid #e5e5e5;
background: white;
}
.cfb-chart-embed-cfb-chart-1763259432376-4152o88ey .chart-title {
font-size: 18px;
font-weight: 600;
color: #171717;
margin: 0;
}
.cfb-chart-embed-cfb-chart-1763259432376-4152o88ey .chart-subtitle {
font-size: 11px;
font-weight: 400;
color: #737373;
margin: 4px 0 0 0;
}
.cfb-chart-embed-cfb-chart-1763259432376-4152o88ey .chart-content {
padding: 20px 24px 24px !important;
}
.cfb-chart-embed-cfb-chart-1763259432376-4152o88ey .chart-content { height: 325px; }
@media (max-width: 640px) {
.cfb-chart-embed-cfb-chart-1763259432376-4152o88ey .chart-content {
padding: 12px 16px 20px !important;
height: 280px !important;
}
.cfb-chart-embed-cfb-chart-1763259432376-4152o88ey .chart-header {
padding: 12px 16px 12px !important;
}
.cfb-chart-embed-cfb-chart-1763259432376-4152o88ey .embed-footer-top {
padding: 8px 12px !important;
}
.cfb-chart-embed-cfb-chart-1763259432376-4152o88ey .data-definitions {
padding: 12px !important;
}
}
.cfb-chart-embed-cfb-chart-1763259432376-4152o88ey .embed-footer {
border-top: 1px solid #e5e5e5;
font-size: 12px;
color: #737373;
}
.cfb-chart-embed-cfb-chart-1763259432376-4152o88ey .embed-footer-top {
display: flex;
justify-content: space-between;
align-items: center;
padding: 12px 16px;
}
.cfb-chart-embed-cfb-chart-1763259432376-4152o88ey .embed-footer-link {
color: #737373;
text-decoration: none;
font-weight: 500;
}
.cfb-chart-embed-cfb-chart-1763259432376-4152o88ey .embed-footer-link:hover {
color: #525252;
text-decoration: underline;
}
.cfb-chart-embed-cfb-chart-1763259432376-4152o88ey .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-1763259432376-4152o88ey .data-definitions-toggle:hover {
color: #525252;
}
.cfb-chart-embed-cfb-chart-1763259432376-4152o88ey .caret {
transition: transform 0.2s ease;
font-size: 10px;
}
.cfb-chart-embed-cfb-chart-1763259432376-4152o88ey .caret.expanded {
transform: rotate(180deg);
}
.cfb-chart-embed-cfb-chart-1763259432376-4152o88ey .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-1763259432376-4152o88ey .data-definitions.expanded {
display: block;
}
.cfb-chart-embed-cfb-chart-1763259432376-4152o88ey .data-definitions ul {
margin: 0;
padding-left: 0;
list-style: none;
}
.cfb-chart-embed-cfb-chart-1763259432376-4152o88ey .data-definitions li {
margin-bottom: 4px;
}
Rush Rate: Alabama
Alabama vs. Oklahoma • Nov 15, 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
- Rush Rate: Percentage of offensive plays that are rushing attempts
- Gray area: Represents 50/50 balanced offense
// Toggle data definitions accordion – unique function per embed
function toggleDefinitions_cfb_chart_1763259432376_4152o88ey() {
const definitions = document.getElementById(‘dataDefinitions_cfb-chart-1763259432376-4152o88ey’);
const caret = document.getElementById(‘caret_cfb-chart-1763259432376-4152o88ey’);
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-1763259432376-4152o88ey’);
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-1763259432376-4152o88ey’);
if (!canvas) {
console.warn(‘Canvas element not found yet, retrying…’);
setTimeout(initChart, 100);
return;
}
// Prevent multiple chart instances
if (canvas.chartInstance) {
console.log(‘Chart already initialized’);
return;
}
try {
// Register the datalabels plugin
Chart.register(ChartDataLabels);
// Embed actual chart data directly
const chartData = {
“datasets”: [
{
“label”: “50/50”,
“data”: [
{
“x”: 1,
“y”: 0
},
{
“x”: 1,
“y”: 0.5
},
{
“x”: 73,
“y”: 0.5
},
{
“x”: 73,
“y”: 0
}
],
“backgroundColor”: “rgba(0,0,0,0.03)”,
“borderColor”: “transparent”,
“pointRadius”: 0,
“fill”: true,
“tension”: 0,
“showLine”: true,
“datalabels”: {
“display”: false
}
},
{
“data”: [
{
“x”: 1,
“y”: 0,
“text”: “T.Simpson pass incomplete short left to #80 J.Cuevas thrown to ALA25”
},
{
“x”: 2,
“y”: 0.5,
“text”: “J.Miller rush middle for 3 yards gain to the ALA23 (#10 K.Lewis)”
},
{
“x”: 3,
“y”: 0.6666666666666666,
“text”: “T.Simpson rush right for 0 yards to the ALA23 (#97 M.Jones Jr.)”
},
{
“x”: 4,
“y”: 0.5,
“text”: “T.Simpson sacked for loss of 7 yards to the ALA18 (#10 K.Lewis)”
},
{
“x”: 5,
“y”: 0.4,
“text”: “T.Simpson pass complete short right to #2 R.Williams caught at ALA15, for 1 yard loss to the ALA17 (#38 O.Heinecke)”
},
{
“x”: 6,
“y”: 0.3333333333333333,
“text”: “T.Simpson pass incomplete deep left to #2 R.Williams thrown to OU 41”
},
{
“x”: 7,
“y”: 0.2857142857142857,
“text”: “T.Simpson pass complete short middle to #5 G.Bernard caught at ALA34, for 17 yards to the ALA37 (#25 M.Boganowski), 1ST DOWN”
},
{
“x”: 8,
“y”: 0.25,
“text”: “T.Simpson pass complete short left to #4 D.Hill caught at ALA38, for 8 yards to the ALA45 (#5 K.Daniels; #25 M.Boganowski)”
},
{
“x”: 9,
“y”: 0.3333333333333333,
“text”: “D.Hill rush left for 1 yard gain to the ALA46 (#11 K.McKinzie)”
},
{
“x”: 10,
“y”: 0.4,
“text”: “D.Hill rush middle for 2 yards gain to the ALA48 (#22 P.Bowen), 1ST DOWN”
},
{
“x”: 11,
“y”: 0.36363636363636365,
“text”: “T.Simpson pass complete short left to #5 G.Bernard caught at OU 37, for 15 yards to the OU 37 (#4 C.Guillory), 1ST DOWN”
},
{
“x”: 12,
“y”: 0.4166666666666667,
“text”: “D.Hill rush right for 7 yards gain to the OU 30 (#13 R.Powers III; #99 M.Strong)”
},
{
“x”: 13,
“y”: 0.38461538461538464,
“text”: “T.Simpson pass intercepted by #23 E.Bowen at OU 13 QB hurried by #10 K.Lewis #23 E.Bowen return 87 yards to the ALA00 TOUCHDOWN, clock 02:03 #29 T.Sandell kick attempt good (H: #87 J.Ulrich, LS: #49 B.Anderson)”
},
{
“x”: 14,
“y”: 0.35714285714285715,
“text”: “T.Simpson pass complete short middle to #80 J.Cuevas caught at ALA27, for 3 yards to the ALA31 (#10 K.Lewis)”
},
{
“x”: 15,
“y”: 0.3333333333333333,
“text”: “T.Simpson pass complete short middle to #5 G.Bernard caught at ALA43, for 11 yards to the ALA42 (#3 R.Spears-Jennings), 1ST DOWN”
},
{
“x”: 16,
“y”: 0.375,
“text”: “J.Miller rush right for 2 yards gain to the ALA44 (#0 D.Stone)”
},
{
“x”: 17,
“y”: 0.35294117647058826,
“text”: “T.Simpson pass complete short left to #5 G.Bernard caught at ALA40, for 8 yards to the OU 48 (#1 J.Hardy; #97 M.Jones Jr.), 1ST DOWN”
},
{
“x”: 18,
“y”: 0.3888888888888889,
“text”: “T.Simpson rush left for 9 yards gain to the OU 39 (#4 C.Guillory)”
},
{
“x”: 19,
“y”: 0.3684210526315789,
“text”: “T.Simpson pass incomplete short right to #5 G.Bernard thrown to OU 25”
},
{
“x”: 20,
“y”: 0.4,
“text”: “D.Hill rush middle for 3 yards gain to the OU 36 (#52 D.Williams; #0 D.Stone), 1ST DOWN”
},
{
“x”: 21,
“y”: 0.38095238095238093,
“text”: “T.Simpson pass complete short left to #81 K.Edwards caught at OU 20, for 25 yards to the OU 11 (#7 S.Omosigho), 1ST DOWN”
},
{
“x”: 22,
“y”: 0.36363636363636365,
“text”: “T.Simpson pass incomplete short middle to #1 I.Horton thrown to OU 01”
},
{
“x”: 23,
“y”: 0.391304347826087,
“text”: “J.Miller rush left for 2 yards gain to the OU 09 (#7 S.Omosigho; #44 T.Wein)”
},
{
“x”: 24,
“y”: 0.4166666666666667,
“text”: “D.Hill rush middle for 1 yard gain to the OU 01 (#52 D.Williams)”
},
{
“x”: 25,
“y”: 0.44,
“text”: “D.Hill rush middle for 1 yard gain to the OU 00 TOUCHDOWN, clock 10:36 #31 C.Talty kick attempt good (H: #38 B.Doud, LS: #45 D.Bird)”
},
{
“x”: 26,
“y”: 0.4230769230769231,
“text”: “T.Simpson pass complete deep right to #2 R.Williams caught at OU 48, for 38 yards to the OU 40 (#23 E.Bowen), 1ST DOWN”
},
{
“x”: 27,
“y”: 0.4074074074074074,
“text”: “T.Simpson pass complete short right to #5 G.Bernard caught at OU 36, for 5 yards to the OU 35 (#23 E.Bowen)”
},
{
“x”: 28,
“y”: 0.39285714285714285,
“text”: “T.Simpson pass complete short right to #17 L.Brooks caught at OU 38, for 6 yards to the OU 29 (#23 E.Bowen), 1ST DOWN”
},
{
“x”: 29,
“y”: 0.3793103448275862,
“text”: “T.Simpson pass incomplete short middle to #5 G.Bernard thrown to OU 13”
},
{
“x”: 30,
“y”: 0.4,
“text”: “D.Hill rush left for 4 yards gain to the OU 25 (#25 M.Boganowski; #52 D.Williams)”
},
{
“x”: 31,
“y”: 0.3870967741935484,
“text”: “T.Simpson pass complete short right to #80 J.Cuevas caught at OU 20, for 25 yards to the OU 00 TOUCHDOWN, clock 06:13, 1ST DOWN #31 C.Talty kick attempt good (H: #38 B.Doud, LS: #45 D.Bird)”
},
{
“x”: 32,
“y”: 0.375,
“text”: “T.Simpson pass complete short right to #26 J.Miller caught at ALA13, for 0 yards to the ALA13 (#13 R.Powers III)”
},
{
“x”: 33,
“y”: 0.36363636363636365,
“text”: “T.Simpson pass complete short right to #80 J.Cuevas caught at ALA18, for 14 yards to the ALA27 (#38 O.Heinecke; #1 J.Hardy), 1ST DOWN”
},
{
“x”: 34,
“y”: 0.35294117647058826,
“text”: “T.Simpson pass complete short right to #2 R.Williams caught at ALA31, for 8 yards to the ALA35 (#10 K.Lewis)”
},
{
“x”: 35,
“y”: 0.34285714285714286,
“text”: “T.Simpson pass complete short middle to #80 J.Cuevas caught at ALA40, for 14 yards to the ALA49 (#34 A.Adebawore; #3 R.Spears-Jennings), 1ST DOWN”
},
{
“x”: 36,
“y”: 0.3333333333333333,
“text”: “T.Simpson pass complete short left to #4 D.Hill caught at OU 49, for 2 yards to the OU 49 (#38 O.Heinecke)”
},
{
“x”: 37,
“y”: 0.32432432432432434,
“text”: “T.Simpson pass complete short middle to #4 D.Hill caught at ALA45, for 16 yards to the OU 43 (#23 E.Bowen)”
},
{
“x”: 38,
“y”: 0.3157894736842105,
“text”: “T.Simpson pass complete short right to #80 J.Cuevas caught at OU 40, for 4 yards to the OU 39 (#44 T.Wein), out of bounds, 1ST DOWN”
},
{
“x”: 39,
“y”: 0.3076923076923077,
“text”: “T.Simpson pass incomplete short middle to #26 J.Miller thrown to OU 35”
},
{
“x”: 40,
“y”: 0.3,
“text”: “T.Simpson pass incomplete deep left to #5 G.Bernard thrown to OU 15 QB hurried by #44 T.Wein”
},
{
“x”: 41,
“y”: 0.2926829268292683,
“text”: “T.Simpson pass incomplete short left to #5 G.Bernard thrown to OU 20 broken up by #23 E.Bowen”
},
{
“x”: 42,
“y”: 0.2857142857142857,
“text”: “T.Simpson pass complete short left to #1 I.Horton caught at OU 29, for 15 yards to the OU 24 (#22 P.Bowen), 1ST DOWN”
},
{
“x”: 43,
“y”: 0.27906976744186046,
“text”: “T.Simpson pass complete short left to #5 G.Bernard caught at OU 18, for 6 yards to the OU 18, out of bounds at OU 18”
},
{
“x”: 44,
“y”: 0.2727272727272727,
“text”: “T.Simpson pass incomplete short right to #5 G.Bernard thrown to ALA41”
},
{
“x”: 45,
“y”: 0.28888888888888886,
“text”: “D.Hill rush right for 28 yards gain to the OU 47 (#23 E.Bowen), out of bounds, 1ST DOWN”
},
{
“x”: 46,
“y”: 0.30434782608695654,
“text”: “D.Hill rush left for 0 yards to the OU 47 (#13 R.Powers III)”
},
{
“x”: 47,
“y”: 0.2978723404255319,
“text”: “T.Simpson pass complete short right to #80 J.Cuevas caught at OU 48, for 20 yards to the OU 27 (#3 R.Spears-Jennings), 1ST DOWN”
},
{
“x”: 48,
“y”: 0.2916666666666667,
“text”: “T.Simpson pass complete deep right to #1 I.Horton caught at OU 03, for 26 yards to the OU 01 (#3 R.Spears-Jennings), out of bounds, 1ST DOWN”
},
{
“x”: 49,
“y”: 0.30612244897959184,
“text”: “J.Miller rush middle for 0 yards to the OU 01 (#56 G.Halton)”
},
{
“x”: 50,
“y”: 0.32,
“text”: “D.Hill rush middle for 1 yard gain to the OU 00 TOUCHDOWN, clock 07:27 #31 C.Talty kick attempt good (H: #38 B.Doud, LS: #52 A.Rozier)”
},
{
“x”: 51,
“y”: 0.3137254901960784,
“text”: “D.Hill pass complete short left to #4 D.Hill caught at ALA22, for 4 yards to the ALA24, End Of Play”
},
{
“x”: 52,
“y”: 0.3269230769230769,
“text”: “D.Hill rush right for 3 yards gain to the ALA27 (#7 S.Omosigho; #11 K.McKinzie)”
},
{
“x”: 53,
“y”: 0.32075471698113206,
“text”: “T.Simpson pass incomplete short middle to #5 G.Bernard thrown to ALA38”
},
{
“x”: 54,
“y”: 0.3333333333333333,
“text”: “J.Miller rush left for 4 yards gain to the ALA22 (#52 D.Williams; #0 D.Stone)”
},
{
“x”: 55,
“y”: 0.34545454545454546,
“text”: “T.Simpson rush right for 8 yards gain to the ALA30 (#22 P.Bowen; #0 D.Stone), 1ST DOWN”
},
{
“x”: 56,
“y”: 0.35714285714285715,
“text”: “J.Miller rush left for 1 yard gain to the ALA31 (#19 J.Johnson)”
},
{
“x”: 57,
“y”: 0.3508771929824561,
“text”: “T.Simpson pass incomplete short left to #5 G.Bernard thrown to ALA30 QB hurried by #44 T.Wein and #34 A.Adebawore”
},
{
“x”: 58,
“y”: 0.3620689655172414,
“text”: “D.Hill rush left for 5 yards gain to the ALA30 (#7 S.Omosigho)”
},
{
“x”: 59,
“y”: 0.3728813559322034,
“text”: “D.Hill rush right for 0 yards to the ALA30 (#11 K.McKinzie)”
},
{
“x”: 60,
“y”: 0.36666666666666664,
“text”: “T.Simpson sacked for loss of 7 yards to the ALA23 (#12 D.Jordan)”
},
{
“x”: 61,
“y”: 0.3770491803278688,
“text”: “D.Hill rush right for 3 yards gain to the ALA09 (#12 D.Jordan)”
},
{
“x”: 62,
“y”: 0.3870967741935484,
“text”: “T.Simpson rush right for 2 yards gain to the ALA11 (#10 K.Lewis), out of bounds”
},
{
“x”: 63,
“y”: 0.38095238095238093,
“text”: “T.Simpson pass complete short left to #5 G.Bernard caught at ALA20, for 9 yards to the ALA20 (#4 C.Guillory), out of bounds, 1ST DOWN”
},
{
“x”: 64,
“y”: 0.390625,
“text”: “J.Miller rush left for 8 yards gain to the ALA28 (#38 O.Heinecke)”
},
{
“x”: 65,
“y”: 0.4,
“text”: “J.Miller rush middle for 5 yards gain to the ALA33 (#4 C.Guillory), 1ST DOWN”
},
{
“x”: 66,
“y”: 0.4090909090909091,
“text”: “J.Miller rush right for 2 yards gain to the ALA35 (#22 P.Bowen)”
},
{
“x”: 67,
“y”: 0.40298507462686567,
“text”: “T.Simpson pass complete short left to #17 L.Brooks caught at ALA40, for 6 yards to the ALA41 (#22 P.Bowen; #99 M.Strong). #17 L.Brooks injured on the play”
},
{
“x”: 68,
“y”: 0.4117647058823529,
“text”: “D.Hill rush middle for 1 yard gain to the ALA42 (#11 K.McKinzie; #56 G.Halton)”
},
{
“x”: 69,
“y”: 0.42028985507246375,
“text”: “L.Brooks rush right for 2 yards gain to the ALA44 (#3 R.Spears-Jennings), 1ST DOWN”
},
{
“x”: 70,
“y”: 0.4142857142857143,
“text”: “T.Simpson sacked for loss of 11 yards to the ALA33 (#10 K.Lewis)”
},
{
“x”: 71,
“y”: 0.4084507042253521,
“text”: “T.Simpson pass incomplete deep right to #1 I.Horton thrown to OU 43”
},
{
“x”: 72,
“y”: 0.4027777777777778,
“text”: “T.Simpson pass complete short right to #1 I.Horton caught at ALA48, for 15 yards to the ALA48 (#10 K.Lewis)”
},
{
“x”: 73,
“y”: 0.3972602739726027,
“text”: “T.Simpson pass incomplete short left to #2 R.Williams thrown to OU 46 broken up by #22 P.Bowen, TURNOVER ON DOWNS”
}
],
“label”: “Alabama Rush Rate”,
“borderColor”: “rgba(101, 0, 20, 0.8)”,
“backgroundColor”: “rgba(245, 229, 233, 0.8)”,
“borderWidth”: 2,
“pointBackgroundColor”: [
“rgba(255,255,255,0.9)”,
“rgba(255,255,255,0.9)”,
“rgba(255,255,255,0.9)”,
“rgba(255,255,255,0.9)”,
“rgba(255,255,255,0.9)”,
“rgba(255,255,255,0.9)”,
“rgba(101, 0, 20, 0.8)”,
“rgba(175, 40, 60, 0.8)”,
“rgba(255,255,255,0.9)”,
“rgba(175, 40, 60, 0.8)”,
“rgba(101, 0, 20, 0.8)”,
“rgba(175, 40, 60, 0.8)”,
“rgba(255,255,255,0.9)”,
“rgba(255,255,255,0.9)”,
“rgba(175, 40, 60, 0.8)”,
“rgba(255,255,255,0.9)”,
“rgba(175, 40, 60, 0.8)”,
“rgba(175, 40, 60, 0.8)”,
“rgba(255,255,255,0.9)”,
“rgba(175, 40, 60, 0.8)”,
“rgba(101, 0, 20, 0.8)”,
“rgba(255,255,255,0.9)”,
“rgba(255,255,255,0.9)”,
“rgba(175, 40, 60, 0.8)”,
“rgba(175, 40, 60, 0.8)”,
“rgba(101, 0, 20, 0.8)”,
“rgba(175, 40, 60, 0.8)”,
“rgba(175, 40, 60, 0.8)”,
“rgba(255,255,255,0.9)”,
“rgba(255,255,255,0.9)”,
“rgba(101, 0, 20, 0.8)”,
“rgba(255,255,255,0.9)”,
“rgba(175, 40, 60, 0.8)”,
“rgba(175, 40, 60, 0.8)”,
“rgba(175, 40, 60, 0.8)”,
“rgba(255,255,255,0.9)”,
“rgba(101, 0, 20, 0.8)”,
“rgba(175, 40, 60, 0.8)”,
“rgba(255,255,255,0.9)”,
“rgba(255,255,255,0.9)”,
“rgba(255,255,255,0.9)”,
“rgba(101, 0, 20, 0.8)”,
“rgba(175, 40, 60, 0.8)”,
“rgba(255,255,255,0.9)”,
“rgba(101, 0, 20, 0.8)”,
“rgba(255,255,255,0.9)”,
“rgba(101, 0, 20, 0.8)”,
“rgba(101, 0, 20, 0.8)”,
“rgba(255,255,255,0.9)”,
“rgba(175, 40, 60, 0.8)”,
“rgba(255,255,255,0.9)”,
“rgba(255,255,255,0.9)”,
“rgba(255,255,255,0.9)”,
“rgba(255,255,255,0.9)”,
“rgba(175, 40, 60, 0.8)”,
“rgba(255,255,255,0.9)”,
“rgba(255,255,255,0.9)”,
“rgba(175, 40, 60, 0.8)”,
“rgba(255,255,255,0.9)”,
“rgba(255,255,255,0.9)”,
“rgba(255,255,255,0.9)”,
“rgba(255,255,255,0.9)”,
“rgba(175, 40, 60, 0.8)”,
“rgba(175, 40, 60, 0.8)”,
“rgba(175, 40, 60, 0.8)”,
“rgba(255,255,255,0.9)”,
“rgba(175, 40, 60, 0.8)”,
“rgba(255,255,255,0.9)”,
“rgba(175, 40, 60, 0.8)”,
“rgba(255,255,255,0.9)”,
“rgba(255,255,255,0.9)”,
“rgba(101, 0, 20, 0.8)”,
“rgba(255,255,255,0.9)”
],
“pointStyle”: [
“triangle”,
“circle”,
“circle”,
“triangle”,
“triangle”,
“triangle”,
“triangle”,
“triangle”,
“circle”,
“circle”,
“triangle”,
“circle”,
“triangle”,
“triangle”,
“triangle”,
“circle”,
“triangle”,
“circle”,
“triangle”,
“circle”,
“triangle”,
“triangle”,
“circle”,
“circle”,
“circle”,
“triangle”,
“triangle”,
“triangle”,
“triangle”,
“circle”,
“triangle”,
“triangle”,
“triangle”,
“triangle”,
“triangle”,
“triangle”,
“triangle”,
“triangle”,
“triangle”,
“triangle”,
“triangle”,
“triangle”,
“triangle”,
“triangle”,
“circle”,
“circle”,
“triangle”,
“triangle”,
“circle”,
“circle”,
“triangle”,
“circle”,
“triangle”,
“circle”,
“circle”,
“circle”,
“triangle”,
“circle”,
“circle”,
“triangle”,
“circle”,
“circle”,
“triangle”,
“circle”,
“circle”,
“circle”,
“triangle”,
“circle”,
“circle”,
“triangle”,
“triangle”,
“triangle”,
“triangle”
],
“pointRadius”: [
5.5,
4,
4,
5.5,
5.5,
5.5,
5.5,
5.5,
4,
4,
5.5,
4,
5.5,
5.5,
5.5,
4,
5.5,
4,
5.5,
4,
5.5,
5.5,
4,
4,
4,
5.5,
5.5,
5.5,
5.5,
4,
5.5,
5.5,
5.5,
5.5,
5.5,
5.5,
5.5,
5.5,
5.5,
5.5,
5.5,
5.5,
5.5,
5.5,
4,
4,
5.5,
5.5,
4,
4,
5.5,
4,
5.5,
4,
4,
4,
5.5,
4,
4,
5.5,
4,
4,
5.5,
4,
4,
4,
5.5,
4,
4,
5.5,
5.5,
5.5,
5.5
],
“pointBorderWidth”: 1,
“pointBorderColor”: “rgba(101, 0, 20, 0.8)”,
“fill”: true
},
{
“label”: “Quarters”,
“data”: [
{
“x”: 1,
“y”: 0
},
{
“x”: 1,
“y”: 1
},
{
“x”: 73,
“y”: 1
},
{
“x”: 73,
“y”: 0
},
{
“x”: 17,
“y”: 0
},
{
“x”: 17,
“y”: 1
},
{
“x”: 73,
“y”: 1
},
{
“x”: 73,
“y”: 0
},
{
“x”: 44,
“y”: 0
},
{
“x”: 44,
“y”: 1
},
{
“x”: 73,
“y”: 1
},
{
“x”: 73,
“y”: 0
},
{
“x”: 58,
“y”: 0
},
{
“x”: 58,
“y”: 1
},
{
“x”: 73,
“y”: 1
},
{
“x”: 73,
“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”: 12,
“seasonType”: “regular”,
“team”: “Alabama”,
“gameId”: “401752765”
}
};
// Chart options (WordPress-safe)
const chartOptions = {
responsive: true,
maintainAspectRatio: false,
animation: {
duration: 1 // Minimal animation to trigger layout calculation (fixes label positioning)
},
elements: ‘line’ === ‘line’ ? ‘team-rush-rate’.includes(‘play-map’) ? {
line: {
tension: 0,
borderWidth: 0
}
} : ‘team-rush-rate’ === ‘win-probability’ ? {
line: {
tension: 0.15,
borderWidth: 2.2,
fill: false
},
point: {
pointRadius: 0,
pointHoverRadius: 4
}
} : {
line: {
tension: 0.25,
borderWidth: 2.2
},
point: {
pointRadius: ‘team-rush-rate’.includes(‘team-lines’) ? 0 : undefined
}
} : {},
plugins: {
datalabels: {
display: function(context) {
// Suppress data labels on line charts
if (‘line’ === ‘line’) {
return false;
}
return context.dataset.datalabels && context.dataset.datalabels.display === true;
},
formatter: function(value, context) {
// Special handling for Overall Team Performance chart
if (‘team-rush-rate’ === ‘overall-team-performance’ && context.dataset.label === ‘Success Rate (SR)’) {
// Use the stored play count data
if (context.dataset.playCountData && context.dataset.playCountData[context.dataIndex]) {
return context.dataset.playCountData[context.dataIndex];
}
// Fallback to percentage if play count data not available
return Math.round(value * 100) + ‘%’;
}
// Handle bar charts with count data (play-type, quarter, down, etc.)
if (context.dataset.label && context.dataset.label.includes(‘ SR’) &&
(chartData.teamCounts || chartData.oppCounts)) {
// Find the first team SR dataset in the chart to determine team order
const allDatasets = context.chart.data.datasets;
const teamSRDataset = allDatasets.find(d => d.label && d.label.includes(‘ SR’) && !d.label.includes(‘NCAA’));
// If this is the first team’s SR dataset, use teamCounts
if (teamSRDataset && context.dataset.label === teamSRDataset.label && chartData.teamCounts) {
return chartData.teamCounts[context.dataIndex] || 0;
}
// Otherwise, use oppCounts for the second team
else if (chartData.oppCounts) {
return chartData.oppCounts[context.dataIndex] || 0;
}
}
// For player charts, show value only if > 0 (matches non-embedded behavior)
if (‘team-rush-rate’.includes(‘top-rushers’) || ‘team-rush-rate’.includes(‘top-passers’) || ‘team-rush-rate’.includes(‘top-receivers’)) {
// Hide data labels for zero or negative values, show actual value for positive values
return value > 0 ? value : null;
}
// For other charts, show values based on type
if (typeof value === ‘number’) {
// If value is between 0 and 1, treat as percentage
if (value >= 0 && value 0 ? ‘#26262660’ : ‘transparent’;
},
borderColor: function(context) {
const value = context.dataset.data[context.dataIndex];
return value > 0 ? ‘rgba(255, 255, 255, 0.2)’ : ‘transparent’;
},
borderRadius: 4,
align: ‘center’,
anchor: ‘center’
},
legend: ‘team-rush-rate’ === ‘win-probability’ ? {
display: false
} : ‘line’ === ‘line’ ? {
position: ‘top’,
align: ‘start’,
labels: ‘team-rush-rate’.includes(‘play-map’) ? {
usePointStyle: true,
generateLabels: function(chart) {
// Call the original generateLabels to get default styling
const original = Chart.defaults.plugins.legend.labels.generateLabels;
const labels = original.call(this, chart);
// Filter and customize each label
const filteredLabels = labels.filter(label => {
return !label.text.includes(‘ {
const dataset = chart.data.datasets[label.datasetIndex];
if (dataset && dataset.label) {
if (dataset.label.includes(‘Rush’)) {
label.pointStyle = ‘circle’;
label.pointStyleWidth = 4;
label.fillStyle = ‘white’;
} else if (dataset.label.includes(‘Pass’)) {
label.pointStyle = ‘triangle’;
label.pointStyleWidth = 4;
label.fillStyle = ‘white’;
} else {
label.pointStyle = ‘rect’;
label.pointStyleWidth = 4;
label.fillStyle = ‘white’;
}
}
});
return filteredLabels;
},
boxWidth: 20,
padding: 12
} : {
usePointStyle: false,
boxWidth: 12,
boxHeight: 12,
padding: 12,
generateLabels: function(chart) {
const original = Chart.defaults.plugins.legend.labels.generateLabels;
const labels = original.call(this, chart);
// Filter out reference areas and ensure white fill
const filteredLabels = labels.filter(label => {
return !label.text.includes(‘NCAA Avg SR’) &&
!label.text.includes(’50/50′) &&
!label.text.includes(‘Quarters’);
});
// Ensure white fill for all line chart legend boxes
filteredLabels.forEach((label) => {
label.fillStyle = ‘white’;
});
return filteredLabels;
}
}
} : {
position: ‘top’,
align: ‘start’,
labels: {
usePointStyle: false,
boxWidth: 12,
boxHeight: 12,
padding: 12,
filter: function(legendItem, chartData) {
return !legendItem.text.includes(‘NCAA Avg SR’) &&
!legendItem.text.includes(‘Quarters’) &&
!legendItem.text.includes(’50/50′);
},
generateLabels: function(chart) {
const data = chart.data;
if (data.datasets.length) {
return data.datasets.map((dataset, i) => {
// Handle backgroundColor arrays (like in Overall Team Performance chart)
let fillColor = dataset.backgroundColor;
if (dataset.label === ‘# Plays’) {
fillColor = ‘white’;
} else if (Array.isArray(dataset.backgroundColor)) {
// For datasets with backgroundColor arrays, use the first color for legend
fillColor = dataset.backgroundColor[0];
}
return {
text: dataset.label,
fillStyle: fillColor,
strokeStyle: dataset.label === ‘# Plays’ ? ‘#666’ : dataset.borderColor,
lineWidth: dataset.label === ‘# Plays’ ? 1 : dataset.borderWidth,
hidden: !chart.isDatasetVisible(i),
datasetIndex: i
};
}).filter((item, index) => {
// Apply the same filter logic as above
const dataset = chart.data.datasets[index];
if (!dataset || !dataset.data) return false;
if (dataset.label === ‘# Plays’) return true; // Always show # Plays
if (dataset.label && (dataset.label.includes(‘NCAA Avg SR’) ||
dataset.label.includes(‘Quarters’) ||
dataset.label.includes(’50/50′))) return false;
return dataset.data.some((value) => value > 0);
});
}
return [];
}
}
},
tooltip: ‘team-rush-rate’ === ‘win-probability’ ? {
mode: ‘index’,
intersect: false,
callbacks: {
title: function(tooltipItems) {
if (tooltipItems && tooltipItems[0]) {
return ‘Play ‘ + (tooltipItems[0].dataIndex + 1);
}
return ”;
},
label: function(context) {
const selectedTeamWinProb = context.parsed.y;
const opponentWinProb = 100 – selectedTeamWinProb;
const selectedTeam = context.dataset.selectedTeam || ‘Team’;
const opponentTeam = context.dataset.opponentTeam || ‘Opponent’;
return [
selectedTeam + ‘: ‘ + selectedTeamWinProb.toFixed(1) + ‘%’,
opponentTeam + ‘: ‘ + opponentWinProb.toFixed(1) + ‘%’
];
},
afterLabel: function(context) {
if (context.dataset.playTexts && context.dataset.playTexts[context.dataIndex]) {
return ‘n’ + context.dataset.playTexts[context.dataIndex];
}
return ”;
}
}
} : {
filter: function(tooltipItem) {
if (‘team-rush-rate’.includes(‘play-map’)) {
return !tooltipItem.dataset.label.includes(‘< 0’) &&
!tooltipItem.dataset.label.includes(‘Quarters’) &&
!tooltipItem.dataset.label.includes(‘Drive’);
}
return !tooltipItem.dataset.label.includes(‘NCAA Avg SR’) &&
!tooltipItem.dataset.label.includes(’50/50′) &&
!tooltipItem.dataset.label.includes(‘ ds.label === ‘Win Probability’);
if (wpDataset && wpDataset.segmentColors) {
wpDataset.segment = {
borderColor: function(ctx) {
// Use p1DataIndex (ending point) so the line inherits the destination color
// This makes momentum shifts more visually intuitive
const index = ctx.p1DataIndex;
if (index !== undefined && wpDataset.segmentColors[index]) {
return wpDataset.segmentColors[index];
}
return wpDataset.borderColor || ‘#8B0000’;
}
};
}
}
// Initialize the chart
const ctx = canvas.getContext(‘2d’);
const chart = new Chart(ctx, {
type: ‘line’,
data: chartData,
options: chartOptions
});
// Store reference to prevent re-initialization
canvas.chartInstance = chart;
console.log(‘CFB Chart initialized successfully’);
} catch (error) {
console.error(‘Error initializing CFB chart:’, error);
// Fallback: show error message in canvas container
const container = document.getElementById(‘cfb-chart-1763259432376-4152o88ey’).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 gave rushing a few good tries, too. Here we do still see a decidedly pass-first team … I mean, by the end of the 1st half, our rushing rate was below 30%, which is low even for this particular team and season.
However, that was after a drive or two in the 2nd quarter where just went totally to the pass — fortunately to some success (unfortunately with a missed FG at the end of the spree). No, it is not lost on me that we were scoring more points when we were passing constantly like this.
But in the 2nd half, Alabama started running. The rush rate climbed steadily through the 3rd quarter and well into late in the 4th quarter, before we tried to pass ourselves out of a hole late in the game to not-quite-enough success.
.cfb-chart-embed-cfb-chart-1763259447403-nxgw18gy1 {
font-family: -apple-system, BlinkMacSystemFont, ‘Segoe UI’, ‘Roboto’, sans-serif;
margin: 0;
padding: 0;
}
.cfb-chart-embed-cfb-chart-1763259447403-nxgw18gy1 .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-1763259447403-nxgw18gy1 .chart-header {
padding: 18px 24px 14px;
border-bottom: 1px solid #e5e5e5;
background: white;
}
.cfb-chart-embed-cfb-chart-1763259447403-nxgw18gy1 .chart-title {
font-size: 18px;
font-weight: 600;
color: #171717;
margin: 0;
}
.cfb-chart-embed-cfb-chart-1763259447403-nxgw18gy1 .chart-subtitle {
font-size: 11px;
font-weight: 400;
color: #737373;
margin: 4px 0 0 0;
}
.cfb-chart-embed-cfb-chart-1763259447403-nxgw18gy1 .chart-content {
padding: 20px 24px 24px !important;
}
.cfb-chart-embed-cfb-chart-1763259447403-nxgw18gy1 .chart-content.top-rushers { height: 372px; }
@media (max-width: 640px) {
.cfb-chart-embed-cfb-chart-1763259447403-nxgw18gy1 .chart-content {
padding: 12px 16px 20px !important;
}
.cfb-chart-embed-cfb-chart-1763259447403-nxgw18gy1 .chart-header {
padding: 12px 16px 12px !important;
}
.cfb-chart-embed-cfb-chart-1763259447403-nxgw18gy1 .embed-footer-top {
padding: 8px 12px !important;
}
.cfb-chart-embed-cfb-chart-1763259447403-nxgw18gy1 .data-definitions {
padding: 12px !important;
}
}
.cfb-chart-embed-cfb-chart-1763259447403-nxgw18gy1 .embed-footer {
border-top: 1px solid #e5e5e5;
font-size: 12px;
color: #737373;
}
.cfb-chart-embed-cfb-chart-1763259447403-nxgw18gy1 .embed-footer-top {
display: flex;
justify-content: space-between;
align-items: center;
padding: 12px 16px;
}
.cfb-chart-embed-cfb-chart-1763259447403-nxgw18gy1 .embed-footer-link {
color: #737373;
text-decoration: none;
font-weight: 500;
}
.cfb-chart-embed-cfb-chart-1763259447403-nxgw18gy1 .embed-footer-link:hover {
color: #525252;
text-decoration: underline;
}
.cfb-chart-embed-cfb-chart-1763259447403-nxgw18gy1 .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-1763259447403-nxgw18gy1 .data-definitions-toggle:hover {
color: #525252;
}
.cfb-chart-embed-cfb-chart-1763259447403-nxgw18gy1 .caret {
transition: transform 0.2s ease;
font-size: 10px;
}
.cfb-chart-embed-cfb-chart-1763259447403-nxgw18gy1 .caret.expanded {
transform: rotate(180deg);
}
.cfb-chart-embed-cfb-chart-1763259447403-nxgw18gy1 .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-1763259447403-nxgw18gy1 .data-definitions.expanded {
display: block;
}
.cfb-chart-embed-cfb-chart-1763259447403-nxgw18gy1 .data-definitions ul {
margin: 0;
padding-left: 0;
list-style: none;
}
.cfb-chart-embed-cfb-chart-1763259447403-nxgw18gy1 .data-definitions li {
margin-bottom: 4px;
}
Top rushers
Alabama vs. Oklahoma • Nov 15, 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_1763259447403_nxgw18gy1() {
const definitions = document.getElementById(‘dataDefinitions_cfb-chart-1763259447403-nxgw18gy1’);
const caret = document.getElementById(‘caret_cfb-chart-1763259447403-nxgw18gy1’);
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-1763259447403-nxgw18gy1’);
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-1763259447403-nxgw18gy1’);
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”: [
“D.Hill”,
“J.Miller”,
“T.Simpson”,
“L.Brooks”,
“X.Robinson”,
“J.Mateer”,
“T.Blaylock”,
“I.Sategna III”
],
“datasets”: [
{
“label”: “Explosive rushes”,
“data”: [
1,
0,
0,
0,
0,
1,
0,
1
],
“backgroundColor”: [
“#3c000cCC”,
“#3c000cCC”,
“#3c000cCC”,
“#3c000cCC”,
“#231500CC”,
“#231500CC”,
“#231500CC”,
“#231500CC”
],
“borderColor”: “#374151”,
“borderWidth”: 1
},
{
“label”: “Successful rushes”,
“data”: [
7,
2,
2,
1,
3,
0,
0,
0
],
“backgroundColor”: [
“rgba(175, 40, 60, 0.8)”,
“rgba(175, 40, 60, 0.8)”,
“rgba(175, 40, 60, 0.8)”,
“rgba(175, 40, 60, 0.8)”,
“#A16207CC”,
“#A16207CC”,
“#A16207CC”,
“#A16207CC”
],
“borderColor”: “#374151”,
“borderWidth”: 1
},
{
“label”: “Unsuccessful rushes”,
“data”: [
7,
7,
2,
0,
7,
7,
4,
0
],
“backgroundColor”: “#FFFFFF”,
“borderColor”: “#374151”,
“borderWidth”: 1
}
],
“currentParams”: {
“year”: 2025,
“week”: 12,
“seasonType”: “regular”,
“team”: “Alabama”,
“gameId”: “401752765”
}
};
// Chart options (WordPress-safe)
const chartOptions = {
responsive: true,
maintainAspectRatio: false,
animation: {
duration: 1 // Minimal animation to trigger layout calculation (fixes label positioning)
},
elements: ‘bar’ === ‘line’ ? ‘top-rushers’.includes(‘play-map’) ? {
line: {
tension: 0,
borderWidth: 0
}
} : ‘top-rushers’ === ‘win-probability’ ? {
line: {
tension: 0.15,
borderWidth: 2.2,
fill: false
},
point: {
pointRadius: 0,
pointHoverRadius: 4
}
} : {
line: {
tension: 0.25,
borderWidth: 2.2
},
point: {
pointRadius: ‘top-rushers’.includes(‘team-lines’) ? 0 : undefined
}
} : {},
plugins: {
datalabels: {
display: function(context) {
// Suppress data labels on line charts
if (‘bar’ === ‘line’) {
return false;
}
return context.dataset.datalabels && context.dataset.datalabels.display === true;
},
formatter: function(value, context) {
// Special handling for Overall Team Performance chart
if (‘top-rushers’ === ‘overall-team-performance’ && context.dataset.label === ‘Success Rate (SR)’) {
// Use the stored play count data
if (context.dataset.playCountData && context.dataset.playCountData[context.dataIndex]) {
return context.dataset.playCountData[context.dataIndex];
}
// Fallback to percentage if play count data not available
return Math.round(value * 100) + ‘%’;
}
// Handle bar charts with count data (play-type, quarter, down, etc.)
if (context.dataset.label && context.dataset.label.includes(‘ SR’) &&
(chartData.teamCounts || chartData.oppCounts)) {
// Find the first team SR dataset in the chart to determine team order
const allDatasets = context.chart.data.datasets;
const teamSRDataset = allDatasets.find(d => d.label && d.label.includes(‘ SR’) && !d.label.includes(‘NCAA’));
// If this is the first team’s SR dataset, use teamCounts
if (teamSRDataset && context.dataset.label === teamSRDataset.label && chartData.teamCounts) {
return chartData.teamCounts[context.dataIndex] || 0;
}
// Otherwise, use oppCounts for the second team
else if (chartData.oppCounts) {
return chartData.oppCounts[context.dataIndex] || 0;
}
}
// For player charts, show value only if > 0 (matches non-embedded behavior)
if (‘top-rushers’.includes(‘top-rushers’) || ‘top-rushers’.includes(‘top-passers’) || ‘top-rushers’.includes(‘top-receivers’)) {
// Hide data labels for zero or negative values, show actual value for positive values
return value > 0 ? value : null;
}
// For other charts, show values based on type
if (typeof value === ‘number’) {
// If value is between 0 and 1, treat as percentage
if (value >= 0 && value 0 ? ‘#26262660’ : ‘transparent’;
},
borderColor: function(context) {
const value = context.dataset.data[context.dataIndex];
return value > 0 ? ‘rgba(255, 255, 255, 0.2)’ : ‘transparent’;
},
borderRadius: 4,
align: ‘center’,
anchor: ‘center’
},
legend: ‘top-rushers’ === ‘win-probability’ ? {
display: false
} : ‘bar’ === ‘line’ ? {
position: ‘top’,
align: ‘start’,
labels: ‘top-rushers’.includes(‘play-map’) ? {
usePointStyle: true,
generateLabels: function(chart) {
// Call the original generateLabels to get default styling
const original = Chart.defaults.plugins.legend.labels.generateLabels;
const labels = original.call(this, chart);
// Filter and customize each label
const filteredLabels = labels.filter(label => {
return !label.text.includes(‘ {
const dataset = chart.data.datasets[label.datasetIndex];
if (dataset && dataset.label) {
if (dataset.label.includes(‘Rush’)) {
label.pointStyle = ‘circle’;
label.pointStyleWidth = 4;
label.fillStyle = ‘white’;
} else if (dataset.label.includes(‘Pass’)) {
label.pointStyle = ‘triangle’;
label.pointStyleWidth = 4;
label.fillStyle = ‘white’;
} else {
label.pointStyle = ‘rect’;
label.pointStyleWidth = 4;
label.fillStyle = ‘white’;
}
}
});
return filteredLabels;
},
boxWidth: 20,
padding: 12
} : {
usePointStyle: false,
boxWidth: 12,
boxHeight: 12,
padding: 12,
generateLabels: function(chart) {
const original = Chart.defaults.plugins.legend.labels.generateLabels;
const labels = original.call(this, chart);
// Filter out reference areas and ensure white fill
const filteredLabels = labels.filter(label => {
return !label.text.includes(‘NCAA Avg SR’) &&
!label.text.includes(’50/50′) &&
!label.text.includes(‘Quarters’);
});
// Ensure white fill for all line chart legend boxes
filteredLabels.forEach((label) => {
label.fillStyle = ‘white’;
});
return filteredLabels;
}
}
} : {
position: ‘top’,
align: ‘start’,
labels: {
usePointStyle: false,
boxWidth: 12,
boxHeight: 12,
padding: 12,
filter: function(legendItem, chartData) {
return !legendItem.text.includes(‘NCAA Avg SR’) &&
!legendItem.text.includes(‘Quarters’) &&
!legendItem.text.includes(’50/50′);
},
generateLabels: function(chart) {
const data = chart.data;
if (data.datasets.length) {
return data.datasets.map((dataset, i) => {
// Handle backgroundColor arrays (like in Overall Team Performance chart)
let fillColor = dataset.backgroundColor;
if (dataset.label === ‘# Plays’) {
fillColor = ‘white’;
} else if (Array.isArray(dataset.backgroundColor)) {
// For datasets with backgroundColor arrays, use the first color for legend
fillColor = dataset.backgroundColor[0];
}
return {
text: dataset.label,
fillStyle: fillColor,
strokeStyle: dataset.label === ‘# Plays’ ? ‘#666’ : dataset.borderColor,
lineWidth: dataset.label === ‘# Plays’ ? 1 : dataset.borderWidth,
hidden: !chart.isDatasetVisible(i),
datasetIndex: i
};
}).filter((item, index) => {
// Apply the same filter logic as above
const dataset = chart.data.datasets[index];
if (!dataset || !dataset.data) return false;
if (dataset.label === ‘# Plays’) return true; // Always show # Plays
if (dataset.label && (dataset.label.includes(‘NCAA Avg SR’) ||
dataset.label.includes(‘Quarters’) ||
dataset.label.includes(’50/50′))) return false;
return dataset.data.some((value) => value > 0);
});
}
return [];
}
}
},
tooltip: ‘top-rushers’ === ‘win-probability’ ? {
mode: ‘index’,
intersect: false,
callbacks: {
title: function(tooltipItems) {
if (tooltipItems && tooltipItems[0]) {
return ‘Play ‘ + (tooltipItems[0].dataIndex + 1);
}
return ”;
},
label: function(context) {
const selectedTeamWinProb = context.parsed.y;
const opponentWinProb = 100 – selectedTeamWinProb;
const selectedTeam = context.dataset.selectedTeam || ‘Team’;
const opponentTeam = context.dataset.opponentTeam || ‘Opponent’;
return [
selectedTeam + ‘: ‘ + selectedTeamWinProb.toFixed(1) + ‘%’,
opponentTeam + ‘: ‘ + opponentWinProb.toFixed(1) + ‘%’
];
},
afterLabel: function(context) {
if (context.dataset.playTexts && context.dataset.playTexts[context.dataIndex]) {
return ‘n’ + context.dataset.playTexts[context.dataIndex];
}
return ”;
}
}
} : {
filter: function(tooltipItem) {
if (‘top-rushers’.includes(‘play-map’)) {
return !tooltipItem.dataset.label.includes(‘< 0’) &&
!tooltipItem.dataset.label.includes(‘Quarters’) &&
!tooltipItem.dataset.label.includes(‘Drive’);
}
return !tooltipItem.dataset.label.includes(‘NCAA Avg SR’) &&
!tooltipItem.dataset.label.includes(’50/50′) &&
!tooltipItem.dataset.label.includes(‘ ds.label === ‘Win Probability’);
if (wpDataset && wpDataset.segmentColors) {
wpDataset.segment = {
borderColor: function(ctx) {
// Use p1DataIndex (ending point) so the line inherits the destination color
// This makes momentum shifts more visually intuitive
const index = ctx.p1DataIndex;
if (index !== undefined && wpDataset.segmentColors[index]) {
return wpDataset.segmentColors[index];
}
return wpDataset.borderColor || ‘#8B0000’;
}
};
}
}
// Initialize the chart
const ctx = canvas.getContext(‘2d’);
const chart = new Chart(ctx, {
type: ‘bar’,
data: chartData,
options: chartOptions
});
// Store reference to prevent re-initialization
canvas.chartInstance = chart;
console.log(‘CFB Chart initialized successfully’);
} catch (error) {
console.error(‘Error initializing CFB chart:’, error);
// Fallback: show error message in canvas container
const container = document.getElementById(‘cfb-chart-1763259447403-nxgw18gy1’).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 Daniel Hill was pretty good as a lead back. This 8-for-15 successful line is one of the better performances that we’ve seen out of an Alabama back in a while, at least in a competitive game, and especially against a defense that was lauded for their rush defense.
Meanwhile, the actual senior running back leader on this team, Jam Miller, delivered a 2-out-of-9 performance for very low efficiency. I am still rooting hard for Jam and hoping that this is more about missing on a few big opportunities, but it’s hard not to notice a pattern at this point.
Still, you’ve got to be encouraged seeing Alabama be willing to try out another back as the lead, and Daniel Hill definitely came away with some nice rushes.
We don’t see the (other) usual hallmarks of a close loss
OK, enough silver linings. At this point, this fan base (relatively spoiled, Roll Tide) has started becoming more accustomed to losing, especially in close games. But this game doesn’t actually bear the hallmarks of a lot of those losses. Let’s take a quick cruise through the usual suspects:
.cfb-chart-embed-cfb-chart-1763259513397-0kj1qwrp4 {
font-family: -apple-system, BlinkMacSystemFont, ‘Segoe UI’, ‘Roboto’, sans-serif;
margin: 0;
padding: 0;
}
.cfb-chart-embed-cfb-chart-1763259513397-0kj1qwrp4 .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-1763259513397-0kj1qwrp4 .chart-header {
padding: 18px 24px 14px;
border-bottom: 1px solid #e5e5e5;
background: white;
}
.cfb-chart-embed-cfb-chart-1763259513397-0kj1qwrp4 .chart-title {
font-size: 18px;
font-weight: 600;
color: #171717;
margin: 0;
}
.cfb-chart-embed-cfb-chart-1763259513397-0kj1qwrp4 .chart-subtitle {
font-size: 11px;
font-weight: 400;
color: #737373;
margin: 4px 0 0 0;
}
.cfb-chart-embed-cfb-chart-1763259513397-0kj1qwrp4 .chart-content {
padding: 20px 24px 24px !important;
}
.cfb-chart-embed-cfb-chart-1763259513397-0kj1qwrp4 .chart-content { height: 325px; }
@media (max-width: 640px) {
.cfb-chart-embed-cfb-chart-1763259513397-0kj1qwrp4 .chart-content {
padding: 12px 16px 20px !important;
height: 280px !important;
}
.cfb-chart-embed-cfb-chart-1763259513397-0kj1qwrp4 .chart-header {
padding: 12px 16px 12px !important;
}
.cfb-chart-embed-cfb-chart-1763259513397-0kj1qwrp4 .embed-footer-top {
padding: 8px 12px !important;
}
.cfb-chart-embed-cfb-chart-1763259513397-0kj1qwrp4 .data-definitions {
padding: 12px !important;
}
}
.cfb-chart-embed-cfb-chart-1763259513397-0kj1qwrp4 .embed-footer {
border-top: 1px solid #e5e5e5;
font-size: 12px;
color: #737373;
}
.cfb-chart-embed-cfb-chart-1763259513397-0kj1qwrp4 .embed-footer-top {
display: flex;
justify-content: space-between;
align-items: center;
padding: 12px 16px;
}
.cfb-chart-embed-cfb-chart-1763259513397-0kj1qwrp4 .embed-footer-link {
color: #737373;
text-decoration: none;
font-weight: 500;
}
.cfb-chart-embed-cfb-chart-1763259513397-0kj1qwrp4 .embed-footer-link:hover {
color: #525252;
text-decoration: underline;
}
.cfb-chart-embed-cfb-chart-1763259513397-0kj1qwrp4 .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-1763259513397-0kj1qwrp4 .data-definitions-toggle:hover {
color: #525252;
}
.cfb-chart-embed-cfb-chart-1763259513397-0kj1qwrp4 .caret {
transition: transform 0.2s ease;
font-size: 10px;
}
.cfb-chart-embed-cfb-chart-1763259513397-0kj1qwrp4 .caret.expanded {
transform: rotate(180deg);
}
.cfb-chart-embed-cfb-chart-1763259513397-0kj1qwrp4 .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-1763259513397-0kj1qwrp4 .data-definitions.expanded {
display: block;
}
.cfb-chart-embed-cfb-chart-1763259513397-0kj1qwrp4 .data-definitions ul {
margin: 0;
padding-left: 0;
list-style: none;
}
.cfb-chart-embed-cfb-chart-1763259513397-0kj1qwrp4 .data-definitions li {
margin-bottom: 4px;
}
SR and XR by Down
Alabama vs. Oklahoma • Nov 15, 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_1763259513397_0kj1qwrp4() {
const definitions = document.getElementById(‘dataDefinitions_cfb-chart-1763259513397-0kj1qwrp4’);
const caret = document.getElementById(‘caret_cfb-chart-1763259513397-0kj1qwrp4’);
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-1763259513397-0kj1qwrp4’);
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-1763259513397-0kj1qwrp4’);
if (!canvas) {
console.warn(‘Canvas element not found yet, retrying…’);
setTimeout(initChart, 100);
return;
}
// Prevent multiple chart instances
if (canvas.chartInstance) {
console.log(‘Chart already initialized’);
return;
}
try {
// Register the datalabels plugin
Chart.register(ChartDataLabels);
// Embed actual chart data directly
const chartData = {
“labels”: [
“1st Down”,
“2nd Down”,
“3rd Down”,
“4th Down”
],
“datasets”: [
{
“data”: [
0.15151515151515152,
0.12,
0.16666666666666666,
0.3333333333333333
],
“stack”: “Team”,
“label”: “Alabama XR”,
“backgroundColor”: “rgba(101, 0, 20, 0.8)”,
“datalabels”: {
“display”: false
}
},
{
“data”: [
0.42424242424242425,
0.52,
0.4166666666666667,
0.6666666666666666
],
“stack”: “Team”,
“label”: “Alabama SR”,
“backgroundColor”: “rgba(175, 40, 60, 0.8)”,
“datalabels”: {
“display”: true
}
},
{
“data”: [
0.14285714285714285,
0.0625,
0.15384615384615385,
0
],
“stack”: “Opponent”,
“label”: “Oklahoma XR”,
“backgroundColor”: “#4c2d00CC”,
“datalabels”: {
“display”: false
}
},
{
“data”: [
0.38095238095238093,
0.1875,
0.23076923076923078,
0
],
“stack”: “Opponent”,
“label”: “Oklahoma SR”,
“backgroundColor”: “#A16207CC”,
“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”: [
33,
25,
12,
3
],
“oppCounts”: [
21,
16,
13,
0
],
“currentParams”: {
“year”: 2025,
“week”: 12,
“seasonType”: “regular”,
“team”: “Alabama”,
“gameId”: “401752765”
}
};
// Chart options (WordPress-safe)
const chartOptions = {
responsive: true,
maintainAspectRatio: false,
animation: {
duration: 1 // Minimal animation to trigger layout calculation (fixes label positioning)
},
elements: ‘bar’ === ‘line’ ? ‘down-bars’.includes(‘play-map’) ? {
line: {
tension: 0,
borderWidth: 0
}
} : ‘down-bars’ === ‘win-probability’ ? {
line: {
tension: 0.15,
borderWidth: 2.2,
fill: false
},
point: {
pointRadius: 0,
pointHoverRadius: 4
}
} : {
line: {
tension: 0.25,
borderWidth: 2.2
},
point: {
pointRadius: ‘down-bars’.includes(‘team-lines’) ? 0 : undefined
}
} : {},
plugins: {
datalabels: {
display: function(context) {
// Suppress data labels on line charts
if (‘bar’ === ‘line’) {
return false;
}
return context.dataset.datalabels && context.dataset.datalabels.display === true;
},
formatter: function(value, context) {
// Special handling for Overall Team Performance chart
if (‘down-bars’ === ‘overall-team-performance’ && context.dataset.label === ‘Success Rate (SR)’) {
// Use the stored play count data
if (context.dataset.playCountData && context.dataset.playCountData[context.dataIndex]) {
return context.dataset.playCountData[context.dataIndex];
}
// Fallback to percentage if play count data not available
return Math.round(value * 100) + ‘%’;
}
// Handle bar charts with count data (play-type, quarter, down, etc.)
if (context.dataset.label && context.dataset.label.includes(‘ SR’) &&
(chartData.teamCounts || chartData.oppCounts)) {
// Find the first team SR dataset in the chart to determine team order
const allDatasets = context.chart.data.datasets;
const teamSRDataset = allDatasets.find(d => d.label && d.label.includes(‘ SR’) && !d.label.includes(‘NCAA’));
// If this is the first team’s SR dataset, use teamCounts
if (teamSRDataset && context.dataset.label === teamSRDataset.label && chartData.teamCounts) {
return chartData.teamCounts[context.dataIndex] || 0;
}
// Otherwise, use oppCounts for the second team
else if (chartData.oppCounts) {
return chartData.oppCounts[context.dataIndex] || 0;
}
}
// For player charts, show value only if > 0 (matches non-embedded behavior)
if (‘down-bars’.includes(‘top-rushers’) || ‘down-bars’.includes(‘top-passers’) || ‘down-bars’.includes(‘top-receivers’)) {
// Hide data labels for zero or negative values, show actual value for positive values
return value > 0 ? value : null;
}
// For other charts, show values based on type
if (typeof value === ‘number’) {
// If value is between 0 and 1, treat as percentage
if (value >= 0 && value 0 ? ‘#26262660’ : ‘transparent’;
},
borderColor: function(context) {
const value = context.dataset.data[context.dataIndex];
return value > 0 ? ‘rgba(255, 255, 255, 0.2)’ : ‘transparent’;
},
borderRadius: 4,
align: ‘center’,
anchor: ‘center’
},
legend: ‘down-bars’ === ‘win-probability’ ? {
display: false
} : ‘bar’ === ‘line’ ? {
position: ‘top’,
align: ‘start’,
labels: ‘down-bars’.includes(‘play-map’) ? {
usePointStyle: true,
generateLabels: function(chart) {
// Call the original generateLabels to get default styling
const original = Chart.defaults.plugins.legend.labels.generateLabels;
const labels = original.call(this, chart);
// Filter and customize each label
const filteredLabels = labels.filter(label => {
return !label.text.includes(‘ {
const dataset = chart.data.datasets[label.datasetIndex];
if (dataset && dataset.label) {
if (dataset.label.includes(‘Rush’)) {
label.pointStyle = ‘circle’;
label.pointStyleWidth = 4;
label.fillStyle = ‘white’;
} else if (dataset.label.includes(‘Pass’)) {
label.pointStyle = ‘triangle’;
label.pointStyleWidth = 4;
label.fillStyle = ‘white’;
} else {
label.pointStyle = ‘rect’;
label.pointStyleWidth = 4;
label.fillStyle = ‘white’;
}
}
});
return filteredLabels;
},
boxWidth: 20,
padding: 12
} : {
usePointStyle: false,
boxWidth: 12,
boxHeight: 12,
padding: 12,
generateLabels: function(chart) {
const original = Chart.defaults.plugins.legend.labels.generateLabels;
const labels = original.call(this, chart);
// Filter out reference areas and ensure white fill
const filteredLabels = labels.filter(label => {
return !label.text.includes(‘NCAA Avg SR’) &&
!label.text.includes(’50/50′) &&
!label.text.includes(‘Quarters’);
});
// Ensure white fill for all line chart legend boxes
filteredLabels.forEach((label) => {
label.fillStyle = ‘white’;
});
return filteredLabels;
}
}
} : {
position: ‘top’,
align: ‘start’,
labels: {
usePointStyle: false,
boxWidth: 12,
boxHeight: 12,
padding: 12,
filter: function(legendItem, chartData) {
return !legendItem.text.includes(‘NCAA Avg SR’) &&
!legendItem.text.includes(‘Quarters’) &&
!legendItem.text.includes(’50/50′);
},
generateLabels: function(chart) {
const data = chart.data;
if (data.datasets.length) {
return data.datasets.map((dataset, i) => {
// Handle backgroundColor arrays (like in Overall Team Performance chart)
let fillColor = dataset.backgroundColor;
if (dataset.label === ‘# Plays’) {
fillColor = ‘white’;
} else if (Array.isArray(dataset.backgroundColor)) {
// For datasets with backgroundColor arrays, use the first color for legend
fillColor = dataset.backgroundColor[0];
}
return {
text: dataset.label,
fillStyle: fillColor,
strokeStyle: dataset.label === ‘# Plays’ ? ‘#666’ : dataset.borderColor,
lineWidth: dataset.label === ‘# Plays’ ? 1 : dataset.borderWidth,
hidden: !chart.isDatasetVisible(i),
datasetIndex: i
};
}).filter((item, index) => {
// Apply the same filter logic as above
const dataset = chart.data.datasets[index];
if (!dataset || !dataset.data) return false;
if (dataset.label === ‘# Plays’) return true; // Always show # Plays
if (dataset.label && (dataset.label.includes(‘NCAA Avg SR’) ||
dataset.label.includes(‘Quarters’) ||
dataset.label.includes(’50/50′))) return false;
return dataset.data.some((value) => value > 0);
});
}
return [];
}
}
},
tooltip: ‘down-bars’ === ‘win-probability’ ? {
mode: ‘index’,
intersect: false,
callbacks: {
title: function(tooltipItems) {
if (tooltipItems && tooltipItems[0]) {
return ‘Play ‘ + (tooltipItems[0].dataIndex + 1);
}
return ”;
},
label: function(context) {
const selectedTeamWinProb = context.parsed.y;
const opponentWinProb = 100 – selectedTeamWinProb;
const selectedTeam = context.dataset.selectedTeam || ‘Team’;
const opponentTeam = context.dataset.opponentTeam || ‘Opponent’;
return [
selectedTeam + ‘: ‘ + selectedTeamWinProb.toFixed(1) + ‘%’,
opponentTeam + ‘: ‘ + opponentWinProb.toFixed(1) + ‘%’
];
},
afterLabel: function(context) {
if (context.dataset.playTexts && context.dataset.playTexts[context.dataIndex]) {
return ‘n’ + context.dataset.playTexts[context.dataIndex];
}
return ”;
}
}
} : {
filter: function(tooltipItem) {
if (‘down-bars’.includes(‘play-map’)) {
return !tooltipItem.dataset.label.includes(‘< 0’) &&
!tooltipItem.dataset.label.includes(‘Quarters’) &&
!tooltipItem.dataset.label.includes(‘Drive’);
}
return !tooltipItem.dataset.label.includes(‘NCAA Avg SR’) &&
!tooltipItem.dataset.label.includes(’50/50′) &&
!tooltipItem.dataset.label.includes(‘ ds.label === ‘Win Probability’);
if (wpDataset && wpDataset.segmentColors) {
wpDataset.segment = {
borderColor: function(ctx) {
// Use p1DataIndex (ending point) so the line inherits the destination color
// This makes momentum shifts more visually intuitive
const index = ctx.p1DataIndex;
if (index !== undefined && wpDataset.segmentColors[index]) {
return wpDataset.segmentColors[index];
}
return wpDataset.borderColor || ‘#8B0000’;
}
};
}
}
// Initialize the chart
const ctx = canvas.getContext(‘2d’);
const chart = new Chart(ctx, {
type: ‘bar’,
data: chartData,
options: chartOptions
});
// Store reference to prevent re-initialization
canvas.chartInstance = chart;
console.log(‘CFB Chart initialized successfully’);
} catch (error) {
console.error(‘Error initializing CFB chart:’, error);
// Fallback: show error message in canvas container
const container = document.getElementById(‘cfb-chart-1763259513397-0kj1qwrp4’).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();
}
})();
Yep, it wasn’t about 3rd downs (or 4th downs, for that matter). Sure, Alabama really could have used one more 4th down conversion there at the end (sigh), but they converted the other two that they tried.
Anyway, Alabama had the higher efficiencies and higher explosiveness rates on literally every single down. How often could that possibly occur in a loss? It must be rare.
.cfb-chart-embed-cfb-chart-1763259520636-dclzpl2jv {
font-family: -apple-system, BlinkMacSystemFont, ‘Segoe UI’, ‘Roboto’, sans-serif;
margin: 0;
padding: 0;
}
.cfb-chart-embed-cfb-chart-1763259520636-dclzpl2jv .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-1763259520636-dclzpl2jv .chart-header {
padding: 18px 24px 14px;
border-bottom: 1px solid #e5e5e5;
background: white;
}
.cfb-chart-embed-cfb-chart-1763259520636-dclzpl2jv .chart-title {
font-size: 18px;
font-weight: 600;
color: #171717;
margin: 0;
}
.cfb-chart-embed-cfb-chart-1763259520636-dclzpl2jv .chart-subtitle {
font-size: 11px;
font-weight: 400;
color: #737373;
margin: 4px 0 0 0;
}
.cfb-chart-embed-cfb-chart-1763259520636-dclzpl2jv .chart-content {
padding: 20px 24px 24px !important;
}
.cfb-chart-embed-cfb-chart-1763259520636-dclzpl2jv .chart-content { height: 325px; }
@media (max-width: 640px) {
.cfb-chart-embed-cfb-chart-1763259520636-dclzpl2jv .chart-content {
padding: 12px 16px 20px !important;
height: 280px !important;
}
.cfb-chart-embed-cfb-chart-1763259520636-dclzpl2jv .chart-header {
padding: 12px 16px 12px !important;
}
.cfb-chart-embed-cfb-chart-1763259520636-dclzpl2jv .embed-footer-top {
padding: 8px 12px !important;
}
.cfb-chart-embed-cfb-chart-1763259520636-dclzpl2jv .data-definitions {
padding: 12px !important;
}
}
.cfb-chart-embed-cfb-chart-1763259520636-dclzpl2jv .embed-footer {
border-top: 1px solid #e5e5e5;
font-size: 12px;
color: #737373;
}
.cfb-chart-embed-cfb-chart-1763259520636-dclzpl2jv .embed-footer-top {
display: flex;
justify-content: space-between;
align-items: center;
padding: 12px 16px;
}
.cfb-chart-embed-cfb-chart-1763259520636-dclzpl2jv .embed-footer-link {
color: #737373;
text-decoration: none;
font-weight: 500;
}
.cfb-chart-embed-cfb-chart-1763259520636-dclzpl2jv .embed-footer-link:hover {
color: #525252;
text-decoration: underline;
}
.cfb-chart-embed-cfb-chart-1763259520636-dclzpl2jv .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-1763259520636-dclzpl2jv .data-definitions-toggle:hover {
color: #525252;
}
.cfb-chart-embed-cfb-chart-1763259520636-dclzpl2jv .caret {
transition: transform 0.2s ease;
font-size: 10px;
}
.cfb-chart-embed-cfb-chart-1763259520636-dclzpl2jv .caret.expanded {
transform: rotate(180deg);
}
.cfb-chart-embed-cfb-chart-1763259520636-dclzpl2jv .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-1763259520636-dclzpl2jv .data-definitions.expanded {
display: block;
}
.cfb-chart-embed-cfb-chart-1763259520636-dclzpl2jv .data-definitions ul {
margin: 0;
padding-left: 0;
list-style: none;
}
.cfb-chart-embed-cfb-chart-1763259520636-dclzpl2jv .data-definitions li {
margin-bottom: 4px;
}
SR and XR by Red Zone
Alabama vs. Oklahoma • Nov 15, 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_1763259520636_dclzpl2jv() {
const definitions = document.getElementById(‘dataDefinitions_cfb-chart-1763259520636-dclzpl2jv’);
const caret = document.getElementById(‘caret_cfb-chart-1763259520636-dclzpl2jv’);
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-1763259520636-dclzpl2jv’);
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-1763259520636-dclzpl2jv’);
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.16417910447761194
],
“stack”: “Team”,
“label”: “Alabama XR”,
“backgroundColor”: “rgba(101, 0, 20, 0.8)”,
“datalabels”: {
“display”: false
}
},
{
“data”: [
0.5,
0.4626865671641791
],
“stack”: “Team”,
“label”: “Alabama SR”,
“backgroundColor”: “rgba(175, 40, 60, 0.8)”,
“datalabels”: {
“display”: true
}
},
{
“data”: [
0.14285714285714285,
0.11627906976744186
],
“stack”: “Opponent”,
“label”: “Oklahoma XR”,
“backgroundColor”: “#4c2d00CC”,
“datalabels”: {
“display”: false
}
},
{
“data”: [
0.14285714285714285,
0.3023255813953488
],
“stack”: “Opponent”,
“label”: “Oklahoma SR”,
“backgroundColor”: “#A16207CC”,
“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”: [
6,
67
],
“oppCounts”: [
7,
43
],
“currentParams”: {
“year”: 2025,
“week”: 12,
“seasonType”: “regular”,
“team”: “Alabama”,
“gameId”: “401752765”
}
};
// 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-1763259520636-dclzpl2jv’).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();
}
})();
The Red Zone wasn’t it either. And hey, even outside of the Red Zone, Alabama was definitively higher performing in SR and XR. In fact, the only successful play that Oklahoma had in the Red Zone was the John Mateer 20-yard rush for a TD.
.cfb-chart-embed-cfb-chart-1763259527629-8wls47jlz {
font-family: -apple-system, BlinkMacSystemFont, ‘Segoe UI’, ‘Roboto’, sans-serif;
margin: 0;
padding: 0;
}
.cfb-chart-embed-cfb-chart-1763259527629-8wls47jlz .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-1763259527629-8wls47jlz .chart-header {
padding: 18px 24px 14px;
border-bottom: 1px solid #e5e5e5;
background: white;
}
.cfb-chart-embed-cfb-chart-1763259527629-8wls47jlz .chart-title {
font-size: 18px;
font-weight: 600;
color: #171717;
margin: 0;
}
.cfb-chart-embed-cfb-chart-1763259527629-8wls47jlz .chart-subtitle {
font-size: 11px;
font-weight: 400;
color: #737373;
margin: 4px 0 0 0;
}
.cfb-chart-embed-cfb-chart-1763259527629-8wls47jlz .chart-content {
padding: 20px 24px 24px !important;
}
.cfb-chart-embed-cfb-chart-1763259527629-8wls47jlz .chart-content { height: 325px; }
@media (max-width: 640px) {
.cfb-chart-embed-cfb-chart-1763259527629-8wls47jlz .chart-content {
padding: 12px 16px 20px !important;
height: 280px !important;
}
.cfb-chart-embed-cfb-chart-1763259527629-8wls47jlz .chart-header {
padding: 12px 16px 12px !important;
}
.cfb-chart-embed-cfb-chart-1763259527629-8wls47jlz .embed-footer-top {
padding: 8px 12px !important;
}
.cfb-chart-embed-cfb-chart-1763259527629-8wls47jlz .data-definitions {
padding: 12px !important;
}
}
.cfb-chart-embed-cfb-chart-1763259527629-8wls47jlz .embed-footer {
border-top: 1px solid #e5e5e5;
font-size: 12px;
color: #737373;
}
.cfb-chart-embed-cfb-chart-1763259527629-8wls47jlz .embed-footer-top {
display: flex;
justify-content: space-between;
align-items: center;
padding: 12px 16px;
}
.cfb-chart-embed-cfb-chart-1763259527629-8wls47jlz .embed-footer-link {
color: #737373;
text-decoration: none;
font-weight: 500;
}
.cfb-chart-embed-cfb-chart-1763259527629-8wls47jlz .embed-footer-link:hover {
color: #525252;
text-decoration: underline;
}
.cfb-chart-embed-cfb-chart-1763259527629-8wls47jlz .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-1763259527629-8wls47jlz .data-definitions-toggle:hover {
color: #525252;
}
.cfb-chart-embed-cfb-chart-1763259527629-8wls47jlz .caret {
transition: transform 0.2s ease;
font-size: 10px;
}
.cfb-chart-embed-cfb-chart-1763259527629-8wls47jlz .caret.expanded {
transform: rotate(180deg);
}
.cfb-chart-embed-cfb-chart-1763259527629-8wls47jlz .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-1763259527629-8wls47jlz .data-definitions.expanded {
display: block;
}
.cfb-chart-embed-cfb-chart-1763259527629-8wls47jlz .data-definitions ul {
margin: 0;
padding-left: 0;
list-style: none;
}
.cfb-chart-embed-cfb-chart-1763259527629-8wls47jlz .data-definitions li {
margin-bottom: 4px;
}
SR and XR by Distance to Go
Alabama vs. Oklahoma • Nov 15, 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_1763259527629_8wls47jlz() {
const definitions = document.getElementById(‘dataDefinitions_cfb-chart-1763259527629-8wls47jlz’);
const caret = document.getElementById(‘caret_cfb-chart-1763259527629-8wls47jlz’);
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-1763259527629-8wls47jlz’);
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-1763259527629-8wls47jlz’);
if (!canvas) {
console.warn(‘Canvas element not found yet, retrying…’);
setTimeout(initChart, 100);
return;
}
// Prevent multiple chart instances
if (canvas.chartInstance) {
console.log(‘Chart already initialized’);
return;
}
try {
// Register the datalabels plugin
Chart.register(ChartDataLabels);
// Embed actual chart data directly
const chartData = {
“labels”: [
“Long (8+)”,
“Medium (4-7)”,
“Short (1-3)”
],
“datasets”: [
{
“data”: [
0.20833333333333334,
0.09090909090909091,
0
],
“stack”: “Team”,
“label”: “Alabama XR”,
“backgroundColor”: “rgba(101, 0, 20, 0.8)”,
“datalabels”: {
“display”: false
}
},
{
“data”: [
0.4166666666666667,
0.45454545454545453,
0.6428571428571429
],
“stack”: “Team”,
“label”: “Alabama SR”,
“backgroundColor”: “rgba(175, 40, 60, 0.8)”,
“datalabels”: {
“display”: true
}
},
{
“data”: [
0.13513513513513514,
0.1111111111111111,
0
],
“stack”: “Opponent”,
“label”: “Oklahoma XR”,
“backgroundColor”: “#4c2d00CC”,
“datalabels”: {
“display”: false
}
},
{
“data”: [
0.2972972972972973,
0.1111111111111111,
0.5
],
“stack”: “Opponent”,
“label”: “Oklahoma SR”,
“backgroundColor”: “#A16207CC”,
“datalabels”: {
“display”: true
}
},
{
“type”: “line”,
“data”: [
0.42,
0.42,
0.42
],
“label”: “NCAA Avg SR”,
“borderColor”: “#757575”,
“borderWidth”: 2,
“borderDash”: [
3,
3
],
“pointRadius”: 0,
“datalabels”: {
“display”: false
}
},
{
“type”: “line”,
“data”: [
null,
null,
null
],
“label”: “# Plays”,
“backgroundColor”: “rgba(0, 0, 0, 0)”,
“borderColor”: “rgba(0, 0, 0, 0)”,
“borderWidth”: 0,
“pointRadius”: 0,
“showLine”: false,
“fill”: false,
“datalabels”: {
“display”: false
}
}
],
“teamCounts”: [
48,
11,
14
],
“oppCounts”: [
37,
9,
4
],
“currentParams”: {
“year”: 2025,
“week”: 12,
“seasonType”: “regular”,
“team”: “Alabama”,
“gameId”: “401752765”
}
};
// Chart options (WordPress-safe)
const chartOptions = {
responsive: true,
maintainAspectRatio: false,
animation: {
duration: 1 // Minimal animation to trigger layout calculation (fixes label positioning)
},
elements: ‘bar’ === ‘line’ ? ‘distance-bars’.includes(‘play-map’) ? {
line: {
tension: 0,
borderWidth: 0
}
} : ‘distance-bars’ === ‘win-probability’ ? {
line: {
tension: 0.15,
borderWidth: 2.2,
fill: false
},
point: {
pointRadius: 0,
pointHoverRadius: 4
}
} : {
line: {
tension: 0.25,
borderWidth: 2.2
},
point: {
pointRadius: ‘distance-bars’.includes(‘team-lines’) ? 0 : undefined
}
} : {},
plugins: {
datalabels: {
display: function(context) {
// Suppress data labels on line charts
if (‘bar’ === ‘line’) {
return false;
}
return context.dataset.datalabels && context.dataset.datalabels.display === true;
},
formatter: function(value, context) {
// Special handling for Overall Team Performance chart
if (‘distance-bars’ === ‘overall-team-performance’ && context.dataset.label === ‘Success Rate (SR)’) {
// Use the stored play count data
if (context.dataset.playCountData && context.dataset.playCountData[context.dataIndex]) {
return context.dataset.playCountData[context.dataIndex];
}
// Fallback to percentage if play count data not available
return Math.round(value * 100) + ‘%’;
}
// Handle bar charts with count data (play-type, quarter, down, etc.)
if (context.dataset.label && context.dataset.label.includes(‘ SR’) &&
(chartData.teamCounts || chartData.oppCounts)) {
// Find the first team SR dataset in the chart to determine team order
const allDatasets = context.chart.data.datasets;
const teamSRDataset = allDatasets.find(d => d.label && d.label.includes(‘ SR’) && !d.label.includes(‘NCAA’));
// If this is the first team’s SR dataset, use teamCounts
if (teamSRDataset && context.dataset.label === teamSRDataset.label && chartData.teamCounts) {
return chartData.teamCounts[context.dataIndex] || 0;
}
// Otherwise, use oppCounts for the second team
else if (chartData.oppCounts) {
return chartData.oppCounts[context.dataIndex] || 0;
}
}
// For player charts, show value only if > 0 (matches non-embedded behavior)
if (‘distance-bars’.includes(‘top-rushers’) || ‘distance-bars’.includes(‘top-passers’) || ‘distance-bars’.includes(‘top-receivers’)) {
// Hide data labels for zero or negative values, show actual value for positive values
return value > 0 ? value : null;
}
// For other charts, show values based on type
if (typeof value === ‘number’) {
// If value is between 0 and 1, treat as percentage
if (value >= 0 && value 0 ? ‘#26262660’ : ‘transparent’;
},
borderColor: function(context) {
const value = context.dataset.data[context.dataIndex];
return value > 0 ? ‘rgba(255, 255, 255, 0.2)’ : ‘transparent’;
},
borderRadius: 4,
align: ‘center’,
anchor: ‘center’
},
legend: ‘distance-bars’ === ‘win-probability’ ? {
display: false
} : ‘bar’ === ‘line’ ? {
position: ‘top’,
align: ‘start’,
labels: ‘distance-bars’.includes(‘play-map’) ? {
usePointStyle: true,
generateLabels: function(chart) {
// Call the original generateLabels to get default styling
const original = Chart.defaults.plugins.legend.labels.generateLabels;
const labels = original.call(this, chart);
// Filter and customize each label
const filteredLabels = labels.filter(label => {
return !label.text.includes(‘ {
const dataset = chart.data.datasets[label.datasetIndex];
if (dataset && dataset.label) {
if (dataset.label.includes(‘Rush’)) {
label.pointStyle = ‘circle’;
label.pointStyleWidth = 4;
label.fillStyle = ‘white’;
} else if (dataset.label.includes(‘Pass’)) {
label.pointStyle = ‘triangle’;
label.pointStyleWidth = 4;
label.fillStyle = ‘white’;
} else {
label.pointStyle = ‘rect’;
label.pointStyleWidth = 4;
label.fillStyle = ‘white’;
}
}
});
return filteredLabels;
},
boxWidth: 20,
padding: 12
} : {
usePointStyle: false,
boxWidth: 12,
boxHeight: 12,
padding: 12,
generateLabels: function(chart) {
const original = Chart.defaults.plugins.legend.labels.generateLabels;
const labels = original.call(this, chart);
// Filter out reference areas and ensure white fill
const filteredLabels = labels.filter(label => {
return !label.text.includes(‘NCAA Avg SR’) &&
!label.text.includes(’50/50′) &&
!label.text.includes(‘Quarters’);
});
// Ensure white fill for all line chart legend boxes
filteredLabels.forEach((label) => {
label.fillStyle = ‘white’;
});
return filteredLabels;
}
}
} : {
position: ‘top’,
align: ‘start’,
labels: {
usePointStyle: false,
boxWidth: 12,
boxHeight: 12,
padding: 12,
filter: function(legendItem, chartData) {
return !legendItem.text.includes(‘NCAA Avg SR’) &&
!legendItem.text.includes(‘Quarters’) &&
!legendItem.text.includes(’50/50′);
},
generateLabels: function(chart) {
const data = chart.data;
if (data.datasets.length) {
return data.datasets.map((dataset, i) => {
// Handle backgroundColor arrays (like in Overall Team Performance chart)
let fillColor = dataset.backgroundColor;
if (dataset.label === ‘# Plays’) {
fillColor = ‘white’;
} else if (Array.isArray(dataset.backgroundColor)) {
// For datasets with backgroundColor arrays, use the first color for legend
fillColor = dataset.backgroundColor[0];
}
return {
text: dataset.label,
fillStyle: fillColor,
strokeStyle: dataset.label === ‘# Plays’ ? ‘#666’ : dataset.borderColor,
lineWidth: dataset.label === ‘# Plays’ ? 1 : dataset.borderWidth,
hidden: !chart.isDatasetVisible(i),
datasetIndex: i
};
}).filter((item, index) => {
// Apply the same filter logic as above
const dataset = chart.data.datasets[index];
if (!dataset || !dataset.data) return false;
if (dataset.label === ‘# Plays’) return true; // Always show # Plays
if (dataset.label && (dataset.label.includes(‘NCAA Avg SR’) ||
dataset.label.includes(‘Quarters’) ||
dataset.label.includes(’50/50′))) return false;
return dataset.data.some((value) => value > 0);
});
}
return [];
}
}
},
tooltip: ‘distance-bars’ === ‘win-probability’ ? {
mode: ‘index’,
intersect: false,
callbacks: {
title: function(tooltipItems) {
if (tooltipItems && tooltipItems[0]) {
return ‘Play ‘ + (tooltipItems[0].dataIndex + 1);
}
return ”;
},
label: function(context) {
const selectedTeamWinProb = context.parsed.y;
const opponentWinProb = 100 – selectedTeamWinProb;
const selectedTeam = context.dataset.selectedTeam || ‘Team’;
const opponentTeam = context.dataset.opponentTeam || ‘Opponent’;
return [
selectedTeam + ‘: ‘ + selectedTeamWinProb.toFixed(1) + ‘%’,
opponentTeam + ‘: ‘ + opponentWinProb.toFixed(1) + ‘%’
];
},
afterLabel: function(context) {
if (context.dataset.playTexts && context.dataset.playTexts[context.dataIndex]) {
return ‘n’ + context.dataset.playTexts[context.dataIndex];
}
return ”;
}
}
} : {
filter: function(tooltipItem) {
if (‘distance-bars’.includes(‘play-map’)) {
return !tooltipItem.dataset.label.includes(‘< 0’) &&
!tooltipItem.dataset.label.includes(‘Quarters’) &&
!tooltipItem.dataset.label.includes(‘Drive’);
}
return !tooltipItem.dataset.label.includes(‘NCAA Avg SR’) &&
!tooltipItem.dataset.label.includes(’50/50′) &&
!tooltipItem.dataset.label.includes(‘ ds.label === ‘Win Probability’);
if (wpDataset && wpDataset.segmentColors) {
wpDataset.segment = {
borderColor: function(ctx) {
// Use p1DataIndex (ending point) so the line inherits the destination color
// This makes momentum shifts more visually intuitive
const index = ctx.p1DataIndex;
if (index !== undefined && wpDataset.segmentColors[index]) {
return wpDataset.segmentColors[index];
}
return wpDataset.borderColor || ‘#8B0000’;
}
};
}
}
// Initialize the chart
const ctx = canvas.getContext(‘2d’);
const chart = new Chart(ctx, {
type: ‘bar’,
data: chartData,
options: chartOptions
});
// Store reference to prevent re-initialization
canvas.chartInstance = chart;
console.log(‘CFB Chart initialized successfully’);
} catch (error) {
console.error(‘Error initializing CFB chart:’, error);
// Fallback: show error message in canvas container
const container = document.getElementById(‘cfb-chart-1763259527629-8wls47jlz’).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();
}
})();
Was it about distribution of success by distance? No, not that either. Sure, Alabama’s defense did somewhat continue the trend of letting the opponent succeed more often on short yardage. But Oklahoma actually only ran four short-yardage plays all day! Most of their plays, similar to last week’s win against LSU, were from long distances. Because Alabama’s defense was holding them well!
Alabama’s offense also converted relatively well from short downs and, compared to the victorious opponent, converted much better on the other downs too. It just did not add up to a victory because we kept losing the ball over in bad spots.
Well, the big season goals are still ahead of us, and it really does look like this team played well enough to win this game and get themselves to the playoffs. So if you’re an optimist, you can take some heart in knowing that play-by-play, this team did better than how you feel right now. It’s just that in a few of the moments when the offense wasn’t executing well, it had back-breaking failures instead of just normal failures. Heck, even if Ty’s pick was just a pick and not a pick six, we have great reason to believe the defense could’ve held them to fewer than 7.
If the Tide play a game like this against Auburn, sans -3 turnover margin, we should expect to come out with a win. Heck, even a -2 margin would’ve done it. That’s what we can hope for at this point, even if we reallllly didn’t want to wait around for an away game in Jordan-Hare Stadium to decide our season. Again.
Roll Tide, anyway.