SK2*_*017 2 javascript d3.js nvd3.js
我正在尝试找出将分布曲线/钟形曲线绘制到NVD3图表上的方法。我已经在网上搜索了很多东西,却发现实际上没有任何东西可用于我所拥有的东西。也许这实际上是不可能的,但是认为这值得一问,也很高兴与其他会寻找类似东西的人认识。
这是我需要我的图看起来的示例(在Google图片上找到)
从示例中可以看到,该线不需要第二条轴,因此不需要“条形图和折线图组合”。我知道您可以使用D3直接在画布上进行绘制,但是我对此还有些不足。
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;
});
Run Code Online (Sandbox Code Playgroud)
分发前的原始数据-
[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]
Run Code Online (Sandbox Code Playgroud)
如果需要更多信息,请询问。
谢谢
如@Altocumulus所述,您可以使用LinePlusBarChart。
那里有很多有关如何执行此操作的信息,所以我将仅解释如何为正态分布生成数据。
以下公式用于创建数据:Wikipedia源
因此,我们需要的是来自总数据集的标准偏差和平均值以及用于直方图的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]
Run Code Online (Sandbox Code Playgroud)
此数据集的平均值和标准差如下:
var average = 507.1944444
var std = 10.43022927
Run Code Online (Sandbox Code Playgroud)
有了这些数据,我们可以计算公式的第一部分:
var ni1 = 1 / (std * Math.sqrt(2 * Math.PI));
Run Code Online (Sandbox Code Playgroud)
公式的第二部分使用仓,因此我们随后遍历每个仓以计算法线曲线的值。
为了将正常值缩放到图表,我们需要每个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;
Run Code Online (Sandbox Code Playgroud)
这是工作中的小提琴。
对于您的图表,您希望将normdata值推入为该行声明的对象中。