我正在尝试将工具提示添加到可折叠树中,我遇到了问题。错误似乎发生在这个代码块中,如下所示(我将附加完整的代码片段以用于调试目的)
// Transition nodes to their new position.
var nodeUpdate = node.transition()
.duration(duration)
.attr("transform", function(d) { return "translate(" + d.y + "," + d.x + ")"; });
nodeUpdate.select("circle")
.attr('r',function(d) { return d.size; })
.style("fill", function(d) { return d._children ? "lightsteelblue" : "#fff"; })
.attr('cursor', 'pointer')
.on("mouseover", mouseover)
.on("mousemove", function(d){mousemove(d);})
.on("mouseout", mouseout);
错误消息:未捕获TypeError:nodeUpdate.select(...)。attr(...)。style(...)。attr(...)。on不是功能 .on函数未被识别为函数。我相信这与节点的转换有关,但我不确定如何解决这个问题。
<!DOCTYPE html>
<meta charset="utf-8">
<style>
div.container {
width: 100%;
}
header {
height: 35px;
padding: 1em;
color: white;
background-color: gray;
clear: left;
text-align: center;
justify-content: center;
font-family: Calibri;
font-size: 35px;
font-weight: bold;
}
.node {
cursor: pointer;
}
.node circle {
fill: #fff;
stroke: steelblue;
stroke-width: 1.5px;
}
.node text {
font: 13px sans-serif;
}
.link {
fill: none;
stroke-opacity: 0.4;
stroke: purple;
stroke-width: 3.5px;
}
#content img {
position: absolute;
bottom: 0px;
right: 0px;
}
h2 {
font-family: Calibri;
font-size: 35px;
font-weight: bold;
text-align: center;
}
div.container1 span {
top: 50%;
justify-content: center;
text-align: center;
div.tooltip {
position: absolute;
text-align: center;
width: 60px;
height: 28px;
padding: 2px;
font: 12px sans-serif;
background: lightsteelblue;
border: 0px;
border-radius: 8px;
pointer-events: none;
}
}
</style>
<body bgcolor='#F8F9F9'>
<script src="https://d3js.org/d3.v3.min.js"></script>
<div class="container">
<table>
<tr>
<td width="90%">
<div id="hier" align="left">
<tr>
<script>
var margin = {
top: 20,
right: 120,
bottom: 20,
left: 120
},
width = 1500 - margin.right - margin.left,
height = 800 - margin.top - margin.bottom;
var flare = {
"name": "AON",
"size": 4,
"children": [{
"name": "India",
"size": 4,
"children": [{
"name": "ARS",
"size": 4,
"children": [
{
"name": "hhh",
"size": 4
},
{
"name": "AAA",
"size": 4
},
{
"name": "BBB",
"size": 4
},
{
"name": "cCC",
"size": 8
},
{
"name": "ddd",
"size": 4
},
{
"name": "eee",
"size": 4
},
{
"name": "fff",
"size": 4
},
{
"name": "ggg",
"size": 4
},
{
"name": "hhh",
"size": 4
},
{
"name": "www",
"size": 4
},
{
"name": "qwww",
"size": 8
},
{
"name": "sd",
"size": 4
},
{
"name": "tere",
"size": 4
},
{
"name": "rtr",
"size": 4
},
{
"name": "wqw",
"size": 4
},
{
"name": "hrfg",
"size": 4
}
]
}]
},
{
"name": "Singapore",
"size": 4,
"children": [{
"name": "H&B",
"size": 4,
"children": [{
"name": "aasd",
"size": 4
},
{
"name": "sdw",
"size": 4
},
{
"name": "ghrr",
"size": 4
},
{
"name": "tyr",
"size": 4
},
{
"name": "wew",
"size": 4
},
{
"name": "ere",
"size": 4
},
{
"name": "wew",
"size": 4
},
{
"name": "eds",
"size": 4
},
{
"name": "hrtr",
"size": 8
},
{
"name": "wew",
"size": 4
},
{
"name": "uyt",
"size": 4
},
{
"name": "wew",
"size": 4
},
{
"name": "wewe",
"size": 4
},
{
"name": "yrt",
"size": 4
},
{
"name": "uyu",
"size": 4
},
{
"name": "erewr",
"size": 4
},
{
"name": "wew",
"size": 4
},
{
"name": "kyjy",
"size": 4
}
]
},
{
"name": "GCP",
"size": 4,
"children": [{
"name": "wew",
"size": 4
},
{
"name": "sdsf",
"size": 4
},
{
"name": "wewt",
"size": 4
},
{
"name": "wetdse",
"size": 4
},
{
"name": "wetw",
"size": 4
},
{
"name": "qwsd",
"size": 4
},
{
"name": "yrytw",
"size": 4
},
{
"name": "wewax",
"size": 4
},
{
"name": "jttut",
"size": 4
},
{
"name": "scscw",
"size": 4
},
{
"name": "wetvd",
"size": 4
},
{
"name": "wewe",
"size": 4
},
{
"name": "zc",
"size": 4
},
{
"name": "wew",
"size": 4
},
{
"name": "zerete",
"size": 8
},
{
"name": "sdaxa",
"size": 4
},
{
"name": "yeer",
"size": 4
},
{
"name": "sdaxa",
"size": 4
},
{
"name": "wewretre",
"size": 4
},
{
"name": "ssdsrere",
"size": 4
},
{
"name": "asdsdere",
"size": 4
},
{
"name": "asdsdere",
"size": 4
}
]
}
]
},
{
"name": "US",
"size": 4,
"children": [{
"name": "Benfield",
"size": 4,
"children": [{
"name": "wes",
"size": 4
},
{
"name": "sd",
"size": 4
},
{
"name": "dds",
"size": 4
},
{
"name": "sdsd",
"size": 4
},
{
"name": "ere",
"size": 4
},
{
"name": "ryr",
"size": 4
},
{
"name": "ty",
"size": 4
},
{
"name": "wewe",
"size": 4
},
{
"name": "ggrt",
"size": 4
},
{
"name": "wetyr",
"size": 4
},
{
"name": "wew",
"size": 4
},
{
"name": "hrfg",
"size": 4
},
{
"name": "wew",
"size": 4
},
{
"name": "hhf",
"size": 8
},
{
"name": "ere",
"size": 4
},
{
"name": "vfgd",
"size": 4
}
]
},
{
"name": "GCP",
"size": 4,
"children": [{
"name": "xx",
"size": 4
},
{
"name": "wqwq",
"size": 4
},
{
"name": "xasa",
"size": 4
},
{
"name": "ooo",
"size": 4
},
{
"name": "ppp",
"size": 4
},
{
"name": "ll",
"size": 4
},
{
"name": "lljk",
"size": 4
},
{
"name": "kjjk",
"size": 4
},
{
"name": "kui",
"size": 4
},
{
"name": "yu",
"size": 4
},
{
"name": "li",
"size": 4
},
{
"name": "uyu",
"size": 4
},
{
"name": "yuik",
"size": 4
},
{
"name": "yjm",
"size": 4
},
{
"name": "yu",
"size": 4
},
{
"name": "yikm",
"size": 4
},
{
"name": "yu",
"size": 8
},
{
"name": "mmui",
"size": 4
},
{
"name": "yum",
"size": 4
},
{
"name": "kyuyy",
"size": 4
},
{
"name": "dffgy",
"size": 4
},
{
"name": "erfdr",
"size": 4
}
]
}
]
}
]
};
var i = 0,
duration = 750,
root;
var tree = d3.layout.tree()
.size([height, width]);
var diagonal = d3.svg.diagonal()
.projection(function(d) {
return [d.y, d.x];
});
var svg = d3.select("#hier").append("svg")
.attr("width", width + margin.right + margin.left)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + 500 + "," + margin.top + ")");
var div = d3.select("#hier").append("div")
.attr("class", "tooltip")
.style("opacity", 0);
root = flare;
root.x0 = height / 2;
root.y0 = 0;
function collapse(d) {
if (d.children) {
d._children = d.children;
d._children.forEach(collapse);
d.children = null;
}
}
root.children.forEach(collapse);
update(root);
d3.select(self.frameElement).style("height", "800px");
function update(source) {
// Compute the new tree layout.
var nodes = tree.nodes(root).reverse(),
links = tree.links(nodes);
// Normalize for fixed-depth.
nodes.forEach(function(d) {
d.y = d.depth * 180;
});
// Update the nodes…
var node = svg.selectAll("g.node")
.data(nodes, function(d) {
return d.id || (d.id = ++i);
});
// Enter any new nodes at the parent's previous position.
var nodeEnter = node.enter().append("g")
.attr("class", "node")
.attr("transform", function(d) {
return "translate(" + source.y0 + "," + source.x0 + ")";
})
.on("click", click);
nodeEnter.append("circle")
.attr("r", 1e-6)
.style("fill", function(d) {
return d._children ? "lightsteelblue" : "#fff";
});
nodeEnter.append("text")
.attr("x", function(d) {
return d.children || d._children ? -10 : 10;
})
.attr("dy", ".35em")
.attr("text-anchor", function(d) {
return d.children || d._children ? "end" : "start";
})
.text(function(d) {
return d.name;
})
.style("fill-opacity", 1e-6);
// Transition nodes to their new position.
var nodeUpdate = node.transition()
.duration(duration)
.attr("transform", function(d) {
return "translate(" + d.y + "," + d.x + ")";
});
nodeUpdate.select("circle")
.attr('r', function(d) {
return d.size;
})
.style("fill", function(d) {
return d._children ? "lightsteelblue" : "#fff";
})
.attr('cursor', 'pointer')
.on("mouseover", mouseover)
.on("mousemove", function(d) {
mousemove(d);
})
.on("mouseout", mouseout);
function mouseover() {
div.transition()
.duration(300)
.style("opacity", 1);
}
function mousemove(d) {
div
.text(d.name)
.style("left", (d3.event.pageX) + "px")
.style("top", (d3.event.pageY) + "px");
}
function mouseout() {
div.transition()
.duration(300)
.style("opacity", 1e-6);
}
nodeUpdate.select("text")
.style("fill-opacity", 1);
// Transition exiting nodes to the parent's new position.
var nodeExit = node.exit().transition()
.duration(duration)
.attr("transform", function(d) {
return "translate(" + source.y + "," + source.x + ")";
})
.remove();
nodeExit.select("circle")
.attr("r", 1e-6);
nodeExit.select("text")
.style("fill-opacity", 1e-6);
// Update the links…
var link = svg.selectAll("path.link")
.data(links, function(d) {
return d.target.id;
});
// Enter any new links at the parent's previous position.
link.enter().insert("path", "g")
.attr("class", "link")
.attr("d", function(d) {
var o = {
x: source.x0,
y: source.y0
};
return diagonal({
source: o,
target: o
});
});
// Transition links to their new position.
link.transition()
.duration(duration)
.attr("d", diagonal);
// Transition exiting nodes to the parent's new position.
link.exit().transition()
.duration(duration)
.attr("d", function(d) {
var o = {
x: source.x,
y: source.y
};
return diagonal({
source: o,
target: o
});
})
.remove();
// Stash the old positions for transition.
nodes.forEach(function(d) {
d.x0 = d.x;
d.y0 = d.y;
});
}
// Toggle children on click.
function click(d) {
if (d.children) {
d._children = d.children;
d.children = null;
} else {
d.children = d._children;
d._children = null;
}
update(d);
}
</script>
</tr>
</div>
</td>
<td width="10%">
</td>
</tr>
</table>
</div>
</body>
&#13;
在代码段上运行时,错误是可重现的。请帮助我理解这个问题。
答案 0 :(得分:2)
过渡不是典型的选择。来自d3v3 documentation:
转换是运营商应用的特殊选择类型 随着时间的推移,而不是瞬间。你得到一个 使用转换运算符从选择转换。而 转换通常支持与选择相同的运算符(例如 作为attr和style),并非所有运营商都受到支持;例如,你 必须在转换开始之前附加元素。删除运算符是 提供了在过渡结束时方便地删除元素。
您正试图在转换中放置.on
个事件:
// Transition nodes to their new position.
var nodeUpdate = node.transition()
.duration(duration)
.attr( .... });
nodeUpdate.select("circle")
.attr(......)
.on("mouseover", mouseover)
.on("mousemove", function(d) {
mousemove(d);
})
.on("mouseout", mouseout);
transition.select()选择与指定选择器字符串匹配的第一个后代元素(如果有),并返回结果选择的转换(API documentation)
但是,v3中的d3转换没有.on
方法。但是,有.each
方法(在v4中重命名为.on
)。但是,该方法允许的事件范围(类型)为三:
如果指定了type,则为转换事件添加一个侦听器, 支持&#34;开始&#34;,&#34;结束&#34;和&#34;中断&#34;事件。听众会 为过渡中的每个单独元素调用。 (documentation)
不使用转换选择来应用.on事件,而是尝试使用典型选择。这将允许您根据需要使用.on。我改变了这一行
nodeUpdate.select("circle")
要
d3.selectAll("circle")
这会将没有问题的.on事件应用于节点。树形图似乎在下面修改的代码段中按预期工作:
<!DOCTYPE html>
<meta charset="utf-8">
<style>
div.container {
width: 100%;
}
header {
height: 35px;
padding: 1em;
color: white;
background-color: gray;
clear: left;
text-align: center;
justify-content: center;
font-family: Calibri;
font-size: 35px;
font-weight: bold;
}
.node {
cursor: pointer;
}
.node circle {
fill: #fff;
stroke: steelblue;
stroke-width: 1.5px;
}
.node text {
font: 13px sans-serif;
}
.link {
fill: none;
stroke-opacity: 0.4;
stroke: purple;
stroke-width: 3.5px;
}
#content img {
position: absolute;
bottom: 0px;
right: 0px;
}
h2 {
font-family: Calibri;
font-size: 35px;
font-weight: bold;
text-align: center;
}
div.container1 span {
top: 50%;
justify-content: center;
text-align: center;
div.tooltip {
position: absolute;
text-align: center;
width: 60px;
height: 28px;
padding: 2px;
font: 12px sans-serif;
background: lightsteelblue;
border: 0px;
border-radius: 8px;
pointer-events: none;
}
}
</style>
<body bgcolor='#F8F9F9'>
<script src="https://d3js.org/d3.v3.min.js"></script>
<div class="container">
<table>
<tr>
<td width="90%">
<div id="hier" align="left">
<tr>
<script>
var margin = {
top: 20,
right: 120,
bottom: 20,
left: 120
},
width = 1500 - margin.right - margin.left,
height = 800 - margin.top - margin.bottom;
var flare = {
"name": "AON",
"size": 4,
"children": [{
"name": "India",
"size": 4,
"children": [{
"name": "ARS",
"size": 4,
"children": [
{
"name": "hhh",
"size": 4
},
{
"name": "AAA",
"size": 4
},
{
"name": "BBB",
"size": 4
},
{
"name": "cCC",
"size": 8
},
{
"name": "ddd",
"size": 4
},
{
"name": "eee",
"size": 4
},
{
"name": "fff",
"size": 4
},
{
"name": "ggg",
"size": 4
},
{
"name": "hhh",
"size": 4
},
{
"name": "www",
"size": 4
},
{
"name": "qwww",
"size": 8
},
{
"name": "sd",
"size": 4
},
{
"name": "tere",
"size": 4
},
{
"name": "rtr",
"size": 4
},
{
"name": "wqw",
"size": 4
},
{
"name": "hrfg",
"size": 4
}
]
}]
},
{
"name": "Singapore",
"size": 4,
"children": [{
"name": "H&B",
"size": 4,
"children": [{
"name": "aasd",
"size": 4
},
{
"name": "sdw",
"size": 4
},
{
"name": "ghrr",
"size": 4
},
{
"name": "tyr",
"size": 4
},
{
"name": "wew",
"size": 4
},
{
"name": "ere",
"size": 4
},
{
"name": "wew",
"size": 4
},
{
"name": "eds",
"size": 4
},
{
"name": "hrtr",
"size": 8
},
{
"name": "wew",
"size": 4
},
{
"name": "uyt",
"size": 4
},
{
"name": "wew",
"size": 4
},
{
"name": "wewe",
"size": 4
},
{
"name": "yrt",
"size": 4
},
{
"name": "uyu",
"size": 4
},
{
"name": "erewr",
"size": 4
},
{
"name": "wew",
"size": 4
},
{
"name": "kyjy",
"size": 4
}
]
},
{
"name": "GCP",
"size": 4,
"children": [{
"name": "wew",
"size": 4
},
{
"name": "sdsf",
"size": 4
},
{
"name": "wewt",
"size": 4
},
{
"name": "wetdse",
"size": 4
},
{
"name": "wetw",
"size": 4
},
{
"name": "qwsd",
"size": 4
},
{
"name": "yrytw",
"size": 4
},
{
"name": "wewax",
"size": 4
},
{
"name": "jttut",
"size": 4
},
{
"name": "scscw",
"size": 4
},
{
"name": "wetvd",
"size": 4
},
{
"name": "wewe",
"size": 4
},
{
"name": "zc",
"size": 4
},
{
"name": "wew",
"size": 4
},
{
"name": "zerete",
"size": 8
},
{
"name": "sdaxa",
"size": 4
},
{
"name": "yeer",
"size": 4
},
{
"name": "sdaxa",
"size": 4
},
{
"name": "wewretre",
"size": 4
},
{
"name": "ssdsrere",
"size": 4
},
{
"name": "asdsdere",
"size": 4
},
{
"name": "asdsdere",
"size": 4
}
]
}
]
},
{
"name": "US",
"size": 4,
"children": [{
"name": "Benfield",
"size": 4,
"children": [{
"name": "wes",
"size": 4
},
{
"name": "sd",
"size": 4
},
{
"name": "dds",
"size": 4
},
{
"name": "sdsd",
"size": 4
},
{
"name": "ere",
"size": 4
},
{
"name": "ryr",
"size": 4
},
{
"name": "ty",
"size": 4
},
{
"name": "wewe",
"size": 4
},
{
"name": "ggrt",
"size": 4
},
{
"name": "wetyr",
"size": 4
},
{
"name": "wew",
"size": 4
},
{
"name": "hrfg",
"size": 4
},
{
"name": "wew",
"size": 4
},
{
"name": "hhf",
"size": 8
},
{
"name": "ere",
"size": 4
},
{
"name": "vfgd",
"size": 4
}
]
},
{
"name": "GCP",
"size": 4,
"children": [{
"name": "xx",
"size": 4
},
{
"name": "wqwq",
"size": 4
},
{
"name": "xasa",
"size": 4
},
{
"name": "ooo",
"size": 4
},
{
"name": "ppp",
"size": 4
},
{
"name": "ll",
"size": 4
},
{
"name": "lljk",
"size": 4
},
{
"name": "kjjk",
"size": 4
},
{
"name": "kui",
"size": 4
},
{
"name": "yu",
"size": 4
},
{
"name": "li",
"size": 4
},
{
"name": "uyu",
"size": 4
},
{
"name": "yuik",
"size": 4
},
{
"name": "yjm",
"size": 4
},
{
"name": "yu",
"size": 4
},
{
"name": "yikm",
"size": 4
},
{
"name": "yu",
"size": 8
},
{
"name": "mmui",
"size": 4
},
{
"name": "yum",
"size": 4
},
{
"name": "kyuyy",
"size": 4
},
{
"name": "dffgy",
"size": 4
},
{
"name": "erfdr",
"size": 4
}
]
}
]
}
]
};
var i = 0,
duration = 750,
root;
var tree = d3.layout.tree()
.size([height, width]);
var diagonal = d3.svg.diagonal()
.projection(function(d) {
return [d.y, d.x];
});
var svg = d3.select("#hier").append("svg")
.attr("width", width + margin.right + margin.left)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + 500 + "," + margin.top + ")");
var div = d3.select("#hier").append("div")
.attr("class", "tooltip")
.style("opacity", 0);
root = flare;
root.x0 = height / 2;
root.y0 = 0;
function collapse(d) {
if (d.children) {
d._children = d.children;
d._children.forEach(collapse);
d.children = null;
}
}
root.children.forEach(collapse);
update(root);
d3.select(self.frameElement).style("height", "800px");
function update(source) {
// Compute the new tree layout.
var nodes = tree.nodes(root).reverse(),
links = tree.links(nodes);
// Normalize for fixed-depth.
nodes.forEach(function(d) {
d.y = d.depth * 180;
});
// Update the nodes…
var node = svg.selectAll("g.node")
.data(nodes, function(d) {
return d.id || (d.id = ++i);
});
// Enter any new nodes at the parent's previous position.
var nodeEnter = node.enter().append("g")
.attr("class", "node")
.attr("transform", function(d) {
return "translate(" + source.y0 + "," + source.x0 + ")";
})
.on("click", click);
nodeEnter.append("circle")
.attr("r", 1e-6)
.style("fill", function(d) {
return d._children ? "lightsteelblue" : "#fff";
});
nodeEnter.append("text")
.attr("x", function(d) {
return d.children || d._children ? -10 : 10;
})
.attr("dy", ".35em")
.attr("text-anchor", function(d) {
return d.children || d._children ? "end" : "start";
})
.text(function(d) {
return d.name;
})
.style("fill-opacity", 1e-6);
// Transition nodes to their new position.
var nodeUpdate = node.transition()
.duration(duration)
.attr("transform", function(d) {
return "translate(" + d.y + "," + d.x + ")";
});
d3.selectAll("circle")
.attr('r', function(d) {
return d.size;
})
.style("fill", function(d) {
return d._children ? "lightsteelblue" : "#fff";
})
.attr('cursor', 'pointer')
.on("mouseover", mouseover)
.on("mousemove", function(d) {
mousemove(d);
})
.on("mouseout", mouseout);
function mouseover() {
div.transition()
.duration(300)
.style("opacity", 1);
}
function mousemove(d) {
div
.text(d.name)
.style("left", (d3.event.pageX) + "px")
.style("top", (d3.event.pageY) + "px");
}
function mouseout() {
div.transition()
.duration(300)
.style("opacity", 1e-6);
}
nodeUpdate.select("text")
.style("fill-opacity", 1);
// Transition exiting nodes to the parent's new position.
var nodeExit = node.exit().transition()
.duration(duration)
.attr("transform", function(d) {
return "translate(" + source.y + "," + source.x + ")";
})
.remove();
nodeExit.select("circle")
.attr("r", 1e-6);
nodeExit.select("text")
.style("fill-opacity", 1e-6);
// Update the links…
var link = svg.selectAll("path.link")
.data(links, function(d) {
return d.target.id;
});
// Enter any new links at the parent's previous position.
link.enter().insert("path", "g")
.attr("class", "link")
.attr("d", function(d) {
var o = {
x: source.x0,
y: source.y0
};
return diagonal({
source: o,
target: o
});
});
// Transition links to their new position.
link.transition()
.duration(duration)
.attr("d", diagonal);
// Transition exiting nodes to the parent's new position.
link.exit().transition()
.duration(duration)
.attr("d", function(d) {
var o = {
x: source.x,
y: source.y
};
return diagonal({
source: o,
target: o
});
})
.remove();
// Stash the old positions for transition.
nodes.forEach(function(d) {
d.x0 = d.x;
d.y0 = d.y;
});
}
// Toggle children on click.
function click(d) {
if (d.children) {
d._children = d.children;
d.children = null;
} else {
d.children = d._children;
d._children = null;
}
update(d);
}
</script>
</tr>
</div>
</td>
<td width="10%">
</td>
</tr>
</table>
</div>
</body>
&#13;