1. ホーム
  2. javascript

[解決済み] D3によるSVG要素のZ-Indexの更新

2023-03-27 17:26:47

質問

D3ライブラリを使って、SVG要素をz-orderの先頭に持ってくる効果的な方法は何でしょうか?

私の具体的なシナリオは、円グラフを強調表示することです(円グラフに stroke を追加したものです。 path ) に変換する。 私のチャートを生成するためのコードブロックは以下のとおりです。

svg.selectAll("path")
    .data(d)
  .enter().append("path")
    .attr("d", arc)
    .attr("class", "arc")
    .attr("fill", function(d) { return color(d.name); })
    .attr("stroke", "#fff")
    .attr("stroke-width", 0)
    .on("mouseover", function(d) {
        d3.select(this)
            .attr("stroke-width", 2)
            .classed("top", true);
            //.style("z-index", 1);
    })
    .on("mouseout", function(d) {
        d3.select(this)
            .attr("stroke-width", 0)
            .classed("top", false);
            //.style("z-index", -1);
    });

いくつかのオプションを試しましたが、今のところうまくいきません。 使用方法 style("z-index") を呼び出して classed を呼び出すことはどちらもうまくいきませんでした。

私のCSSでは、"top"クラスは次のように定義されています。

.top {
    fill: red;
    z-index: 100;
}

fill ステートメントは、オン/オフが正しく行われていることを確認するためにあります。 そうです。

を使うというのは sort を使うというのもあるようですが、"selected"要素を一番上に持ってくるというのがどう実装されるのかが不明です。

UPDATEしました。

私は、以下のコードで特定の状況を解決しました。 mouseover イベントで SVG に新しい弧を追加し、ハイライトを表示します。

svg.selectAll("path")
    .data(d)
  .enter().append("path")
    .attr("d", arc)
    .attr("class", "arc")
    .style("fill", function(d) { return color(d.name); })
    .style("stroke", "#fff")
    .style("stroke-width", 0)
    .on("mouseover", function(d) {
        svg.append("path")
          .attr("d", d3.select(this).attr("d"))
          .attr("id", "arcSelection")
          .style("fill", "none")
          .style("stroke", "#fff")
          .style("stroke-width", 2);
    })
    .on("mouseout", function(d) {
        d3.select("#arcSelection").remove();
    });

どのように解決するのですか?

開発者が提示した解決策の1つは、"D3のソート演算子を使って要素を並べ替えることです" ( https://github.com/mbostock/d3/issues/252 )

このように考えると、データのない要素であれば、そのデータ、または位置を比較することによって、要素をソートすることができるかもしれません。

.on("mouseover", function(d) {
    svg.selectAll("path").sort(function (a, b) { // select the parent and sort the path's
      if (a.id != d.id) return -1;               // a is not the hovered element, send "a" to the back
      else return 1;                             // a is the hovered element, bring "a" to the front
  });
})