I am trying to figure out a way to get a distribution curve / bell curve onto a NVD3 chart. I have searched the net a lot and found literally nothing to work with what I've got. Maybe it isn't actually possible, but thought It was worth asking and also good to know for anyone else who would looks for something like this.
This is an example of what I need my graph to look like (Found on google images)
As you can see from the example, the line doesn't need a second axis, so there would be no need for a 'bar and line chart bo'. I know you can draw directly onto the canvas with D3 but I'm a little under experienced with that.
And Here is my code and jsfiddle If anyone would like to look
var json = [{ "values": [{"label":"450-456", "value":0, "color":"#D62728"},{"label":"456-462", "value":0, "color":"#D62728"},{"label":"462-468", "value":0, "color":"#D62728"},{"label":"468-474", "value":0, "color":"#D62728"},{"label":"474-480", "value":0, "color":"#D62728"},{"label":"480-486", "value":1, "color":"#D62728"},{"label":"486-492", "value":5, "color":"#D62728"},{"label":"492-498", "value":3, "color":"#D62728"},{"label":"498-504", "value":5, "color":"#D62728"},{"label":"504-510", "value":6, "color":"#D62728"},{"label":"510-516", "value":9, "color":"#D62728"},{"label":"516-522", "value":6, "color":"#D62728"},{"label":"522-528", "value":1, "color":"#D62728"},{"label":"528-534", "value":0, "color":"#D62728"},{"label":"534-540", "value":0, "color":"#D62728"},{"label":"540-546", "value":0, "color":"#D62728"},{"label":"546-552", "value":0, "color":"#D62728"},{"label":"552-558", "value":0, "color":"#D62728"},{"label":"558-564", "value":0, "color":"#D62728"},{"label":"564-570", "value":0, "color":"#D62728"}]}];
nv.addGraph(function() {
var chart = nv.models.discreteBarChart()
.x(function(d) {
return d.label
})
.y(function(d) {
return d.value
})
.staggerLabels(true)
.tooltips(true)
.showValues(true)
.transitionDuration(250)
;
chart.yAxis
.tickFormat(d3.format('.0f'))
chart.valueFormat(d3.format('d'));
// REMOVE DECIMAL PLACES FROM Y AXIS
chart.forceY([0,10]);
d3.select('#chartDisribution svg')
.datum(json)
.call(chart);
d3.select('#chartDisribution svg')
.append("text")
.attr("x", '50%')
.attr("y", 10)
.attr("text-anchor", "middle")
.style("font-size", "14px")
.style("text-decoration", "underline")
.style("font-weight", "bold")
.style("height", "20px")
.text("DISRIBUTION");
nv.utils.windowResize(chart.update);
return chart;
});
Original data before sorting for disribution -
[518, 514, 512, 514, 518, 498, 510, 516, 520, 508, 504, 504, 517, 494, 492, 491, 515, 507, 492, 527, 509, 500, 491, 506, 517, 516, 518, 505, 514, 486, 516, 504, 503, 490, 515, 498]
If any more info is needed please ask.
Thank you
I am trying to figure out a way to get a distribution curve / bell curve onto a NVD3 chart. I have searched the net a lot and found literally nothing to work with what I've got. Maybe it isn't actually possible, but thought It was worth asking and also good to know for anyone else who would looks for something like this.
This is an example of what I need my graph to look like (Found on google images)
As you can see from the example, the line doesn't need a second axis, so there would be no need for a 'bar and line chart bo'. I know you can draw directly onto the canvas with D3 but I'm a little under experienced with that.
And Here is my code and jsfiddle If anyone would like to look
var json = [{ "values": [{"label":"450-456", "value":0, "color":"#D62728"},{"label":"456-462", "value":0, "color":"#D62728"},{"label":"462-468", "value":0, "color":"#D62728"},{"label":"468-474", "value":0, "color":"#D62728"},{"label":"474-480", "value":0, "color":"#D62728"},{"label":"480-486", "value":1, "color":"#D62728"},{"label":"486-492", "value":5, "color":"#D62728"},{"label":"492-498", "value":3, "color":"#D62728"},{"label":"498-504", "value":5, "color":"#D62728"},{"label":"504-510", "value":6, "color":"#D62728"},{"label":"510-516", "value":9, "color":"#D62728"},{"label":"516-522", "value":6, "color":"#D62728"},{"label":"522-528", "value":1, "color":"#D62728"},{"label":"528-534", "value":0, "color":"#D62728"},{"label":"534-540", "value":0, "color":"#D62728"},{"label":"540-546", "value":0, "color":"#D62728"},{"label":"546-552", "value":0, "color":"#D62728"},{"label":"552-558", "value":0, "color":"#D62728"},{"label":"558-564", "value":0, "color":"#D62728"},{"label":"564-570", "value":0, "color":"#D62728"}]}];
nv.addGraph(function() {
var chart = nv.models.discreteBarChart()
.x(function(d) {
return d.label
})
.y(function(d) {
return d.value
})
.staggerLabels(true)
.tooltips(true)
.showValues(true)
.transitionDuration(250)
;
chart.yAxis
.tickFormat(d3.format('.0f'))
chart.valueFormat(d3.format('d'));
// REMOVE DECIMAL PLACES FROM Y AXIS
chart.forceY([0,10]);
d3.select('#chartDisribution svg')
.datum(json)
.call(chart);
d3.select('#chartDisribution svg')
.append("text")
.attr("x", '50%')
.attr("y", 10)
.attr("text-anchor", "middle")
.style("font-size", "14px")
.style("text-decoration", "underline")
.style("font-weight", "bold")
.style("height", "20px")
.text("DISRIBUTION");
nv.utils.windowResize(chart.update);
return chart;
});
Original data before sorting for disribution -
[518, 514, 512, 514, 518, 498, 510, 516, 520, 508, 504, 504, 517, 494, 492, 491, 515, 507, 492, 527, 509, 500, 491, 506, 517, 516, 518, 505, 514, 486, 516, 504, 503, 490, 515, 498]
If any more info is needed please ask.
Thank you
Share edited Oct 15, 2015 at 14:12 SK2017 asked Oct 15, 2015 at 7:24 SK2017SK2017 7833 gold badges10 silver badges40 bronze badges 6- If you want to stick to a nvd3-only solution, why not use the Line Plus Bar Chart and remove the y2 axis? – altocumulus Commented Oct 15, 2015 at 8:21
- Yes, but still it would need a data source to create the line, which I also don't know how to do. – SK2017 Commented Oct 15, 2015 at 8:47
- Do you have the original data set with the explicit values? You will need this to calculate the normal line using the Mean and Standard Deviation.. – Stacey Burns Commented Oct 15, 2015 at 13:16
- @StaceyBurns Edited to add Original data – SK2017 Commented Oct 15, 2015 at 14:13
- @Dan, I have done this in JavaScript before, its not that simple but I'll post my code tomorrow, don't have time today :-) – Stacey Burns Commented Oct 15, 2015 at 15:27
1 Answer
Reset to default 6As @Altocumulus stated, you can use the LinePlusBarChart.
There is a lot of info out there on how to do this so I will explain only how to generate the data for the normal distribution.
The following formula is used to create the data: Wikipedia Source
So what we need is the Standard Deviation and Average from the total data set and the bins you are using for the histogram.
I won't go into detail on how to calculate the Average and Standard Deviation from your data set but the code to do this is included in the fiddle below.
We first declare the data set and the bins:
var values = [518, 514, 512, 514, 518, 498, 510, 516, 520, 508, 504, 504, 517, 494, 492, 491, 515, 507, 492, 527, 509, 500, 491, 506, 517, 516, 518, 505, 514, 486, 516, 504, 503, 490, 515, 498];
var bins=[450, 456, 462, 468, 474, 480, 486, 492, 498, 504, 510, 516, 522, 528, 534, 540, 546, 552, 558, 564]
the mean and the std for this data set are as follows:
var average = 507.1944444
var std = 10.43022927
With this data we can calculate the first part of the formula:
var ni1 = 1 / (std * Math.sqrt(2 * Math.PI));
The second part of the formula uses the bins so we then loop through each bin to calculate the values for the normal curve.
To scale the normal values to the chart, we need the size between each bin and we need the total number of values.
(I have also added a variable called norm but we only use this to output the results to the screen)
var norm ="norm data"
var length = bins.length;
var bin_distance = 6;
var num_records = 36;
for(var i=0;i<length;i++){
// This is the second part of the formula
var ni2 = Math.exp(-1*((bins[i]-average)*(bins[i]-average))/(2* (std*std)))
// this is the final calculation for the norm values. I also rounded the value but thats up to you if you want, you can remove this for unrounded values.
var normdata = Math.round(ni1*ni2*bin_distance*num_records);
//append value to norm to output to screen
norm = norm +"<p>"+ bins[i]+" - "+normdata+"</p>"
}
//output results to screen:
document.getElementById('chartDisribution').innerHTML = norm;
Here is a working fiddle.
For your chart, you would want to push the normdata value into the object you have declared for your line.
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745062455a4609048.html
评论列表(0条)