问题
Do you know how to sort SVG group elements by translate x value? Here is the code:
<svg>
<g class="element" transform="translate(479, 247) scale(1)">...</g>
<g class="element" transform="translate(874, 145) scale(1)">...</g>
<g class="element" transform="translate(643, 356) scale(1)">...</g>
</svg>
As you can see x values of each element is 479,874, and 643. I want to sort these 3 groups by that element's x value and append back to same SVG.
Expected Result:
<svg>
<g class="element" transform="translate(874, 145) scale(1)">...</g>
<g class="element" transform="translate(643, 356) scale(1)">...</g>
<g class="element" transform="translate(479, 247) scale(1)">...</g>
</svg>
回答1:
If you are interested in a slightly different way of doing it with lots of ES6 and functional ideas:
I modified the example a bit to show the order by the order in which the groups are painted on the SVG (in the order they appear in the DOM) by adding <text/>
and <rect/>
elements. So before it looks like this:
Then after it looks like this:
i.e. <g class="element" transform="translate(479, 247) scale(1)">...</g>
is painted last because it is the last child of the <svg/>
tag.
Code is below and codepen here: https://codepen.io/Alexander9111/pen/PowLQZO
HTML:
<svg width=1000 height="1000">
<g class="element" transform="translate(479, 247) scale(1)">
<rect stroke="blue" fill="blue" x="0" y="0" height="200" width="450"/>
<text>479</text>
</g>
<g class="element" transform="translate(874, 145) scale(1)">
<rect stroke="red" fill="red" x="0" y="0" height="250" width="300"/>
<text>874</text>
</g>
<g class="element" transform="translate(643, 356) scale(1)">
<rect stroke="green" fill="green" x="0" y="0" height="200" width="350"/>
<text>643</text>
</g>
</svg>
And Javascript:
const svg = document.querySelector("svg");
const groups = [...document.querySelectorAll("g")];
groups.map(child => {
console.log(getValue(child))
});
function getValue(child){
var transform = child.getAttribute("transform")
.replace("translate(","")
.replace(/\) scale.*/i,"");
return transform.split(",")
.map(el => parseInt(el));
}
groups.sort((a,b) => {
return getValue(b)[0] - getValue(a)[0];
})
groups.forEach((el,index) => {
svg.appendChild(el);
});
You could adapt the line return getValue(b)[0] - getValue(a)[0];
to a - b
and then it sorts ascending instead of descending. Also you can change the index from (a)[0]
to (a)[1]
to sort by y-translation instead.
回答2:
You can use jQuery sort
and some string parsing logic to retrieve your first parameter of translate
:
function getValue(input){
return parseInt(input.outerHTML.substring(input.outerHTML.indexOf('(') + 1, input.outerHTML.indexOf(',')));
}
$('svg g').sort(function(a, b) {
return getValue(a) < getValue(b) ? 1 : -1;
}).appendTo('svg');
来源:https://stackoverflow.com/questions/59906589/jquery-how-to-sort-svg-g-element-by-translate-filter-value