The renderings are as follows:
Implementation
1. First realize the vertical x-axis of markLine
The x-axis has two categories, one is category for discrete point drawing, and the other is value for continuous point drawing.
When markLine is vertical to the x-axis, the main axis of the x-axis is used, and the data point type is continuous point. Note: If the data point type here is a category discrete type, then markLine can only display the marker lines contained in this data point. And our continuous point can draw a marker line at any position within the data range
2. The complete implementation code of the basic version is as follows:
const nums = 1.398
const datas1 = [ 12.12 , 18.3 , 19.7 , 21.1 , 22.49 , 23.89 , 25.29 , 26.69 , 28.09 , 29.48 , 30.88 , 35.55 ]
const lsl = 23.12
const usl = 28
const nom = 25.34
const sigma_plus3 = 34.26
const sigma_minus3 = 14.34
const mean = 24.30
const std1 = 3.32
const std2 = 3.43
const range = [ 12.12 , 35.55 ]
const resolution = 10000
const xData = [ ]
const step = ( range[ 1 ] - range[ 0 ] ) / resolution
for ( let i = range[ 0 ] ; i <= range[ 1 ] ; i += step) {
xData. push ( parseFloat ( i. toFixed ( 2 ) ) )
}
const barData = [ [ 18.3 , 51 ] , [ 19.7 , 64 ] , [ 21.1 , 65 ] , [ 22.49 , 67 ] , [ 23.89 , 55 ] , [ 25.29 , 81 ] , [ 18.3 , 51 ] ,
[ 26.69 , 80 ] , [ 28.09 , 50 ] , [ 29.48 , 40 ] , [ 30.88 , 7 ] ] ;
const yData1 = [ ]
for ( let i = 0 ; i < xData. length; i++ ) {
let x = xData[ i]
let y = Math. exp ( - 0.5 * Math. pow ( ( x - mean) / std1, 2 ) ) / ( std1 * Math. sqrt ( 2 * Math. PI ) )
yData1. push ( y) ;
}
const yData2 = [ ]
for ( let i = 0 ; i < xData. length; i++ ) {
let x = xData[ i]
let y = Math. exp ( - 0.5 * Math. pow ( ( x - mean) / std2, 2 ) ) / ( std2 * Math. sqrt ( 2 * Math. PI ) )
yData2. push ( y) ;
}
option = {
title : {
text : '正态分布图' ,
subtext : ''
} ,
legend : {
'data' : [ '过程能力(估算)' , '过程能力(实测)' ]
} ,
tooltip : {
trigger : 'item' ,
axisPointer : {
type : 'shadow'
} ,
formatter : function ( params ) {
if ( params. componentType === 'series' ) {
return ` ${
params. seriesName} <br> ${
parseFloat ( parseFloat ( params. value[ 0 ] ) - nums * 0.5 ) . toFixed ( 2 ) } ~ ${
parseFloat ( parseFloat ( params. value[ 0 ] ) + parseFloat ( nums * 0.5 ) ) . toFixed ( 2 ) } : ${
params. value[ 1 ] } </br> `
} else {
return ` ${
params. name} : ${
params. value} `
}
}
} ,
toolbox : {
show : true ,
feature : {
saveAsImage : {
show : true }
}
} ,
xAxis : [ {
type : 'value' ,
axisLabel : {
showMinLabel : false ,
showMaxLabel : false
} ,
boundaryGap : false ,
min : Math. min . apply ( null , xData) ,
max : Math. max . apply ( null , xData) ,
} ,
{
type : 'category' ,
axisTick : {
show : false
} ,
axisLabel : {
show : false ,
formatter : '{value}'
} ,
data : xData
}
] ,
yAxis : [
{
type : 'value' ,
name : '频数' ,
position : 'left' ,
splitLine : {
show : false
} ,
axisLine : {
show : true ,
lineStyle : {
color : 'orange'
}
} ,
} , {
type : 'value' ,
name : ''
} ,
{
type : 'value' ,
name : '概率' ,
position : 'right' ,
splitLine : {
show : false
} ,
axisLine : {
show : true ,
lineStyle : {
color : 'black'
}
} ,
} ] ,
series : [
{
name : '数据个数' ,
type : 'bar' ,
yAxisIndex : 0 ,
xAxisIndex : 0 ,
barCategoryGap : '40%' ,
itemStyle : {
normal : {
show : true ,
color : 'rgba(255, 204, 0,.3)' ,
borderColor : '#FF7F50'
}
} ,
data : barData,
} , {
name : '过程能力(估算)' ,
type : 'line' ,
xAxisIndex : 1 ,
yAxisIndex : 1 ,
symbol : 'none' ,
smooth : true ,
data : yData1,
} ,
{
name : '过程能力(实测)' ,
type : 'line' ,
yAxisIndex : 1 ,
xAxisIndex : 1 ,
symbol : 'none' ,
smooth : true ,
data : yData2,
} ,
{
name : '' ,
type : 'line' ,
xAxisIndex : 0 ,
yAxisIndex : 0 ,
symbol : 'none' ,
smooth : true ,
markLine : {
symbol : [ 'none' ] ,
itemStyle : {
color : '#FF0000' } ,
animation : false ,
label : {
show : true ,
fontSize : 14 ,
fontWeight : 'bold' ,
formatter : function ( params ) {
if ( params. name === '-3σ' || params. name === '+3σ' || params. name === 'X-bar' ) {
return ` ${
params. name} \n ` ;
} else {
return ` ${
params. name} ` ;
}
} ,
} ,
data : [
{
name : 'LSL' ,
xAxis : lsl,
lineStyle : {
color : '#066d06' , width : 2 } ,
label : {
color : '#066d06' , position : 'end' }
} ,
{
name : 'USL' ,
xAxis : usl,
lineStyle : {
color : '#066d06' , width : 2 } ,
label : {
color : '#066d06' , position : 'end' }
} ,
{
name : 'NOM' ,
xAxis : nom,
lineStyle : {
color : '#ffbe11' , width : 2 } ,
label : {
color : '#ffbe11' , position : 'end' }
} ,
{
name : '-3σ' ,
xAxis : sigma_minus3,
lineStyle : {
color : 'red' , width : 2 } ,
label : {
color : 'red' , position : 'end' }
} ,
{
name : '+3σ' ,
xAxis : sigma_plus3,
lineStyle : {
color : 'red' , width : 2 } ,
label : {
color : 'red' , position : 'end' }
} ,
{
name : 'X-bar' ,
xAxis : mean,
lineStyle : {
color : 'red' , width : 2 } ,
label : {
color : 'red' , position : 'end' }
} ,
]
}
}
]
}
3. The final effect is as follows: