echart绘制直方图+正态分布曲线
效果展示echart细节
效果展示
echart
index.html代码
* {
margin: 0;
padding: 0;
}
#chart-container {
position: relative;
height: 100vh;
overflow: hidden;
}
body {
background: #12141e;
background-size: cover;
color: #666;
font-size: 0.1rem;
font-family: "微软雅黑";
}
index.js代码
var dom = document.getElementById("chart-container");
var myChart = echarts.init(dom, null, {
renderer: "canvas",
useDirtyRect: false
});
var app = {};
//正态分布计算
function func(x, u, a) {
return (
(1 / Math.sqrt(2 * Math.PI)) *
a *
Math.exp((-1 * ((x - u) * (x - u))) / (2 * a * a))
);
}
var data = [
"22.08",
"22.08",
"22.08",
"22.08",
"22.08",
"22.07",
"22.07",
"22.07",
"22.06",
"22.06",
"22.06",
"22.06",
"22.04",
"22.04",
"22.04",
"22.02",
"22.02",
"22.02",
"22.02",
"22.00",
"22.00",
"22.00",
"22.00",
"22.00",
"22.00",
"21.99",
"21.99",
"21.99",
"21.99",
"21.99",
"21.99",
"21.99",
"21.99",
"21.99",
"21.99",
"21.98",
"21.98",
"21.98",
"21.98",
"21.98",
"21.98",
"21.98",
"21.98",
"21.98",
"21.98",
"21.98",
"21.98",
"21.98",
"21.98",
"21.98",
"21.97",
"21.97",
"21.97",
"21.97",
"21.97",
"21.97",
"21.97",
"21.97",
"21.97",
"21.97",
"21.97",
"21.97",
"21.97",
"21.96",
"21.96",
"21.96",
"21.96",
"21.96",
"21.96",
"21.96",
"21.95",
"21.95",
"21.95",
"21.95",
"21.95",
"21.95",
"21.95",
"21.95",
"21.95",
"21.95",
"21.94",
"21.94",
"21.94",
"21.94",
"21.93",
"21.93",
"21.93",
"21.93",
"21.93"
];
var xMin = 21; //LowLimit
var xMax = 23; //UpLimit
var mean = math.mean(data); //平均值 计算方法来自math.js
var stdev = math.std(data); //方差
var threeSigUp = mean + 3 * stdev;
var threeSigLow = mean - 3 * stdev;
//数据升序排序
const dataSec = data.sort((a, b) => {
return a - b;
});
//计算频数
var resNum = {};
for (var m = 0; m < dataSec.length; m++) {
var key = parseFloat(dataSec[m]);
if (parseFloat(key) === 0) continue;
if (resNum[key]) resNum[key] += 1;
else resNum[key] = 1;
}
var xArr = []; //横坐标值
var fArr = []; //频数
var yArr = []; //正态值
for (var k in resNum) {
xArr.push(parseFloat(k));
}
xArr = xArr.sort((a, b) => {
return a - b;
});
//console.log(xArr);
//计算x值对应的频数
for (var i = 0; i < xArr.length; i++) {
var xNy = [xArr[i], resNum[xArr[i]]];
fArr.push(xNy);
}
//计算x值对应的正态分布值
var distance = xMax - xMin; //为了更好看,设置正态曲线起止位置
for (var j = xMin + distance / 4; j < xMax - distance / 4; j += 0.01) {
var xy = [j, func(j, mean, stdev)];
yArr.push(xy);
}
var option;
option = {
//backgroundColor: "#12141e",
tooltip: {
trigger: "axis",
axisPointer: {
type: "shadow"
}
},
legend: {
orient: "vertical",
x: "right",
y: "top",
top: "5px",
data: ["频数", "正态分布"],
textStyle: {
color: "rgba(255,255,255,1)",
fontSize: "12"
}
},
grid: {
left: "2%",
top: "18px",
right: "2%",
bottom: "2%",
containLabel: true
},
xAxis: [
{
type: "value",
min: xMin,
max: xMax,
axisLabel: {
textStyle: {
color: "rgba(255,255,255,1)",
fontSize: 10
}
},
axisLine: {
show: true,
lineStyle: {
color: "rgba(255,255,255,1)"
}
},
splitLine: {
show: false
}
}
],
yAxis: [
{
type: "value", //数值轴
name: "正态曲线",
position: "right",
axisTick: { show: true },
axisLine: {
show: false,
lineStyle: {
color: "rgba(255,255,255,1)"
}
},
axisLabel: {
show: true,
textStyle: {
color: "rgba(255,255,255,1)",
fontSize: 10
}
},
splitLine: {
show: false
}
},
{
type: "value",
name: "频数",
position: "left",
axisLabel: {
//formatter: '{value} %'
show: true,
textStyle: {
color: "rgba(255,255,255,1)",
fontSize: "12"
}
},
axisTick: {
show: true
},
axisLine: {
show: true,
lineStyle: {
color: "rgba(0,0,0,.1)",
width: 1,
type: "solid"
}
},
splitLine: {
lineStyle: {
color: "rgba(255,255,255,.3)"
}
}
}
],
series: [
{
name: "正态分布",
type: "line",
smooth: true,
yAxisIndex: 0,
symbol: "circle",
symbolSize: 5,
showSymbol: false,
lineStyle: {
normal: {
color: "#ceb664",
width: 2
}
},
itemStyle: {
normal: {
color: "#ceb664",
borderColor: "rgba(221, 220, 107, .1)",
borderWidth: 10
}
},
data: yArr,
markLine: {
symbol: ["none"],
lineStyle: {
type: "dotted",
color: "yellow"
},
itemStyle: {
normal: {
show: true,
color: "black"
}
},
label: {
show: true,
position: "end"
},
data: [
{
name: "3σ",
xAxis: threeSigLow.toFixed(2),
label: {
show: true,
formatter: "3σ"
}
},
{
name: "3σ",
xAxis: threeSigUp.toFixed(2),
label: {
show: true,
formatter: "3σ"
}
}
]
}
},
{
name: "频数",
type: "bar",
yAxisIndex: 1,
xAxisIndex: 0,
barWidth: 8,
barGap: 1,
symbol: "solid",
symbolSize: 5,
showSymbol: true,
itemStyle: {
normal: {
color: "#0184d5",
opacity: 1,
barBorderRadius: 3
}
},
data: fArr,
markLine: {
symbol: ["none"],
lineStyle: {
type: "dotted",
color: "red"
},
itemStyle: {
normal: {
show: true,
color: "black"
}
},
label: {
show: true,
position: "middle"
},
data: [
{
name: "LowLimit",
xAxis: xMin.toFixed(2),
label: {
show: true,
formatter: "Low"
}
},
{
name: "High",
xAxis: xMax.toFixed(2),
label: {
show: true,
formatter: "High"
}
}
]
}
}
]
};
if (option && typeof option === "object") {
myChart.setOption(option);
}
window.addEventListener("resize", myChart.resize);
细节
刚开始x轴设置为类目轴,直方图可以显示,但是加入正态曲线展示效果不是很理想,为了能更好显示频数与正态曲线,所以 x轴,y轴都采用了数值轴,其对应的y轴数组fArr与yArr中存放的值为[x,y]。
文章链接
发表评论