NVD3 width error inside Tabs - d3.js

I am very new to charting with D3 and NDV3.
I am putting the charts inside tabs. (Using Foundation 6.4)
The first chart is fine but the chart on the next clicked tab has a width issue. If I re-size the window it expands to the proper size.
Here is the code based on their example. Both charts are the same code - just with different IDs.
Thanks for any insight on using charts inside jquery tabs.
the code:
<div id="chart1"></div>
<script>
var chart;
var data;
var legendPosition = "top";
nv.addGraph(function () {
chart = nv.models.lineChart()
.options({
duration: 300,
useInteractiveGuideline: true
})
;
chart.xAxis
.axisLabel("Time (s)")
.tickFormat(d3.format(',.1f'))
.staggerLabels(true)
;
chart.yAxis
.axisLabel('Voltage (v)')
.tickFormat(function (d) {
return d3.format(',.2f')(d);
})
;
data = sinAndCos();
d3.select('#chart1').append('svg')
.datum(data)
.attr('height', 400)
.call(chart);
nv.utils.windowResize(chart.update);
return chart;
});
function sinAndCos() { ... }
</script>
First tab is fine - second one is very narrow.
this is the link for the Foundation Tabs.
https://foundation.zurb.com/sites/docs/tabs.html
Thank you very much. Cheers.

Looking at the source code of nvd3 the width and height are determined by the style attribute of the svg.
Add the svg to the div yourself and give it a style attribute. Maybe it also works with a CSS style width and height, for responsive websites. Just like an image you specify the size.
<div id="chart1">
<svg id="svg-chart1" style="width:800;height:400;"></svg>
</div>
<script>
....
d3.select('#svg-chart1')
.datum(data)
.call(chart);
....
</script>
Or with a different selector
<div id="chart1">
<svg style="width:800;height:400;"></svg>
</div>
<script>
....
d3.select('#chart1 svg')
.datum(data)
.call(chart);
....
</script>
I used the line chart example from the NVD3 site and got errors on these lines
.useInteractiveGuideline(true) //We want nice looking tooltips and a guideline!
.transitionDuration(350) //how fast do you want the lines to transition?
so I commented them out. But looking at your example you set these with the options() method. Using options() I get the interactive guideline and no errors.

Related

vuejs scoped styles not working with d3js

I am trying to integrate Vue.js and D3.js. What I notice is sometimes the CSS classes don't really work on the svg elements. I am giving the snippet of the vue component below.
<template>
<div>
<h1>Hello world</h1>
<svg width="300" height="100" ref="barchart"></svg>
</div>
</template>
<script>
import * as d3 from "d3";
export default {
name: "LineChart",
mounted() {
d3.select("h1").attr("class","red-text")
var data = [10,20,15,30,60];
var barHeight = 20;
var bar = d3
.select(this.$refs.barchart)
.selectAll("rect")
.data(data)
.enter()
.append("rect")
.attr("class","rect")
.attr("width", function(d) {
return d;
})
.attr("height", barHeight - 1)
.attr("transform", function(d, i) {
return "translate(0," + i * barHeight + ")";
});
}
};
</script>
<style scoped>
.rect{
fill: blue;
}
.red-text{
color:red;
}
</style>
Its output is obtained as :-
scoped css output
But as sson as I remove the scoped attribute, the code works fine. New output :-
global css output
Thanks in advance!
Scoped styles work by vue assigning a unique attribute to dom elements, and then adjusting the style rules by adding an extra criteria for elements to have that attribute. Example in vue guide. However, since elements dynamically created with d3 aren't managed by vue (since they aren't part of the template), it doesn't work out of the box. One way to solve this, is to to use deep selector (e.g. svg >>> .rect { ... }), which doesn't attach the additional unique attribute criteria for the child elements.
If you just want to color the bars you don't need explicit css. You can just set:
.style("fill", function(d) { return 'blue'; })
on your bar.

What is the maximum value for the .duration() command in d3.js?

I am going through D3 Tips & Tricks and i'm on this graph: http://bl.ocks.org/d3noob/7030f35b72de721622b8.
I am playing around with the different axises to get them to re-render and re-size dynamically upon a JavaScript function has been called via a button. I want to re-render the x axis so that it takes longer to fully load than the re-generated line element.
// Select the section we want to apply our changes to
var svg = d3.select("body").transition().delay(500).style("stroke", "green");
// Make the changes
svg.select(".line") // change the line
.duration(750)
.style("stroke", "red")
.attr("d", valueline(data));
svg.select(".x.axis") // change the x axis
.duration(1750)
.call(xAxis);
svg.select(".y.axis") // change the y axis
.duration(1000000000)
.call(yAxis);
});
In theory, I suppose that .duration() command can take the highest integer value that JavaScript accepts as a .millisecond. Is that correct? I am keen to know if there is a limit here as to the longest possible duration I can make.
I just coded up a quick example with Number.MAX_VALUE and d3 doesn't complain:
<!DOCTYPE html>
<html>
<head>
<script data-require="d3#4.0.0" data-semver="4.0.0" src="https://d3js.org/d3.v4.min.js"></script>
</head>
<body>
<script>
var svg = d3.select('body')
.append('svg')
.attr('width', 500)
.attr('height', 500);
var c = svg.append('circle')
.attr('transform', 'translate(20,20)')
.attr('r', 20)
.style('fill', 'steelblue');
c.transition()
.duration(Number.MAX_VALUE)
.ease(d3.easeLinear)
.tween("attr.transform", function() {
var self = d3.select(this),
i = d3.interpolateTransformSvg('translate(20,20)', 'translate(400,400)');
return function(t) {
console.log(i(t));
self.attr('transform',i(t));
};
});
</script>
</body>
</html>
Some quick calculations tell me though that it'll take 1x10306 iterations of the transition loop to move my circle 1px, so assuming the transition loop is firing every 17 milliseconds, that's around 5.34 × 10296 years before I see any movement....

NVD3 Format Date Differently From X-Axis

I have a NVD3 chart and would like to format the date value in the tooltip window as a complete date down to the seconds, while changing the labels in the x-axis only by the day.
Here is my chart:
d3.json("mydata.json", function (error,data) {
var chart;
nv.addGraph(function() {
var chart = nv.models.lineChart()
.margin({left: 100}) //Adjust chart margins to give the x-axis some breathing room.
.useInteractiveGuideline(true) //We want nice looking tooltips and a guideline!
.transitionDuration(350) //how fast do you want the lines to transition?
.showLegend(true) //Show the legend, allowing users to turn on/off line series.
.showYAxis(true) //Show the y-axis
.showXAxis(true) //Show the x-axis
;
chart.xAxis //Chart x-axis settings
.axisLabel('Date')
.tickFormat(function(d){return d3.time.format('%d-%m-%y')(new Date(d));});
chart.yAxis //Chart y-axis settings
.axisLabel('Temperature')
.tickFormat(d3.format('.02f'));
d3.select('#chart svg') //Select the <svg> element you want to render the chart in.
.datum(data) //Populate the <svg> element with chart data...
.call(chart); //Finally, render the chart!
nv.utils.windowResize(function() { chart.update() });
return chart;
});
});
And some example data:
[{"key":"Ambient Temperature","color":"#0000ff","values":[{"x":1407978270000,"y":22.47},{"x":1407978353000,"y":22.53},{"x":1407978353000,"y":22.53},{"x":1407978415000,"y":22.63},{"x":1407978523000,"y":22.51},{"x":1407978524000,"y":22.51},{"x":1407978546000,"y":22.5},{"x":1407978562000,"y":22.41},{"x":1407978571000,"y":22.35}]},{"key":"Windchill Temperature","color":"#00ff00","values":[{"x":1407978270000,"y":22.47},{"x":1407978353000,"y":22.53},{"x":1407978353000,"y":22.53},{"x":1407978415000,"y":22.63},{"x":1407978523000,"y":22.51},{"x":1407978524000,"y":22.51},{"x":1407978546000,"y":22.5},{"x":1407978562000,"y":22.41},{"x":1407978571000,"y":22.35}]},{"key":"Dewpoint Temperature","color":"#ff0000","values":[{"x":1407978270000,"y":10.86},{"x":1407978353000,"y":10.05},{"x":1407978353000,"y":10.05},{"x":1407978415000,"y":9.6},{"x":1407978523000,"y":9.97},{"x":1407978524000,"y":9.97},{"x":1407978546000,"y":10.83},{"x":1407978562000,"y":11.19},{"x":1407978571000,"y":11.15}]}]
Any suggestions on how to achieve this? Thanks!
http://cmaurer.github.io/angularjs-nvd3-directives/multi.bar.chart.html
You can look this :
Work with angular, Isn't my work !:
$scope.toolTipContentFunction = function(){
return function(key, x, y, e, graph) {
return 'Super New Tooltip' +
'<h1>' + key + '</h1>' +
'<p>' + y + ' at ' + x + '</p>'
}
}
<div ng-controller="ExampleCtrl">
<nvd3-multi-bar-chart
data="exampleData"
id="toolTipContentExample"
width="550"
height="350"
xAxisTickFormat="xAxisTickFormatFunction()"
showXAxis="true"
showYAxis="true"
interactive="true"
tooltips="true"
tooltipcontent="toolTipContentFunction()">
<svg></svg>
</nvd3-multi-bar-chart>
</div>

How to implement chart animations with the latest NVD3 refactor?

How can I implement an animation for the pie chart when the page loads? I've set the transition, duration and ease methods but it currently just renders without animation.
I'm creating my chart like so...
nv.addGraph(function() {
//Set Simple Chart Options
var chart = nv.models.pieChart()
.x(function(d) { return d.title })
.y(function(d) { return d.value })
.showLabels(options_obj.show_labels)
.showLegend(options_obj.legend)
.width(options_obj.width)
.height(options_obj.height)
.color(colorRange)
.tooltips(options_obj.tooltips)
.donut(options_obj.doughnut);
//Set chart width/height and initialize animation
d3.select('#chart')
.datum(row_data)
.transition().duration(350).ease('linear')
.attr('width', options_obj.width)
.attr('height', options_obj.height)
.call(chart);
return chart;
});
I'd really like the animation to be similar to http://bl.ocks.org/mbostock/4341574 (but maybe only the first half).
Any help would be greatly appreciated!
Strainy
Use the duration setting on your chart
More details available on the new documentation page.
http://nvd3-community.github.io/nvd3/examples/documentation.html

NVD3 RotateLabels not working on MultiChart

First and last labels are rendered incorrectly. Does anyone know if there's a way to fix this, or is it a bug?
Here's how it's rendering for me
http://i.imgur.com/F4I9FjL.png
The solution can change depending of the elements you've inside body tag. I've selected all .nv-x .nv-axis elements inside <body>. The line that defines the attr option, you can change de translate and rotate values.
var chart = nv.models.discreteBarChart();
nv.addGraph(function() {
... (chart options like chart.x and chart.y, load data, etc.)
d3.select('body')
.selectAll('.nv-x.nv-axis > g')
.selectAll('g')
.selectAll('text')
.attr('transform', function(d) { return 'translate (-13, 15) rotate(-45 0,0)' });
});
return chart;
});

Resources