I have donut chart, check the jsfiddle. There is text in side donut chart. Right now the text inside donut chart is shows foreground color's percentage. What I want is when I click on text of foreground percentage, I should get midground's percentage with flip transition, something like this flip action in css. I tried on click on this code, but I have no idea how to use
var text = svg.append("text")
.text('0%')
.attr("text-anchor", "middle")
.style("font-size",fontSize+'px')
.attr("dy",fontSize/3)
.attr("dx",2);
How can I do this in d3?
You can achieve this effect with chained transitions that scale in one dimension:
.on("click", function() {
d3.select(this)
.transition().duration(1000)
.attr("transform", "scale(0,1)")
.transition().duration(1000)
.attr("transform", "scale(1,1)")
.text("foo");
});
Complete example here.
Related
I have created a foot and added color gradient as shown in the solution for the below questions.
Add multi color gradient for different points in d3.js
d3.js scatter plot connecting dots with line
I have used clipath method to clip this foot. Now I want to set a black outline to this foot mask like in the picture below
Here is the Stackblitz Link
Add:
this.svgInner
.append("path")
.attr("d", line(ordered))
.style("stroke", "black")
.style("stroke-width", 1)
.style("fill", "none");
After line 300 of scatter-plot.component.ts in your StackBlitz
My implementation for Brush & Zoom functionality in my d3 line chart is not working as expected,
I followed this link - https://bl.ocks.org/EfratVil/92f894ac0ba265192411e73f633a3e2f,
Problems what I am facing is -
chart is not showing all the values, I have 4 data but it only shows 3 data
onClick of dot I am showing the rect which is not moving with the brush functionality
minor thing but chart always goes out of the box
My code sandbox - https://codesandbox.io/s/proud-firefly-xy1py
Can someone point out what I am doing wrong? thanks.
Please suggest me what I am doing wrong, thanks.
Your first point is going behind your clip area. For example, if you right click on the first visible circle and inspect element you will see all 4 circle elements are present in the dom. The first circle element is behind the axis.
This means you have to move your plot to the right. Unfortunately, the way you have coded the chart you have not appended a g element for the main chart and then appended the circles and path to that g element. As a result this has to be done in multiple places.
First we adjust your clip path as:
svg
.append("defs")
.append("SVG:clipPath")
.attr("id", "clip")
.append("SVG:rect")
.attr("width", containerWidth)
.attr("height", height)
.attr("x", 40)
.attr("y", 0);
next we adjust your circles
scatter
.selectAll(".foo")
.data(data)
.enter()
.append("circle")
.attr("class", "foo")
.attr("transform", "translate(40,0)")
and then your line
scatter
.append("path")
.datum(data)
.attr("class", "line")
.attr("d", line)
.attr("transform", "translate(40,0)");
You will have to account for this 40 px translate for your other elements as well. Although I am having a hard time destructuring your svg. I think this should give you the idea though. Check the axis matches the time points as well.
Check the code sand box
Update
To make the rectangles move with the brush, you will have to add code to your brushed const function to recalculate the x, y, width and height using the updated scales.
Update2
After going through the codesandbox presented in the comments I was able to add the code to update the rectangles to the brushed const as below to make the rects also move with the brushing:
// update rectangles
scatter
.selectAll(".rect-elements")
.attr("x", d => {
console.log(d);
return xScale(d.startTime) - 12.5;
})
.attr("y", 0)
.attr("width", 24)
.attr("height", height + 5);
Full working Code Sandbox.
I'm adding a tooltip to my stacked bar chart using d3-tip.js. The expected out put of my tooltip should be when the mouse hoover to the specific stack of a bar, the tooltip will show the population of that specific stack. As shown below, each stack on each bar represent a gender, male or female. The number above the bar is the sum of the population of male and female. Now I want the tooltip display the individual population of each gender. However, there are 3 problem in my implementation:
The data seems not render successfully, as the graph shown below, the data dose not render successfully.
The second problem is the tooltip shared between bars. For example, as the graph shown below, when my mouse is over the "female" (pink) stack of the Unknown relationship, you can see both the stack of "Unknown" bar and "Other" bar are highlighted, so seems like they shared the same tooltip across bars.
The position of the tooltip display is incorrect. As shown below, when my mouse is on the Male (blue) stack of Other, the position of the tooltip is not on the "Other", instead, it is on the "unknown" bar.
Below is the code of adding tooltips:
var tip = d3.tip()
.attr('class', "d3-tip")
.style("color", "white")
.style("background-color", "black")
.style("padding", "6px")
.style("border-radius", "4px")
.style("font-size", "12px")
.offset([-10, 0])
.html(function(d) { return `<strong>${d3.format(',')(keys, d => z(d.key))}</strong> population`; });
svg.call(tip);
svg
.selectAll('g.layer')
.on('mouseover', function(d) {
// show the tooltip on mouse over
tip.show(d, this);
// when the bar is mouse-overed, we slightly decrease opacity of the bar.
d3.select(this).style('opacity', 0.7);
})
.on('mouseout', function(d) {
// hide the tooltip on mouse out
tip.hide();
d3.select(this).style('opacity', 1)
});
And here is the link of the live demo of my graph in Plunker:
http://plnkr.co/edit/6xB2Kzi46hWL37UjlgTs?p=preview
Currently learning d3.js v5
I am working with a graph that displays a tooltip when an area of the graph is hovered over, along with highlighting the graph area selected. The issue I have noticed is that whenever any bar or line is hovered over, the tooltip won't display, and the area is no longer highlighted until I move off that area.
I was wondering if there is a way to have the mouseover element read the SVG element under the bars and lines or if I also need to add event listeners to the bars and lines.
I could potentially add another rect element that is invisible over all the other elements so that it is triggered first, however I also want to add interactivity to the bars and lines in the graph.
d3.csv("test.csv").then(function(dataset) {
backBar.selectAll("rectBack")
.data(dataset)
.enter()
.append("rect")
.attr("class","rectBack")
.attr("x",(d)=>xScale((d.year)))
.attr("y",margin.top)
.attr("width",(w)/dataset.length)
.attr("height",h-topBottom)
.attr("opacity",0)
.attr("fill","lightgrey")
.on("mouseover",function(d){
d3.select(this)
.attr("opacity",0.3);
showTooltip(d);
})
.on("mouseout",function(){
d3.select(this)
.attr("opacity",0);
removeTooltip();
})
function showTooltip(d){
d3.select("body")
.append("div")
.attr("class","tooltip")
.attr("opacity",0.5)
.html("<h5>"+d.year+"</h5>")
.style("top", yLineScale(d.line1) + svgPos.offsetTop)
.style("left", xScale(d.year) + svgPos.offsetLeft)
console.log(d);
}
function removeTooltip(){
d3.selectAll(".tooltip")
.remove("*");
}
}
svgPos is a variable that holds the coordinates of the SVG
yLineScale and xScale are both scales for the X and Y axis respectively
Link to image of graph: https://imgur.com/a/7rJFQjd
tried to create a scatterplot which can be zoomed but only the axis is getting zoomed and not the data. Not able to figure out whats wrong anybody any help with this one?.
github link of project : scatterplot with zoom
I see two separate issues with the way the zoom is working:
You are not selecting the <circle>s (points in the scatter plot) correctly when zooming. Consequently when you zoom only the axes are changing (as you described). An easy way to fix this is to give each <circle> a class (e.g. class="dot"), and then use that to select them.
First add the class="dot" to each of your circles (line ~140):
svg.selectAll("dot")
.data(data)
.enter().append("circle")
.attr("class", "dot")
Then update the function zoom to select them correctly (line ~195):
svg.selectAll(".dot") // <---- select all circles with class "dot"
.attr("cx", function(d) { return x(d.date); })
.attr("cy", function(d) { return y(d.close); });
Right now the zoom only occurs when you try to zoom in on an axis or individual point. If you want a user to be able to zoom in no matter where their mouse is over your scatter plot, you can add a background <rect> that will make sure the zoom event is detected for the SVG.
svg.append("rect")
.style("fill", "#fff")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
Making these two changes fixes the zoom.