How to display match statistics with side-by-side bars
O endpoint /fixtures/statistics retorna as estatisticas de um jogo divididas por time. Neste tutorial veremos como buscar e renderizar barras comparativas lado a lado.
The /fixtures/statistics endpoint returns match statistics split by team. In this tutorial we'll fetch and render side-by-side comparison bars.
const API_KEY = 'YOUR_API_KEY';
const BASE = 'https://football.api.insyde.one';
async function getMatchStats(fixtureId) {
const url = `${BASE}/fixtures/statistics?fixture=${fixtureId}&key=${API_KEY}`;
const res = await fetch(url);
const data = await res.json();
return data.response;
}
const stats = await getMatchStats(1234567);
// stats[0] = home team, stats[1] = away team
Resposta da API / API response:
{
"response": [
{
"team": { "id": 127, "name": "Flamengo" },
"statistics": [
{ "type": "Shots on Goal", "value": 8 },
{ "type": "Shots off Goal", "value": 7 },
{ "type": "Total Shots", "value": 18 },
{ "type": "Blocked Shots", "value": 3 },
{ "type": "Shots insidebox", "value": 12 },
{ "type": "Shots outsidebox", "value": 6 },
{ "type": "Fouls", "value": 11 },
{ "type": "Corner Kicks", "value": 7 },
{ "type": "Offsides", "value": 2 },
{ "type": "Ball Possession", "value": "62%" },
{ "type": "Yellow Cards", "value": 2 },
{ "type": "Red Cards", "value": 0 },
{ "type": "Goalkeeper Saves", "value": 3 },
{ "type": "Total passes", "value": 487 },
{ "type": "Passes accurate", "value": 424 },
{ "type": "Passes %", "value": "87%" }
]
},
{
"team": { "id": 131, "name": "Corinthians" },
"statistics": [
{ "type": "Shots on Goal", "value": 4 },
...
]
}
]
}
Cada time tem um array de statistics com os mesmos tipos na mesma ordem. Para comparar, basta parear por indice:
function pairStats(homeStats, awayStats) {
return homeStats.map((h, i) => ({
label: h.type,
home: h.value,
away: awayStats[i].value
}));
}
const paired = pairStats(
stats[0].statistics,
stats[1].statistics
);
// [{ label: "Shots on Goal", home: 8, away: 4 }, ...]
function renderStatBar(label, home, away) {
// Parse numeric values (handle "62%" format)
const hNum = parseFloat(home) || 0;
const aNum = parseFloat(away) || 0;
const max = Math.max(hNum, aNum) || 1;
const hPct = (hNum / max) * 100;
const aPct = (aNum / max) * 100;
return `
<div class="stat-row">
<span class="val">${home}</span>
<div class="bar left">
<div class="fill home" style="width:${hPct}%"></div>
</div>
<span class="label">${label}</span>
<div class="bar">
<div class="fill away" style="width:${aPct}%"></div>
</div>
<span class="val">${away}</span>
</div>
`;
}
Ball Possession — Posse de bola (formato: "62%")Total Shots, Shots on Goal, Shots off Goal, Blocked ShotsShots insidebox, Shots outsideboxCorner Kicks, Offsides, FoulsYellow Cards, Red CardsGoalkeeper SavesTotal passes, Passes accurate, Passes %expected_goals — xG (quando disponivel / when available)value: null se nao estiverem disponiveis. Trate como 0 na renderizacao.
value: null if not available. Treat as 0 when rendering.