私のプロジェクトでは、D3 フォース レイアウトでほろ酔いポップアップを「トグル」することを組み合わせようとしています。基本的に、画像をクリックしてそこにポップアップを表示し、ユーザーが操作できるようにしたいと考えています。ユーザーが完了したら、別の画像をクリックするか、同じ画像をクリックして閉じます。
コードの D3 部分は、強制レイアウトで画像のレンダリングを行います。基本的にコードは次のようになります。
var node = vis.selectAll("circle.node")
.data(data.nodes)
.enter().append("svg:image")
.attr("class", "node")
.attr("xlink:href", function (d) { return d.icon; })
.attr("x", function (d) { return d.x - 12; })
.attr("y", function (d) { return d.y - 12; })
.attr("width", '24px')
.attr("height", '24px')
.style("fill", function (d) { return fill(d.group); })
Tipsy のリンクはhttp://onehackoranother.com/projects/jquery/tipsy/#にあります。基本をまっすぐにするために、次のようにテストしました。
$('.node').tipsy({
gravity: 'w',
opacity: 1,
html: true,
title: function () {
var d = this.__data__, icon = d.icon;
return '<img src="' + icon + '" style="width: 100px; height:100px;"/>;
}
});
ここまでは順調ですね; このコードを使用してホバーすると、すべて機能します。
最後の調整として、trigger: 'manual'
Tipsy のオプションを追加し、D3 ノードにいくつかのコードを追加しました。
// this variable is declared on top somewhere:
var prev = null;
// and to the D3 code, this is added:
.on("click",
function () {
if (this == prev)
{
$(this).tipsy("hide");
prev = null;
}
else
{
// show
if (prev != null) {
$(prev).tipsy("hide");
}
$(this).tipsy("show");
prev = this;
}
});
ご覧のとおり、コードはhttp://onehackoranother.com/projects/jquery/tipsy/# (セクション: ツールチップを手動でトリガーする) のコードを厳密に反映しています。
このコードを実行すると、突然動作しなくなります。よく調べてみると、Tipsy コードの次の部分に問題があることに気付きました。
} else if (typeof options == 'string') {
console.debug(this); // added some debug info
var tipsy = this.data('tipsy');
if (tipsy) tipsy[options]();
return this;
}
このコードを実行するthis.data('tipsy')
と、常にundefined
. ただし、選択されている要素は正しいようです。
私は他のSOの投稿を見てきましたが、これまでのところ運が悪いです。一部の人から提案されたように、さまざまなバージョンの jQuery を試したり、D3 の代わりに jQuery から onclick をバインドしようとしたりしました。これまでのところ、すべて同じ動作です。
誰かが私に欠けているものを教えてもらえますか?
最小限のテストケース
この作業が基づいているほろ酔い & D3 の単純な最小限のテスト ケースは、次のリンクにあります: http://bl.ocks.org/ilyabo/1373263。HTML コードは次のように置き換えることができます。
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="http://mbostock.github.com/d3/d3.js"></script>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.6.2.min.js"></script>
<script type="text/javascript" src="jquery.tipsy.js"></script>
<link href="tipsy.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="chart"></div>
<script type="text/javascript">
var w = 800, h = 500;
var colors = d3.scale.category20();
var vis = d3.select("#chart").append("svg:svg")
.attr("width", w)
.attr("height", h);
var data = d3.range(20).map(function(i) {
return { i:i, x:Math.random()*w, y:Math.random()*h, r:Math.random()*30 }
});
var prev = null;
vis.selectAll("circle")
.data(data)
.enter().append("svg:circle")
.attr("stroke", "black")
.attr("fill", function(d, i) { return colors(i); })
.attr("cx", function(d, i) { return d.x; })
.attr("cy", function(d, i) { return d.y; })
.attr("r", function(d, i) { return d.r; })
.on("click",
function () {
if (this == prev)
{
$(this).tipsy("hide");
prev = null;
}
else
{
if (prev != null)
{
$(prev).tipsy("hide");
}
$(this).tipsy("show");
prev = this;
}
});
$('svg circle').tipsy({
trigger: 'manual',
gravity: 'w',
html: true,
title: function() {
var d = this.__data__, c = colors(d.i);
return 'Hi there! My color is <span style="color:' + c + '">' + c + '</span>';
}
});
</script>
</body>
</html>