1.0.6 • Public • Published

    Replay Table

    A library fo visualizing sport season results with interactive standings:


    Live Demos


    1. Prepare an input file with season results or download one from our examples.

    2. Put a div with replayTable class on your page and supply a link to the input file using data-source attribute:

      <div class="replayTable"
    3. Include D3.js and Replay Table scripts (70+16 KB gzipped) and the stylesheet. Apply some magic to the body:

          <script type="text/javascript" src=""></script>
          <script type="text/javascript" src=""></script>
          <link rel="stylesheet" type="text/css" href="">
          <script type="text/javascript">replayTable.magic()</script>
    4. Enjoy!

    The library is highly customizable via data- attributes. Check out customization for the details.

    Also feel free to embed ready-to-use Replay Tables from our gallery.


    npm install -S replay-table

    The only dependency is D3.js. D3 is not included with the library so don't forget to plug it up.

    The library consists of 5 modules: configure → extract → transform → calculate → visualize. Take a look at how we use them in the magic function:

    return Array.from(document.getElementsByClassName('replayTable'))
            .map(table => {
                const config = replayTable.configure(, table.dataset); //build a config from data- attributes
                return Promise.resolve(replayTable.extract(config.extract)) //fetch the input
                    .then(raw => {
                        const transformed = replayTable.transform(raw, config.transform); //transform into predefined format
                        const calculated = replayTable.calculate(transformed, config.calculate); //calculate wins, goals, etc.
                        return replayTable.visualize(calculated, config.visualize); //render interactive standings
                    .catch(error => crash(error));

    Sometimes you won't need all the modules: for example, feel free to omit configure if you already have a config.

    A Replay Table is returned from the visualize module. It has methods like play() and to(roundIndex) so you can control its behaviour from code.



    Makes configs for other modules based on the div data- attributes. The output looks like this:

    extract: {
        extractor: csv
    transform: {
        transformer: 'pointsTable',
        changeToOutcome: {
            25: 'win'
        insertStartRound: 'Start →'
    calculate: {
        orderBy: ['points', 'wins']
    visualize: {
        columns: ['position', 'item', 'points', 'points.change'],
        labels: ['#', 'Driver', 'Points']


    To save you some time and cognitive effort we've constructed presets that you can use via data-preset attribute: matches, f1, winLoss, chgk.

    So this table:

    <div class="replayTable"
        data-change-to-outcome="{ 1: 'win', 0: 'loss' }"
        data-labels="#,Team,G,W,L,Win %"

    is identical to this:

    <div class="replayTable"


    Fetches the input file, returns a promise.

    Parameter Attribute Required Accepts Default Examples
    source data-source yes string null /assets/data/football/2016-2017/english-premier-league.json
    extractor data-extractor no extractor csv csv, json

    If extractor is not defined we try to guess it from the file extension.


    Transforms raw data into the predefined format:

            name: 'round name',
            results: {
                        change: 25,
                        extras: {
                            item: {
                                team: 'Mercedes'
                        item: 'Lewis Hamilton',
                        outcome: 'win'
    Parameter Attribute Accepts Parses Default Examples
    transformer data-transformer transformer listOfMatches listOfMatches, pointsTable
    changeToOutcome data-change-to-outcome object JSON object { 3: 'win', 1: 'draw', 0: 'loss'} { 1: 'win', 0: 'loss'}
    filterItems data-filter-items array of strings comma-separated string [] ['Golden State Warriors', 'San Antonio Spurs', ...]
    insertStartRound data-insert-start-round string 0 Start

    List of Matches

    The structure looks like this:

    Round name First Item First Item Score Second Item Second Item Score
    Round Item Score Item Score

    List should be sorted by round.

    Here is an example:

    Match Week Home Points Away Points
    1 Bournemouth 0 Aston Villa 1
    1 Chelsea 2 Swansea 2
    1 Everton 2 Watford 2
    ... ... ... ... ...

    Also works with fixtures.

    Parameter Attribute Accepts Default Examples
    format data-format csv or csv csv,
    locationFirst data-location-first home or away home home, away
    collapseToRounds data-collapse-to-rounds boolean false true, false

    Use collapseToRounds when you've got dates instead of match weeks: it groups each team's 1st, 2nd, 3rd, ... games.

    Points Table

    The structure looks like this:

    Item name [1st extra column name] [2nd extra column name] [...] 1st round name 2nd round name ... last round name
    item [1st piece of extra info] [2nd piece of extra info] [...] 1st round points 2nd round points ... last round points

    The Formula One example (csv):

    Driver Team Australia Bahrain ... Abu Dhabi
    Lewis Hamilton Mercedes 18 15 ... 25
    Nico Rosberg Mercedes 25 25 ... 18
    Daniel Ricciardo Red Bull 12 12 ... 10
    ... ... .... ... ... ...

    Watch the live demo.

    Parameter Attribute Accepts Default Examples
    extraColumnsNumber data-extra-columns-number int 0 1, 2


    Calculates wins, goals, points, etc. and adds metadata. The output looks like this:

        meta: {
            lastRound: 38
        results: {
                    meta: {
                        index: 2,
                        isLast: false,
                        items: 20,
                        name: "2"
                    results: {
                                change: 3,
                                draws: {
                                    change: 0,
                                    total: 0
                                extras: {},
                                item: 'Leicester',
                                losses: {
                                    change: 0,
                                    total: 0
                                match: {
                                    location: "away",
                                    opponent: "West Ham",
                                    opponentScore: 1,
                                    score: 2
                                outcome: "win",
                                points: {
                                    change: 3,
                                    total: 6
                                position: {
                                    highest: 1,
                                    lowest: 4,
                                    strict: 1
                                wins: {
                                    change: 1,
                                    total: 2
                                ...//goalsFor, goalsAgainst, goalsDifference, rounds, winningPercentage

    See the whole list of calculations in the calculations.js.

    Parameter Attribute Accepts Parses Default Examples
    orderBy data-order-by array of calculations comma-separated string ['points'] ['winningPercentage', 'wins']


    Renders interactive standings out of calculated data.

    Returns a class instance with useful methods:

    • first(), last(), next(), previous() and to(roundIndex)
    • play() and pause()
    • preview(roundIndex) and endPreview()
    • drillDown(item) and endDrillDown()
    Parameter Attribute Accepts Parses Default Examples
    visualizer data-visualizer visualizer classic classic, sparklines
    controls data-conrols array of controls comma-separated string ['play', 'previous', 'next', 'slider'] ['play', 'slider']
    startFromRound data-start-from-round int null 0, 15
    roundsTotalNumber data-rounds-total-number int null 38, 82
    positionWhenTied data-position-when-tied int strict, highest, range or average strict, highest
    animationSpeed data-animation-speed float 1.0 0.5, 2.0



    Formula One

    A simple table with controls on top. Works for any sport and is highly customizable.

    Parameter Attribute Accepts Parses Default Examples
    columns data-columns array of columns comma-separated string ['position', 'item', 'points'] ['position', 'item', 'points', 'outcome', 'points.change]
    labels data-labels array of strings comma-separated string ['#', 'Team', 'Points'] ['Position', 'Driver', 'Points']
    colors data-colors object JSON object { 'win': '#ACE680', 'draw': '#B3B3B3', 'loss': '#E68080' } { 'win': 'green', 'draw': 'gray', 'loss': 'red' }
    durations data-durations object JSON object { move: 750, freeze: 750, outcomes: 200} { move: 500, freeze: 400, outcomes: 250}



    English Premier League

    A powerful interactive visualization for the sports with matches and points. Might be slow on old devices and in Firefox.

    Parameter Attribute Accepts Parses Default Examples
    controls data-conrols array of controls comma-separated string ['play'] ['play', 'previous', 'next']
    colors data-colors object JSON object { 'win': '#21c114', 'draw': '#828282', 'loss': '#e63131' } { 'win': 'green', 'draw': 'gray', 'loss': 'red' }
    sparkColors data-spark-colors object JSON object { 'win': '#D7E7C1', 'draw': '#F0F0F0', 'loss': '#EFCEBA' } { 'win': 'green', 'draw': 'gray', 'loss': 'red' }
    currentSparkColors data-current-spark-colors object JSON object { 'win': '#AAD579', 'draw': '#CCCCCC', 'loss': '#E89B77' } { 'win': 'green', 'draw': 'gray', 'loss': 'red' }
    durations data-durations object JSON object { move: 1000, freeze: 500, pre: 750} { move: 750, freeze: 750, pre: 375}
    pointsLabel data-points-label string points очков
    allLabel data-all-label string All Все


    Please, post your suggestions and bugs via Github issues. PRs are also welcome!

    If you own an API or a database with sports results we'd be happy to collaborate.

    We'd also be happy to work with sport journalists to leverage Replay Table for a better season recap.


    The library was built using the orange time at Targetprocess by Anton Iokov (@antoniokov) and Daria Krupenkina (@dariak).

    Sparklines prototype was made by Vitali Yanusheuski.


    We're open to your ideas and are ready to help with integrating Replay Table into your website.

    Please, write us an email to or ping on Twitter at @antoniokov.


    npm i replay-table

    DownloadsWeekly Downloads






    Last publish


    • antoniokov