利用d3.layout.histogram布局
const width = 700, height = 500, padding = {top: 160, left: 130};
d3.json("city.json", function (error, data) {
const svg = d3.select("body").append("svg")
.attr("width", width + padding.left * 2)
.attr("height", height + padding.top * 2)
.append("g")
.attr("transform", `translate(${padding.left },${padding.top})`);
// 生成正态分布的随机数 p1:平均值 p2:上下随机间距 此处即为(150~190)
const rand = d3.random.normal(170, 10);
const dataSet = [];
for (let i = 0; i < 100; i++) {
dataSet.push(rand())
}
const [binNum, rangeMin, rangeMax] = [20, 130, 210];
const histogram = d3.layout.histogram()
// 设置区间范围
.range([rangeMin, rangeMax])
// 设置区间个数
.bins(binNum)
// 按照数据统计方式计算
.frequency(true);
// 计算出正态分布布局
const hisData = histogram(dataSet);
// [[x: 130, dx: 4, y: 0],[153.20540533990544, 153.36122403282945, 153.31323675114461, 150.71198861798564, x: 150, dx: 4, y: 4]....]
// 包含该区间的所有数值及布局数据
console.log(hisData);
// 获取x数组
const xTicks = hisData.map(d=>d.x);
const xAxisWidth = 650;
// 创建序数比例尺
const xScale = d3.scale.ordinal()
// 用计算出的正态分布区间作为x轴的区间
.domain(xTicks)
.rangeRoundBands([0,xAxisWidth],.3);
// 创建y轴比例尺
const yScale = d3.scale.linear()
.domain([d3.min(hisData,d=>d.y),d3.max(hisData,d=>d.y)])
.range([0,height]);
// 创建x轴线图并且格式化数据不显示小数
const xAxis = d3.svg.axis().scale(xScale).orient("bottom").tickFormat(d3.format('.0f'));
svg.append("g")
.attr("class","axis")
.attr("transform",`translate(${padding.left},${height})`)
.call(xAxis );
// 创建柱状图
svg.append("g")
.selectAll("class","rect")
.attr("transform",`translate(${padding.left},${height})`)
.data(hisData)
.enter()
.append("rect")
.attr("class","rect")
.attr("x",d=>xScale(d.x)+padding.left)
.attr("y",d=>height-yScale(d.y))
.attr("width",xScale.rangeBand())
.attr("height",d=>yScale(d.y));
});
结果: