我想找到一种方法将分布曲线/钟形曲线放到NVD3图表上。我已经在网上搜索了很多东西,发现我没有用到我所拥有的东西。也许它实际上是不可能的,但是认为对于那些寻找这样的东西的人来说,值得询问并且也很有用。
这是我需要图表的示例(在谷歌图片上找到)
从示例中可以看出,该行不需要第二个轴,因此不需要'条形图和折线图组合'。我知道你可以用D3直接画在画布上,但我对此经验不足。
这是我的代码和jsfiddle如果有人想看
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;
});
排序前的原始数据 -
[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]
如果需要更多信息,请询问。
谢谢
答案 0 :(得分:4)
正如@Altocumulus所说,你可以使用LinePlusBarChart。
关于如何执行此操作有很多信息,因此我将仅解释如何为正态分布生成数据。
以下公式用于创建数据:Wikipedia Source
所以我们需要的是总数据集中的标准偏差和平均值以及您用于直方图的分档。
我不会详细介绍如何从数据集中计算平均值和标准偏差,但执行此操作的代码包含在下面的小提琴中。
我们首先声明数据集和bin:
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]
该数据集的均值和标准如下:
var average = 507.1944444
var std = 10.43022927
通过这些数据,我们可以计算公式的第一部分:
var ni1 = 1 / (std * Math.sqrt(2 * Math.PI));
公式的第二部分使用了分档,因此我们循环遍历每个分档以计算正常曲线的值。
要将正常值缩放到图表,我们需要每个bin之间的大小,我们需要值的总数。
(我还添加了一个名为norm的变量,但我们只使用它将结果输出到屏幕上)
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;
对于您的图表,您可能希望将normdata值推送到您为该行声明的对象中。