How to fasten the d3 zoomable sunburst transitions? - javascript

I have created a zoomable sunburst with the reference from the following website. http://bl.ocks.org/mbostock/4348373
The problem is I have a lot of arcs in the final level i.e the outermost ring (nearly 2000 arcs) and this is slowing the sunburst transitions on click.
One way through which I am trying to fasten the process is show the outermost arcs only when the user dives into the sunburst (clicks on any of the sub arcs). If the outermost arc is fourth concentric circle. Show that only when user selects levels 2/3.
I created the initial dataset to have size set to 0 for the outermost arcs. And on click I wrote a function to set the size to 1. However it is not working. Below is the link http://jsfiddle.net/Claw_22/1400rdu0/6/
function sizeFunc(data){
if (!data.children) {
if (data.level=="3") {
data.size="1";
}
}
else {
for (i=0;i<data.children.length;i++) {
sizeFunc(data.children[i]);
}
}
}
Kindly let me know how we can achieve this. (Alternate solutions to achieve faster performance are also helpful.)

You can change the transition duration to a min level in click function. Something like following
function click(d) {
path.transition()
.duration(100) //sets the delay in transition
.attrTween("d", arcTween(d));}

Related

D3-Force-Quicker stabilization of nodes & transition of elements in projectiles

I have implemented the following version of the force diagram to show inter-cluster movement of nodes.
https://jsfiddle.net/Edwig_Noronha/67ey5rz0/
The nodes are grouped into four clusters. After the first initialization of the force diagram ends I call a function to transition the nodes from source to destination clusters.
function moveNodes() {
Object.keys(inputdata).forEach(function(key, index) {
svg.selectAll("circle.viewernodes" + index)
.each(function(d) {
d.type = d.destination;
});
});
viewersTransitioned = true;
force.start();
}
However, The stabilization of the first initialization of the force diagram takes about 35 seconds. Hence the transition happens after that much time.
Q1) is it possible to achieve a quicker stabilization of the force diagram with collision detection?
The transition of the nodes from source to destination clusters happens along a linear path.
Q2) Is it possible to make the nodes move along projectile paths?
To achieve quicker stabilization you can do one of two things in my experience.
Initialize the nodes X and Y values to be near to their end/goal state
Such as nodes[i].x = 500 etc, then calling the simulation start.
This would somewhat defeat the purpose of what you're trying to show in your example, unless you don't want the nodes to be shown moving to the groups and just be in them to begin with...
Stronger force
Have the force moving/pulling the nodes be stronger. This would require an essentially fundamental change to your approach to this example. Instead of just transitioning their positions, create custom forces within your force-layout that affect the appropriate nodes only based on their attributes. Place these forces in the center of your 'sorting circles' and they would attract the nodes appropriately.
See here for what something like this would look like: https://bl.ocks.org/mbostock/1021841

how to improve the drilling performance of d3 sunburst chart when there are too many paths? like dynamically show partial levels?

I'm new to d3 and now trying to render a sunburst chart with a really big set of data. But I find out that with the number of paths goes up, the drilling of chart becomes dull, like stops for one sec and then drills.
Is there any way to improve this? I'm thinking to display a limited number of levels but how to make showing levels dynamically change when the center changes?
function click(d) {
var duration = config.animationDuration || config.animationDuration === 0 ? config.animationDuration : 1000;
path.transition()
.duration(duration)
.attrTween("d", arcTween(d))
path.attr("display", function(d){
if(d.depth>config.drillDownPath.length + data.levelLimit-1) return "none";
}); }
In the code above, I tracked the chart drilldown path to decide if a path is shown or not. But this didn't solve the question because the the path still exists in the DOM.
Can anyone help me with this? Thanks!
I know this is a bit late, but I might try this example for displaying a large hierarchical dataset allowing for the user to drill down to any level.
By only rendering and transitioning 2-3 levels of arcs at a time, your transitions will probably lag less and the chart would probably be more readable. However, as mentioned by Lars, it's really hard to give you a concrete demo without seeing more code...

D3.js - Data and Axis Not Synchronized During Pan

I created a scatter plot using D3.js that updates every 20 seconds. It also pans and zooms. The problem is the data lags behind the axis during the pan. I've looked for examples of a similar implementation but all I can find are ones that either do zoom/pan or do intervals, not both. I can't find the source of the problem. A simplified demo of my code can be found here: http://jsbin.com/yurik/1/edit. Any help is appreciated.
The synchronization issue comes from the fact that you are using a transition to move the circles and not using a transition to update the x-axis. Here's the relevant snippet from the draw function:
circles.transition()
.attr("cx", function(d) { return x(dateFn(d)) })
.attr("cy", function(d) { return yValueFn(d) });
svg.selectAll("g.x.axis").call(xAxis);
Because D3 has a default transition duration of 250 milliseconds, the circles are lagging behind the axis, which is updated instantly. You can synchronize the two by reducing the transition duration to 0 like this:
circles.transition().duration(0)
That should make the x-axis and circles move synchronously.

How do I make specific elements appear on top of others in D3.js?

I have a plot in D3 where I draw some circles and then some ellipses afterwards to show the median. I have a 1.5 second delay on my median, to try and draw it after the circles have appeared, but I still run into problems.
Here is a screenshot of an example: http://puu.sh/8csEK.png
The circle to the far right are behind it's median, the rest of the circles are all in front. When areas are crowded you cannot see the median anymore.
I have even tried using the following on transitions of my circles, but it's no use:
.each("end", <call function to draw ellipses>)
So my question is, how do i make sure that my ellipses are drawn on top of my circles?
I have a function that draws my ellipses and a function that draws my circles right now.
I'm assuming that you're using SVG to render your elements. In SVG, the display order is the order of drawing/appending to the DOM. That is, the element you append first is drawn at the back, the element you append last at the front. Child elements (e.g. something underneath a g) are drawn when their parent elements are drawn.
To make sure that groups of elements have the right order, it's usually easiest to add them to different SVG groups that are drawn in the right order. In code, this looks something like this.
var circles = svg.append("g");
var ellipses = svg.append("g");
// ...
ellipses.append(...); // this element appears in the front although it is drawn
// earlier because it is appended to the group appended last
circles.append(...); // this element appears behind the one appended to ellipses

responsive d3 area graph stretches circle interaction points

I have been experimenting with a simple d3 google analytics-style area graph demo. I'd like to make it stretch to the full width of its container, which I have managed to do. However the little circles are of course stretching out of shape too. I'd like their positions to be responsive, but not their dimensions (so they remain circular).
Fiddle link: http://jsfiddle.net/46PfK/2/
I'm trying to use the SVGPanUnscale.js script. I have tried calling it with unscaleEach('.dot'); and [].forEach.call($('.dot'),unscale); but neither appear to do anything.
This example is responsive in a similar way to mine and uses the script to 'unscale' the axis labels: http://meloncholy.com/static/demos/responsive-svg-graph-1/
This example also uses circle elements:
http://phrogz.net/svg/scale-independent-elements.svg
I looked at solutions involving the css attribute:
circle {
vector-effect: non-scaling-stroke;
}
which created a circular stroke on an ellipse - weird.
A CSS solution would be preferable to a JS one, provided it works across browsers.
Any suggestions?
Thanks to #leMoisela for pointing me in the right direction. I fixed my issue nicely using JS to redraw the graph on resize:
http://jsfiddle.net/46PfK/4/
window.onresize = function(e){
draw_graph();
};
There's a good example on resizing with D3 https://blog.safaribooksonline.com/2014/02/17/building-responsible-visualizations-d3-js/
After you update your scales, only thing left to resize your circles would be something like this:
/* Force D3 to recalculate and update the points */
svg.selectAll('circle')
.attr('cx', function (d) { return xScale(d.x); })
.attr('cy', function (d) { return yScale(d.y); })
.attr('r', 4);

Categories