spc x-bar 正态分布 echarts demo

使用echarts,elementUi,vue编写的spc分析的demo示例.

含x-bar和正态分布图,同一数据可以互转

在这里插入图片描述
在这里插入图片描述

chart.vue

<template><div class="app-container"><el-row><el-col :span="4" class="button-container"><el-button @click="redrawChart">重新绘制</el-button><el-button type="warning" @click="analyzeData">重新解析数据并绘制</el-button><el-button type="primary" @click="drawNormalChart">正态分布(X)</el-button><el-button type="success" @click="showSpecDialog">更新SPEC(X)</el-button><el-button type="info">计算cpk(X)</el-button><el-button type="danger">危险按钮(X)</el-button></el-col><el-col :span="20"><div id="mainChart" style="height: 720px;width: 1080px;"/></el-col></el-row><div>min:{{ dData.min.toFixed(3) }}max:{{ dData.min.toFixed(3) }}mean:{{ dData.min.toFixed(3) }}std:{{ dData.min.toFixed(3) }}</div><div>说明1.x-bar等图的上线边界,计算上下边界,如果数据过于集中,自动图表缩放会导致usl甚至是ucl超出y轴范围,不能正常绘制,那么需要手动计算上下边界<br/>上边界取max值和usl+0.5*(usl-ucl)更大的那个<br/>下边界取min值和lsl-0.5*(lcl-lsl)更小的那个<br/>为避免出现小数位数过多/精度不足 取3位小数<br/>2.关闭SPEC弹框时由于数据已经被更新,所以在关闭弹框时间上直接绑定了重绘事件.但是由于上下边界是在解析数据阶段完成的,所以不会重新解析上下边界</div><el-dialog title="更新SPEC" :visible.sync="visibleSpecDialog" width="800px" top="5vh" @closed="onSpecDialogClose" append-to-body><el-form ref="form" :model="dData" label-width="200px"><el-form-item label="usl"><el-input v-model="dData.usl"/></el-form-item><el-form-item label="ucl"><el-input v-model="dData.ucl"/></el-form-item><el-form-item label="lcl"><el-input v-model="dData.lcl"/></el-form-item><el-form-item label="lsl"><el-input v-model="dData.lsl"/></el-form-item></el-form></el-dialog></div>
</template><script>
import * as echarts from "echarts";
import * as utils from './utils';//定义显示的颜色
let red="#FF0000"
let yellow="#CCCC00"
let green="#009000"export default {data() {//参数定义return {//主chart实例对象mainChart: {},//从服务器查询数据参数对象queryParams: {},//从服务器获取的原始数据(originalData)oData: {usl: 0,ucl: 0,cl: 0,lcl: 0,lsl: 0,dataList: []},//预定义维度数组,注意顺序,不要轻易改变,注意需要调整analyzeData的转二维数组的内容columns: ["dataTime", "paramValue", "remark"],//绘制图需要的数据格式,(drawData)dData: {//控制参数usl: 0,ucl: 0,cl: 0,lcl: 0,lsl: 0,//计算参数min: 0,max: 0,mean: 0,std: 0,upperY: 0,lowerY: 0,//仅提取paramValue作为值数组valueData: [],//x-barData 数据格式,就是二维数组xBarData: [],//正态分布数据格式normalData: {//正态分布前后距离dataRangeMinOP: 1,dataRangeMaxOP: 1.1,//组间距interval: 1,// 这3个就不构建datasource来处理了,直接用好了// 构建离散值x轴xAxis: [],// 构建柱状y轴barYaxis: [],// 构建线性y轴lineYaxis: []}},// 当前图表类型 1.XR 2.XS 3.WR 4.ZT FIXMEshowChartType: 1,//显示更新SPEC弹框标记visibleSpecDialog: false};},mounted() {this.init();},methods: {/*** 初始化方法* 调用过程如下:* init->queryData->analyzeData->redrawChart->createOption->this.chart.setOption*/init() {//从dom加载echarts对象let chartDom = document.getElementById("mainChart");this.chart = echarts.init(chartDom);this.queryData();},/*** 从服务器获取原始数据* 实际参数:this.queryParams.... 返回结果到this.oData* 回调触发redrawChart*/queryData() {this.oData.dataList = []//模拟写入数据for (let n = 0; n < 100; n++) {this.oData.dataList.push({dataTime: n + ":00",paramValue: 30 + Math.random() * 30,remark: (Math.random() * 20).toFixed(3)});}this.oData.usl = 55;this.oData.ucl = 50;this.oData.cl = 45;this.oData.lcl = 40;this.oData.lsl = 35;//解析原始为图表需要的数据this.analyzeData();},/*** 绘制,或重新绘制主chart图*/redrawChart() {//清除图表this.chart.clear()//创建option并绘制let option = this.createOption();this.chart.setOption(option);//弹框说明this.$message.success("绘制图表成功!");},drawNormalChart() {if (this.showChartType === 1) {this.showChartType = 4;} else {this.showChartType = 1;}this.redrawChart();},showSpecDialog() {this.visibleSpecDialog = true;},//Spec弹框被关闭onSpecDialogClose() {this.redrawChart();},/*** 将原始数据解析为x-bar等图需要的格式* 计算mean,std.,cpk..等数据返回* 实际参数:this.oData.... 返回结果到this.dData*/analyzeData() {//copy基础数据this.dData.usl = this.oData.usl;this.dData.ucl = this.oData.ucl;this.dData.cl = this.oData.cl;this.dData.lcl = this.oData.lcl;this.dData.lsl = this.oData.lsl;//仅提取paramValue作为值数组this.dData.valueData = this.oData.dataList.map(obj => obj.paramValue);//计算其他数据,最大最小cpk什么的this.dData.min = Math.min(...this.dData.valueData);this.dData.max = Math.max(...this.dData.valueData);this.dData.mean = this.dData.valueData.reduce((sum, val) => sum + val, 0) / this.dData.valueData.length;this.dData.std = utils.getStd(this.dData.valueData, this.dData.mean)//计算上下边界,如果数据过于集中,自动图表缩放会导致usl甚至是ucl超出y轴范围,不能正常绘制,那么需要手动计算上下边界//取max值和usl+0.5*(usl-ucl)更大的那个//取min值和lsl-0.5*(lcl-lsl)更小的那个this.dData.upperY = Math.max(this.dData.usl + 0.5 * (this.dData.usl - this.dData.ucl), this.dData.max).toFixed(3)this.dData.lowerY = Math.min(this.dData.lsl - 0.5 * (this.dData.lcl - this.dData.lsl), this.dData.min).toFixed(3)// 转x-bar需要数据// 对象数组转二维数组this.dData.xBarData = []this.dData.xBarData = this.oData.dataList.map(obj => [obj.dataTime, obj.paramValue, obj.remark]);// 转正态分布数据// 构建x轴let start = this.dData.min - this.dData.normalData.dataRangeMinOP;let end = this.dData.max + this.dData.normalData.dataRangeMaxOP;// 计算区间数量let numIntervals = Math.ceil((end - start) / this.dData.normalData.interval);// 构建离散值x轴let xAxis = [];for (let i = start; i <= end; i = i + this.dData.normalData.interval) {let str = i.toFixed(1).toString();xAxis.push(str);}this.dData.normalData.xAxis = xAxis;// 构建柱状y轴,遍历数组并计算频数let barYaxis = new Array(numIntervals).fill(0);this.dData.valueData.forEach((value) => {if (value >= start && value <= end) {// 找到值所在的区间let intervalIndex = Math.floor((value - start) / this.dData.normalData.interval);// 增加该区间的频数barYaxis[intervalIndex]++;}});this.dData.normalData.barYaxis = barYaxis;// 构建线性y轴this.dData.normalData.lineYaxis = utils.fxNormalDistribution(xAxis, this.dData.std, this.dData.mean);this.redrawChart();},/*** 构建图图表参数* @returns*/createOption() {//内部匿名方法无法访问到this,用这个处理,下面都采用thatlet that = this;//optionlet option = {};//正态分布if (this.showChartType === 4) {//定义实际数据的频数柱状图let barDataSet = {type: "bar",smooth: true,yAxisIndex: 0,areaStyle: {opacity: 0,},data: that.dData.normalData.barYaxis,name: "实际分布频数",label: {formatter: "{c} %",show: false, //默认显示position: "top", //在上方显示textStyle: {//数值样式fontSize: 16,},},};//计算实际数据的正态分布图let lineDataSet = {type: "line",smooth: true,yAxisIndex: 1,areaStyle: {opacity: 0,},data: that.dData.normalData.lineYaxis,name: "实际正态分布",label: {formatter: "{c} %",show: false, //开启显示position: "top", //在上方显示textStyle: {//数值样式fontSize: 16,},},};option = {title: {text: 'SPC',},//提示框组件tooltip: {trigger: "axis",axisPointer: {type: "shadow",},},xAxis: {boundaryGap: true,type: "category",data: that.dData.normalData.xAxis,},//定义y轴yAxis: [{type: "value",}, {type: "value",}],series: [barDataSet, lineDataSet],};}//x-barelse {option = {title: {text: 'SPC',},tooltip: {trigger: 'axis',//轴数据指示axisPointer: {type: 'cross'},},xAxis: {type: 'category'},yAxis: {type: 'value',max: that.dData.upperY,min: that.dData.lowerY},dataset: [{//定义数据字段dimensions: [{name: "dataTime", type: 'ordinal'}, "paramValue", "remark"],//定义数据内容source: that.dData.xBarData},],series: [{name: 'Dow-Jones index',type: 'line',//密集点数过多是否显示showAllSymbol: true,//定义xy轴取数据那一列值encode: {x: 'dataTime',y: 'paramValue',tooltip: ["paramValue", "dataTime", "remark"],},//定义点样式,依据数据定义点样式以及大小颜色symbol: function (params) {if (params[1] > that.dData.ucl || params[1] < that.dData.lcl) {if (params[1] > that.dData.usl || params[1] < that.dData.lsl) {return 'triangle';}return 'circle';} else {return 'emptyCircle';}},symbolSize: function (params) {if (params[1] > that.dData.ucl || params[1] < that.dData.lcl) {if (params[1] > that.dData.usl || params[1] < that.dData.lsl) {return 10;}return 9;} else {return 8;}},itemStyle: {color: function (params) {if (params.data[1] > that.dData.ucl || params.data[1]< that.dData.lcl) {if (params.data[1] > that.dData.usl || params.data[1] < that.dData.lsl) {return red;}return yellow;} else {return green;}}},//定义规格线markLine: {silent: true,symbol: 'none',data: [{name: 'USL',yAxis: that.dData.usl,lineStyle: {color: red},label: {color: red, formatter: 'USL:' + that.dData.usl, fontSize: 10}},{name: 'UCL',yAxis: that.dData.ucl,lineStyle: {color: yellow},label: {color: yellow, formatter: 'UCL:' + that.dData.ucl, fontSize: 10}},{name: 'CL',yAxis: that.dData.cl,lineStyle: {color: green},label: {color: green, formatter: 'CL:' + that.dData.cl, fontSize: 10}},{name: 'LCL',yAxis: that.dData.lcl,lineStyle: {color: yellow},label: {color: yellow, formatter: 'LCL:' + that.dData.lcl, fontSize: 10}},{name: 'LSL',yAxis: that.dData.lsl,lineStyle: {color: red},label: {color: red, formatter: 'LSL:' + that.dData.lsl, fontSize: 10}}]}}]};}return option;}},};
</script><style scoped>
.button-container {display: grid;grid-template-columns: 1fr; /* 单列 */grid-auto-rows: minmax(auto, auto); /* 自动行高 */row-gap: 10px; /* 行间距 *//* 可以根据需要添加更多样式 */
}.button-container .el-button {margin-right: 10px;margin-left: 10px;
}
</style>

utils.js

//计算正态曲线
export function fxNormalDistribution(array, std, mean) {let valueList = [];for (let i = 0; i < array.length; i++) {let ND =Math.sqrt(2 * Math.PI) *std *Math.pow(Math.E,-(Math.pow(array[i] - mean, 2) / (2 * Math.pow(std, 2))));valueList.push(ND.toFixed(3));}return valueList;
}//计算标准差
export function getStd(data, mean) {let sumXY = function (x, y) {return Number(x) + Number(y);};let square = function (x) {return Number(x) * Number(x);};let deviations = data.map(function (x) {return x - mean;});return Math.sqrt(deviations.map(square).reduce(sumXY) / (data.length - 1));
}//对有序数组求中位数
export function getMedianSorted(arr) {// 获取数组长度let len = arr.length;// 如果没有元素,返回undefined或你可以返回其他合适的值if (len === 0) {return undefined;}// 如果只有一个元素,那么它就是中位数if (len === 1) {return arr[0];}// 如果数组长度是奇数,返回中间的数if (len % 2 === 1) {return arr[Math.floor(len / 2)];}// 如果数组长度是偶数,返回中间两个数的平均值else {let mid1 = arr[len / 2 - 1];let mid2 = arr[len / 2];return (mid1 + mid2) / 2.0;}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/746487.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【vue项目中点击下载】弹窗提示:离开此网站?系统可能不会保存您所做的更改,改为直接下载,不提示此弹窗内容,已解决

项目中用的是window.location.href实现下载 在Web浏览器中&#xff0c;当尝试通过window.location.href重定向到一个文件下载URL时&#xff0c;浏览器通常会显示一个确认对话框&#xff0c;询问用户是否要离开当前页面&#xff0c;因为下载的文件通常是在新窗口或新标签页中打…

程序员如何平衡主业与副业?

程序员的副业有哪些&#xff1f; 常见的有接私活&#xff0c;即外包一些软件项目来做&#xff0c;或者是写文章、拍教学视频、开直播等等。在这里&#xff0c;我更推荐程序员的副业是找个软件开发外包平台来接单&#xff0c;就是在工作之外接一下软件开发、外包项目等&#xf…

软件无线电系列——模拟无线电、数字无线电、软件无线电

本节目录 一、模拟无线电 二、数字无线电 1、窄带数字无线电 2、宽带数字无线电 三、软件无线电本节内容 一、模拟无线电 20世纪80年代的模拟体制(美国的AMPS/欧洲的TACS)被称为第一代移动通信&#xff0c;简称1G,主要目标是为在大范围内有限的用户提供移动电话服务。最主要的…

如何关闭 Visual Studio 双击异常高亮

[问题描述]&#xff1a; 最近 Visual Studio 更新后&#xff0c;双击选中关键字快要亮瞎我的眼睛了 &#x1f440;&#x1f440; [解决方法]&#xff1a; 摸索了一下&#xff0c;找到了关闭的方法&#xff1a;工具 → 选项 → 文本编辑器 → 常规&#xff0c;然后取消 勾选 sel…

vue3动态组件未渲染问题

渲染问题 component动态组件写法与vue2写法一致&#xff0c;代码如下&#xff1a; <component :is"componentName"/><script setup>import { ref } from vueimport account from ./user/account.vue// 组件名称const componentName ref(account)// 点击…

【算法】一类支持向量机OC-SVM(1)

【算法】一类支持向量机OC-SVM 前言一类支持向量机OC-SVM 概念介绍示例编写数据集创建实现一类支持向量机OC-SVM完整的示例输出 前言 由于之前毕设期间主要的工具就是支持向量机&#xff0c;从基础的回归和分类到后来的优化&#xff0c;在接触到支持向量机还有一类支持向量机的…

unity

Unity官方下载_Unity最新版_从Unity Hub下载安装 | Unity中国官网 Unity Remote - Unity 手册 登陆账号&#xff0c;找到一个3d 免费资源 3D Animations & Models | Unity Asset Store unity 里面window->package Manager 里面可以看到自己的asset &#xff0c;下载后…

MySQL 数据库压力测试

文章目录 前言1. 安装部署1.1 二进制安装1.2 源码安装 2. 服务器性能测试2.1 CPU2.2 内存2.3 磁盘 3. MySQL 基准测试3.1 参数解析3.2 压测命令3.3 输出解读3.4 结果分析 前言 Sysbench 是一个开源的多线程基准测试工具&#xff0c;也是目前使用最多的 MySQL 压力测试工具。本…

树莓派与电脑视频实时传输实现

编程环境 1、 树莓派 4B 2、 windows 编程语言 python 应用 tkinter scoket opencv 效果 视频同传 服务端视频初始化 服务端视频读取 windows 客户端接收视频流&#xff0c;队列存储 解析视频&#xff0c;存入队列 ui页面数据刷新 下载链接&#xff1a;https://…

elasticsearch篇:数据聚合

1.数据聚合 聚合&#xff08;aggregations&#xff09;可以让我们极其方便的实现对数据的统计、分析、运算。例如&#xff1a; 什么品牌的手机最受欢迎&#xff1f; 这些手机的平均价格、最高价格、最低价格&#xff1f; 这些手机每月的销售情况如何&#xff1f; 实现这些…

VUE3项目学习系列--Axios二次封装(五)

Axios中文文档 | Axios中文网 (axios-http.cn) Axios 是一个基于 promise 网络请求库&#xff0c;作用于node.js 和浏览器中。 它是 isomorphic 的(即同一套代码可以运行在浏览器和node.js中)。在服务端它使用原生 node.js http 模块, 而在客户端 (浏览端) 则使用 XMLHttpRequ…

【洛谷 P8637】[蓝桥杯 2016 省 B] 交换瓶子 题解(贪心算法)

[蓝桥杯 2016 省 B] 交换瓶子 题目描述 有 N N N 个瓶子&#xff0c;编号 1 ∼ N 1 \sim N 1∼N&#xff0c;放在架子上。 比如有 5 5 5 个瓶子&#xff1a; 2 , 1 , 3 , 5 , 4 2,1,3,5,4 2,1,3,5,4 要求每次拿起 2 2 2 个瓶子&#xff0c;交换它们的位置。 经过若干次…

解释器模式(Interpreter Pattern)

解释器模式 说明 解释器模式&#xff08;Interpreter Pattern&#xff09;属于行为型模式&#xff0c;是指给定一门语言&#xff0c;定义它的语法&#xff08;文法&#xff09;的一种表示&#xff0c;并定义一个解释器&#xff0c;该解释器使用该表示来解释语言中的句子。是一…

[NSSRound#18 Basic]web解析

文章目录 门酱想玩什么呢&#xff1f;Becomeroot 门酱想玩什么呢&#xff1f; 打开题目&#xff0c;加载完视频后要求我们给个游戏链接 点开评论区不难发现应该是想玩元梦之星&#xff0c;这里有个评论功能可以上传图片 我们随便输入点东西发现是插入并赋值到content元素里面 …

提示找不到MSVCP140.dll无法继续执行此代码的多种解决方法

当计算机系统在运行过程中突然提示“丢失MSVCP140.dll”这一错误信息时&#xff0c;意味着系统无法找到并加载这个至关重要的动态链接库文件。MSVCP140.dll是Microsoft Visual C Redistributable Package的一部分&#xff0c;对于许多基于Windows的应用程序来说&#xff0c;尤其…

Exam in MAC [容斥]

题意 思路 正难则反 反过来需要考虑的是&#xff1a; (1) 所有满条件一的(x,y)有多少对&#xff1a; x 0 时&#xff0c;有c1对 x 1 时&#xff0c;有c对 ...... x c 时&#xff0c;有1对 以此类推 一共有 (c2)(c1)/2 对 (2) 符合 x y ∈ S的有多少对&#xff1a…

openssl3.2 - note - Getting Started with OpenSSL

文章目录 openssl3.2 - note - Getting Started with OpenSSL概述笔记openssl 历史版本Configure 选项开关支持的OSopenssl 文档简介安装新闻每个平台的安装文档支持的命令列表配置文件格式环境变量 END openssl3.2 - note - Getting Started with OpenSSL 概述 看到官方文档…

物联网技术助力智慧城市转型升级:智能、高效、可持续

目录 一、物联网技术概述及其在智慧城市中的应用 二、物联网技术助力智慧城市转型升级的路径 1、提升城市基础设施智能化水平 2、推动公共服务智能化升级 3、促进城市治理现代化 三、物联网技术助力智慧城市转型升级的成效与展望 1、成效显著 2、展望未来 四、物联网技…

【C++初阶】C++入门(上)

C的认识 ①什么是C&#xff1f; ​ C语言是结构化和模块化的语言&#xff0c;适合处理较小规模的程序。对于复杂的问题&#xff0c;规模较大的程序&#xff0c;需要高度的抽象和建模时&#xff0c;C语言则不合适。 ​ 于是1982年&#xff0c;Bjarne Stroustrup&#xff08;本…

D-阿洛酮糖-DAEase酶固定化载体及混合糖液分离

#D-阿洛酮糖-DAEase酶固定化载体及混合糖液分离 ​阿洛酮糖为白色固体晶体&#xff0c;无气味&#xff0c;具有较大的溶解度&#xff0c;柔和的口感&#xff0c;其具有传统甜味剂蔗糖70%的甜度&#xff0c;却几乎不提供任何热量。其与食物中的蛋白质&#xff0c;如鸡蛋蛋白发生…