I am new java script and D3, I am building some sample reports using D3, but constantly facing "Uncaught TypeError: data.map is not a function" in stackAreaChart display. I tried all my best to get rid of this error but no joy.
Exception:
nv.d3.js:14314 Uncaught TypeError: data.map is not a function
at nv.d3.js:14314
at nv.utils.state._set (nv.d3.js:1248)
at nv.utils.state.update (nv.d3.js:1269)
at SVGSVGElement.<anonymous> (nv.d3.js:14353)
at d3.min.js:3
at Y (d3.min.js:1)
at Array.Co.each (d3.min.js:3)
at Array.chart (nv.d3.js:14339)
at Array.Co.call (d3.min.js:3)
at Object.generate (main.js:250)
Sample data I am sending for stackAreaChart:
[{"key":"RT.Gjoa_SPS.E","values":[[1499955690000,-0.019999314282704246],[1499955
750000,0.05166495085946679],[1499955810000,-0.056664803271206064],[1499955870000
,0.08833037627180006]]},{"key":"RT.Gjoa_SPS","values":[[1499955690000,23.4658844
70517647],[1499955750000,104.52984900503316],[1499955810000,-631.4456184793839],
[1499955870000,1683.1438952034932]]},{"key":"RT.Gjoa_SPS.B","values":[[149995587
0000,0.002222081668744225]]},{"key":"RT.Gjoa_SPS.D","values":[[1499955690000,0],
[1499955750000,-0.003333234941159513],[1499955810000,0.003333234941159513],[1499
955870000,0]]}]
Below is my complete main.js: please check if anything i am missing or need to be handled in order to get rid of this error.
main.js
var socket = io.connect('http://HOST_IP:3000');
/////////////////////////////////////////////////////////////////////////////////////////////////////
// // // TimeSeries Chart
// // /////////////////////////////////////////////////////////////////////////////////////////////////////
var timeSeriesChart;
var timeSeriesChartData = [];
//function drawTimeSeriesChart()
//{
nv.addGraph(function() {
timeSeriesChart = nv.models.lineChart().duration(750).useInteractiveGuideline(true).margin({right:40});
timeSeriesChart.xAxis.axisLabel("Timestamp").tickFormat(function(d){ return d3.time.format("%Y-%m-%d %H:%M:%S")(new Date(d));});
timeSeriesChart.yAxis.axisLabel("Stats").tickFormat(d3.format(',.2f'));
d3.select('#FMCChart1').append('svg').datum(timeSeriesChartData).call(timeSeriesChart);
nv.utils.windowResize(timeSeriesChart.update());
return timeSeriesChart;
});
//}
socket.on("timeSeriesChartData",function(timeSeriesData){
console.log("chart updated");
d3.select('#FMCChart1 svg')
.datum(timeSeriesData)
.call(timeSeriesChart);
});
/////////////////////////////////////////////////////////////////////////////////////////////////////
// // // Discrete Bar Chart
// // /////////////////////////////////////////////////////////////////////////////////////////////////////
var discreteChart;
var discreteChartData;
function drawDiscreteChart()
{
nv.addGraph(function() {
discreteChart = nv.models.discreteBarChart()
.x(function(d) { return d.label}) //Specify the data accessors.
.y(function(d) { return +d.value})
.staggerLabels(true) //Too many bars and not enough room? Try staggering labels.
//.tooltips(false) //Don't show tooltips
.showValues(true) //...instead, show the bar value right on top of each bar.
//.transitionDuration(350)
;
d3.select('#FMCChart2 svg')
.datum(discreteChartData)
.call(discreteChart);
nv.utils.windowResize(discreteChart.update);
return discreteChart;
});
}
socket.on("discreteChartData",function(disChartData){
discreteChartData=disChartData;
console.log("Discrete Chart ", disChartData[0].values[0].value);
//discreteChart.update();
drawDiscreteChart();
});
// // ///////////////////////////////////////////////////////////////////////////////////////////////
//Pie Chart
// // ///////////////////////////////////////////////////////////////////////////////////////////////
var pieChart;
var pieChartData;
function drawPieChart() {
//Donut chart example
nv.addGraph(function() {
pieChart = nv.models.pieChart()
.x(function(d) { return d.label })
.y(function(d) { return +d.value })
.showLabels(true) //Display pie labels
.labelThreshold(.05) //Configure the minimum slice size for labels to show up
.labelType("percent") //Configure what type of data to show in the label. Can be "key", "value" or "percent"
.donut(true) //Turn on Donut mode. Makes pie chart look tasty!
.donutRatio(0.35); //Configure how big you want the donut hole size to be.
d3.select("#FMCChart3 svg")
.datum(pieChartData)
//.transition().duration(350)
.call(pieChart); /// ERROR OCCURRED ON THIS LINE
return pieChart;
});
}
socket.on("pieChartData",function(pChartData){
pieChartData=pChartData;
console.log("Pie Chart: ",pChartData[0].label,pChartData[0].value);
drawPieChart();
});
///////////////////////////////////////////////////////////////////////////////////////////////
//Donut Chart
///////////////////////////////////////////////////////////////////////////////////////////////
var donutChart;
var donutChartData;
function drawDonutChart() {
//Donut chart example
nv.addGraph(function() {
donutChart = nv.models.pieChart()
.x(function(d) { return d.label })
.y(function(d) { return +d.value })
.showLabels(true) //Display pie labels
.labelThreshold(.05) //Configure the minimum slice size for labels to show up
.labelType("percent") //Configure what type of data to show in the label. Can be "key", "value" or "percent"
.donut(true) //Turn on Donut mode. Makes pie chart look tasty!
.donutRatio(0.35); //Configure how big you want the donut hole size to be.
d3.select("#FMCChart4 svg")
.datum(donutChartData)
//.transition().duration(350)
.call(donutChart); /// ERROR OCCURRED ON THIS LINE
return donutChart;
});
}
socket.on("donutChartData",function(dChartData){
donutChartData=dChartData;
console.log("Donut Chart: ",dChartData[0].label,dChartData[0].value);
drawDonutChart();
});
///////////////////////////////////////////////////////////////////////////////////////////////
//Alert Chart
///////////////////////////////////////////////////////////////////////////////////////////////
socket.on('fetched-callRestAPI',function(msg){
// console.log("warning : " + msg);
console.log("Rest Call --- >> ",msg);
var data = JSON.parse(msg);
if(data.content == "true") {
$('#flag').toggleClass("card-panel green");
}
else{
$('#flag').toggleClass("card-panel red");
}
});
///////////////////////////////////////////////////////////////////////////////////////////////
//Stacked Area Chart
///////////////////////////////////////////////////////////////////////////////////////////////
var stackedAreaChart;
var stackedAreaChartData;
function drawStackedAreaChart() {
//Donut chart example
nv.addGraph(function() {
stackedAreaChart = nv.models.stackedAreaChart()
.margin({right: 100})
.x(function(d) { return d[0] }) //We can modify the data accessor functions...
.y(function(d) { return d[1] }) //...in case your data is formatted differently.
.useInteractiveGuideline(true) //Tooltips which show all data points. Very nice!
.rightAlignYAxis(true) //Let's move the y-axis to the right side.
//.transitionDuration(500)
.showControls(true) //Allow user to choose 'Stacked', 'Stream', 'Expanded' mode.
.clipEdge(true); //Configure how big you want the donut hole size to be.
//Format x-axis labels with custom function.
stackedAreaChart.xAxis
.tickFormat(function(d) {
return d3.time.format('%x')(new Date(d))
});
stackedAreaChart.yAxis
.tickFormat(d3.format(',.2f'));
d3.select("#FMCChart5 svg")
.datum(stackedAreaChartData)
//.transition().duration(350)
.call(stackedAreaChart); /// ERROR OCCURRED ON THIS LINE
return stackedAreaChart;
});
}
socket.on("openTSDBRestAPIData",function(openTSDBData){
stackedAreaChartData=openTSDBData;
console.log("stackedAreaChartData: ",openTSDBData);
drawStackedAreaChart();
});
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.
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.
I'm a n00b and having trouble with NVD3, and there're some smart people on here, so I hope you can help.
I'm trying to create a drop box that will select data to display.
I can call a function with but I cannot get the chart to change its data location.
HTML:
<select name="slct" id="name" onchange="data(this.value)">
<option>Select power data</option>
<option value="Residence_supply_data">Average kwh residences supplied to the grid</option>
<option value="Residence_need_data">Average kwh supplied to residences</option>
</select>
NOTE: I've created JSON libraries with the values above as names.
Javascript:
function data(value) {
console.log(value);
var dat_select = value;
return dat_select;
};
var chart;
nv.addGraph(function() {
chart = nv.models.multiBarHorizontalChart().x(function(d) {
return d.label
}).y(function(d) {
return d.value
}).margin({
top : 30,
right : 105,
bottom : 30,
left : 100
})
//.showValues(true)
.tooltips(true).barColor(d3.scale.category20().range()).showControls(false);
chart.yAxis.tickFormat(d3.format(',.0f'));
d3.select('#chart1 svg').datum(dat_select).transition().duration(1000).call(chart);
nv.utils.windowResize(chart.update);
chart.dispatch.on('stateChange', function(e) {
nv.log('New State:', JSON.stringify(e));
});
return chart;
});
Everything works otherwise, and the function logs the results, just can't select the data I need to. If I set d3.select('#chart1 svg').datum(Residence_supply_data), it loads that data.
You have my gratitude.
At the point where d3.slect('#chart1 svg') assign it to a variable(global variable)
myChart = d3.select('#chart1 svg').datum(dat_select).transition()
.duration(1000).call(chart);
So now myChart contains the nvd3 multiBarHorizontalChart() chart.
So when you want the chart updated by calling a function updateMyChart() for example from a place of your choice you could update it like this :
function updateMyChart() {
// myChart is passed to your new data
// myChart also calls chart which hold the attributes you
// had set earlier for multiBarHorizontalChart
myChart.datum(Residence_supply_data).transition().duration(1000).call(chart);
// Update the chart during the window screen resizing
nv.utils.windowResize(myChart.update);
}
Hope this helps you.
I am using nvd3 library to generate grouped multi bar graph. This is my dataset (in JSON FORM)
[{"key":"Param 1","values":[{"y":2.0,"x":"2010-04-01"},{"y":0,"x":"2010-10-01"},{"y":0,"x":"2010-12-01"},{"y":0,"x":"2011-01-01"},{"y":0,"x":"2011-04-01"},{"y":0,"x":"2011-10-01"},{"y":0,"x":"2012-01-01"},{"y":0,"x":"2012-03-01"},{"y":0,"x":"2012-05-01"},{"y":0,"x":"2012-08-01"},{"y":0,"x":"2012-10-01"},{"y":0,"x":"2012-11-01"},{"y":25.0,"x":"2012-12-01"},{"y":0,"x":"2013-01-01"},{"y":0,"x":"2013-02-01"},{"y":0,"x":"2013-03-01"},{"y":0,"x":"2013-04-01"}]},{"key":"Param 2","values":[{"y":160.0,"x":"2010-04-01"},{"y":0,"x":"2010-10-01"},{"y":0.0,"x":"2010-12-01"},{"y":0,"x":"2011-01-01"},{"y":4.0,"x":"2011-04-01"},{"y":0,"x":"2011-10-01"},{"y":0.0,"x":"2012-01-01"},{"y":45.0,"x":"2012-03-01"},{"y":9.0,"x":"2012-05-01"},{"y":0,"x":"2012-08-01"},{"y":10.0,"x":"2012-10-01"},{"y":0,"x":"2012-11-01"},{"y":30.0,"x":"2012-12-01"},{"y":0.0,"x":"2013-01-01"},{"y":58.0,"x":"2013-02-01"},{"y":52.0,"x":"2013-03-01"},{"y":36.0,"x":"2013-04-01"}]},{"key":"Param 3","values":[{"y":80.0,"x":"2010-04-01"},{"y":12.0,"x":"2010-10-01"},{"y":0.0,"x":"2010-12-01"},{"y":0,"x":"2011-01-01"},{"y":2.0,"x":"2011-04-01"},{"y":0.0,"x":"2011-10-01"},{"y":0.0,"x":"2012-01-01"},{"y":33.0,"x":"2012-03-01"},{"y":16.0,"x":"2012-05-01"},{"y":20.0,"x":"2012-08-01"},{"y":0.0,"x":"2012-10-01"},{"y":150.0,"x":"2012-11-01"},{"y":65.0,"x":"2012-12-01"},{"y":0.0,"x":"2013-01-01"},{"y":44.0,"x":"2013-02-01"},{"y":116.0,"x":"2013-03-01"},{"y":24.0,"x":"2013-04-01"}]},{"key":"Param 4","values":[{"y":0,"x":"2010-04-01"},{"y":8.0,"x":"2010-10-01"},{"y":0,"x":"2010-12-01"},{"y":0,"x":"2011-01-01"},{"y":0,"x":"2011-04-01"},{"y":0.0,"x":"2011-10-01"},{"y":4.0,"x":"2012-01-01"},{"y":0,"x":"2012-03-01"},{"y":0,"x":"2012-05-01"},{"y":0,"x":"2012-08-01"},{"y":0,"x":"2012-10-01"},{"y":0,"x":"2012-11-01"},{"y":0.0,"x":"2012-12-01"},{"y":0,"x":"2013-01-01"},{"y":0,"x":"2013-02-01"},{"y":67.0,"x":"2013-03-01"},{"y":0,"x":"2013-04-01"}]},{"key":"Param 5","values":[{"y":0,"x":"2010-04-01"},{"y":0,"x":"2010-10-01"},{"y":0,"x":"2010-12-01"},{"y":15.0,"x":"2011-01-01"},{"y":0,"x":"2011-04-01"},{"y":0,"x":"2011-10-01"},{"y":0,"x":"2012-01-01"},{"y":0,"x":"2012-03-01"},{"y":0,"x":"2012-05-01"},{"y":0,"x":"2012-08-01"},{"y":0,"x":"2012-10-01"},{"y":0,"x":"2012-11-01"},{"y":0,"x":"2012-12-01"},{"y":0,"x":"2013-01-01"},{"y":250.0,"x":"2013-02-01"},{"y":120.0,"x":"2013-03-01"},{"y":100.0,"x":"2013-04-01"}]}]
And this is the code I am using:
var chart;
nv.addGraph(function() {
chart = nv.models.multiBarChart()
.barColor(d3.scale.category20().range());
chart.xAxis
.showMaxMin(true).tickFormat(function(d){return d3.time.format('%b-%y')(new Date(d));});
chart.yAxis
.tickFormat(d3.format(',1f'));
d3.select('#plot_container svg')
.datum(plot_data)
.transition().duration(500).call(chart);
nv.utils.windowResize(chart.update);
chart.dispatch.on('stateChange', function(e) { nv.log('New State:', JSON.stringify(e)); });
return chart;
The labels I am getting on the x-axis are gererated by the library itself. I want all the months on x-axis for which data is available. Also, all such months should be equally spaced, not linear in time.
I have tried stuff like tickValues to no avail.
How should this be done?