Transition on labels in d3 pie/donut chart
By : Hiran
Date : March 29 2020, 07:55 AM
around this issue Add same transition effect to label group also DEMO code :
label_group.data(pie)
.transition().duration(750)
.attr("transform", function(d) {
var c = arc.centroid(d);
return "translate(" + c[0] +"," + c[1] + ")";
})
|
D3 exit mutli-series line chart labels on transition
By : ahmer khan
Date : March 29 2020, 07:55 AM
will be helpful for those in need You are appending a new text element to each person every time you render and not removing the old ones. Presumably the code you posted gets run every time you want to draw the chart with new data, so you end up with more text elements every time, rather than updating the existing ones. You need to only append on the "enter" selection. You did this right on the path elements, so you just need to make the text work more like the path. I've updated your example with comments to highlight what I changed. code :
var line = d3.svg.line()
.interpolate("basis")
.x(function(d) { return x(d.Date); })
.y(function(d) { return y(d.candidate); });
var person = svg_multi.selectAll(".candidate")
// I added a key function here to make sure you always update the same
// line for every person. This ensures that when you re draw with different
// data, the line for Trump doesn't become the line for Sanders, for example.
.data(people, function(d) { return d.name});
var personGroups = person.enter()
.append("g")
.attr("class", "candidate");
// This isn't needed. The path and text get appended to the group above,
// so this one just sits empty and clutters the DOM
// person
// .enter().append("g")
// .attr("class", "candidate");
personGroups.append("path")
.attr("class", "line")
// You do this down below, so no need to duplicate it here
// .attr("d", function(d) { return line(d.values); })
.style("stroke", function(d) { return color(d.name); });
// Append the text element to only new groups in the enter selection
personGroups.append("text")
// Set any static attributes here that don't update on data
.attr("x", 3)
.attr("dy", ".35em");
var personUpdate = d3.transition(person);
personUpdate.select("path")
.transition()
.duration(1000)
.attr("d", function(d) {
return line(d.values);
});
person.select("text")
// You don't have to do this datum call because the text element will have
// the same data as its parent, but it does make it easier to get to the last
// value in the list, so you can do it if you want
.datum(function(d) { return {name: d.name, value: d.values[d.values.length - 1]}; })
.attr("transform", function(d) { return "translate(" + x(d.value.Date) + "," + y(d.value.candidate) + ")"; })
.text(function(d) { return d.name; });
// Remove this. You don't need it anymore since you are updating the text above
// person.selectAll("text").transition()
// .attr("transform", function(d) { return "translate(" + x(d.value.Date) + "," + y(d.value.candidate) + ")"; });
person.exit().remove();
|
How to display labels in pie transition chart using d3.js?
By : Salik Bin Rashid
Date : March 29 2020, 07:55 AM
Hope this helps To display the text in the "exact location" (which I supposed is in the middle of the arc), you can use the centroid() function: code :
var labels = arcs.append("text")
.attr("transform", function(d) {
d.innerRadius = 120;
return "translate(" + arc.centroid(d) + ")";
})
.attr("dy", ".35em")
.text(function(d) { return d.value; });
var w = 400,
h = 400,
r = Math.min(w, h) / 2,
data = [25,45], // Data values
color = d3.scale.category20(),
arc = d3.svg.arc().outerRadius(r),
donut = d3.layout.pie();
var vis = d3.select("body").append("svg") // Place the chart in 'pie-chart-div'
.data([data])
.attr("width", w)
.attr("height", h);
var arcs = vis.selectAll("g.arc")
.data(donut)
.enter().append("g")
.attr("class", "arc")
.attr("transform", "translate(" + r + "," + r + ")");
var paths = arcs.append("path")
.attr("fill", function(d, i) { return color(i); });
var labels = arcs.append("text")
.attr("transform", function(d) { d.innerRadius = 120; return "translate(" + arc.centroid(d) + ")"; })
.attr("dy", ".35em")
.text(function(d) { return d.value; });
paths.transition()
.ease("bounce")
.duration(2000)
.attrTween("d", tweenPie);
paths.transition()
.ease("elastic")
.delay(function(d, i) { return 2000 + i * 50; })
.duration(750)
.attrTween("d", tweenDonut);
function tweenPie(b) {
b.innerRadius = 0;
var i = d3.interpolate({startAngle: 0, endAngle: 0}, b);
return function(t) {
return arc(i(t));
};
}
function tweenDonut(b) {
b.innerRadius = r * .6;
var i = d3.interpolate({innerRadius: 0}, b);
return function(t) {
return arc(i(t));
};
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
|
Transition of labels in D3.js: Rename label names on change and transition smoothly
By : user3112927
Date : March 29 2020, 07:55 AM
With these it helps The problem is that you are removing the DOM elements for the text and not updating them. If there is a need to remove them then you can fade out the text and remove them at the end as such d3.select("text").transition().duration(300).style("opacity","0").on("end", () => { d3.select("text").removeAll() }); but I suggest that you reuse the labels and just update their content using the same d3.select("").transition().duration(300) way
|
How to add direct labels to a bar chart in ggplot for numeric x axis
By : user3517532
Date : March 29 2020, 07:55 AM
To fix the issue you can do I think it will be easier to do a bit of data prep so you can put all the boxes in one facet with a shared x-axis. For instance, we can calc the cumulative sum of reduction Kg, and use that to define the starting x for each box. EDIT -- added ylim = c(0, NA), xlim = c(0, NA), to keep ggrepel::geom_text_repel text within positive range of plot. code :
library(ggplot2)
library(ggrepel)
library(stringr)
library(dplyr)
Cost %>%
arrange(desc(Average.of.Cost_Per_Kg_P_Removal.undiscounted..LOW_Oncost)) %>%
mutate(Row.Labels = forcats::fct_inorder(Row.Labels),
cuml_reduc = cumsum(Average.of.FS_Annual_P_Reduction_Kg),
bar_start = cuml_reduc - Average.of.FS_Annual_P_Reduction_Kg,
bar_center = cuml_reduc - 0.5*Average.of.FS_Annual_P_Reduction_Kg) %>%
ggplot(aes(xmin = bar_start, xmax = cuml_reduc,
ymin = 0, ymax = Average.of.Cost_Per_Kg_P_Removal.undiscounted..LOW_Oncost)) +
geom_rect(fill = "grey", colour = "black") +
geom_text_repel(aes(x = bar_center,
y = Average.of.Cost_Per_Kg_P_Removal.undiscounted..LOW_Oncost,
label = str_wrap(Row.Labels, 15)),
ylim = c(0, NA), xlim = c(0, NA), ## EDIT
size = 3, nudge_y = 1E4, nudge_x = 2, lineheight = 0.7,
segment.alpha = 0.3) +
scale_y_continuous(labels = scales::comma) +
labs(x = "Measure code and average P reduction (kg/P/yr)",
y = "Mean annual TOTEX (£/kg) of P removal (thousands)")
|