Я пытаюсь создать подобный таблицам объект в документе SVG. В настоящее время из-за того, что SVG не имеет элемента таблицы, я использую HTML-парсер для просмотра и преобразования HTML-таблицы (созданной пользователем в HTML-Builder Builder) в группу объектов SVG и затем добавив это в мой общий рисунок SVG. Мне было интересно, сможет ли кто-нибудь найти лучшую альтернативу этому методу, например, построитель таблицы SVG? Я ищу для этого, используя Javascript или jquery. Любые идеи или предложения будут оценены.
Создание таблицы в 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>
Ответ 2
U может использовать этот способ:
В SVG нет элементов типа "table", но вы можете добиться аналогичного визуального и интерактивного эффекта, используя элементы "text" и "tspan". Слева находятся два таких табличных представления, верхний с колоночной макетой (то есть пользователь может выбрать весь текст в столбце), а нижнюю таблицу - с раскладкой на основе строк. Очевидным недостатком такого подхода является то, что вы не можете создать таблицу с вертикальной и горизонтальной селективностью. Менее очевидным недостатком является то, что создание табличного внешнего вида не дает семантических качеств реальной таблицы, что является невыгодным для доступности и не способствует насыщенной интерактивности и навигации.
Пример:
<?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
Ответ 3
Вот пример, показывающий SVG foreignobject, который содержит табличное расположение вложенных элементов SVG. Он работает только в Chrome.
Он включает HTML таблицу и flexbox с использованием элементов div.
A 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>
Ответ 4
Я нашел проект github, который автоматически генерирует HTML-подобную таблицу из структуры данных JavaScript: https://github.com/cocuh/SVG-Table
Поскольку он не полагается на foreignObject, его переносимость между браузерами намного лучше.
Ответ 5
Я просто хотел добавить свои мысли об этом для потомков. Есть много довольно сложных опций, но если вы просто хотите что-то похожее на таблицу, это может заставить вас начать...
//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 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.
Это явно грубо, но может привести к тому, что вы начнете с нужной дорожки.