JSFiddle - React, Tailwind, and code Playground

HTML

<div id="ctr">
    <div id="left">
        <canvas height="729" width="729" style="height: 729px; width: 729px;" id="c"></canvas>
    </div>
    <div id="right">
        <table>
            <thead>
                <tr>
                    <th>X</th>
                    <th>Y</th>
                    <th>Color</th>
                    <th>Delete</th>
                </tr>
            </thead>
            <tbody id="candidates-ctr">
            </tbody>
        </table>
        <div>
            <button id="add-candidate">Add Candidate</button>
        </div>
        <div>
            <button id="run-sim">Run Sim</button>
        </div>
        <div>
            <button id="stop-sim">Stop Sim</button>
        </div>
        <div>
            <label for="depth-ipt">Depth</label>
            <input type="number" min="1" max="6" id="depth-ipt" value="5" />
        </div>
        <div>
            <label for="nvoters-ipt">Num Voters</label>
            <input type="number" min="1" max="1000000" id="nvoters-ipt" value="10000" />
        </div>
        <div>
            <label for="sigma-ipt">Standard Deviation of Voter Position</label>
            <input type="number" min="0" max="10" step="0.001" id="sigma-ipt" value="0.5" />
        </div>
    </div>
</div>

CSS

#ctr {
    position: relative;
}

#left {
    position: absolute;
    left: 0%;
    width: 50%;
}

#right {
    position: absolute;
    left: 50%;
    width: 50%;
}

table {
    width: 100%;
    border-collapse: collapse;
}

td,
th {
    border: 1px solid black;
}

JavaScript

var canvas, context, candidates, queue, job, depth, nVoters, sigma;

function addCandidateRow(candidates, i) {
    var candidate = candidates[i];
    var ctr = document.getElementById('candidates-ctr');

    var row = document.createElement('tr');

    var xCtr = document.createElement('td');
    var xIpt = document.createElement('input');
    xIpt.setAttribute('type', 'number');
    xIpt.setAttribute('step', '0.01');
    xIpt.setAttribute('min', '-0.25');
    xIpt.setAttribute('max', '0.25');
    xIpt.setAttribute('value', candidate[0]);
    xIpt.addEventListener('change', e => candidate[0] = parseFloat(e.target.value));

    var yCtr = document.createElement('td');
    var yIpt = document.createElement('input');
    yIpt.setAttribute('type', 'number');
    yIpt.setAttribute('step', '0.01');
    yIpt.setAttribute('min', '-0.25');
    yIpt.setAttribute('max', '0.25');
    yIpt.setAttribute('value', candidate[1]);
    yIpt.addEventListener('change', e => candidate[1] = parseFloat(e.target.value));

    var colorCtr = document.createElement('td');
    var colorIpt = document.createElement('input');
    colorIpt.setAttribute('type', 'color');
    colorIpt.setAttribute('value', candidate[2]);
    colorIpt.addEventListener('change', e => candidate[2] = e.target.value);

    var delCtr = document.createElement('td');
    var delBtn = document.createElement('button');
    delBtn.textContent = 'Delete';
    delBtn.addEventListener('click', e => {
        candidates.splice(i, 1);
        ctr.removeChild(row);
    });

    xCtr.appendChild(xIpt);
    yCtr.appendChild(yIpt);
    colorCtr.appendChild(colorIpt);
    delCtr.appendChild(delBtn);

    row.appendChild(xCtr);
    row.appendChild(yCtr);
    row.appendChild(colorCtr);
    row.appendChild(delCtr);

    ctr.appendChild(row);
}

function fillCell(resolution, x, y, color) {
    context.fillStyle = color;
    var size = 729 / (3 ** resolution);
    var tileX = Math.floor(x * 3 ** resolution) * size;
    var tileY =...