{
const data = tracking_data.filter(d => d.play == "Fulham 0 - [1] Liverpool");
const pitch = d3_soccer.pitch();
const chart = d3.create('div')
.style('font-family', 'Helvetica')
const svg = chart.append('svg')
.attr('width', pitch.width())
.attr('height', pitch.height() + 110);
const header = d3_soccer.matchHeader()
.hed("Premier League")
.score([0, 1])
.logoAway("https://upload.wikimedia.org/wikipedia/fr/thumb/5/54/Logo_FC_Liverpool.svg/langfr-130px-Logo_FC_Liverpool.svg.png")
.logoHome("https://upload.wikimedia.org/wikipedia/en/thumb/e/eb/Fulham_FC_%28shield%29.svg/150px-Fulham_FC_%28shield%29.svg.png");
svg.append('g').attr("transform", "translate(15, 20)").call(header);
svg.selectAll("image").attr("height", 35);
svg.append('g').attr("transform", "translate(0, 90)").call(pitch);
svg.append('text')
.attr('x', pitch.width() - 10)
.attr('y', pitch.height() + 100)
.attr('text-anchor', 'end')
.style("fill", "grey")
.style("font-style", "italic")
.style("font-size", "11px")
.text("Data provided by LastRowView");
let plot_layer = chart.select(".above")
let voronoi_layer = chart.select(".below")
let x = d3.scaleLinear()
.domain([0, 100])
.range([0, 105]);
let y = d3.scaleLinear()
.domain([0, 100])
.range([0, 68]);
function updateData(frame) {
// Get all data for the current frame
let frameData = data.filter(d => d.frame == frame);
// Plot the locations of all players and the ball
let u = plot_layer.selectAll('circle')
.data(frameData, d => parseInt(d.player) || 0);
u.enter().append('circle')
.attr('cx', d => x(parseFloat(d.x)))
.attr('cy', d => y(parseFloat(d.y)))
.attr('r', 1)
.attr('fill', d => d.bgcolor || 'black')
.attr('stroke', d => d.edgecolor)
.attr('stroke-width', .2)
.attr('fill-opacity', 0.5);
u.attr('cx', d => x(parseFloat(d.x)))
.attr('cy', d => y(parseFloat(d.y)))
u.exit().remove();
// Add the Voronoi on top
let voronoiData = frameData.filter(d => parseInt(d.player)); // Remove the ball
let delaunay = d3.Delaunay.from(
voronoiData,
d => x(parseFloat(d.x)),
d => y(parseFloat(d.y))
), voronoi = delaunay.voronoi([ 0, 0, 105, 68 ])
let w = voronoi_layer.selectAll('path')
.data( voronoiData.map((d,i) => voronoi.renderCell(i)) )
w.enter()
.append('path')
.attr('d', d => d)
.style('fill', (_,i) => voronoiData[i].bgcolor)
.style('opacity', 0.1)
.style('stroke', 'black')
.attr('stroke-width', .2);
w.attr('d', d => d);
w.exit().remove();
}
let frames = d3.max(data, d => parseInt(d.frame));
// Data provided has 20 frames per second --> update every 50 ms.
var i = 0
setInterval(function(){
i = i === frames ? 0 : i + 1;
updateData(i)
}, 50);
return chart.node()
}