admin管理员组文章数量:1297082
I am using the d3
v3 script to visualize the Data. I need to highlight and bring the node front in mousecenter and vice versa in mouseleave. Now I can able to high light the node by increasing height and width of the node.
Can't able to bring the node front. I've tried using CSS like opacity, z-index.
Script
<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
*
*/
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>
JSON Data
{
"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"
}
]
}
]
}
In the attached screenshot, node "M" is in focus, mouse over on that element. Node highlights by increasing the width and height, same as node should e front, overlapping nodes should go back.
By Fading the other elements also enough, or else re-arrange the node elements to fix the problem.
Awaiting Suggestions? Thanks in Advance.
I am using the d3
v3 script to visualize the Data. I need to highlight and bring the node front in mousecenter and vice versa in mouseleave. Now I can able to high light the node by increasing height and width of the node.
Can't able to bring the node front. I've tried using CSS like opacity, z-index.
Script
<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/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>
JSON Data
{
"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"
}
]
}
]
}
In the attached screenshot, node "M" is in focus, mouse over on that element. Node highlights by increasing the width and height, same as node should e front, overlapping nodes should go back.
By Fading the other elements also enough, or else re-arrange the node elements to fix the problem.
Awaiting Suggestions? Thanks in Advance.
Share Improve this question edited Mar 16, 2018 at 17:15 timiTao 1,4133 gold badges22 silver badges36 bronze badges asked Mar 6, 2018 at 18:46 KeerthivasanKeerthivasan 1,6611 gold badge22 silver badges47 bronze badges 9- 1 You can contol the positioning ("absolute", "relative" etc) or the z index property with d3. Maybe start there. – Ryan Morton Commented Mar 6, 2018 at 18:57
- @RyanMorton Already tried. Not working. – Keerthivasan Commented Mar 6, 2018 at 19:03
-
3
v4 has a
selection.raise()
method which does just that. Unfortunately v3 does not, but selection.order might do it. – pmkro Commented Mar 6, 2018 at 19:19 -
2
moveToFront()
? bl.ocks/eesur/4e0a69d57d3bfc8a82c2 – Ryan Morton Commented Mar 6, 2018 at 19:19 - 2 Please provide the data that you're using in var url so that we can replicate the issue. – SilentStone Commented Mar 9, 2018 at 20:24
3 Answers
Reset to default 5d3.v4 - d3.v5 - d3.v6
.on('mouseenter', function() {
d3.select(this).raise()
})
Example
As already mentioned, drawing order of SVG elements is determined by their order in DOM.
The this.parentNode.appendChild(this)
trick works as long as it's performed on the right element. In your case, it's not the <image>
but its parent <g>
that has to move.
images.on('mouseenter', function() {
var parent = this.parentNode; // <g>
parent.parentNode.appendChild(parent);
var currNode = d3.select(this);
//...
})
Example (with placeholder images)
I'm sure you know by now that SVG doesn't have z-index. Instead, it layers the elements based on insertion order. To solve your issue, add the node again so that it's inserted after (and displayed over) everything else.
Here's the JSFiddle with the solution, running with a sample image.
To summarize:
Add an ID to the SVG so that selections are simple and unambiguous:
vis = d3.select("#visfel_map").append("svg") .attr("width", w).attr("height", h).attr("id", "mainSvg");
Add an ID for each node during setup:
var idStart = "letter_"; // Append images var images = nodeEnter.append("svg:image") .attr("xlink:href", "https://www.freeclipartnow./d/39895-1/decorative-letter-A.jpg") .attr("id", function(d){return idStart + d.name;})
...`
Next, add the function to move the desired element to the end of the insertion list. I based it on this block but I'm specifying the ID of the SVG element to avoid confusion.
d3.selection.prototype.moveToSvgFront = function() { return this.each(function(){ d3.select("#mainSvg").node().appendChild(this); }); };
Finally, update the mouseenter function, using moveToSvgFront. Also invoke your existing nodeTransform function to ensure that the element is positioned correctly:
.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); ... } })
**Edit: @Keerthivasan Here's a JSFiddle with code to also moves and styles the text. Note that
a. CSS has been added for the new class (focusLabel)
b. The labels have been given an ID related to the node's ID; this is used to access the label in the mouseenter function, which sets the translation based on the node's position and size
c. The original coordinates are reapplied in the mouseleave function.
本文标签: javascripthow to bring the selected node front in d3 jsStack Overflow
版权声明:本文标题:javascript - how to bring the selected node front in d3 js? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741621443a2388834.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论