Xbar-S-2.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552
  1. <template>
  2. <div class="container1">
  3. <div class="databox">
  4. <el-scrollbar :style="{ height: Height + 'px' }">
  5. <div class="box" v-show="!addStatus">
  6. <div
  7. style="
  8. display: flex;
  9. align-items: center;
  10. justify-content: space-between;
  11. "
  12. >
  13. <div style="display: flex; align-items: center">
  14. <div class="bg"></div>
  15. 控制图绘制
  16. </div>
  17. <el-button
  18. type="primary"
  19. v-print="'#print'"
  20. style="margin-left: 10px; height: 25px"
  21. >打 印</el-button
  22. >
  23. </div>
  24. <div class="info">
  25. <div id="print">
  26. <div id="charts" :style="{ height: maxHeight / 2 + 'px' }"></div>
  27. <div id="charts1" :style="{ height: maxHeight / 2 + 'px' }"></div>
  28. </div>
  29. </div>
  30. </div>
  31. </el-scrollbar>
  32. </div>
  33. </div>
  34. </template>
  35. <script setup>
  36. import * as echarts from "echarts";
  37. import { useDictionaryStore } from "@/store";
  38. import { XBarSCompute } from "@/api/analysis";
  39. const tableData = ref([]);
  40. const chartData = ref([]);
  41. const getTableData = async (data) => {
  42. data.lclX = data.lclX.toFixed(4);
  43. data.uclS = data.uclS.toFixed(4);
  44. data.sBar = data.sBar.toFixed(4);
  45. data.xDoubleBar = data.xDoubleBar.toFixed(4);
  46. data.uclX = data.uclX.toFixed(4);
  47. data.lclS = data.lclS.toFixed(4);
  48. data.subgroupStdDevs = data.subgroupStdDevs.map((num) =>
  49. parseFloat(num.toFixed(4))
  50. );
  51. data.subgroupMeans = data.subgroupMeans.map((num) =>
  52. parseFloat(num.toFixed(4))
  53. );
  54. chartData.value = data;
  55. chartsOption1.value.title[0].text = `${title.value}的Xbar-S控制图`;
  56. setChart1();
  57. setChart2();
  58. };
  59. const { dicts } = useDictionaryStore();
  60. const opOptions = ref([...dicts.spc_operation]);
  61. const value = ref(opOptions.value[0].remark);
  62. const Y1value = ref([]);
  63. const X1array = ref([]);
  64. const setY1value = () => {
  65. Y1value.value = [];
  66. chartData.value.subgroupMeans.forEach((item) => {
  67. Y1value.value.push(item);
  68. });
  69. Y1value.value.unshift("");
  70. Y1value.value.push("");
  71. chartsOption1.value.series[0].data = Y1value.value;
  72. };
  73. const setX1array = async () => {
  74. X1array.value = await [];
  75. chartData.value.subgroupMeans.forEach((item, index) => {
  76. X1array.value.push(index + 1);
  77. });
  78. X1array.value.unshift("");
  79. X1array.value.push("");
  80. chartsOption1.value.xAxis[0].data = X1array.value;
  81. };
  82. const setChart1Info = () => {
  83. // chartsOption1.value.title[0].text = `上限=${showData.value.avgMax ? showData.value.avgMax : "-"}`;
  84. // chartsOption1.value.title[0].text = `x̄=${showData.value.avgAvg ? showData.value.avgAvg : "-"}`;
  85. chartsOption1.value.series[0].markLine.data[0].yAxis = chartData.value.uclX;
  86. chartsOption1.value.series[0].markLine.data[0].label.formatter = `上限=${
  87. chartData.value.uclX
  88. }`;
  89. chartsOption1.value.series[0].markLine.data[1].yAxis = chartData.value.lclX;
  90. chartsOption1.value.series[0].markLine.data[1].label.formatter = `下限=${chartData.value.lclX}`;
  91. chartsOption1.value.series[0].markLine.data[2].yAxis =
  92. chartData.value.xDoubleBar;
  93. chartsOption1.value.series[0].markLine.data[2].label.formatter = `x̄=${
  94. chartData.value.xDoubleBar
  95. }`;
  96. // chartsOption1.value.title[2].text = `下限=${showData.value.avgMin ? showData.value.avgMin : "0"}`;
  97. };
  98. const setChart2Info = () => {
  99. // chartsOption2.value.title[0].text = `上限=${showData.value.rangeMax ? showData.value.rangeMax : "-"}`;
  100. // chartsOption2.value.title[0].text = `R=${showData.value.rangeAvg ? showData.value.rangeAvg : "-"}`;
  101. chartsOption2.value.series[0].markLine.data[0].yAxis = chartData.value.uclS;
  102. chartsOption2.value.series[0].markLine.data[0].label.formatter = `上限=${
  103. chartData.value.uclS
  104. }`;
  105. chartsOption2.value.series[0].markLine.data[1].yAxis = chartData.value.lclS;
  106. chartsOption2.value.series[0].markLine.data[1].label.formatter = `下限=${
  107. chartData.value.lclS
  108. }`;
  109. chartsOption2.value.series[0].markLine.data[2].yAxis = chartData.value.sBar;
  110. chartsOption2.value.series[0].markLine.data[2].label.formatter = `x̄=${
  111. chartData.value.sBar
  112. }`;
  113. // chartsOption2.value.title[2].text = `下限=${showData.value.rangeMin ? showData.value.rangeMin : "0"}`;
  114. };
  115. const setChart1 = () => {
  116. setChart1Info();
  117. setY1value();
  118. setX1array();
  119. charts1.value.setOption(chartsOption1.value, true);
  120. };
  121. const setChart2 = () => {
  122. setChart2Info();
  123. setY2value();
  124. setX2array();
  125. charts2.value.setOption(chartsOption2.value, true);
  126. };
  127. const title = ref("调阻精度");
  128. const showLable = ref("调阻");
  129. const changeSelect = () => {
  130. setTimeout(async () => {
  131. // showLable.value = selectRef.value.currentPlaceholder;
  132. // opOptions.value.forEach((item) => {
  133. // if (item.dictLabel == showLable.value) {
  134. // lableValue.value = item.dictValue;
  135. // }
  136. // });
  137. // switch (showLable.value) {
  138. // case "调阻":
  139. // title.value = "调阻精度";
  140. // break;
  141. // case "粘片":
  142. // title.value = "剪切强度";
  143. // break;
  144. // case "键合":
  145. // title.value = "键合强度";
  146. // break;
  147. // default:
  148. // title.value = "调阻精度";
  149. // break;
  150. // }
  151. // await getTableData();
  152. chartsOption1.value.title[0].text = `${title.value}的Xbar-S控制图`;
  153. setChart1();
  154. setChart2();
  155. }, 0);
  156. };
  157. const maxHeight = ref(null);
  158. const maxWidth = ref(null);
  159. const charts1 = shallowRef(null);
  160. const charts2 = shallowRef(null);
  161. const chartsOption1 = ref({
  162. title: [
  163. // {
  164. // text: `x̄=${showData.value.avgAvg ? showData.value.avgAvg : "-"}`,
  165. // right: "5%",
  166. // top: "42%",
  167. // textStyle: {
  168. // fontSize: 15,
  169. // color: "#333",
  170. // fontWeight: 100,
  171. // },
  172. // },
  173. {
  174. text: `${title.value}的Xbar-S控制图`,
  175. left: "40%",
  176. },
  177. {
  178. text: "均",
  179. left: "4%",
  180. top: "42%",
  181. },
  182. {
  183. text: "值",
  184. left: "4%",
  185. top: "49%",
  186. },
  187. ],
  188. grid: {
  189. right: "15%",
  190. },
  191. toolbox: {
  192. feature: {
  193. saveAsImage: {},
  194. },
  195. },
  196. tooltip: {
  197. show: true,
  198. },
  199. xAxis: [
  200. {
  201. type: "category",
  202. boundaryGap: false,
  203. data: [],
  204. },
  205. ],
  206. yAxis: [
  207. {
  208. type: "value",
  209. scale: true, // 开启自适应缩放
  210. },
  211. ],
  212. series: [
  213. {
  214. type: "line",
  215. lineStyle: {
  216. color: "rgb(26, 122, 240)",
  217. },
  218. symbolSize: 13,
  219. symbol: "circle",
  220. itemStyle: {
  221. color: (params) => {
  222. const paramValue = Number(params.value);
  223. if (
  224. paramValue <= Number(chartData.value.uclX) &&
  225. paramValue >= Number(chartData.value.lclX)
  226. ) {
  227. return "rgb(26, 122, 240)";
  228. } else {
  229. return "red";
  230. }
  231. },
  232. },
  233. markLine: {
  234. silent: true,
  235. data: [
  236. {
  237. silent: false,
  238. yAxis: 0,
  239. label: {
  240. position: "end",
  241. formatter: `上限=${chartData.value.uclX}`,
  242. color: "#333",
  243. },
  244. lineStyle: { type: "solid", color: "#333", width: 2 },
  245. },
  246. {
  247. silent: false,
  248. yAxis: 0,
  249. label: {
  250. position: "end",
  251. formatter: `下限=${chartData.value.lclX}`,
  252. color: "#333",
  253. },
  254. lineStyle: {
  255. type: "solid",
  256. color: "#333",
  257. width: 2,
  258. },
  259. },
  260. {
  261. yAxis: 0,
  262. silent: false,
  263. label: {
  264. position: "end",
  265. formatter: ``,
  266. color: "#333",
  267. },
  268. lineStyle: {
  269. type: "solid",
  270. color: "#333",
  271. width: 2,
  272. },
  273. },
  274. ],
  275. },
  276. },
  277. ],
  278. });
  279. const chartsOption2 = ref({
  280. title: [
  281. // {
  282. // text: `R=${showData.value.rangeAvg ? showData.value.rangeAvg : "-"}`,
  283. // right: "5%",
  284. // top: "42%",
  285. // textStyle: {
  286. // fontSize: 15,
  287. // color: "#333",
  288. // fontWeight: 100,
  289. // },
  290. // },
  291. {
  292. text: "标",
  293. left: "4%",
  294. top: "35%",
  295. },
  296. {
  297. text: "准",
  298. left: "4%",
  299. top: "42%",
  300. },
  301. {
  302. text: "差",
  303. left: "4%",
  304. top: "49%",
  305. },
  306. ],
  307. toolbox: {
  308. feature: {
  309. saveAsImage: {},
  310. },
  311. },
  312. grid: {
  313. right: "15%",
  314. },
  315. xAxis: [
  316. {
  317. type: "category",
  318. boundaryGap: false,
  319. data: [],
  320. },
  321. ],
  322. yAxis: [
  323. {
  324. type: "value",
  325. scale: true, // 开启自适应缩放
  326. },
  327. ],
  328. tooltip: {
  329. show: true,
  330. },
  331. series: [
  332. {
  333. type: "line",
  334. lineStyle: {
  335. color: "rgb(26, 122, 240)",
  336. },
  337. symbolSize: 13,
  338. symbol: "circle",
  339. itemStyle: {
  340. color: (params) => {
  341. const paramValue = Number(params.value);
  342. if (
  343. paramValue <= Number(chartData.value.uclS) &&
  344. paramValue >= Number(chartData.value.lclS)
  345. ) {
  346. return "rgb(26, 122, 240)";
  347. } else {
  348. return "red";
  349. }
  350. },
  351. },
  352. markLine: {
  353. silent: true,
  354. data: [
  355. {
  356. silent: false,
  357. yAxis: 0,
  358. label: {
  359. position: "end",
  360. formatter: `上限=${chartData.value.uclS}`,
  361. color: "#333",
  362. },
  363. lineStyle: { type: "solid", color: "#333", width: 2 },
  364. },
  365. {
  366. silent: false,
  367. yAxis: 0,
  368. label: {
  369. position: "end",
  370. formatter: `下限=${chartData.value.lclS}`,
  371. color: "#333",
  372. },
  373. lineStyle: { type: "solid", color: "#333", width: 2 },
  374. },
  375. {
  376. yAxis: 0,
  377. silent: false,
  378. label: {
  379. position: "end",
  380. formatter: ``,
  381. color: "#333",
  382. },
  383. lineStyle: {
  384. type: "solid",
  385. color: "#333",
  386. width: 2,
  387. },
  388. },
  389. ],
  390. },
  391. },
  392. ],
  393. });
  394. const Height = ref(0);
  395. const setHeight = () => {
  396. Height.value = document.querySelector(".databox").clientHeight;
  397. maxHeight.value = document.querySelector(".info").clientHeight;
  398. maxWidth.value = document.querySelector(".info").clientWidth;
  399. };
  400. const Y2value = ref([]);
  401. const X2array = ref([]);
  402. const setY2value = () => {
  403. Y2value.value = [];
  404. chartData.value.subgroupStdDevs.forEach((item) => {
  405. Y2value.value.push(item);
  406. });
  407. Y2value.value.unshift("");
  408. Y2value.value.push("");
  409. chartsOption2.value.series[0].data = Y2value.value;
  410. };
  411. const setX2array = () => {
  412. X2array.value = [];
  413. chartData.value.subgroupStdDevs.forEach((item, index) => {
  414. X2array.value.push(index + 1);
  415. });
  416. X2array.value.unshift("");
  417. X2array.value.push("");
  418. chartsOption2.value.xAxis[0].data = X2array.value;
  419. };
  420. const setView = () => {
  421. setHeight();
  422. charts1.value = echarts.init(document.getElementById("charts"));
  423. charts2.value = echarts.init(document.getElementById("charts1"));
  424. charts1.value.setOption(chartsOption1.value, true);
  425. charts2.value.setOption(chartsOption2.value, true);
  426. };
  427. onMounted(() => {
  428. init();
  429. });
  430. const init = async (data) => {
  431. tableData.value = data;
  432. setHeight();
  433. if (data) {
  434. charts1.value = echarts.init(document.getElementById("charts"));
  435. charts2.value = echarts.init(document.getElementById("charts1"));
  436. window.addEventListener("resize", setView);
  437. await getTableData(data);
  438. // changeSelect();
  439. charts1.value.setOption(chartsOption1.value, true);
  440. charts2.value.setOption(chartsOption2.value, true);
  441. }
  442. // nextTick(() => {
  443. // if (tableData.value != undefined && tableData.value.length > 0) {
  444. // getTableData();
  445. // // changeSelect();
  446. // }
  447. //
  448. // charts1.value = echarts.init(document.getElementById("charts"));
  449. // charts2.value = echarts.init(document.getElementById("charts1"));
  450. // charts1.value.setOption(chartsOption1.value, true);
  451. // charts2.value.setOption(chartsOption2.value, true);
  452. // });
  453. // window.addEventListener("resize", setView);
  454. };
  455. onBeforeUnmount(() => {
  456. window.removeEventListener("resize", setView);
  457. });
  458. // 暴露 init 方法
  459. defineExpose({
  460. init,
  461. });
  462. </script>
  463. <style lang="scss" scoped>
  464. @media print {
  465. #print {
  466. margin-left: -18%;
  467. }
  468. }
  469. .formStyle {
  470. width: 400px;
  471. margin: 20px auto;
  472. }
  473. .container1 {
  474. width: 100%;
  475. height: 100%;
  476. display: flex;
  477. background-color: white;
  478. .infobox {
  479. width: 200px;
  480. .header {
  481. height: 120px;
  482. border-bottom: 2px solid #00000010;
  483. padding: 20px;
  484. }
  485. .body {
  486. padding: 20px;
  487. }
  488. }
  489. .databox {
  490. flex: 1;
  491. border-left: 2px solid #00000010;
  492. .box {
  493. height: 710px;
  494. padding: 5px 20px;
  495. display: flex;
  496. flex-direction: column;
  497. .illustrate {
  498. padding: 20px 60px;
  499. }
  500. .tableTitle {
  501. text-align: center;
  502. margin: 10px 0;
  503. padding-right: 40px;
  504. }
  505. .header {
  506. margin-top: 20px;
  507. //margin-left: 100px;
  508. display: flex;
  509. width: 100%;
  510. height: auto;
  511. }
  512. //.title {
  513. // height: 50px;
  514. // display: flex;
  515. // align-items: center;
  516. // margin-bottom: 10px;
  517. // justify-content: space-between;
  518. // .btns {
  519. // display: flex;
  520. // align-items: center;
  521. // .btn {
  522. // height: 24px;
  523. // font-size: 14px;
  524. // margin: 0 5px;
  525. // }
  526. // }
  527. //}
  528. .info {
  529. margin-top: 20px;
  530. flex: 1;
  531. height: 300px;
  532. }
  533. }
  534. }
  535. }
  536. </style>