Javascript 在 SVG 中创建表格
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6987005/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Create a table in SVG
提问by Jlange
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.
我正在尝试在 SVG 文档中创建一个类似表格的对象。目前,由于 SVG 没有 table 元素,我使用 HTML 解析器将 HTML 表(由用户在 HTML 表生成器中创建)转换为一组 SVG 对象,并且然后将其添加到我的整体 SVG 绘图中。我想知道是否有人能够找到这种方法的更好替代方法,例如 SVG 表构建器?我希望使用 Javascript 或 jquery 来完成此操作。任何想法或建议将不胜感激。
回答by Phrogz
I would simply embed a real table in my SVG:
我会简单地在我的 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>
回答by Hymansonfdam
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
SVG 中没有“表格”类型的元素,但您可以使用“文本”和“tspan”元素实现类似的视觉和交互效果。左边是 2 个这样的表格表示,顶部是柱状布局(即用户可以选择一列中的所有文本),底部是基于行的布局。这种方法的一个明显缺点是您不能创建具有垂直和水平选择性的表。一个不太明显的缺陷是,创建表格外观并不能赋予真实表格的语义品质,不利于可访问性,不利于丰富的交互性和导航性
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>
回答by jperry1147
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 lookslike 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.
这显然很粗糙,但可能会让您走上正轨。
回答by John Zabroski
I found a project on github which automatically generates an HTML-like table from a JavaScript data structure: https://github.com/cocuh/SVG-Table
我在 github 上找到了一个项目,它可以从 JavaScript 数据结构自动生成一个类似 HTML 的表格:https: //github.com/cocuh/SVG-Table
Since it does not rely on foreignObject, it's portability across browsers is much better.
由于它不依赖于foreignObject,因此跨浏览器的可移植性要好得多。
回答by Ed Evans
Here is an example showing an SVG foreignobjectwhich contains a tabular layout of nested SVG elements. It only works in Chrome though.
这是一个显示 SVG外来对象的示例,其中包含嵌套 SVG 元素的表格布局。不过它只适用于 Chrome。
It includes an HTML tablelayout and a flexboxlayout using div elements.
它包括一个 HTML表格布局和一个使用 div 元素的flexbox布局。
A jsfiddle is here.
一个 jsfiddle 在这里。
<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>