UNPKG

d3-soccer

Version:

A d3 plugin to visualize soccer data.

3 lines (2 loc) 36.8 kB
// https://github.com/probberechts/d3-soccer v0.2.0 Copyright 2024 undefined !function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("d3-selection"),require("d3-shape"),require("d3-color"),require("d3-scale"),require("d3-scale-chromatic")):"function"==typeof define&&define.amd?define(["exports","d3-selection","d3-shape","d3-color","d3-scale","d3-scale-chromatic"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).d3=t.d3||{},t.d3,t.d3,t.d3,t.d3,t.d3)}(this,(function(t,e,r,n,a,o){"use strict";function l(t){var e=Object.create(null);return t&&Object.keys(t).forEach((function(r){if("default"!==r){var n=Object.getOwnPropertyDescriptor(t,r);Object.defineProperty(e,r,n.get?n:{enumerable:!0,get:function(){return t[r]}})}})),e.default=t,Object.freeze(e)}var i,c,s=l(o),u=105,d=68,f=[{label:"Fail"},{label:"Success"},{label:"Offside"},{label:"Own goal"},{label:"Yellow card"},{label:"Red card"}],p=[{label:"Pass"},{label:"Cross"},{label:"Throw in"},{label:"Freekick (cross)"},{label:"Freekick (short)"},{label:"Corner (cross)"},{label:"Corner (short)"},{label:"Dribble"},{label:"Foul"},{label:"Tackle"},{label:"Interception"},{label:"Shot"},{label:"Penalty"},{label:"Freekick (shot)"},{label:"Save"},{label:"Claim"},{label:"Punch"},{label:"Pick up"},{label:"Clearance"},{label:"Bad touch"},{label:"-"},{label:"Carry"},{label:"Goal kick"}],h=[{label:"Foot"},{label:"Head"},{label:"Other"}];function y(t,e){let r;if(void 0===e)for(const e of t)null!=e&&(r<e||void 0===r&&e>=e)&&(r=e);else{let n=-1;for(let a of t)null!=(a=e(a,++n,t))&&(r<a||void 0===r&&a>=a)&&(r=a)}return r}var m=function(){if(c)return i;function t(t,e={}){e=Object.assign({extrapolate:!1,scaleX:1,scaleY:1,translateX:0,translateY:0},e);const r=t[1][1],n=-.5*t[1][0]+.5*t[1][2],a=t[1][0]+-2.5*t[1][1]+2*t[1][2]+-.5*t[1][3],o=-.5*t[1][0]+1.5*t[1][1]+-1.5*t[1][2]+.5*t[1][3],l=-.5*t[0][1]+.5*t[2][1],i=1/4*t[0][0]+-1/4*t[0][2]+-1/4*t[2][0]+1/4*t[2][2],c=-.5*t[0][0]+5/4*t[0][1]+-1*t[0][2]+1/4*t[0][3]+.5*t[2][0]+-5/4*t[2][1]+t[2][2]+-1/4*t[2][3],s=1/4*t[0][0]+-3/4*t[0][1]+3/4*t[0][2]+-1/4*t[0][3]+-1/4*t[2][0]+3/4*t[2][1]+-3/4*t[2][2]+1/4*t[2][3],u=t[0][1]+-2.5*t[1][1]+2*t[2][1]+-.5*t[3][1],d=-.5*t[0][0]+.5*t[0][2]+5/4*t[1][0]+-5/4*t[1][2]+-1*t[2][0]+t[2][2]+1/4*t[3][0]+-1/4*t[3][2],f=t[0][0]+-2.5*t[0][1]+2*t[0][2]+-.5*t[0][3]+-2.5*t[1][0]+6.25*t[1][1]+-5*t[1][2]+5/4*t[1][3]+2*t[2][0]+-5*t[2][1]+4*t[2][2]+-1*t[2][3]+-.5*t[3][0]+5/4*t[3][1]+-1*t[3][2]+1/4*t[3][3],p=-.5*t[0][0]+1.5*t[0][1]+-1.5*t[0][2]+.5*t[0][3]+5/4*t[1][0]+-3.75*t[1][1]+3.75*t[1][2]+-5/4*t[1][3]+-1*t[2][0]+3*t[2][1]+-3*t[2][2]+t[2][3]+1/4*t[3][0]+-3/4*t[3][1]+3/4*t[3][2]+-1/4*t[3][3],h=-.5*t[0][1]+1.5*t[1][1]+-1.5*t[2][1]+.5*t[3][1],y=1/4*t[0][0]+-1/4*t[0][2]+-3/4*t[1][0]+3/4*t[1][2]+3/4*t[2][0]+-3/4*t[2][2]+-1/4*t[3][0]+1/4*t[3][2],m=-.5*t[0][0]+5/4*t[0][1]+-1*t[0][2]+1/4*t[0][3]+1.5*t[1][0]+-3.75*t[1][1]+3*t[1][2]+-3/4*t[1][3]+-1.5*t[2][0]+3.75*t[2][1]+-3*t[2][2]+3/4*t[2][3]+.5*t[3][0]+-5/4*t[3][1]+t[3][2]+-1/4*t[3][3],g=1/4*t[0][0]+-3/4*t[0][1]+3/4*t[0][2]+-1/4*t[0][3]+-3/4*t[1][0]+9/4*t[1][1]+-9/4*t[1][2]+3/4*t[1][3]+3/4*t[2][0]+-9/4*t[2][1]+9/4*t[2][2]+-3/4*t[2][3]+-1/4*t[3][0]+3/4*t[3][1]+-3/4*t[3][2]+1/4*t[3][3];return(t,b)=>{if(t=t*e.scaleX+e.translateX,b=b*e.scaleY+e.translateY,t<0||b<0||t>1||b>1)throw"cannot interpolate outside the square from (0, 0) to (1, 1): ("+t+", "+b+")";const v=t*t,x=b*b,k=b*x;return r+n*b+a*x+o*k+(l+i*b+c*x+s*k)*t+(u+d*b+f*x+p*k)*v+(h+y*b+m*x+g*k)*(t*v)}}function e(e,r={}){r=Object.assign({extrapolate:!1,scaleX:1,scaleY:1,translateX:0,translateY:0},r);const n=e.length,a=e[0].length,o=[];if(r.extrapolate){e[-2]=[],e[-1]=[],e[n]=[],e[n+1]=[];for(var l=0;l<a;l++){const t=e[0][l]-e[1][l],r=e[n-1][l]-e[n-2][l];e[-2][l]=e[0][l]+2*t,e[-1][l]=e[0][l]+t,e[n][l]=e[n-1][l]+r,e[n+1][l]=e[n-1][l]+2*r}for(var i=-2;i<n+2;i++){const t=e[i][0]-e[i][1],r=e[i][a-1]-e[i][a-2];e[i][-2]=e[i][0]+2*t,e[i][-1]=e[i][0]+t,e[i][a]=e[i][a-1]+r,e[i][a+1]=e[i][a-1]+2*r}for(i=-1;i<n;i++)o[i]=[]}else for(i=1;i<n-2;i++)o[i]=[];return(l,i)=>{if(l=l*r.scaleX+r.translateX,i=i*r.scaleY+r.translateY,r.extrapolate){if(l<-1||i<-1||l>n||i>a)throw"cannot interpolate outside the rectangle from (-1, -1) to ("+n+", "+a+") even when extrapolating: ("+l+", "+i+")"}else if(l<1||i<1||l>n-2||i>a-2)throw"cannot interpolate outside the rectangle from (1, 1) to ("+(n-2)+", "+(a-2)+"): ("+l+", "+i+"), you might want to enable extrapolating";var c=Math.floor(l),s=Math.floor(i);r.extrapolate?(l===n&&c--,i===a&&s--):(l===n-2&&c--,i===a-2&&s--),o[c][s]||(o[c][s]=t([[e[c-1][s-1],e[c-1][s],e[c-1][s+1],e[c-1][s+2]],[e[c+0][s-1],e[c+0][s],e[c][s+1],e[c][s+2]],[e[c+1][s-1],e[c+1][s],e[c+1][s+1],e[c+1][s+2]],[e[c+2][s-1],e[c+2][s],e[c+2][s+1],e[c+2][s+2]]],{translateX:-c,translateY:-s}));return(0,o[c][s])(l,i)}}return c=1,i={createInterpolator:t,createGridInterpolator:e,createMultiInterpolator:function(e,r={}){const n=e[0][0].length,a=[];for(var o=0;o<n;o++)a[o]=t(e.map((t=>t.map((t=>t[o])))),r);return(t,e)=>a.map((r=>r(t,e)))},createMultiGridInterpolator:function(t,r={}){const n=t[0][0].length,a=[];for(var o=0;o<n;o++)a[o]=e(t.map((t=>t.map((t=>t[o])))),r);return(t,e)=>a.map((r=>r(t,e)))}}}();function g(t,e){(null==e||e>t.length)&&(e=t.length);for(var r=0,n=Array(e);r<e;r++)n[r]=t[r];return n}function b(t,e){var r="undefined"!=typeof Symbol&&t[Symbol.iterator]||t["@@iterator"];if(!r){if(Array.isArray(t)||(r=x(t))||e){r&&(t=r);var n=0,a=function(){};return{s:a,n:function(){return n>=t.length?{done:!0}:{done:!1,value:t[n++]}},e:function(t){throw t},f:a}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var o,l=!0,i=!1;return{s:function(){r=r.call(t)},n:function(){var t=r.next();return l=t.done,t},e:function(t){i=!0,o=t},f:function(){try{l||null==r.return||r.return()}finally{if(i)throw o}}}}function v(t,e){return function(t){if(Array.isArray(t))return t}(t)||function(t,e){var r=null==t?null:"undefined"!=typeof Symbol&&t[Symbol.iterator]||t["@@iterator"];if(null!=r){var n,a,o,l,i=[],c=!0,s=!1;try{if(o=(r=r.call(t)).next,0===e);else for(;!(c=(n=o.call(r)).done)&&(i.push(n.value),i.length!==e);c=!0);}catch(t){s=!0,a=t}finally{try{if(!c&&null!=r.return&&(l=r.return(),Object(l)!==l))return}finally{if(s)throw a}}return i}}(t,e)||x(t,e)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function x(t,e){if(t){if("string"==typeof t)return g(t,e);var r={}.toString.call(t).slice(8,-1);return"Object"===r&&t.constructor&&(r=t.constructor.name),"Map"===r||"Set"===r?Array.from(t):"Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r)?g(t,e):void 0}}var k={value:()=>{}};function w(){for(var t,e=0,r=arguments.length,n={};e<r;++e){if(!(t=arguments[e]+"")||t in n||/[\s.]/.test(t))throw new Error("illegal type: "+t);n[t]=[]}return new _(n)}function _(t){this._=t}function j(t,e){for(var r,n=0,a=t.length;n<a;++n)if((r=t[n]).name===e)return r.value}function A(t,e,r){for(var n=0,a=t.length;n<a;++n)if(t[n].name===e){t[n]=k,t=t.slice(0,n).concat(t.slice(n+1));break}return null!=r&&t.push({name:e,value:r}),t}_.prototype=w.prototype={constructor:_,on:function(t,e){var r,n,a=this._,o=(n=a,(t+"").trim().split(/^|\s+/).map((function(t){var e="",r=t.indexOf(".");if(r>=0&&(e=t.slice(r+1),t=t.slice(0,r)),t&&!n.hasOwnProperty(t))throw new Error("unknown type: "+t);return{type:t,name:e}}))),l=-1,i=o.length;if(!(arguments.length<2)){if(null!=e&&"function"!=typeof e)throw new Error("invalid callback: "+e);for(;++l<i;)if(r=(t=o[l]).type)a[r]=A(a[r],t.name,e);else if(null==e)for(r in a)a[r]=A(a[r],t.name,null);return this}for(;++l<i;)if((r=(t=o[l]).type)&&(r=j(a[r],t.name)))return r},copy:function(){var t={},e=this._;for(var r in e)t[r]=e[r].slice();return new _(t)},call:function(t,e){if((r=arguments.length-2)>0)for(var r,n,a=new Array(r),o=0;o<r;++o)a[o]=arguments[o+2];if(!this._.hasOwnProperty(t))throw new Error("unknown type: "+t);for(o=0,r=(n=this._[t]).length;o<r;++o)n[o].value.apply(e,a)},apply:function(t,e,r){if(!this._.hasOwnProperty(t))throw new Error("unknown type: "+t);for(var n=this._[t],a=0,o=n.length;a<o;++a)n[a].value.apply(e,r)}};const O={passive:!1},P={capture:!0,passive:!1};function T(t){t.stopImmediatePropagation()}function C(t){t.preventDefault(),t.stopImmediatePropagation()}var I=t=>()=>t;function z(t,{sourceEvent:e,subject:r,target:n,identifier:a,active:o,x:l,y:i,dx:c,dy:s,dispatch:u}){Object.defineProperties(this,{type:{value:t,enumerable:!0,configurable:!0},sourceEvent:{value:e,enumerable:!0,configurable:!0},subject:{value:r,enumerable:!0,configurable:!0},target:{value:n,enumerable:!0,configurable:!0},identifier:{value:a,enumerable:!0,configurable:!0},active:{value:o,enumerable:!0,configurable:!0},x:{value:l,enumerable:!0,configurable:!0},y:{value:i,enumerable:!0,configurable:!0},dx:{value:c,enumerable:!0,configurable:!0},dy:{value:s,enumerable:!0,configurable:!0},_:{value:u}})}function E(t){return!t.ctrlKey&&!t.button}function S(){return this.parentNode}function F(t,e){return null==e?{x:t.x,y:t.y}:e}function B(){return navigator.maxTouchPoints||"ontouchstart"in this}function M(){var t,r,n,a,o=E,l=S,i=F,c=B,s={},u=w("start","drag","end"),d=0,f=0;function p(t){t.on("mousedown.drag",h).filter(c).on("touchstart.drag",g).on("touchmove.drag",b,O).on("touchend.drag touchcancel.drag",v).style("touch-action","none").style("-webkit-tap-highlight-color","rgba(0,0,0,0)")}function h(i,c){if(!a&&o.call(this,i,c)){var s,u,d,f=x(this,l.call(this,i,c),i,c,"mouse");if(f)e.select(i.view).on("mousemove.drag",y,P).on("mouseup.drag",m,P),s=i.view,u=s.document.documentElement,d=e.select(s).on("dragstart.drag",C,P),"onselectstart"in u?d.on("selectstart.drag",C,P):(u.__noselect=u.style.MozUserSelect,u.style.MozUserSelect="none"),T(i),n=!1,t=i.clientX,r=i.clientY,f("start",i)}}function y(e){if(C(e),!n){var a=e.clientX-t,o=e.clientY-r;n=a*a+o*o>f}s.mouse("drag",e)}function m(t){var r,a,o,l;e.select(t.view).on("mousemove.drag mouseup.drag",null),r=t.view,a=n,o=r.document.documentElement,l=e.select(r).on("dragstart.drag",null),a&&(l.on("click.drag",C,P),setTimeout((function(){l.on("click.drag",null)}),0)),"onselectstart"in o?l.on("selectstart.drag",null):(o.style.MozUserSelect=o.__noselect,delete o.__noselect),C(t),s.mouse("end",t)}function g(t,e){if(o.call(this,t,e)){var r,n,a=t.changedTouches,i=l.call(this,t,e),c=a.length;for(r=0;r<c;++r)(n=x(this,i,t,e,a[r].identifier,a[r]))&&(T(t),n("start",t,a[r]))}}function b(t){var e,r,n=t.changedTouches,a=n.length;for(e=0;e<a;++e)(r=s[n[e].identifier])&&(C(t),r("drag",t,n[e]))}function v(t){var e,r,n=t.changedTouches,o=n.length;for(a&&clearTimeout(a),a=setTimeout((function(){a=null}),500),e=0;e<o;++e)(r=s[n[e].identifier])&&(T(t),r("end",t,n[e]))}function x(t,r,n,a,o,l){var c,f,h,y=u.copy(),m=e.pointer(l||n,r);if(null!=(h=i.call(t,new z("beforestart",{sourceEvent:n,target:p,identifier:o,active:d,x:m[0],y:m[1],dx:0,dy:0,dispatch:y}),a)))return c=h.x-m[0]||0,f=h.y-m[1]||0,function n(l,i,u){var g,b=m;switch(l){case"start":s[o]=n,g=d++;break;case"end":delete s[o],--d;case"drag":m=e.pointer(u||i,r),g=d}y.call(l,t,new z(l,{sourceEvent:i,subject:h,target:p,identifier:o,active:g,x:m[0]+c,y:m[1]+f,dx:m[0]-b[0],dy:m[1]-b[1],dispatch:y}),a)}}return p.filter=function(t){return arguments.length?(o="function"==typeof t?t:I(!!t),p):o},p.container=function(t){return arguments.length?(l="function"==typeof t?t:I(t),p):l},p.subject=function(t){return arguments.length?(i="function"==typeof t?t:I(t),p):i},p.touchable=function(t){return arguments.length?(c="function"==typeof t?t:I(!!t),p):c},p.on=function(){var t=u.on.apply(u,arguments);return t===u?p:t},p.clickDistance=function(t){return arguments.length?(f=(t=+t)*t,p):Math.sqrt(f)},p}z.prototype.on=function(){var t=this._.on.apply(this._,arguments);return t===this._?this:t};var Y=[{label:"Pass",plot:R,symbol:q},{label:"Cross",plot:R,symbol:q},{label:"Throw in",plot:R,symbol:q},{label:"Freekick (cross)",plot:R,symbol:q},{label:"Freekick (short)",plot:R,symbol:q},{label:"Corner (cross)",plot:R,symbol:q},{label:"Corner (short)",plot:R,symbol:q},{label:"Dribble",plot:function(t,e,r,n,a){var o=.1*a,l=t.classed("dribble",!0);l.append("line").attr("x1",(function(t){return t.start_x})).attr("y1",(function(t){return 68-t.start_y})).attr("x2",(function(t){return t.end_x})).attr("y2",(function(t){return 68-t.end_y})).attr("stroke-width",o).style("stroke-dasharray","1,1").attr("stroke","black").attr("marker-end","url(#triangle)"),l.append("g").attr("class","marker").attr("marker","marker-start").attr("transform",(function(t){return"translate("+t.start_x+","+(68-t.start_y)+")"})).call(G,e,r,n,a)},symbol:G},{label:"Foul",plot:function(t,e,r,n,a){t.classed("foul",!0).append("g").attr("class","marker").attr("marker","marker-start").attr("transform",(function(t){return"translate("+t.start_x+","+(68-t.start_y)+")"})).call(K,e,r,n,a)},symbol:K},{label:"Tackle",plot:N,symbol:W},{label:"Interception",plot:N,symbol:W},{label:"Shot",plot:X,symbol:D},{label:"Penalty",plot:X,symbol:D},{label:"Freekick (shot)",plot:X,symbol:D},{label:"Save",plot:N,symbol:W},{label:"Claim",plot:N,symbol:W},{label:"Punch",plot:H,symbol:U},{label:"Pick up",plot:N,symbol:W},{label:"Clearance",plot:H,symbol:U},{label:"Bad touch",plot:N,symbol:W},{label:"-",plot:function(){return null},symbol:function(){return null}},{label:"Carry",plot:function(t,e,r,n,a){var o=1*a,l=t.classed("carry",!0);l.append("line").attr("x1",(function(t){return t.start_x})).attr("y1",(function(t){return 68-t.start_y})).attr("x2",(function(t){return t.end_x})).attr("y2",(function(t){return 68-t.end_y})).attr("stroke-width",.05).style("stroke-dasharray","0.4,0.4").attr("stroke","grey"),l.append("g").attr("class","marker").attr("marker","marker-start").attr("transform",(function(t){return"translate("+t.start_x+","+(68-t.start_y)+")"})).append("circle").attr("stroke-width",0).attr("fill","#000").attr("opacity",0).attr("r",o)},symbol:function(){return null}},{label:"Goal kick",plot:R,symbol:q}];function X(t,e,r,n,a){var o=.1*a,l=t.classed("shot",!0);l.append("line").attr("x1",(function(t){return t.start_x})).attr("y1",(function(t){return 68-t.start_y})).attr("x2",(function(t){return t.end_x})).attr("y2",(function(t){return 68-t.end_y})).attr("stroke-width",o).attr("stroke","black").attr("marker-end","url(#triangle)");var i=l.append("g").attr("class","marker").attr("marker","marker-start").attr("transform",(function(t){return"translate("+t.start_x+","+(68-t.start_y)+")"}));i.call(D,e,r,n,a)}function D(t,e,r,a,o){var l=1*o,i=.1*o,c=t.append("g").attr("class","symbol shot");c.append("circle").attr("r",l).attr("stroke-width",i).attr("stroke","grey").attr("fill",a),c.append("text").attr("text-anchor","middle").attr("dominant-baseline","central").style("font-size",.8*l+"px").attr("fill",n.hsl(a).l>=.6?"#000":"#fff").text(r)}function R(t,e,r,n,a){var o=.1*a,l=t.classed("pass",!0);l.append("line").attr("x1",(function(t){return t.start_x})).attr("y1",(function(t){return 68-t.start_y})).attr("x2",(function(t){return t.end_x})).attr("y2",(function(t){return 68-t.end_y})).attr("stroke-width",o).attr("stroke","#000").attr("marker-end","url(#triangle)");var i=l.append("g").attr("class","marker").attr("marker","marker-start").attr("transform",(function(t){return"translate("+t.start_x+","+(68-t.start_y)+")"}));i.call(q,e,r,n,a)}function q(t,e,r,n,a){var o=1*a,l=.1*a,i=t.append("g").attr("class","symbol pass");i.append("circle").attr("r",o).attr("stroke-width",l).attr("stroke",n).attr("fill","#fff"),i.append("text").attr("text-anchor","middle").attr("dominant-baseline","central").style("font-size",.8*o+"px").attr("fill","#000").text(r)}function G(t,e,r,n,a){var o=1*a,l=.1*a,i=t.append("g").attr("class","symbol dribble");i.append("circle").attr("r",o).attr("stroke-width",l).attr("stroke",n).attr("fill","#fff"),i.append("text").attr("text-anchor","middle").attr("dominant-baseline","central").style("font-size",.8*o+"px").attr("fill","#000").text(r)}function H(t,e,r,n,a){var o=t.classed("clearance",!0).append("g").attr("class","marker").attr("marker","marker-start").attr("transform",(function(t){return"translate("+t.start_x+","+(68-t.start_y)+")"}));o.call(U,e,r,n,a)}function U(t,e,a,o,l){var i=2*l*l,c=.1*l,s=t.append("g").attr("class","symbol clearance"),u=r.symbol().size(i).type(r.symbolTriangle);s.append("path").attr("fill",o).attr("stroke","grey").attr("stroke-width",c).attr("d",u),s.append("text").attr("dominant-baseline","central").style("text-anchor","middle").style("font-size",.8*l+"px").attr("fill",n.hsl(o).l>=.6?"#000":"#fff").text(a)}function N(t,e,r,n,a){var o=t.classed("block",!0).append("g").attr("class","marker").attr("marker","marker-start").attr("transform",(function(t){return"translate("+t.start_x+","+(68-t.start_y)+")"}));o.call(W,e,r,n,a)}function W(t,e,r,a,o){var l=2*o,i=.1*o,c=t.append("g").attr("class","symbol block");c.append("rect").attr("x",-l/2).attr("y",-l/2).attr("width",l).attr("height",l).attr("stroke-width",i).attr("stroke","grey").attr("fill",a),c.append("text").attr("text-anchor","middle").attr("dominant-baseline","central").style("text-anchor","middle").style("font-size",.4*l+"px").attr("fill",n.hsl(a).l>=.6?"#000":"#fff").text(r)}function K(t,e,a,o,l){var i=2*l*l,c=.1*l,s=t.append("g").attr("class","symbol foul"),u=r.symbol().size(i).type(r.symbolCross);s.append("path").attr("fill",o).attr("stroke","grey").attr("stroke-width",c).attr("d",u),s.append("text").attr("dominant-baseline","central").style("text-anchor","middle").style("font-size",.8*l+"px").attr("fill",n.hsl(o).l>=.6?"#000":"#fff").text(a)}t.actionTooltip=function(){var t=e.select("#tooltip");function r(e){t.size()||(t=e.append("div").style("position","absolute").style("pointer-events","none").style("z-index",6).style("opacity",0).attr("class","tooltip").attr("id","tooltip"))}return r.show=function(n,a){t.html('\n <table>\n <tr>\n <th colspan="2">'.concat(p[a.type_id].label,"</th>\n <tr>\n <td>Player</td>\n <td>").concat(a.player_name||a.player_id,"</td>\n </tr>\n <tr>\n <td>Team</td>\n <td>").concat(a.team_name||a.team_id,"</td>\n </tr>\n <tr>\n <td>Result</td>\n <td>").concat(f[a.result_id].label,"</td>\n </tr>\n <tr>\n <td>Body part</td>\n <td>").concat(h[a.bodypart_id].label,"</td>\n </tr>\n <tr>\n <td>Time</td>\n <td>").concat(Math.floor(a.time_seconds/60)," min ").concat(a.time_seconds%60," sec</td>\n </tr>\n <tr>\n <td>Start</td>\n <td>x=").concat(a.start_x.toFixed(2)," , y=").concat(a.start_y.toFixed(2),"</td>\n </tr>\n <tr>\n <td>End</td>\n <td>x=").concat(a.end_x.toFixed(2)," , y=").concat(a.end_y.toFixed(2),"</td>\n </tr>\n </table>\n "));var o=v(e.pointer(n,document.body),2),l=o[0],i=o[1];return t.style("opacity",.95).style("left",l+"px").style("top",i+"px"),r},r.hide=function(){return t.style("opacity",0),r},r},t.actions=function(t){var r=4,n=!1,a=!1,o={},l=function(){};function i(i){i.each((function(i){var c=e.select(this).call(t).select(".above");c.append("svg:defs").append("svg:marker").attr("id","triangle").attr("refX",11).attr("refY",6).attr("dy",6).attr("markerWidth",12).attr("markerHeight",12).attr("orient","auto").append("path").attr("d","M 0 0 12 6 0 12 3 6");var s,u=M().on("start",(function(){e.select(this).classed("active",!0)})).on("drag",(function(t){var r=v(e.pointer(c.node()),2),n=r[0],a=r[1],o=e.select(this).attr("marker");e.select(this).attr("transform","translate("+n+","+a+")");var l=e.select("#action-".concat(t.action_id));"marker-start"===o?(l.select("line").attr("x1",n).attr("y1",a),e.select("#action-".concat(t.action_id-1)).select("line").attr("x2",n).attr("y2",a)):l.select("line").attr("x2",n).attr("y2",a)})).on("end",(function(t){var r=v(e.pointer(c.node()),2),n=r[0],a=r[1],o=e.select(this).attr("marker");e.select(this).classed("active",!1);var s=i.slice();if("marker-start"===o){s.find((function(e){return e.action_id===t.action_id})).start_x=n,s.find((function(e){return e.action_id===t.action_id})).start_y=68-a;var u=s.find((function(e){return e.action_id===t.action_id-1}));u&&(u.end_x=n,u.end_y=68-a)}else s.find((function(e){return e.action_id===t.action_id})).end_x=n,s.find((function(e){return e.action_id===t.action_id})).end_y=68-a;l(s)})),d=["#FDB913","#87CEEB"],f=b(i);try{for(f.s();!(s=f.n()).done;){var p=s.value;if(p.team_id in o==!1){if(Object.keys(o).length>=2)throw"You specified ids of teams that do not occur in the data!";o[p.team_id]=d[Object.keys(o).length]}}}catch(t){f.e(t)}finally{f.f()}var h=c.selectAll("g.action").data(i);h.each((function(t,a){e.select(this).selectAll("*").remove(),e.select(this).attr("class","action").attr("id","action-".concat(t.action_id)).call(Y[t.type_id].plot,t,a+1,o[t.team_id],r).selectAll("g.symbol").on("mouseover",(function(t,e){return n&&n.show(t,e)})).on("mouseout",(function(){return n&&n.hide()}))})),h.enter().append("g").attr("class","action").each((function(t,a){e.select(this).attr("class","action").attr("id","action-".concat(t.action_id)).call(Y[t.type_id].plot,t,a+1,o[t.team_id],r).selectAll("g.symbol").on("mouseover",(function(t,e){return n&&n.show(t,e)})).on("mouseout",(function(){return n&&n.hide()}))})),c.selectAll(".action:last-of-type").selectAll("g.marker-end").data((function(t){return[t]})).enter().append("g").attr("class","marker marker-end").attr("marker","marker-end").attr("transform",(function(t){return"translate("+t.end_x+","+(68-t.end_y)+")"})).append("circle").attr("stroke-width",0).attr("fill","#000").attr("opacity",0).attr("r",2),h.exit().remove(),a&&u(c.selectAll("g.marker"))}))}return i.showTooltip=function(t){return arguments.length?(n=t,i):n},i.scale=function(t){return arguments.length?(r=t,i):r},i.draggable=function(t){return arguments.length?(a=Boolean(t),i):a},i.teamColors=function(t){return arguments.length?(o=t,i):o},i.onUpdate=function(t){return arguments.length?(l=t,i):l},i},t.actionsTable=function(){var t=9,r={symbol:"",team_name:"Team",player_name:"Player",type_id:"Type",result_id:"Result"},n={};function a(a){a.each((function(a){var o,l=["#FDB913","#87CEEB"],i=b(a);try{for(i.s();!(o=i.n()).done;){var c=o.value;if(c.team_id in n==!1){if(Object.keys(n).length>=2)throw"You specified ids of teams that do not occur in the data!";n[c.team_id]=l[Object.keys(n).length]}}}catch(t){i.e(t)}finally{i.f()}var s=function(t,e){t.html("");var r=t.append("table"),n=r.append("thead"),a=r.append("tbody");return r.attr("class","actions-table"),n.append("tr").selectAll("th").data(Object.values(e)).enter().append("th").text((function(t){return t})),a}(e.select(this),r),u=s.selectAll("tr").data(a),d=u.enter().append("tr").attr("id",(function(t){return t.action_id}));u.exit().remove(),d.selectAll("td").data((function(t,e){return Object.keys(r).map((function(r){return{column:r,value:t[r],i:e,data:t}}))})).enter().append("td").each((function(r){"symbol"===r.column?e.select(this).attr("class",r.column).style("text-align","center").append("svg").attr("height",20).attr("width",20).call(Y[r.data.type_id].symbol,r.data,r.i+1,n[r.data.team_id],t).select("g").attr("transform","translate(10,10)"):e.select(this).attr("class",r.column).html((function(t){return"type_id"===t.column?p[+t.value].label:"result_id"===t.column?f[+t.value].label:"bodypart_id"===t.column?h[+t.value].label:t.value}))}))}))}return a.tableColumns=function(t){return arguments.length?(r=t,a):r},a.scale=function(e){return arguments.length?(t=e,a):t},a.teamColors=function(t){return arguments.length?(n=t,a):n},a},t.grid=function(){function t(t){for(var e=[],r=t.length,n=t[0].length,a=u/r,o=d/n,l=0,i=0;i<r;i++)for(var c=0;c<n;c++)t[i][c]>l&&(l=t[i][c]),e.push({i:i,j:c,x:i*a,y:c*o,width:a,height:o,value:t[i][c]});return e}return t},t.header=function(){var t=void 0,r=void 0,n=void 0;function a(a){a.each((function(){var a=e.select(this).append("g").attr("class","header");a.append("defs").attr("id","imgdefs").append("pattern").attr("id","imgpattern").attr("height",1).attr("width",1).attr("x","0").attr("y","0").append("image").attr("x",0).attr("y",10).attr("height",80).attr("xlink:href",n),a.append("circle").attr("class","circle").attr("r",40).attr("cy",50).attr("cx",50).attr("stroke","#333").attr("fill","url(#imgpattern)"),a.append("text").attr("class","h2").attr("x",110).attr("y",40).attr("font-size","21px").attr("fill","#333").text(r),a.append("text").attr("class","h1").attr("x",110).attr("y",80).attr("font-weight","bold").attr("font-size","32px").attr("fill","black").text(t)}))}return a.hed=function(e){return arguments.length?(t=e,a):t},a.subhed=function(t){return arguments.length?(r=t,a):r},a.img=function(t){return arguments.length?(n=t,a):n},a},t.heatmap=function(t){var r=!1,o=[void 0,void 0],l=function(){},i=function(){},c=a.scaleSequential(s.interpolateGreens).domain([void 0,void 0]),u="#00000011",d="#FF6600",f=!1,p=!1,h=function(t){return t},g=function(t){return.2*t+"px"},b="body";function v(a){a.each((function(a){var s=o[0],v=o[1];c.domain().some(isNaN)&&c.domain(function(t,e){let r,n;if(void 0===e)for(const e of t)null!=e&&(void 0===r?e>=e&&(r=n=e):(r>e&&(r=e),n<e&&(n=e)));else{let a=-1;for(let o of t)null!=(o=e(o,++a,t))&&(void 0===r?o>=o&&(r=n=o):(r>o&&(r=o),n<o&&(n=o)))}return[r,n]}(a,(function(t){return t.value})));var x,k,w,_,j=e.select(this).call(t).select(".below"),A=j.selectAll("rect.cell").data(a),O=A.enter().append("g").attr("class","cell").attr("id",(function(t){return"cell(".concat(t.i,",").concat(t.j,")")}));if(O.append("rect").attr("x",(function(t){return t.x})).attr("y",(function(t){return t.y})).attr("width",(function(t){return t.width})).attr("height",(function(t){return t.height})).attr("data",(function(t){return t.value})).style("stroke",(function(t){return s===t.x&&v===t.y?d:u})).style("stroke-width",(function(t){return s===t.x&&v===t.y?.5:0})).style("fill",(function(t){return f?"transparent":c(+t.value)})).style("cursor",r?"crosshair":"default").on("mouseover",(function(t,n){r&&e.select(this).style("stroke",d).style("stroke-width",.5),l(n.x,n.y,n.value)})).on("mouseout",(function(t,n){r&&e.select(this).style("stroke",u).style("stroke-width",0),i(n.x,n.y,n.value)})),A.merge(O).select("rect").attr("x",(function(t){return t.x})).attr("y",(function(t){return t.y})).attr("width",(function(t){return t.width})).attr("height",(function(t){return t.height})).attr("data",(function(t){return t.value})).style("fill",(function(t){return f?"transparent":c(+t.value)})),A.exit().select("rect").attr("width",0).attr("height",0).remove(),p&&(O.append("text").attr("x",(function(t){return t.x+t.width/2})).attr("y",(function(t){return t.y+t.height/2})).attr("dy",".35em").attr("text-anchor","middle").text((function(t){return h(t.value)})).style("fill","white").style("mix-blend-mode","difference").style("font-size",(function(t){return g(t.height,t.width,t.value)})).style("pointer-events","none"),A.merge(O).select("text").attr("x",(function(t){return t.x+t.width/2})).attr("y",(function(t){return t.y+t.height/2})).text((function(t){return h(t.value)})),A.exit().select("text").style("font-size",0).remove()),f){for(var P=y(a,(function(t){return t.i}))+1,T=y(a,(function(t){return t.j}))+1,C=[],I=0;I<P;I++){C.push([]);for(var z=0;z<T;z++)C[I].push(a.find((function(t){return t.i===I&&t.j===z})).value)}var E=e.select(b).style("position","relative").append("canvas").style("z-index",-1).style("position","absolute").style("pointer-events","none"),S=(x=j,k=e.select(b),w=x.node().getBoundingClientRect(),_=k.node().getBoundingClientRect(),{top:w.top-_.top,left:w.left-_.left,width:w.width,bottom:w.bottom-_.top,height:w.height,right:w.right-_.left}),F=parseInt(S.height),B=parseInt(S.width),M=(t.clip()[1][0]-t.clip()[0][0])/105,Y=(t.clip()[1][1]-t.clip()[0][1])/68;t.rotate()&&(Y=(t.clip()[1][1]-t.clip()[0][1])/105,M=(t.clip()[1][0]-t.clip()[0][0])/68),E.attr("width",B*M).attr("height",F*Y).style("left",S.left+"px").style("top",S.top+"px");for(var X=m.createGridInterpolator(C,{extrapolate:!0,scaleX:t.rotate()?P/F:P/B,scaleY:t.rotate()?T/B:T/F,translateX:-.5,translateY:-.5}),D=E.node().getContext("2d"),R=D.createImageData(B,F),q=0,G=0;G<F;++G)for(var H=0;H<B;++H){var U;U=t.rotate()?X(F-G,H):X(H,G);var N=n.rgb(c(U||0));R.data[q+0]=N.r,R.data[q+1]=N.g,R.data[q+2]=N.b,R.data[q+3]=255,q+=4}D.putImageData(R,0,0)}}))}return v.colorScale=function(t){return arguments.length?(c=t,v):c},v.selected=function(t){return arguments.length?(o=t,v):o},v.enableInteraction=function(t){return arguments.length?(r=Boolean(t),v):r},v.showValues=function(t){return arguments.length?(p=Boolean(t),v):p},v.valueFormatter=function(t){return arguments.length?(h=t,v):h},v.valueFontSize=function(t){return arguments.length?(g=t,v):g},v.interpolate=function(t){return arguments.length?(f=Boolean(t),v):f},v.parent_el=function(t){return arguments.length?(b=t,v):b},v.onSelect=function(t){return l=t,v},v.onDeselect=function(t){return i=t,v},v},t.matchHeader=function(){var t="Premier League",r=void 0,n=void 0,a=[0,0];function o(o){o.each((function(){var o=e.select(this).append("g").attr("id","scoreboard").attr("class",".hed");o.append("svg:image").attr("xlink:href",r).attr("width",40).attr("x",0).attr("y",25),o.append("svg:image").attr("xlink:href",n).attr("width",40).attr("x",130).attr("y",25),o.append("text").attr("x",0).attr("y",5).attr("dominant-baseline","hanging").attr("font-size","16px").attr("fill","#333").text(t),o.append("text").attr("x",55).attr("y",55).attr("font-weight","bold").attr("font-size","32px").attr("fill","black").text("".concat(a[0]," : ").concat(a[1]))}))}return o.hed=function(e){return arguments.length?(t=e,o):t},o.logoHome=function(t){return arguments.length?(r=t,o):r},o.logoAway=function(t){return arguments.length?(n=t,o):n},o.score=function(t){return arguments.length?(a=t,o):a},o},t.pitch=function(){var t={top:0,right:u,bottom:d,left:0},n=300,a=!1,o=(-t.left+t.right)/(-t.top+t.bottom)*n,l=.5,i=!1,c=!1,s=p;function f(t){t.append("rect").attr("stroke-width",l).attr("fill","none").attr("x",-2).attr("y",30.34).attr("width",2).attr("height",7.32),t.append("rect").attr("stroke-width",l).attr("fill","none").attr("x",u).attr("y",30.34).attr("width",2).attr("height",7.32)}function p(t){t.append("rect").attr("stroke-width",0).attr("x",1.5*-l).attr("y",30.34).attr("width",3*l).attr("height",7.32),t.append("rect").attr("stroke-width",0).attr("x",u-1.5*l).attr("y",30.34).attr("width",3*l).attr("height",7.32)}function h(f){f.each((function(){var f=e.select(this).append("svg").attr("width",o).attr("height",n).attr("viewBox",(function(){var e,r,n,o,l=t.right-t.left,i=t.bottom-t.top;return a?(n=i===d?4:2,o=l===u?4:2,e=-t.left+t.right+o,r=-t.top+t.bottom+n):(n=i===d?4:2,o=l===u?4:2,r=-t.top+t.bottom+n,e=-t.left+t.right+o),"-2 -2 ".concat(e," ").concat(r)})).append("g").attr("class","pitch").attr("transform","translate(".concat(-t.left,", ").concat(-t.top,")rotate(").concat(a?-90:0," 0 0)translate(").concat(a?-105:0," 0)"));f.append("g").attr("class","below");var p=f.append("g").attr("class","lines").attr("stroke","#000").attr("fill","#000").attr("pointer-events","none");p.append("line").attr("stroke-width",l).attr("x1",52.5).attr("y1",0).attr("x2",52.5).attr("y2",d),p.append("circle").attr("stroke-width",l).attr("fill","none").attr("cx",52.5).attr("cy",34).attr("r",9.15),p.append("circle").attr("stroke-width",0).attr("cx",52.5).attr("cy",34).attr("r",l);var h=r.arc().innerRadius(9.15).outerRadius(9.15).startAngle(Math.PI/180*38).endAngle(Math.PI/180*142);p.append("path").attr("stroke-width",l).attr("d",h).attr("transform","translate(11,34)");var y=r.arc().innerRadius(9.15).outerRadius(9.15).startAngle(Math.PI/180*218).endAngle(Math.PI/180*322);p.append("path").attr("stroke-width",l).attr("d",y).attr("transform","translate(94,34)"),p.append("rect").attr("stroke-width",l).attr("fill","none").attr("x",0).attr("y",24.84).attr("width",5.5).attr("height",18.32),p.append("rect").attr("stroke-width",l).attr("fill","none").attr("x",99.5).attr("y",24.84).attr("width",5.5).attr("height",18.32),p.append("rect").attr("stroke-width",l).attr("fill","none").attr("x",0).attr("y",13.84).attr("width",16.5).attr("height",40.32),p.append("rect").attr("stroke-width",l).attr("fill","none").attr("x",88.5).attr("y",13.84).attr("width",16.5).attr("height",40.32),p.append("circle").attr("stroke-width",0).attr("cx",11).attr("cy",34).attr("r",l),p.append("circle").attr("stroke-width",0).attr("cx",94).attr("cy",34).attr("r",l),i&&p.append("polygon").attr("opacity",.1).attr("stroke-width",0).attr("class","shaded").attr("points","\n 25,".concat(32," \n 35,").concat(32," \n 35,").concat(29," \n 40,").concat(34," \n 35,").concat(39," \n 35,").concat(36," \n 25,").concat(36," \n 25,").concat(32,"\n ")),p.append("rect").attr("stroke-width",l).attr("fill","none").attr("x",0).attr("y",0).attr("width",u).attr("height",d),s(p),f.append("g").attr("class","above"),c&&p.append("rect").attr("opacity",.1).attr("class","shaded").attr("x",35).attr("y",0).attr("width",35).attr("height",d)}))}return h.height=function(e){return arguments.length?(n=+e,o=(-t.left+t.right)/(-t.top+t.bottom)*n,h):n},h.width=function(){return o},h.rotate=function(t){return arguments.length?(a=Boolean(t),h):a},h.showDirOfPlay=function(t){return arguments.length?(i=Boolean(t),h):i},h.shadeMiddleThird=function(t){return arguments.length?(c=Boolean(t),h):c},h.pitchStrokeWidth=function(t){return arguments.length?(l=+t,h):l},h.goals=function(t){return arguments.length?(s="box"===t?f:"line"===t?p:t,h):s},h.clip=function(e){return arguments.length?(t={top:e[0][1],bottom:e[1][1],left:e[0][0],right:e[1][0]},o=(-t.left+t.right)/(-t.top+t.bottom)*n,h):[[t.left,t.top],[t.right,t.bottom]]},h},t.rectbin=function(){var t=.1,e=.1,r=function(t){return t[0]},n=function(t){return t[1]};function a(t){return t<0?Math.ceil(t):Math.floor(t)}function o(l){for(var i={},c=[0,105],s=[0,68],u=s[0],d=0;u<s[1]-1e-4;u+=e,d++)for(var f=c[0],p=0;f<c[1]-1e-4;f+=t,p++){var h=i[p+"-"+d]=[];h.i=p,h.j=d,h.x=f,h.y=u,h.width=t,h.height=e,h.value=0}return l.forEach((function(l,c){var s=a(n.call(o,l,c)/e),u=a(r.call(o,l,c)/t),d=i[u+"-"+s];d&&(d.push(l),d.value+=1)})),Object.values(i)}return o.x=function(t){return arguments.length?(r=t,o):r},o.y=function(t){return arguments.length?(n=t,o):n},o.dx=function(e){return arguments.length?(t=e,o):t},o.dy=function(t){return arguments.length?(e=t,o):e},o},t.scoreline=function(){var t,r,n=23,a=170,o=[{label:"H",color:"#87CEEB"},{label:"A",color:"#FDB913"}],l=[0,0],i=0;function c(c){c.each((function(){var c=e.select(this),s=c.append("g");s.append("rect").attr("x",0).attr("y",0).attr("width",45).attr("height",n).attr("fill",o[0].color),s.append("text").text(o[0].label).attr("x",5).attr("y",n/2).attr("dominant-baseline","middle").attr("fill","white");var u=c.append("g").attr("transform","translate(".concat(85,", 0)"));u.append("rect").attr("x",0).attr("y",0).attr("width",51).attr("height",n).attr("fill",o[1].color),u.append("text").text(o[1].label).attr("x",5).attr("y",n/2).attr("dominant-baseline","middle").attr("fill","white"),c.append("text").attr("id","scoreline").text("".concat(l[0]," : ").concat(l[1])).attr("x",50).attr("y",n/2).attr("dominant-baseline","middle").attr("fill","black");var d=c.append("g");d.append("polyline").attr("points","".concat(130,",").concat(n/2,"\n ").concat(136,",0\n ").concat(a,",0\n ").concat(a,",").concat(n,"\n ").concat(136,",").concat(n)).attr("fill","white"),d.append("text").attr("id","clock").text("".concat(i,"'")).attr("x",145).attr("y",n/2).attr("dominant-baseline","middle").attr("fill","black"),c.append("rect").attr("x",0).attr("y",0).attr("width",a).attr("height",n).attr("fill","rgba(0,0,0,0)").attr("stroke","black").attr("stroke-width",.5),r=function(){c.select("#clock").text("".concat(i,"'"))},t=function(){c.select("#scoreline").text("".concat(l[0]," : ").concat(l[1]))}}))}return c.height=function(t){return arguments.length?(n=+t,c):n},c.teams=function(t){return arguments.length?(o=t,c):o},c.score=function(e){return arguments.length?(l=e,"function"==typeof t&&t(),c):l},c.clock=function(t){return arguments.length?(i=t,"function"==typeof r&&r(),c):i},c}}));