Search code examples
javascripthtmlhtml-table

How to draw arrow in HTML table across cells?


I have a simple html table with some cells which I create with the td tag. Now I need to draw an arrow from cell A2 to C2 for example. I thought about creating a jQuery function to get the XY coordinates of the middle of cell A2 and C2 and then somehow draw an arrow.

What is a good way of achieving the look and feel as shown in the picture?

Table cells with arrow


Solution

  • You can do this dynamically by using a canvas element to contain your arrow, which you will dynamically draw via the 2D context drawing functions. You can absolutely position the canvas element using javascript.

    Here is sample code:

    HTML:

    <canvas id="canvas" width="100" height="100">
    </canvas>
    
    
    
     <table>
     <tr><td>1</td><td>2</td></tr>
     <tr><td>3</td><td>4</td></tr>
     <tr><td>5</td><td>6</td></tr>
     </table>
    

    Javascript:

     var canvas = document.querySelector('canvas');
     var ctx = canvas.getContext('2d');
    
     canvas.style.top = 7 + "px";
     canvas.style.left = 7 + "px";
    
     var fromx = 0;
     var fromy = 12;
     var tox = 25;
     var toy = 12;
    
     var headlen = 10;   // length of head in pixels
     var angle = Math.atan2(toy-fromy,tox-fromx);
     var arrowSize = 2;
     var headlen = 10;
    
     var angle = Math.atan2(toy-fromy,tox-fromx);
     //starting path of the arrow from the start square to the end square and drawing the stroke
     ctx.beginPath();
    ctx.moveTo(fromx, fromy);
     ctx.lineTo(tox, toy);
     ctx.strokeStyle = "#cc0000";
     ctx.lineWidth = arrowSize;
     ctx.stroke();
    
     //starting a new path from the head of the arrow to one of the sides of the point
     ctx.beginPath();
     ctx.moveTo(tox, toy);
     ctx.lineTo(tox-headlen*Math.cos(angle-Math.PI/7),toy-headlen*Math.sin(angle-Math.PI/7));
    
     //path from the side point of the arrow, to the other side point
     ctx.lineTo(tox-headlen*Math.cos(angle+Math.PI/7),toy-headlen*Math.sin(angle+Math.PI/7));
    
     //path from the side point back to the tip of the arrow, and then again to the opposite side point
     ctx.lineTo(tox, toy);
     ctx.lineTo(tox-headlen*Math.cos(angle-Math.PI/7),toy-headlen*Math.sin(angle-Math.PI/7));
    
     //draws the paths created above
     ctx.strokeStyle = "#cc0000";
     ctx.lineWidth = arrowSize;
     ctx.stroke();
     ctx.fillStyle = "#cc0000";
     ctx.fill();
    

    CSS:

     #canvas {
            position: absolute;
            top: 0px;
            left: 0px;
            width: 100px;
            height: 100px;
     }
    

    You can programmatically obtain the positioning information of your table elements in order to set the correct values for fromx, fromy, etc., and for setting canvas.style.top and canvas.style.left.

    I borrowed the arrow drawing code from Draw arrow on canvas tag