Single data table on chart

by stitot

HTML

<script src="https://github.highcharts.com/10a37be8ce/highcharts.js?esbuild"></script>
<script src="https://github.highcharts.com/10a37be8ce/grid/grid-pro.js?esbuild"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@highcharts/grid-pro/css/grid-pro.css" />

<h1>Chart and Grid with shared DataTable</h1>
<div class="outer-container">
    <div id="chart-container"></div>
    <div id="grid-container"></div>
</div>

<div class="button-row">
    <button id="addrow" class="highcharts-demo-button">Add row</button>
    <button id="updaterow" class="highcharts-demo-button">Update row</button>
    <button id="deleterow" class="highcharts-demo-button">Delete row</button>
    <button id="setcolumn" class="highcharts-demo-button">Set column</button>
</div>

CSS

* {
    font-family: Helvetica, Arial, sans-serif;
}

h1 {
    display: block;
    max-width: 1000px;
    text-align: center;
    font-size: 1.5rem;
    margin: 1rem auto;
}

.outer-container {
    max-width: 1000px;
    display: flex;
    margin: 0 auto;
}

#chart-container {
    height: 400px;
    width: 50%;
    margin: 10px;
}

#grid-container {
    width: 50%;
    margin: 10px;
}

.button-row {
    max-width: 1000px;
    margin: 0 auto;
}

.highcharts-demo-button {
    background: #f2f2f2;
    border: none;
    border-radius: 4px;
    cursor: pointer;
    display: inline-block;
    font-size: 0.8rem;
    padding: 0.5rem 1.5rem;
    margin: 0.5rem -5px 0.5rem 10px;
    transition: background 250ms;
}

@media screen and (max-width: 600px) {
    .outer-container {
        display: block;
    }

    #chart-container,
    #grid-container {
        margin: 10px auto;
        width: 95%;
    }
}

JavaScript

// Define the common data table
const dataTable = new Grid.DataTable({
    columns: {
        year: [2020, 2021, 2022, 2023],
        cost: [11, 13, 12, 14],
        revenue: [12, 15, 14, 18]
    }
});

// Create the chart
Highcharts.chart('chart-container', {
    dataTable,
    chart: {
        type: 'column'
    },
    title: {
        text: ''
    },
    series: [{
        name: 'Cost',
        dataMapping: {
            x: {
                column: 'year'
            },
            y: {
                column: 'cost'
            }
        }
    }, {
        name: 'Revenue',
        dataMapping: {
            x: {
                column: 'year'
            },
            y: {
                column: 'revenue'
            }
        }
    }]
});

// Create the grid
Grid.grid('grid-container', {
    data: {
        dataTable,
        updateOnChange: true
    },
    columnDefaults: {
        cells: {
            editMode: {
                enabled: true
            }
        }
    },
    columns: [{
        id: 'year',
        cells: {
            // No thousands separator
            format: '{value}'
        }
    }],
    rendering: {
        rows: {
            virtualization: true
        }
    }
});

document.getElementById('addrow').addEventListener('click', e => {
    dataTable.setRow({
        year: 2024,
        cost: 15,
        revenue: 20
    });
    e.target.disabled = true;
});

document.getElementById('updaterow').addEventListener('click', () => {
    dataTable.setRow({
        cost: Math.round(15 * Math.random()),
        revenue: Math.round(10 * Math.random())
    }, 1);
});

document.getElementById('deleterow').addEventListener('click', e => {
    dataTable.deleteRows(0);
    e.target.disabled = true;
});

document.getElementById('setcolumn').addEventListener('click', () => {
    dataTable.setColumn(
        'revenue',
       ...