Pie chart animation when data changes in plottable.js - javascript

I am trying to animate a pie chart when data changes. Below is a code snippet
var piePlot = new Plottable.Plots.Pie()
.addDataset(dataset)
.outerRadius(function() { return Math.floor(piePlot.width()/10) + 40 })
.innerRadius(function() { return Math.floor(piePlot.width()/10) })
.sectorValue(function(d) { return d.y; })
.attr("fill", function(d) { return d.x; }, colorScale)
.attr("opacity",0.8)
.animated(true)
.animator(Plottable.Plots.Animator.MAIN,new Plottable.Animators.Easing().easingMode("quad").stepDuration(3500));
My confusion is the animation works great for charts such as line chart and area chart but doesnot work for other charts like rectangle chart, pie chart, scatter chart etc. Why is it so ? Do we need to make a custom animation function or what ? If yes can you please guide me...
Like I said this works perfectly
var linePlot = new Plottable.Plots.Line()
.addDataset(dataset)
.x(function(d) { return d.x; }, xScale)
.y(function(d) { return d.y; }, yScale)
.attr("stroke","#FA8116")
.animated(true)
.animator(Plottable.Plots.Animator.MAIN,new Plottable.Animators.Easing().easingMode("quad").stepDuration(3500));

Apparently it seems that there is no implementation of animation support for pie and rectangle chart.

Related

Add description text and links in zoomable circle packing graph with d3

I am still new at d3 and want to create a zoomable circle graph with title text, description text and links (the links only displayed in the leafs) that can be clicked and open a new page.
I have figured out how I can add those in a normal circle pack, but I can't implement it with the zoomable circle graph (not displayed)
It would be so great if someone could help me with it because I am so stuck with this.
Here my full working example at CodePen https://codepen.io/Lea12/pen/ExvoEgx
And the not working code
var description = g.selectAll("text")
.append("text")
.attr("class","description")
.attr("dy", +80)
.style("display", function(d) {
return d.parent === root ? "inline" : "none";
})
.text(function(d) {
return d.data.description;
});
var url = g.selectAll("text")
.append("text")
.attr("class","description")
.attr("dy", +120)
.text("click for more information")
.on("click", function(d) {
window.open(d.data.url,"_blank")
})

NVD3 - Adding and resizing multiple vertical lines to stacked area chart

I'm trying to add multiple vertical lines to the stacked area chart.
Adding multiple lines was achieved using a for-loop (maybe not the best way). The problem is, for-loop did not seem to work when updating the lines with nv.utils.windowResize() --- only the last line was updated eventually.
Maybe this could be done in a more D3 way without using a loop? Here is a fiddle for reproducing the problem (line 207 - 235).
I'd re-write your custom lines to be a little more d3-ish in nature (use data-binding, no explicit loops, etc...)
var xgrid = [1166996800000, 1186996800000, 1216996800000];
// add vertical lines
var custLine = d3.select('#stackedbarchart')
.select('.nv-areaWrap')
.append('g');
custLine.selectAll('line')
.data(xgrid)
.enter()
.append('line')
.attr({
x1: function(d){ return chart.xAxis.scale()(d) },
y1: function(d){ return chart.yAxis.scale()(0) },
x2: function(d){ return chart.xAxis.scale()(d) },
y2: function(d){ return chart.yAxis.scale()(1) }
})
.style("stroke", "#000000");
And then the update becomes:
nv.utils.windowResize(function() {
chart.update();
custLine.selectAll('line')
.transition()
.attr({
x1: function(d){ return chart.xAxis.scale()(d) },
y1: function(d){ return chart.yAxis.scale()(0) },
x2: function(d){ return chart.xAxis.scale()(d) },
y2: function(d){ return chart.yAxis.scale()(1) }
});
});
Note the use of the transition in there so the lines move a little better with the re-draw of the chart.
Updated fiddle.
You don't really need a for-loop to do this, just use selectAll. Here's one way:
First, to select the vertical lines easily I assigned them an id called vlines, in the for-loop on line 210
.attr('id', 'vlines')
Then use selectAll with this id to update the lines on resize. Here's your updated resize function:
nv.utils.windowResize(function() {
chart.update();
d3.selectAll('#vlines')
.attr('x1', function (d,i) { return chart.xAxis.scale()(xgrid[i]); })
.attr('y1', function (d,i) { return chart.yAxis.scale()(0); })
.attr('x2', function (d,i) { return chart.xAxis.scale()(xgrid[i]); })
.attr('y2', function (d,i) { return chart.yAxis.scale()(1); });
});
Using selectAll and functions, you can easily avoid loops in most cases.

Strange functionality of NVD3 Graph when updating data

I have some graphs using d3/nvd3. I am now wanting to be able to update the chart data with the click of a button, I have got it working 90% but when I update the data, the functionality becomes inconsistent.
By this I mean that the clickable legend stops working properly, usually you can double click one of them and it would single out the data.
I think somehow when the data updates, it still has the old data in it's memory and this is causing some issues?
Here is my javascript -
$( document ).ready(function() {
var negative_test_data = [{"key":"O1","values":[{"x":"NRW ","y":1},{"x":"WFW ","y":3}]},{"key":"O2","values":[{"x":"MED ","y":1},{"x":"FSEST ","y":1},{"x":"SW ","y":1},{"x":"LW ","y":4}]},{"key":"O3","values":[{"x":"SEEG ","y":1},{"x":"DLRW ","y":1},{"x":"SEM ","y":1},{"x":"DEN ","y":1},{"x":"LEW ","y":3}]},{"key":"O4","values":[{"x":"BUC ","y":2}]}];
var chart;
nv.addGraph(function() {
chart = nv.models.multiBarChart()
.color(d3.scale.category10().range())
.rotateLabels(0) //Angle to rotate x-axis labels.
.transitionDuration(200)
.showControls(false) //Allow user to switch between 'Grouped' and 'Stacked' mode.
.groupSpacing(0.24) //Distance between each group of bars.
;
chart.reduceXTicks(false).staggerLabels(true).groupSpacing(0.3);
chart.x (function(d) { return d.x; })
chart.yAxis
.tickFormat(d3.format(',.1f'))
.axisLabel('Defect Count')
.axisLabelDistance(40);
d3.select('#chart1M svg')
.datum(negative_test_data)
.call(chart);
return chart;
});
});
var update = function() {
var data = [{"key":"O1","values":[{"x":"NRW ","y":20},{"x":"WW ","y":3}]},{"key":"O2","values":[{"x":"ME ","y":1},{"x":"FST ","y":1},{"x":"SW ","y":1},{"x":"LEW ","y":4}]},{"key":"O3","values":[{"x":"SEEG ","y":1},{"x":"DLW ","y":1},{"x":"SEM ","y":1},{"x":"DE ","y":1},{"x":"LW ","y":3}]},{"key":"O4","values":[{"x":"BUDC ","y":2}]}];
var chart;
nv.addGraph(function() {
chart = nv.models.multiBarChart()
.color(d3.scale.category10().range())
.rotateLabels(0) //Angle to rotate x-axis labels.
.transitionDuration(250)
.showControls(false) //Allow user to switch between 'Grouped' and 'Stacked' mode.
.groupSpacing(0.24) //Distance between each group of bars.
;
chart.reduceXTicks(false).staggerLabels(true).groupSpacing(0.3);
chart.x (function(d) { return d.x; })
chart.yAxis
.tickFormat(d3.format(',.1f'))
.axisLabel('Defect Count')
.axisLabelDistance(40);
d3.select('#chart1M svg')
.datum(data)
.call(chart);
return chart;
});
};
Here is the JSFIDDLE - http://jsfiddle.net/kd82ep7p/8/ so that it can be demonstrated,
Before the data is updated you can play with the legend and select the data you want to see and even double click it.
After you click the update button, it becomes a problem,
If anyone could take a look I would greatly appreciate it.

D3 circle pack - Adding labels to nodes

While I've seen this question asked a few times, I'm having a bit trouble implementing. What I'd like to do is have the label attribute centered within each circle (as mentioned here). I believe I'd be adding the text attribute to:
canvas.selectAll('circles')
.data(nodes)
.enter()
.append('svg:circle')
.attr('cx', function (d) {
return d.x;
})
.attr('cy', function (d) {
return d.y;
})
.attr('r', function (d) {
return d.r;
})
.attr('fill', function (d) {
return d.color;
});
But am confused on why the instructions they gave in the previous example I linked to doesn't work with the setup I currently have. I believe it's the pack option that could be throwing me off (about the difference between the two), but any further examples would be a huge help. Thanks!
Update
Thanks for the answers/suggestions, I updated the Codepen with my progress (as I needed two lines of data; should have clarified) which seems to be working well. Now this is packing into a circle - at the end of the day, I'd love for this to be packed in the actual #canvas width/height (which is a rectangle). I saw this treemap example - would that be what I'm going for here?
Demo of what I have so far
Perhaps the confusion is that you can't add labels to the circle selection (because in SVG, a circle element can't contain a text element). You need to either make a g element that contains both circle and text, or a separate selection for the text, e.g.:
canvas.selectAll('text')
.data(nodes)
.enter()
.append('svg:text')
.attr('x', function (d) {
return d.x;
})
.attr('y', function (d) {
return d.y;
})
// sets the horizontal alignment to the middle
.attr('text-anchor', "middle")
// sets the vertical alignment to the middle of the line
.attr('dy', '0.35em')
.text(function(d) {
return d.label;
});
See the updated demo: http://codepen.io/anon/pen/djebv

How can you color each circle in the D3 circle pack layout

Here is an example of the pack layout in d3js:
http://bl.ocks.org/4063530
Is it possible to control the colors of the individual cirles?
Here is another example of the pack layout with colors:
http://bl.ocks.org/4063269
Can you help me understand how the colors are assigned to the bubbles in the second chart?
You can just add the attribute fill to change the color:
node.append("circle")
.attr("r", function(d) { return d.r; })
.style("fill", function(d){ return d.color; });
In the example above, suppose your data contains a color field.

Categories