ArticleTemplates/assets/js/bootstraps/football.js (159 lines of code) (raw):

import { init as initYoutube } from 'modules/youtube'; import { init as initListenToArticle } from 'modules/listen-to-article'; import { getElemsFromHTML } from 'modules/util'; import { arc, pie, select } from 'd3'; function footballChart(homeTeam, awayTeam) { const pieChart = document.getElementsByClassName('pie-chart--possession')[0]; const data = [ [awayTeam, (pieChart && pieChart.getAttribute('data-away')) || null, 'away'], [homeTeam, (pieChart && pieChart.getAttribute('data-home')) || null, 'home'] ]; const width = 250; const height = 250; const radius = Math.min(height, width) / 2; const arcShape = arc() .outerRadius(radius) .innerRadius(radius / 3); const pieShape = pie() .sort(null) .value(d => d[1]); const // Init d3 chart vis = select('.pie-chart') .attr('preserveAspectRatio', 'xMinYMin slice') .attr('viewBox', '0 0 250 250') .append('g') .attr('class', 'pie-chart__inner') .attr('transform', `translate(${width / 2},${width / 2})`); // Add percentage symbol to center vis.append('text') .attr('class', 'pie-chart__key') .text('%') .attr('transform', 'translate(-18,15)'); // Background const backgroundData = [['null', 100]]; const backgroundarc = arc() .outerRadius(radius - 1) .innerRadius((radius / 3) + 1); vis.append('path') .data(pieShape(backgroundData)) .attr('class', 'pie-chart__pie') .attr('d', backgroundarc); // Draw Segements const g = vis.selectAll('.pie-chart__segment') .data(pieShape(data)) .enter().append('g') .attr('class', 'pie-chart__segment'); g.append('path') .attr('class', d => `pie-chart__segment-arc pie-chart__segment-arc--${d.data[2]}`) .attr('d', arcShape); // Add Text Labels const tblock = vis.selectAll('.pie-chart__label') .data(pieShape(data)) .enter().append('foreignObject') .attr('class', d => `pie-chart__label pie-chart__label--${d.data[2]}`) .attr('width', 75) .attr('height', 50) .attr('text-anchor', 'middle') .attr('transform', d => { d.innerRadius = 0; d.outerRadius = radius; let textpoint = arcShape.centroid(d); textpoint = [textpoint[0] - 35, textpoint[1] - 25]; return `translate(${textpoint})`; }); tblock.append('xhtml:div') .attr('class', 'pie-chart__label-text') .attr('width', '50') .attr('x', 0) .attr('dy', '1.2em') .text(d => d.data[0]); tblock.append('xhtml:div') .attr('class', 'pie-chart__label-value') .attr('x', 0) .attr('dy', '1.2em') .text(d => d.data[1]); } function footballGoal(side, newScore, scorerHtml, aggScore) { let i; let matchSummary; const matchSummarySide = document.getElementsByClassName(`match-summary__${side}__score__label`)[0]; const matchSummaryParagraphs = document.querySelectorAll(`.match-summary__${side}__info p`); const matchSummaryInfo = document.getElementsByClassName(`match-summary__${side}__info`)[0]; if (aggScore) { matchSummary = document.getElementsByClassName('match-summary')[0]; if (matchSummary) { matchSummary.classList.add('is-agg'); } if (matchSummarySide) { matchSummarySide.innerHTML = `${newScore} <span class="match-summary__score__agg">${aggScore}</span>`; } } else if (matchSummarySide) { matchSummarySide.innerHTML = `${newScore} <span class="match-summary__score__agg"></span>`; } for (i = 0; i < matchSummaryParagraphs.length; i++) { matchSummaryParagraphs[i].parentNode.removeChild(matchSummaryParagraphs[i]); } if (matchSummaryInfo) { matchSummaryInfo.innerHTML += scorerHtml; } } function footballStatus(className, label) { let i; let matchStatus; let matchTime; if (className !== '(null)' && label !== '(null)') { matchStatus = document.getElementsByClassName('match-status')[0]; if (matchStatus) { for (i = matchStatus.classList.length; i > 0; i--) { if (matchStatus.classList[i - 1].includes('match-status--')) { matchStatus.classList.remove(matchStatus.classList[i]); } } matchStatus.classList.add(`match-status--${className}`); matchTime = document.getElementsByClassName('match-status__time')[0]; if (matchTime) { matchTime.innerText = label; } } } } function footballMatchInfo(html, replaceContent, homeTeam, awayTeam) { let elemsToAppend; const footballStatsPanel = document.getElementById('football__tabpanel--stats'); let i; while (footballStatsPanel.firstChild) { footballStatsPanel.removeChild(footballStatsPanel.firstChild); } elemsToAppend = getElemsFromHTML(html); for (i = 0; i < elemsToAppend.length; i++) { footballStatsPanel.appendChild(elemsToAppend[i]); } footballChart(homeTeam, awayTeam); if (document.querySelectorAll('[aria-selected="true"]').length === 0) { footballStatsPanel.style.display = 'none'; } } function footballMatchInfoFailed() { let tabToShow; let panelToShow; const footballStatsPanel = document.getElementById('football__tabpanel--stats'); const footballStatsTab = document.querySelector('.tabs [href="#football__tabpanel--stats"]'); footballStatsPanel.parentNode.removeChild(footballStatsPanel); if (footballStatsTab) { if (footballStatsTab.getAttribute('aria-selected') === 'true') { tabToShow = document.querySelector('.tabs a:first-of-type'); if (tabToShow) { tabToShow.setAttribute('aria-selected', 'true'); panelToShow = document.querySelector(tabToShow.getAttribute('href')); if (panelToShow) { panelToShow.style.display = 'block'; } } } footballStatsTab.classList.add('unavailable'); footballStatsTab.addEventListener('touchstart', e => { e.preventDefault(); e.stopPropagation(); }); } } function setupGlobals() { // Global function to handle football, called by native code window.footballMatchInfo = footballMatchInfo; window.footballMatchInfoFailed = footballMatchInfoFailed; window.footballGoal = footballGoal; window.footballStatus = footballStatus; window.applyNativeFunctionCall('footballMatchInfo'); window.applyNativeFunctionCall('footballMatchInfoFailed'); } function init() { setupGlobals(); initYoutube(); initListenToArticle(); } export { init };