I have a bar chart and want to add effect to fade bars one by one with some delay.
Here is what I have now but it fades in all bars that are path at once. How can I make them appear one after another with some delay?
.selectAll("path")
.attr "opacity", (d,i)->
0
.transition().delay(3000).duration(1000)
.attr "opacity", (d,i)->
1
Answer
Use the index value to stagger the delay
.delay(function(d,i){return i * 300;})
Because the index is zero based this means the first item has no delay. If this is not desired then you could do something like something like
.delay(function(d,i){return (1+i) * 300;})
Example
For those less familiar with D3 a quick example of this in action at this JSFiddle
Related
I have a bar chart. I want to change the fill of specific bars to red based on the value of their data.
I don't want there to be a "flash" when the chart redraws; I never want the user to see the original fill. So it makes logical sense to change the fill of the bars on pretransition so that the color is changed before the bar displays on screen. However, when I try to do this, the bars flash red as they are rendering, but transition back to blue again as they render, making them look exactly the same as the others by the time they finish rendering. See this fiddle. Essentially, I tried this:
barChart.on('pretransition', chart => {
chart.selectAll('rect.bar').filter(d => d.data.value > 18)
.attr('fill', 'red');
})
How can I get the bars to be red while they are transitioning as well as after they finish rendering? I tried repeating the code on the renderlet as well, but they still transition to blue during the transition, then flash back to red after the transition.
Also, I don't want to turn the transitions off altogether by something like this:
barChart.transitionDuration(0)
I want to see the bars grow, just have them be red the entire time.
I am moving a rectangle from point a to point i in a picture, i want to mark a stop delay of 5s for each point (there are 8 points). the transitions work fine in the code below (the delay works only for point b).The problem is that i can't add more delays for my other transitions.
Is there any way to do it ?
Thank you all in advance.
function TRANSITION(access,dur=10000,Delay=5000,b=390.5,c=523,d=632.5,e=810.8,f=942.5,g=1063,h=1196,i=1334.5)
{
access.transition().duration(dur).attr('x',b)
.transition().delay(Delay).duration(dur).attr('x',c)
.transition().duration(dur).attr('x',d)
.transition().duration(dur).attr('x',e)
.transition().duration(dur).attr('x',f)
.transition().duration(dur).attr('x',g)
.transition().duration(dur).attr('x',h)
.transition().duration(dur).attr('x',i)
}
You could add a transition that changes no attributes but still has a duration:
.transition()
.duration(dur)
.attr('x',d)
.transition() // don't transition anything
.duration(5000) // but take five seconds doing it
.transition()
.duration(dur)
.attr('x',e)
I've only tested this in version 4, so it is possible that this might not work in version 3. Alternatively, you could add the .attr line in the delaying transition if you were to leave some attribute the same.
In my code so far, I have appended the tick markers and labels to the jQuery UI slider. When I increase/decrease the size of the browser window, these ticks go out of sync with the slider.
It is happening because of the following piece of code:
$('<span class="ui-slider-tick-mark"> <br/>'+ date[i] +'</span>') // line # 44 in JS
.css('left', (spacing * i - 3.5) + '%')
.appendTo($slider);
I tried to play around with the static value but it seems that as long as this value is static, its not going to be responsive.
I believe that if the first and last tick stays at the start and end of the slider respectively, it will be synchronized.
How do I achieve this?
jsFiddle
you shouldn't add any additional value to percentage (spacing * i - 3.5)
http://jsfiddle.net/f5dxq8mj/22/
I am trying to implement a search function on a d3 force directed graph example.
When I type in the search query in the text field, relevant items will be shown and the irrelevant ones will fade out.
I have implemented the methods searchUpdate and count as shown in the following jsfiddle.
I need some help to fade the items. Currently d3.select("svg") fades the whole graph, while d3.select("#"+n.id) produces an error.
When you d3.select("svg") you're selecting the SVG canvas and setting its opacity. What you want to do is
d3.selectAll("circle")
or
d3.selectAll("circle.node")
and apply the opacity there.
Then what you want to do is select the circles that match by ID using d3.select("#"+n.id) but to do so you'll have to create an id when you create the circles, like
.attr("id", function(d,i) {return "circle"+i})
Otherwise you don't have an id to select with.
I've created a 'donut' chart originally from this jsfiddle, using raphael.
I have tweaked this script to suit my needs and currently have this being rendered.
My aim is to animate each slice (at the same time); for example make the blue slice grow to 60%; and the red slice shrink to 40%.
I have been able to redraw the slices by removing the existing one and quickly re-rendering a new one with adjusted values (e.g. 51, 49). But the problem here is that it is instant.
My question is,
(a) Can I animate this without the need to redraw the object (and how)?
(b) If not, how I can animate this effect using a redraw logic?
Yes. There is an example of doing this very thing on the Raphael demos page where you got the pie chart. See the Growing Pie demo.
You should separate the code in which you generate the path into a standalone function so you can use it later to return new paths. In order to use animate(), you'll need to define a function on the customAttributes object; it should return (at least) an object with the path property set to your slice's new path.
Since you have labels, you'll probably want to modify the code such that the pie slices expand/shrink relative to their center, so that you don't have to move the labels, too, since the labels are centered on their slice's "axis."
Update
Here's a JSFiddle with a simple example, pretty much the same as Dmitri's Growing Pie demo, except more like your chart. I export a setValue() method to change slice sizes and call it when the page loads. See his blog post about adding customAttributes, too.
In my last paragraph above, I was off the mark a bit. Your chart wasn't the one with labels; I had them mixed up. Also, it would be harder to keep slices centered, so I didn't do that after all. The animate() function sets each segment to its new starting and ending points on the circle, and Raphael figures out the intermediate points. As you can see, you can pass multiple arguments in an array.
this.customAttributes.slice = function(a0, a1) { /*...*/ }
// ...
chart.push(paper.path().attr({slice:[0, Math.PI/2 ]})
Can't see all the fiddle because I'm on iPod however it sounds like you need to have an animate call inside a function that you will need to write
Use the callback parameter that calls the function it sits inside.
Code your recursively called function so it eventually completes when all the work is done.
Each call to the function will happen at the end of every elapssed time interval you specify...