Text Transition on Click D3.js - javascript

I have been searching on the internet for a simple fiddle of taking text with two x y coordinates and transitioning it from point 1 to point 2 but cannot seem to find anything if anyone knows of any examples it would be much appreciated. However on to the main point This first snippet of code successfully plots text at the center of the point.
svg.selectAll("text")
.data(data)
.enter()
.append("text")
.text(function(d) {
return d.Name;
})
.attr("x", function(d) {
return xScale(d.x);
})
.attr("y", function(d) {
return yScale(d.y);
})
.attr("font-family", "sans-serif")
.attr("font-size", "0.5px")
.style('text-anchor','middle')
.attr("fill", "black")
This transition is an attempt to change the text and transition to new locations
svg.selectAll('text')
.on('click', function (d) {
svg.selectAll("text")
d3.selectAll("text")
.transition()
.duration(1000)
.data(data)
.enter()
.append("text")
.text(function(d) {
return d.newNames;
})
.attr("x", function(d) {
return xScale(d.xx);
})
.attr("y", function(d) {
return yScale(d.yy);
})
.attr("font-family", "sans-serif")
.attr("font-size", "11px")
.attr("fill", "black")
})
Which does not work and does not show the text but also raises no errors in the console. I have done this before with svg shapes and it works the exact same way but for whatever reason I cant seem to get it to transition with text any help is appreciated Thanks

Your code kinda works, but is a bit strange. First, your initial font-size of 0.5px doesn't render for me in chrome. Second, your transition code has a syntax error in:
svg.selectAll("text")
d3.selectAll("text")
Third, you should be binding data, then doing the transition and not binding during the transition. Also, if you only want to move the existing text and your data didn't change, why rebind at all? And you certainly don't need to .enter().append().
Here's what I think you are after:
svg.selectAll('text')
.on('click', function(d) {
svg.selectAll("text")
.transition()
.duration(1000)
.text(function(d) {
return d.newNames;
})
.attr("x", function(d) {
return d.xx;
})
.attr("y", function(d) {
return d.yy;
})
.attr("font-family", "sans-serif")
.attr("font-size", "30px")
.attr("fill", "black")
});
Full code:
<!DOCTYPE html>
<html>
<head>
<script data-require="d3#3.5.3" data-semver="3.5.3" src="//cdnjs.cloudflare.com/ajax/libs/d3/3.5.3/d3.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body>
<script>
var data = [{
x: 20,
y: 20,
xx: 200,
yy: 200,
Name: "Hello",
newNames: "GoodBye"
},{
x: 100,
y: 20,
xx: 300,
yy: 200,
Name: "Love",
newNames: "Hate"
}];
var svg = d3.select('body')
.append('svg')
.attr('width', 500)
.attr('height', 500);
svg.selectAll("text")
.data(data)
.enter()
.append("text")
.text(function(d) {
return d.Name;
})
.attr("x", function(d) {
return d.x;
})
.attr("y", function(d) {
return d.y;
})
.attr("font-family", "sans-serif")
.attr("font-size", "14px")
.style('text-anchor', 'middle')
.attr("fill", "black");
svg.selectAll('text')
.on('click', function(d) {
svg.selectAll("text")
.transition()
.duration(1000)
.text(function(d) {
return d.newNames;
})
.attr("x", function(d) {
return d.xx;
})
.attr("y", function(d) {
return d.yy;
})
.attr("font-family", "sans-serif")
.attr("font-size", "30px")
.attr("fill", "black")
})
</script>
</body>
</html>

Related

mouseover doesn't work on d3 rectangle

I am new at d3. I have written the below code for 3 rectangles to appear and make them have some mouse interaction.
svg.append("g").selectAll("rect")
.data([1,2,3])
.enter()
.append("rect")
.attr("x",function(d,i){return 600+i*50;})
.attr("y",30)
.attr("width",40)
.attr("height",40)
.attr("fill","blue")
.on("mouseover",function(d) {
d3.select(this).append("text")
.attr("y", "100")
.attr("x", "500")
.attr("class", "hover")
.attr("font-family", "sans-serif")
.attr("font-size", "12px")
.style("fill", "black")
.text(function(d){console.log("mouseover");
return "Text I want";})
})
.on("mouseout", function(d) {
d3.select(this).select("text.hover").remove();
})
.on("click",function(d){console.log(d);
if(d==1)
Pie(array1,array2);
if(d==2)
Pie(array3,array4);
if(d==3)
Pie(array5,array6);
})
.style("opacity",1e-6)
.transition()
.duration(1000)
.style("opacity",0.8);
The console.log("mouseover") appears at the console, but no text is shown at the browser. The click event works with pie charts being constructed. Can anybody spot what is going wrong? Thank you in advance.
In your mouseover:
d3.select(this).append("text")
would append the text to the rect but rect elements can not have children.
Changing it to:
svg.append("text")
works. Full code example:
<!DOCTYPE html>
<html>
<head>
<script data-require="d3#3.5.3" data-semver="3.5.3" src="//cdnjs.cloudflare.com/ajax/libs/d3/3.5.3/d3.js"></script>
</head>
<body>
<script>
var svg = d3.select('body')
.append('svg')
.attr('width', 500)
.attr('height', 500);
svg.append("g").selectAll("rect")
.data([1, 2, 3])
.enter()
.append("rect")
.attr("x", function(d, i) {
return 10 + i * 50;
})
.attr("y", 30)
.attr("width", 40)
.attr("height", 40)
.attr("fill", "blue")
.on("mouseover", function(d) {
svg.append("text")
.attr("y", "100")
.attr("x", "200")
.attr("class", "hover")
.attr("font-family", "sans-serif")
.attr("font-size", "12px")
.style("fill", "black")
.text(function(d) {
console.log("mouseover");
return "Text I want";
})
})
.on("mouseout", function(d) {
svg.select("text.hover").remove();
})
.on("click", function(d) {
console.log(d);
if (d == 1)
Pie(array1, array2);
if (d == 2)
Pie(array3, array4);
if (d == 3)
Pie(array5, array6);
})
.style("opacity", 1e-6)
.transition()
.duration(1000)
.style("opacity", 0.8);
</script>
</body>
</html>
I think you should use d3-tip module for d3. It provides very nice hover tooltip
http://bl.ocks.org/Caged/6476579
var tip = d3.tip()
.attr('class', 'd3-tip')
.offset([-10, 0])
.html(function(d) {
return "<strong>Frequency:</strong> <span style='color:red'>" + d.frequency + "</span>";
})
and on bars or rectangles use
.on('mouseover', tip.show)
.on('mouseout', tip.hide)

Adding labels to the middle of a sunburst on mouseover

I've been working on a sunburst visualization example provided by the following link http://bl.ocks.org/mbostock/4063423. I want the label to display the name of the partition in question that has been moused over. Right now whenever I mouseover a partition it shows "flare" in the middle only. Is there a way for me to access the names of the children?
d3.json("flare.json", function(error, root) {
var path = svg.datum(root).selectAll("path")
.data(partition.nodes) //access the nodes
.enter()
.append("path")
.attr("display", function(d) { return d.depth ? null : 'none';}) //hide inner ring
.attr("d", arc)//used whenever I come across a path
.style("stroke", "#fff")
.style("fill", function(d) { return color((d.children ? d : d.parent).name);})
.style("fill-rule", "evenodd")
.each(stash)
.on("mouseover", mouseover)
.on("mouseout", mouseout);
var label = svg.append("text")
.attr("id", "tooltip")
.attr("x", 10)
.attr("y", 50)
.attr("text-anchor", "middle")
.attr("font-family", "sans-serif")
.attr("font-size", "11px")
.attr("font-weight", "bold")
.attr("fill", "black")
.style("opacity", 0)
.text(function(d) { return d.name; });
function mouseover(d) {
d3.select(this)
.transition()
.duration(100)
.style("opacity", 0.3);
label.style("opacity", .9);
console.log('mouseover', mouseover);
};
function mouseout(d) {
d3.select(this)
.transition()
.duration(100)
.style("opacity", 1);
label.style("opacity", 0);
console.log('mouseout', mouseout);
};
This problem is solved by first of all appending text elements to a g element and not svg element. Second you want to create a text element outside the mousehandler with a specific id then call it using that Id within the event handler like so.
d3.json("flare.json", function(error, root) {
var g = svg.selectAll("g")
.data(partition.nodes(root))
.enter().append("g");
var path =
g.append("path")
.attr("display", function(d) { return d.depth ? null : 'none';}) //hide inner ring
.attr("d", arc)//used whenever I come across a path
.attr("id", "part")
.style("stroke", "#fff")
.style("fill", function(d) { return color((d.children ? d : d.parent).name);})
.style("fill-rule", "evenodd")
.each(stash)
.on("mouseover", mouseover)
.on("mouseout", mouseout);
var text = g.selectAll("text")
.data(partition.nodes(root))
.enter()
.append("text")
.attr("id", "tip")
.attr("x", 10)
.attr("y", 50)
.attr("font-size", "11px")
.style("opacity", 0);
function mouseover(d) {
d3.select(this)
.transition()
.duration(1000)
.ease('elastic')
.style("opacity", 0.3);
//label.style("opacity", .9);
d3.select("#tip").text(d.name).style("opacity", 0.9);
console.log('mouseover', mouseover);
};
function mouseout(d) {
d3.select(this)
.transition()
.duration(100)
.style("opacity", 1);
d3.select("#tip").text(d.name).style("opacity", 0);
console.log('mouseout', mouseout);
};

D3: Day names on x-axis: Invalid value for <text> attribute x="NaN"

I have a D3 area chart showing values over time. Along my x-axis, I have 1-7 relating to days of the week. I want to replace these with mo, tu, we, etc etc etc
this.g.selectAll(".xLabel")
.data(_this.x.ticks(6))
.enter().append("svg:text")
.attr("class", "xLabel")
.text(String)
.attr("x", function(d) { return _this.x(d) })
.attr("y", 0)
.attr("text-anchor", "end")
.attr("stroke", "white")
.attr("opacity", .5);
I thought this could be easily achieved by replacing
.attr("x", function(d) { return _this.x(d) })
with
.attr("x", function(d) { return _this.x(_this.arrDays[d]) })
(with _this.arrDays being a simple ["mo", "tu",......] array) but this is giving me the following error:
Error: Invalid value for attribute x="NaN"
Anyone care to shed some light?
Sorted with:
this.g.selectAll(".xLabel")
.data(_this.x.ticks(6))
.enter().append("svg:text")
.attr("class", "xLabel")
.text(function(d) {return _this.arrDays[d-1]}) //changed this line
.attr("x", function(d) { return _this.x(d) })
.attr("y", "0")
.attr("text-anchor", "end")
.attr("stroke", "white")
.attr("opacity", .5);

d3.js force-collapsible with labels

Actually I've integrated collapsible feature inside bounded force directed graph. But when I tried to put a label on each node, I got unexpected output.
I used bellow code to append labels on node:
node.enter().append("text")
.attr("class","node")
.attr("cx", function(d) { return d.x; })
.attr("cy", function(d) { return d.y; })
.on("click",click)
.text(function(d){return d.name})
.call(force.drag);
And below code I've written inside a tick function:
node.attr("transform", function(d) {
return "translate(" + d.x + "," + d.y + ")";
});
What I might be doing wrong?
I need to append the g tag and then circle and text:
var nodeEnter = node.enter().append("g")
.attr("class", "node")
.on("click", click)
.call(force.drag);
nodeEnter.append("circle")
.attr("r", function(d) { return Math.sqrt(d.size) / 10 || 8.5; });
nodeEnter.append("text")
.attr("dy", ".35em")
.text(function(d) { return d.name; });
node.select("circle")
.style("fill", color);

JS D3 textPath isn't displayed

i have the code below and wonder, why the textpath isn't displayed? Can anyone help?
var areas = svg.append("g").selectAll("path")
.data(chord.groups)
.enter().append("path")
.style("fill", function(d) { return fill(d.index); })
.style("stroke", function(d) { return fill(d.index); })
.attr("class", "bar")
.attr("id", function(d, i) { return "group" + i; })
.attr("d", d3.svg.arc().innerRadius(innerRadius).outerRadius(outerRadius))
.on("mouseover", fade(.1))
.on("mouseout", fade(1));
svg.selectAll(".bar").append("text")
.style("font-size", "10px")
.attr("fill", "black")
.append("textPath")
.attr("x", 8)
.attr("dy", ".35em")
.style("fill", "#ff00ff")
.attr("xlink:href", function(d, i) { return "#group" + i; })
.text("Textexample");
Thank you very much!
Benjamin

Categories

Resources