我正在尝试使用d3v4和角度7构建简单的概率直方图,但是由于某些原因,我无法正确计算每个垃圾箱的高度。相反,当我运行代码时,我得到的所有垃圾箱的高度都很大,超出了预期的比例。
这是我正在使用的代码。
private buildChart() {
this.chartProps = {};
let _this = this;
// Number of bins for the histogram
let numHistBins = 10;
// If true, the number of bins are calculated automatically and numHistBins is overwritten
let calcHistBinsAutmoatic = true;
// calculate the number of histogram bins
if (calcHistBinsAutmoatic) {
numHistBins = Math.ceil(Math.sqrt(this.plotData.length));
}
// Bandwith (smoothing constant) h of the kernel density estimator
let bandwith = 1.06 * this.standardDeviation(this.plotData) * Math.pow(this.plotData.length, - 1 / 5);
// Set the dimensions of the canvas / graph
let margin = {top: 20, right: 30, bottom: 30, left: 40},
width = 960 - margin.left - margin.right,
height = 350 - margin.top - margin.bottom;
// Calculate the range of the b_values
let dist = d3.max(this.plotData) - d3.min(this.plotData);
// Define the bins function
let bins = d3.histogram().thresholds(numHistBins);
// Get the total number of elements ( used because of the probability histogram )
this.chartProps.totalData = this.plotData.length;
// Define the X/Y scales
this.chartProps.x = d3.scaleLinear()
.range([0, width])
.domain([d3.min(this.plotData) - (dist / 2), d3.max(this.plotData) + (dist / 2)]);
this.chartProps.y = d3.scaleLinear()
.range([height, 0])
.domain([0, d3.max(bins(this.plotData), function (d) {
return d.length/_this.chartProps.totalData;
}) + 0.1]);
this.chartProps.yForHistogram = d3.scaleLinear()
.domain([0, d3.max(bins(this.plotData), function(d) {
return d.length/_this.chartProps.totalData;
})])
.range([height, 0]);
// Define the axes
var xAxis = d3.axisBottom(this.chartProps.x);
var yAxis = d3.axisLeft(this.chartProps.y);
// Calculate Kernel Density Estimator
var kde = this.kernelDensityEstimator(this.gaussianKernel(bandwith), this.chartProps.x.ticks(100));
// Define the line function (Used if KDE is true)
var line = d3.line<any>()
.x( d => { return _this.chartProps.x(d[0]); })
.y( d => { return _this.chartProps.y(d[1]); });
// Prepare the SVG
var svg = d3.select(this.chartElement.nativeElement)
.append('svg')
.attr('width', width + margin.left + margin.right)
.attr('height', height + margin.top + margin.bottom)
.append('g')
.attr('transform', `translate(${margin.left},${margin.top})`);
// Add the X Axis
svg.append('g')
.attr('class', 'x axis')
.attr('transform', `translate(0,${height})`)
.call(xAxis)
.append("text")
.attr("class", "label")
.attr("x", width)
.attr("y", -6)
.style("text-anchor", "end")
.text("Value");
// Add the Y Axis
svg.append("g")
.attr("class", "y axis")
.call(yAxis);
// Add the bars of histogram
svg.selectAll(".bar")
.data(bins(_this.plotData))
.enter().insert("rect", ".axis")
.attr("class", "bar")
.attr("fill", "#bbb")
.attr("x", d => {
return this.chartProps.x(d.x0) + 1;
})
.attr("y", d => this.chartProps.y(d.length))
.attr("width", d => Math.max(0, this.chartProps.x(d.x1) - this.chartProps.x(d.x0) - 1))
.attr("height", d => {
return this.chartProps.yForHistogram(0) - this.chartProps.yForHistogram(d.length)
});
if (_this.showKDP == true) {
// console.log(kde(_this.plotData));
svg.append("path")
.datum(kde(_this.plotData))
.attr("class", "line")
.attr("stroke", "red")
.attr("fill", "none")
.attr("d", line);
}
...
}
这也是图形的外观
任何关于我在这里做错事情的想法都会受到欢迎。