【问题标题】:Create a table in SVG在 SVG 中创建表格
【发布时间】:2011-10-22 15:42:13
【问题描述】:

我正在尝试在 SVG 文档中创建一个类似表格的对象。目前,由于 SVG 没有表格元素,我正在使用 HTML 解析器将 HTML 表格(由用户在 HTML 表格生成器中创建)转换为一组 SVG 对象,以及然后将其添加到我的整体 SVG 绘图中。我想知道是否有人能够找到这种方法的更好替代方法,例如 SVG 表生成器?我希望使用 Javascript 或 jquery 来完成此操作。任何想法或建议将不胜感激。

【问题讨论】:

    标签: javascript jquery dom svg


    【解决方案1】:

    我只想在我的 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>
    

    【讨论】:

    • 另一种变体是在普通表格上覆盖一个 svg 元素,例如如果您只想在单元格上绘制箭头。这样您就可以将 svg 与表格结合起来,而无需使用外来对象。但原来的问题还是一个好问题,我今天的用例是我想把一个表格带进inkscape中,用在更大的图表中。
    • chrome 对 ForeignObject 的支持真的很不稳定。这是一个耻辱。因此,我不得不求助于使用原生 svg 元素来实现很多事情。对于初学者来说,有一些渲染错误。如果您在其周围拖动异物,则会留下阴影,这些阴影会在页面滚动后消失,但会分散核心的注意力。 SVG 变换不适用于 chrome 中的外来对象元素。不过,Firefox 并非如此。
    • 任何ie版本都不支持外来对象。最近遇到了同样的问题。研究使用 group (g)、text 和 tspand 替代方案。
    • foreignobject 应拼写为foreignObject
    • @Shane 谢谢。我很惊讶不正确的外壳在这个答案中存在了近 5 年。 :)
    【解决方案2】:

    你可以这样使用:

    SVG 中没有“table”类型的元素,但您可以使用“text”和“tspan”元素实现类似的视觉和交互效果。左边是 2 个这样的表格表示,顶部的表格采用列式布局(即用户可以选择一列中的所有文本),底部的表格采用基于行的布局。这种方法的一个明显缺点是您无法创建同时具有垂直和水平选择性的表。一个不太明显的缺陷是,创建表格外观并不能赋予真实表格的语义品质,这不利于可访问性,也不利于丰富的交互性和导航

    例子:

    <?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>
    

    来源:http://svg-whiz.com/svg/table.svg

    【讨论】:

    • 我很惊讶没有人编写使用 svg.g 对象生成表格的 JavaScript/D3 插件?
    • 这样构造的 SVG 表格与以纯 HTML 构造的 之间的一个主要区别在于,该 SVG 表格是面向列的,而 HTML 表格是面向行的。
    • @TheRedPea:在链接页面上,您还可以看到面向行的变体。
    • Mozilla 很好地引用了https://developer.mozilla.org/en-US/docs/Web/SVG/Element/tspan 的 tspan 元素。
    【解决方案3】:

    我只是想为后代添加我的想法。那里有很多相当复杂的选项,但如果你只是想要一个看起来像桌子的东西,这可能会让你开始......

    //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.
    

    这显然很粗略,但可能会让你走上正确的道路。

    【讨论】:

      【解决方案4】:

      我也有类似的需求,但找不到合适的工具来自动构建 SVG 图像以显示表格数据(我可以通过 Google 找到的工具产生难以辨认或无法使用的结果),所以我自己构建了。您或在搜索此类工具时登陆此页面的任何其他人可能会发现它很有帮助:

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

      此工具使用 CSV 作为输入,因此如果您必须从 HTML 表格中转出,您可以修改脚本以将表格转换为 JavaScript 对象,或生成 CSV 作为中间步骤。

      一般来说,我同意这里其他用户的观点,他们提出 SVG 不是显示表格数据的好格式,并且为了可用性和兼容性,您应该尽可能选择使用实际的 HTML 表格。但在某些情况下,这是不可能的。

      【讨论】:

        【解决方案5】:

        我在 github 上找到了一个项目,它可以从 JavaScript 数据结构自动生成一个类似 HTML 的表格:https://github.com/cocuh/SVG-Table

        由于不依赖foreignObject,跨浏览器的可移植性要好很多。

        【讨论】:

        • 自述文件中的引用:已弃用:强烈建议不要使用此库
        • 这已于 2019 年 9 月 7 日弃用。感谢您提醒人们,我会考虑如何更新答案,但随着最近 Stackoverflow 领导层的变化,您在这里做出贡献的愿望要低得多。
        【解决方案6】:

        这是一个示例,显示了一个 SVG foreignobject,其中包含嵌套 SVG 元素的表格布局。不过它只适用于 Chrome。

        它包括一个 HTML table 布局和一个使用 div 元素的 flexbox 布局。

        jsfiddle 是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>
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2015-03-09
          • 2017-05-03
          • 2013-06-18
          • 2017-02-19
          • 2015-05-27
          • 2015-01-31
          • 2014-11-17
          • 2011-10-08
          相关资源
          最近更新 更多