Create a table in SVG

后端 未结 5 562
甜味超标
甜味超标 2020-12-03 01:11

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

相关标签:
5条回答
  • 2020-12-03 01:44

    Here is an example showing an SVG foreignobject which contains a tabular layout of nested SVG elements. It only works in Chrome though.

    It includes an HTML table layout and a flexbox layout using div elements.

    A jsfiddle is here.

    <body>
    <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
        <defs>
            <g id="shape">
                <rect x="0" y="0" rx="5" ry="5" width="100%" height="100%" fill="inherit" />
                <circle cx="50%" cy="50%" r="8" fill="yellow" />
            </g>
        </defs>
        <foreignobject width="100%" height="50px" y="0">
    
            <body xmlns="http://www.w3.org/1999/xhtml">
                <table width="100%">
                    <tr>
                        <td colspan="3">
                            <div style="height:20px">
                                <svg>
                                    <use xlink:href="#shape" fill="CornflowerBlue" />
                                </svg>
                            </div>
                        </td>
                    </tr>
                    <tr>
                        <td>
                            <div style="height:20px">
                                <svg>
                                    <use xlink:href="#shape" fill="SlateBlue" />
                                </svg>
                            </div>
                        </td>
                        <td>
                            <div style="height:20px">
                                <svg>
                                    <use xlink:href="#shape" fill="SlateBlue" />
                                </svg>
                            </div>
                        </td>
                        <td>
                            <div style="height:20px">
                                <svg>
                                    <use xlink:href="#shape" fill="SlateBlue" />
                                </svg>
                            </div>
                        </td>
                    </tr>
                </table>
            </body>
        </foreignobject>
        <foreignobject width="100%" height="50px" y="60">
    
            <body xmlns="http://www.w3.org/1999/xhtml">
                <div style="display:flex;flex-direction:column">
                    <div>
                        <div style="height:20px;padding:2px">
                            <svg>
                                <use xlink:href="#shape" fill="orange" />
                            </svg>
                        </div>
                    </div>
                    <div style="display:flex;flex-direction:row;align-items:stretch">
                        <div style="width:33.333%;height:20px;padding:2px">
                            <svg>
                                <use xlink:href="#shape" fill="forestgreen" />
                            </svg>
                        </div>
                        <div style="width:33.333%;height:20px;padding:2px">
                            <svg>
                                <use xlink:href="#shape" fill="forestgreen" />
                            </svg>
                        </div>
                        <div style="width:33.333%;height:20px;padding:2px">
                            <svg>
                                <use xlink:href="#shape" fill="forestgreen" />
                            </svg>
                        </div>
                    </div>
                </div>
            </body>
        </foreignobject>
    </svg>
    

    0 讨论(0)
  • 2020-12-03 01:47

    I would simply embed a real table in my SVG:

    <?xml version="1.0" standalone="yes"?>
    <svg xmlns="http://www.w3.org/2000/svg">
      <foreignObject x="10" y="10" width="100" height="150">
        <body xmlns="http://www.w3.org/1999/xhtml">
          <table><!-- ... --></table>
        </body>
      </foreignObject>
      <!-- ... -->
    </svg>
    
    0 讨论(0)
  • 2020-12-03 01:48

    I just wanted to add my thoughts on this for posterity. There are a lot of fairly complicated options out there but if you just want something which looks like a table, this might get you started...

    //assuming you have a table with an ID of src_table
    var my_svg = '<svg xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" id="svg_table" width="'+$("#src_table").width()+'px" height="'+$("#src_table").height()+'px">'
    var table_offset = $('#src_table').offset();
    $('#src_table').find('td').each(function() {
            //Add a rectangle for each <td> in the same place in SVG as the <td> is in relation to the top left of where the table is on page
            my_svg += '<rect x="'+(this_offset.left - table_offset.left)+'" y="'+(this_offset.top - table_offset.top)+'" width="'+$(this).width()+'" height="'+$(this).height()+'" stroke="black" stroke-width="'+$(this).css('border-width').replace('px','')+'"/>';
    
           //Text is assumed to be in a <p> tag. If it's not, just use the .html() of the <td> element
           (this).children('p').each(function(){
                    t_offset = $(this).offset();
                    var this_text = '<text x="'+(t_offset.left - table_offset.left)+'" y="'+(t_offset.top - table_offset.top)+'"  style="font-size:'+$(this).css('font-size')+'; fill: #ffffff">';
                        // Look for <br> tags and split them onto new lines.
                        var this_lines = $(this).html().split('<br>');
                        for(var i=0;i<this_lines.length;i++){
                            this_text += '<tspan x="'+(t_offset.left - table_offset.left)+'" dy="'+$(this).css('font-size')+'">'+this_lines[i]+'</tspan>';
                        }
                this_text += '</text>';
                my_svg +=  this_text;
            })
        }
    });
    my_svg += '</svg>';
    
    //Either append my_svg to a div or pass the code onto whatever else you need to do with it.
    

    This is obviously rough but might get you started down the right track.

    0 讨论(0)
  • 2020-12-03 01:53

    I found a project on github which automatically generates an HTML-like table from a JavaScript data structure: https://github.com/cocuh/SVG-Table

    Since it does not rely on foreignObject, it's portability across browsers is much better.

    0 讨论(0)
  • 2020-12-03 02:03

    U can use this way:

    There are no 'table'-type elements in SVG, but you can achieve a similar visual and interactive effect using the 'text' and 'tspan' elements. On the left are 2 such tabular representations, the top one with columnar layout (that is, the user can select all the text in a column), and the bottom table with row- based layout. An obvious disadvantage to this approach is that you cannot create a table with both vertical and horizontal selectivity. A less obvious flaw is that creating a tabular appearance does not confer the semantic qualities of a real table, which is disadvantageous to accessibility and is not conducive to rich interactivity and navigation

    Example:

    <?xml version='1.0' standalone='no'?>
    <!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN'
      'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'>
    <svg width='100%' height='100%' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'>
    
       <title>SVG Table</title>
    
       <g id='columnGroup'>
          <rect x='65' y='10' width='75' height='110' fill='gainsboro'/>
          <rect x='265' y='10' width='75' height='110' fill='gainsboro'/>
    
          <text x='30' y='30' font-size='18px' font-weight='bold' fill='crimson'>
             <tspan x='30' dy='1.5em'>Q1</tspan>
             <tspan x='30' dy='1em'>Q2</tspan>
             <tspan x='30' dy='1em'>Q3</tspan>
             <tspan x='30' dy='1em'>Q4</tspan>
          </text>
    
          <text x='100' y='30' font-size='18px' text-anchor='middle'>
             <tspan x='100' font-weight='bold' fill='crimson'>Sales</tspan>
             <tspan x='100' dy='1.5em'>$ 223</tspan>
             <tspan x='100' dy='1em'>$ 183</tspan>
             <tspan x='100' dy='1em'>$ 277</tspan>
             <tspan x='100' dy='1em'>$ 402</tspan>
          </text>
    
          <text x='200' y='30' font-size='18px' text-anchor='middle'>
             <tspan x='200' font-weight='bold' fill='crimson'>Expenses</tspan>
             <tspan x='200' dy='1.5em'>$ 195</tspan>
             <tspan x='200' dy='1em'>$ 70</tspan>
             <tspan x='200' dy='1em'>$ 88</tspan>
             <tspan x='200' dy='1em'>$ 133</tspan>
          </text>
    
          <text x='300' y='30' font-size='18px' text-anchor='middle'>
             <tspan x='300' font-weight='bold' fill='crimson'>Net</tspan>
             <tspan x='300' dy='1.5em'>$ 28</tspan>
             <tspan x='300' dy='1em'>$ 113</tspan>
             <tspan x='300' dy='1em'>$ 189</tspan>
             <tspan x='300' dy='1em'>$ 269</tspan>
          </text>
       </g>
    </svg>
    

    Source: http://svg-whiz.com/svg/table.svg

    0 讨论(0)
提交回复
热议问题