Créer une table en SVG

J'essaie de créer un objet semblable à un tableau dans un document SVG. Actuellement, en raison du fait que SVG n'a pas d'élément de table, j'utilise un analyseur HTML pour passer et convertir une table HTML (créée par l'utilisateur dans un générateur de table HTML), à un groupe d'objets SVG et Puis en ajoutant cela à mon dessin SVG global. Je me demandais si quelqu'un pouvait trouver une meilleure alternative à cette méthode, comme un générateur de table SVG? Je cherche à accomplir ceci en utilisant Javascript ou jquery. Toutes les idées ou suggestions seront appréciées.

Je voudrais simplement intégrer une vraie table dans mon 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> 

U peut utiliser de cette façon:

Il n'y a pas d'éléments de type «table» dans SVG, mais vous pouvez réaliser un effet visuel et interactif similaire à l'aide des éléments «texte» et «tspan». Sur la gauche, il y a 2 représentations tabulaires de ce type, la première avec une disposition en colonne (c'est-à-dire que l'utilisateur peut sélectionner tout le texte dans une colonne) et la table inférieure avec une disposition en ligne. Un inconvénient évident de cette approche est que vous ne pouvez pas créer une table avec une sélectivité verticale et horizontale. Un défaut moins évident est que créer une apparence tabulaire ne confère pas les qualités sémantiques d'une table réelle, ce qui est désavantageux pour l'accessibilité et n'est pas propice à une interactivité et une navigation riches

Exemple:

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

Voici un exemple montrant un objet étranger SVG qui contient une disposition tabulaire d'éléments SVG imbriqués. Cela fonctionne uniquement avec Chrome.

Il comprend une disposition de table HTML et une mise en page Flexbox utilisant des éléments div.

Un jsfiddle est ici .

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

J'ai trouvé un projet sur github qui génère automatiquement une table de type HTML à partir d'une structure de données JavaScript: https://github.com/cocuh/SVG-Table

Comme il ne repose pas sur ForeignObject, sa portabilité à travers les navigateurs est bien meilleure.

Je voulais simplement ajouter mes réflexions à ce sujet pour la postérité. Il y a beaucoup d'options assez compliquées là-bas, mais si vous voulez juste quelque chose qui ressemble à une table, cela pourrait vous faire démarrer …

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

C'est évidemment brutal mais pourrait vous faire démarrer sur la bonne voie.