Jquery: How to sort SVG g element by translate filter value?

瘦欲@ 提交于 2021-02-11 06:07:51

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!