Kee*_*san 6 javascript css html5 data-driven d3.js
我正在使用d3v3脚本来可视化数据.我需要在mouseleave中突出显示并将节点置于鼠标中心,反之亦然.现在,我可以通过增加节点的高度和宽度来高亮点亮节点.
无法将节点带到前面.我尝试过使用像opacity,z-index这样的CSS.
脚本
<script>
// some colour variables
var tcBlack = "purple";
// rest of vars
var w = 1500,
h = 800,
maxNodeSize = 50,
x_browser = 25,
y_browser = 25,
root;
var vis;
var force = d3.layout.force();
vis = d3.select("#visfel_map").append("svg").attr("width", w).attr("height", h);
d3.json(url, function(error,json) {
if (error)
return console.warn(error);
root = json;
root.fixed = true;
root.x = w / 2;
root.y = h / 4;
// Build the path
var defs = vis.insert("svg:defs")
.data(["end"]);
defs.enter().append("svg:path")
.attr("d", "M0,-5L10,0L0,5");
update();
});
function update() {
var nodes = flatten(root),
links = d3.layout.tree().links(nodes);
force.nodes(nodes)
.links(links)
.gravity(0.05)
.charge(-2500)
.linkDistance(200)
.friction(0.5)
.linkStrength(function(l, i) {return 1; })
.size([w, h])
.on("tick", tick)
.start();
var path = vis.selectAll("path.link")
.data(links, function(d) { return d.target.id; });
path.enter().insert("svg:path")
.attr("class", "link")
// .attr("marker-end", "url(#end)")
.style("stroke", "#ff8888");
// Exit any old paths.
path.exit().remove();
// Update the nodes…
var node = vis.selectAll("g.node")
.data(nodes, function(d) { return d.id; });
// Enter any new nodes.
var nodeEnter = node.enter().append("svg:g")
.attr("class", "node")
.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; })
.on("click", click)
.call(force.drag);
// Append a circle
nodeEnter.append("svg:circle")
.attr("r", function(d) { return Math.sqrt(d.size) / 10 || 4.5; })
.style("fill", "#eee");
// Append images
var images = nodeEnter.append("svg:image")
.attr("xlink:href", function(d) { return d.img;})
.attr("x", function(d) { return -25;})
.attr("y", function(d) { return -25;})
.attr("height", 65)
.attr("width", 65);
// make the image grow a little on mouse over and add the text details on click
var setEvents = images
.on( 'click', function (d) {
console.log(d.sub_category_id)
})
.on( 'mouseenter', function() {
var currNode = d3.select(this);
currNode.transition()
.attr("x", function(d) { return -60;})
.attr("y", function(d) { return -60;})
.attr("height", 300)
.attr("width", 300);
})
// set back
.on( 'mouseleave', function() {
d3.select(this)
.transition()
.attr("x", function(d) { return -25;})
.attr("y", function(d) { return -25;})
.attr("height", 65)
.attr("width", 65);
});
// Append name on roll over next to the node as well
nodeEnter.append("text")
.attr("class", "nodetext")
.attr("x", function(d) { return d.children ? 70 : 70; })
.attr("y", function(d) { return d.children ? 10 : 10; })
.style("text-anchor", function(d) { return d.children ? "end" : "end"; })
.attr("fill", tcBlack)
.text(function(d) { return d.name; });
// Exit any old nodes.
node.exit().remove();
// Re-select for update.
path = vis.selectAll("path.link");
node = vis.selectAll("g.node");
function tick() {
path.attr("d", function(d) {
var dx = d.target.x - d.source.x,
dy = d.target.y - d.source.y,
dr = Math.sqrt(dx * dx + dy * dy);
return "M" + d.source.x + ","
+ d.source.y
+ "A" + dr + ","
+ dr + " 0 0,1 "
+ d.target.x + ","
+ d.target.y;
});
node.attr("transform", nodeTransform);
}
}
/**
* Gives the coordinates of the border for keeping the nodes inside a frame
* http://bl.ocks.org/mbostock/1129492
*/
function nodeTransform(d) {
d.x = Math.max(maxNodeSize, Math.min(w - (d.imgwidth/2 || 16), d.x));
d.y = Math.max(maxNodeSize, Math.min(h - (d.imgheight/2 || 16), d.y));
return "translate(" + d.x + "," + 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();
}
/**
* Returns a list of all nodes under the root.
*/
function flatten(root) {
var nodes = [];
var i = 0;
function recurse(node) {
if (node.children)
node.children.forEach(recurse);
if (!node.id)
node.id = ++i;
nodes.push(node);
}
recurse(root);
return nodes;
}
</script>
Run Code Online (Sandbox Code Playgroud)
JSON数据
{
"type": "map",
"tree_size": "2",
"map_id": "1",
"name": "Sounds for Speech",
"img": "manage/visfel_images/map-1516338051-sounds for speech.png",
"children": [
{
"type": "category",
"tree_size": "2",
"category_id": "1",
"name": "Vowels",
"img": "manage/visfel_images/category-1516338094-vowel sound.png",
"children": [
{
"type": "sub",
"tree_size": "2",
"sub_category_id": "1",
"name": "A",
"img": "manage/visfel_images/sub-1516338159-A.png"
},
{
"type": "sub",
"tree_size": "2",
"sub_category_id": "2",
"name": "E",
"img": "manage/visfel_images/sub-1516338189-E.png"
},
{
"type": "sub",
"tree_size": "2",
"sub_category_id": "3",
"name": "I",
"img": "manage/visfel_images/sub-1516338212-i.png"
},
{
"type": "sub",
"tree_size": "2",
"sub_category_id": "4",
"name": "O",
"img": "manage/visfel_images/sub-1516338235-O.png"
},
{
"type": "sub",
"tree_size": "2",
"sub_category_id": "5",
"name": "U",
"img": "manage/visfel_images/sub-1516338260-U.png"
}
]
},
{
"type": "category",
"tree_size": "2",
"category_id": "2",
"name": "Consonents",
"img": "manage/visfel_images/category-1516338121-consonents.png",
"children": [
{
"type": "sub",
"tree_size": "2",
"sub_category_id": "6",
"name": "B",
"img": "manage/visfel_images/sub-1516338304-B.png"
},
{
"type": "sub",
"tree_size": "2",
"sub_category_id": "7",
"name": "C",
"img": "manage/visfel_images/sub-1516338323-C.png"
},
{
"type": "sub",
"tree_size": "2",
"sub_category_id": "8",
"name": "D",
"img": "manage/visfel_images/sub-1516338342-D.png"
},
{
"type": "sub",
"tree_size": "2",
"sub_category_id": "9",
"name": "F",
"img": "manage/visfel_images/sub-1516338362-F.png"
},
{
"type": "sub",
"tree_size": "2",
"sub_category_id": "10",
"name": "G",
"img": "manage/visfel_images/sub-1516338380-G.png"
},
{
"type": "sub",
"tree_size": "2",
"sub_category_id": "11",
"name": "H",
"img": "manage/visfel_images/sub-1516338401-H.png"
},
{
"type": "sub",
"tree_size": "2",
"sub_category_id": "12",
"name": "J",
"img": "manage/visfel_images/sub-1516338427-J.png"
},
{
"type": "sub",
"tree_size": "2",
"sub_category_id": "13",
"name": "K",
"img": "manage/visfel_images/sub-1516338452-K.png"
},
{
"type": "sub",
"tree_size": "2",
"sub_category_id": "14",
"name": "L",
"img": "manage/visfel_images/sub-1516338470-L.png"
},
{
"type": "sub",
"tree_size": "2",
"sub_category_id": "15",
"name": "M",
"img": "manage/visfel_images/sub-1516338489-M.png"
},
{
"type": "sub",
"tree_size": "2",
"sub_category_id": "16",
"name": "N",
"img": "manage/visfel_images/sub-1516338508-N.png"
},
{
"type": "sub",
"tree_size": "2",
"sub_category_id": "17",
"name": "P",
"img": "manage/visfel_images/sub-1516338542-P.png"
},
{
"type": "sub",
"tree_size": "2",
"sub_category_id": "18",
"name": "Q",
"img": "manage/visfel_images/sub-1516338560-Q.png"
},
{
"type": "sub",
"tree_size": "2",
"sub_category_id": "19",
"name": "R",
"img": "manage/visfel_images/sub-1516338579-R.png"
},
{
"type": "sub",
"tree_size": "2",
"sub_category_id": "20",
"name": "S",
"img": "manage/visfel_images/sub-1516338604-S.png"
},
{
"type": "sub",
"tree_size": "2",
"sub_category_id": "21",
"name": "T",
"img": "manage/visfel_images/sub-1516338619-T.png"
},
{
"type": "sub",
"tree_size": "2",
"sub_category_id": "22",
"name": "V",
"img": "manage/visfel_images/sub-1516338635-V.png"
},
{
"type": "sub",
"tree_size": "2",
"sub_category_id": "23",
"name": "W",
"img": "manage/visfel_images/sub-1516338650-W.png"
},
{
"type": "sub",
"tree_size": "2",
"sub_category_id": "24",
"name": "X",
"img": "manage/visfel_images/sub-1516338666-X.png"
},
{
"type": "sub",
"tree_size": "2",
"sub_category_id": "25",
"name": "Y",
"img": "manage/visfel_images/sub-1516338705-Y.png"
},
{
"type": "sub",
"tree_size": "2",
"sub_category_id": "26",
"name": "Z",
"img": "manage/visfel_images/sub-1516338742-Z.png"
}
]
}
]
}
Run Code Online (Sandbox Code Playgroud)
在附带的屏幕截图中,节点"M"处于焦点,鼠标悬停在该元素上.节点通过增加宽度和高度突出显示,与节点应该在前面相同,重叠节点应该返回.
通过逐渐淡化其他元素,或者重新排列节点元素以解决问题.
等待建议?提前致谢.
d3.v4 - d3.v5 - d3.v6
.on('mouseenter', function() {
d3.select(this).raise()
})
Run Code Online (Sandbox Code Playgroud)
我相信您现在已经知道 SVG 没有 z-index。相反,它根据插入顺序对元素进行分层。要解决您的问题,请再次添加该节点,以便将其插入到其他所有内容之后(并显示在其他所有内容之上)。
这是包含解决方案的JSFiddle,它使用示例图像运行。
总结一下:
向 SVG 添加 ID,以便选择简单且明确:
vis = d3.select("#visfel_map").append("svg")
.attr("width", w).attr("height", h).attr("id", "mainSvg");
Run Code Online (Sandbox Code Playgroud)在设置过程中为每个节点添加 ID:
var idStart = "letter_";
// Append images
var images = nodeEnter.append("svg:image")
.attr("xlink:href", "https://www.freeclipartnow.com/d/39895-1/decorative-letter-A.jpg")
.attr("id", function(d){return idStart + d.name;})
Run Code Online (Sandbox Code Playgroud)
...`
接下来,添加将所需元素移动到插入列表末尾的函数。我基于此块,但我指定了 SVG 元素的 ID 以避免混淆。
d3.selection.prototype.moveToSvgFront = function() {
return this.each(function(){
d3.select("#mainSvg").node().appendChild(this);
});
};
Run Code Online (Sandbox Code Playgroud)最后,使用 moveToSvgFront 更新 mouseenter 函数。还要调用现有的 nodeTransform 函数以确保元素定位正确:
.on( 'mouseenter', function() {
var currNode = d3.select(this);
if(currNode.attr("id").length === idStart.length + 1){ // only run for letters, not for titles (which cause an error in nodeTransform)
currNode.moveToSvgFront();
currNode.attr("transform", nodeTransform);
...
}
})
Run Code Online (Sandbox Code Playgroud)**编辑:@Keerthivasan 这是一个 JSFiddle,其中包含用于移动文本并设置文本样式的代码。注意
A。已为新类 (focusLabel) 添加 CSS
b. 标签已被赋予与节点 ID 相关的 ID;这用于访问 mouseenter 函数中的标签,该函数根据节点的位置和大小设置平移
C。原始坐标在 mouseleave 函数中重新应用。