如何切换D3 SVG元素的位置

时间:2019-07-16 14:35:06

标签: javascript d3.js

我用D3创建的页面上有一些SVG元素。全部是一个父SVG的子代。每个元素都包含其他D3元素,例如路径和文本。单击一个按钮,我希望其中两个子SVG切换位置,以便它们在页面上向上或向下移动(所有位置都位于上方/下方)。

我已经尝试创建组(“ g”)而不是子SVG并访问/更改它们的位置。但是,我似乎无法访问该元素的y位置。 我还尝试使用“ insertAfter”,但这仅适用于div,不适用于SVG(但是,我正在寻找类似的行为)。

$(".move_up").click(function() {
  var svg = $("#second_child"); //ID is actually retrieved from an attribute of the button
  svg.insertBefore(svg.prev()); //does obviously not work
});

上移按钮的HTML(每个子SVG有一个):

<a class="move_up">
  <span class="grey glyphicon glyphicon-chevron-up" title="Move up"></span>
</a>

用于SVG的HTML:

<div>
  <svg id="parent">
    <svg id="first_child"
      <path></path>
      <rect></rect>
      <text></text>
      ...
    </svg>
    <svg id="second_child"
      <path></path>
      <rect></rect>
      <text></text>
      ...
    </svg>
    <rect></rect>
    <text></text>
    ...
  </svg>
</div>

当要使用向上(或向下)按钮时,我希望第一和第二子SVG切换位置。

2 个答案:

答案 0 :(得分:0)

您正在使用SVG作为包装器,并且位置与html不同。在SVG中,您需要定义X和Y位置。

let ids = ['ex1', 'ex2', 'ex3', 'ex4', 'ex5']
let btn = document.getElementById('move')

const sortArrayAsYouWish = (array) => {
    array.sort(() => Math.random() - 0.5);
}

const changeOrder = () => {
  let posY = 35
  sortArrayAsYouWish(ids) // change order
  ids.forEach((id, i) => {
    let $el =  document.getElementById(id)  
    $el.style.transform = `translate(0, ${posY*i}px)`
  })
}

btn.onclick = changeOrder

changeOrder()
svg {
  width: 500px;
  height: 340px;
  border: solid 1px #ccc;
}
g {
  transition: transform 0.4s;  
}

text {
  fill: #fff;
  text-anchor: middle;
}

#ex2 rect {
  fill: blue;
}
#ex3 rect {
  fill: yellow;
}
#ex4 rect {
  fill: red;
}
#ex5 rect {
  fill: cyan;
}
<div><button id="move">Move</button></div>
<svg>
  <g id="ex1">
    <rect width="120" height="30" x="0" y="0" />
    <text x="60" y="15">Hello example 1</text>
  </g>
  
  <g id="ex2">
    <rect width="120" height="30" x="0" y="0" />
    <text x="60" y="15">Hello example 2</text>
  </g>

  <g id="ex3">
    <rect width="120" height="30" x="0" y="0" />
    <text x="60" y="15">Hello example 3</text>
  </g>

  <g id="ex4">
    <rect width="120" height="30" x="0" y="0" />
    <text x="60" y="15">Hello example 4</text>
  </g>

  <g id="ex5">
    <rect width="120" height="30" x="0" y="0" />
    <text x="60" y="15">Hello example 5</text>
  </g>
</svg>

答案 1 :(得分:0)

这就是我最终要做的:

let group = $("#first_group");
let next_group = $('#second_group");

let diff = 58; // Height of a group
let translate_y = 0;
let translate_y_next = 0;

if (next_group.offset()) {
    if (group.attr("transform")) {
        let string = group.attr("transform");
        translate_y = parseInt(string.substring(string.indexOf("(")+1, string.indexOf(")")).split(",")[1]);
    }

    if (prev_group.attr("transform")) {
        let string_next = prev_group.attr("transform");
        translate_y_next = parseInt(string_next.substring(string_next.indexOf("(")+1, string_next.indexOf(")")).split(",")[1]);
    }

    group.attr("transform", `translate(0, ${translate_y + diff})`);
    next_group.attr("transform", `translate(0, ${translate_y_next - diff})`);
}

“上移”按钮的工作原理类似。只要确保更改最后两行中的符号即可!

也许不是超级优雅,但是可以做到。