Brno? Vypsali jsme pro vás nové termíny školení OOP v Brně!

Diskuze: Rendrování SVG po přidání nového prvku pomocí JS

Aktivity (2)
Avatar
Pavol Hejný
Autoredaktor
Avatar
Pavol Hejný:10. února 16:26

Mám na stránce SVG a potřebuji do něj přidávat nové prvky za běhu. Problém je, že po přidání nového prvku se daný prvek nevyrendruje.

Konkrétní příklad:

$('#svg').append($(`
    <g transform="translate(4,4)">
        <rect width="30" height="30" x="0" y="0" style="fill: #E42C1A; stroke: #1A6AA3;"></rect>
    </g>
`));

Pokud aktualizuju už existující prvky (např. měním transform.translate nad SVG>G), vše funguje.

Neumím přijít na to, zda dělám něco špatně já, nebo zda jde o nějakou něšťastnou optimalizaci SVG rendrování.

Funguje mi hack, kdy vynutím přerendrování natvrdo, ale to je z hlediska paměti docela prasárna:

$('#svg').html($('#svg').html());

PS: Používám zde jQuery, ale to je irelevantní, při použití čistého DOMu je chování identické.
PPS: Firefox, Chrome i Edge se chovají stejně.

Editováno 10. února 16:27
Odpovědět 10. února 16:26
/^(web )?(app )?developer$/
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:11. února 8:24

Hlavne je dobre nedat zadny kod k testovani, ze? :)

Zhlediska JS, prvek s id #svg je totez jako prvek s id #123.
U jquery vubec netusim, co ti to udela, ale append dela js appendChild, ne? To je uspornejsi nez innerHTML. Ale asi u svg to tak uplne nefunguje. Tam bys musel asi vyvolat nejake redraw podobne jako u canvasu.

Cili, bud bych to resil tak, ze do divu (#canvas) pridam novy svg element s kodem. (needituji jako ty uz vyvoreny)
Nebo bych si kod svg ukladal do promene bokem a vykresloval pres html(str)

Tady asi resi neco podobneho.
https://stackoverflow.com/…s-for-redraw

<button id="update">Update</id>
<script>
var svg = d3.selectAll("body").append("svg");
svg.append("circle").attr("cx",20).attr("cy",20).attr("r",20).style("fill","red");

d3.select("#update")
    .on("click",update);

function update() {
    svg.remove();
    svg = d3.selectAll("body").append("svg");
    svg.append("circle")
        .attr("cx",40)
        .attr("cy",40)
        .attr("r",20)
        .style("fill","blue");
}
</script>
 
Nahoru Odpovědět 11. února 8:24
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 2 zpráv z 2.