Create a table in SVG

Viewed 45381

I'm trying to create a table-like object within an SVG document. Currently, due to the fact that SVG does not have a table element, I am using an HTML parser to go through and convert an HTML table, (created by the user in an HTML table Builder), to a group of SVG objects, and then adding that to my overall SVG drawing. I was wondering if any one was able to find a better alternative to this method, such as an SVG table builder? I'm looking to accomplish this using Javascript or jquery. Any ideas or suggestions would be appreciated.

7 Answers

I had a similar need and was not able to find a suitable tool for automatically building an SVG image to display tabular data (the tools I could find via Google produced illegible or otherwise unusable results) so I built my own. You or anyone else who lands on this page while searching for such a tool may find it helpful:

https://topherrhodes.com/svg-table/

This tool uses a CSV as input, so if you have to go from an HTML table you could modify the script to convert the table to a JavaScript object, or generate a CSV as an intermediate step.

Generally, I agree with the other users here who have brought up how SVG is not a good format for displaying tabular data and that for usability and compatibility you should opt to use an actual HTML table whenever possible. But there may be certain cases where that's not possible.

Necromancing.
The trouble is, when you need a table that can have an indefinite amount of rows and columns, with an unknown and variable row-height, as well as texts unknown at compile-time, that needs to resize to fit into a container, and which should neither be clipped nor overflow.

Fortunately, I've found the solution !
It requires setting the viewBox at runtime with JavaScript, though.
Works in Firefox and Chrome.

<?xml version="1.0" standalone="yes"?>
<html>
    <head>
        <title>Evacuation Plan</title>
        
        <style type="text/css">
        /*<![CDATA[*/
            
            .A4 
            { 
                width: 21cm; 
                height: 29.7cm;
            } 
            
        /*]]>*/
        </style>
        
    </head>
    <body class="A4">
        <div id="positionRoot" style="position: relative;">
        
        <div id="sizerForTable" style="position: absolute; display: block; top: 2.5cm; left: 5cm; width: 2.5cm; height: 2.5cm; background-color: hotpink;">
            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 0 0" preserveAspectRatio="xMinYMin meet" width="100%" height="100%" >
              
              <rect id="rectBG" x="0" y="0" width="0" height="0" fill="#FF0000" />
              <foreignObject id="foTableContainer" x="0" y="0" width="100%" height="100%">
                <body xmlns="http://www.w3.org/1999/xhtml">
                  
                  <!--
                  <style type="text/css">
                  /*<![CDATA[*/
                        
                        .testTableLayout 
                        { 
                            font-size: 5px; 
                            line-height: 1em; 
                        } 
                        
                  /*]]>*/
                  </style>
                  -->
                  
                  <!-- also: Tabelle ausmessen - dies in Viewbox - dann verkleiners sich automatisch -->
                  
                  <table id="tblTest" class="testTableLayout" style="border-collapse: collapse; border: none;" cellpadding="0" cellspacing="0">
                    <tr style="background-color: orange;">
                        <td>Row1</td>
                        <td>C1.2</td>
                        <td>Test<br />Me<br />More</td>
                    </tr>
                    <tr>
                        <td>Row2</td>
                        <td>C2.2</td>
                        <td>Test<!--&nbsp;Me&nbsp;More--></td>
                    </tr>
                    <tr>
                        <td>Row3</td>
                        <td>C3.2</td>
                        <td>Test</td>
                    </tr>
                    
                    <tr>
                        <td>Row4</td>
                        <td>C4.2</td>
                        <td>Test</td>
                    </tr>
                    <tr>
                        <td>Row5</td>
                        <td>C5.2</td>
                        <td>Test</td>
                    </tr>
                    <!--
                    -->
                    
                  </table>
                  
                  <script type="text/javascript">
                    //<![CDATA[
                    
                    (function () {
                        
                        var tbl = document.getElementById("tblTest"); 
                        var bg = document.getElementById("rectBG"); 
                        var nvb = ["0", "0", Math.ceil(tbl.offsetWidth).toString(), Math.ceil(tbl.offsetHeight).toString()]; 
                        
                        bg.setAttribute("width", nvb[2]); 
                        bg.setAttribute("height", nvb[3]); 
                        document.getElementById("foTableContainer").ownerSVGElement.setAttribute("viewBox", nvb.join(" ") ); 
                        
                        // console.log("newViewBox:", nvb); 
                        // console.log("w,h:", tbl.offsetWidth, tbl.offsetHeight); 
                        // console.log(document.getElementById("foTableContainer").ownerSVGElement.getAttribute("viewBox")); 
                    })();
                    
                    //]]>
                  </script>
                  
                </body>
              </foreignObject>
            </svg>
        </div>
        </div>
    </body>
</html>
Related