YewErrorBarChart.vue 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  1. <template>
  2. <div>
  3. <!-- 图表控制面板 -->
  4. <div style="display: flex; align-items: center">
  5. <!-- <div style="margin-right: 20px; display: flex; align-items: center">
  6. <el-color-picker
  7. size="small"
  8. v-model="color1"
  9. show-alpha
  10. @change="updateChartColor"
  11. ></el-color-picker>
  12. <span style="margin-left: 10px">自定义颜色</span>
  13. </div> -->
  14. <div>
  15. <el-button size="small" @click="toggleChartType">
  16. 切换为{{ chartType === "bar" ? "折线图" : "柱状图" }}
  17. </el-button>
  18. </div>
  19. </div>
  20. <!-- 图表容器 -->
  21. <div
  22. v-loading="loading"
  23. :id="`bar-chart-sum` + index"
  24. style="width: 100%; height: 400px"
  25. >
  26. <el-empty v-if="isError" description="请求失败"></el-empty>
  27. </div>
  28. </div>
  29. </template>
  30. <script>
  31. import { nextTick } from "vue"; // 导入 nextTick
  32. import Plotly from "plotly.js-dist";
  33. import axios from "axios";
  34. import { myMixin } from "@/mixins/chartRequestMixin";
  35. export default {
  36. props: {
  37. zongFaultCsvData: {
  38. default: [],
  39. type: Array,
  40. },
  41. index: {
  42. type: String,
  43. },
  44. setUpImgData: {
  45. default: () => [],
  46. type: Array,
  47. },
  48. },
  49. mixins: [myMixin],
  50. data() {
  51. return {
  52. chartData: {
  53. analysisTypeCode: "",
  54. engineCode: "",
  55. engineTypeName: "",
  56. xaixs: "",
  57. yaixs: "",
  58. data: [],
  59. },
  60. chartType: "bar", // 当前图表类型 ('bar' 或 'scatter')
  61. color1: "#406DAB", // 默认颜色
  62. isError: false, // 错误标志
  63. loading: true, // 加载标志
  64. };
  65. },
  66. mounted() {
  67. nextTick(() => {
  68. this.drawChart();
  69. this.isError = false;
  70. this.loading = false;
  71. });
  72. },
  73. methods: {
  74. getData() {
  75. // console.log(this.zongFaultCsvData[0].data);
  76. },
  77. // 为每个数据点返回对应颜色
  78. getColor(value) {
  79. if (value <= 3) {
  80. return "#8AC8BE"; // (0, 3]
  81. } else if (value <= 5) {
  82. return "#407DB3"; // (3, 5]
  83. } else {
  84. return "#1B2973"; // (5, ∞]
  85. }
  86. },
  87. drawChart() {
  88. const chartDataset = this.zongFaultCsvData[0].data;
  89. const xData = chartDataset.map((item) => item.engine_name); // 机组编号
  90. const yData = chartDataset.map((item) => item.yaw_error1); // 偏航误差值
  91. // 为每个数据点分配颜色
  92. const colors = yData.map(this.getColor);
  93. const trace = {
  94. x: xData, // 横坐标数据
  95. y: yData, // 纵坐标数据
  96. type: this.chartType, // 当前图表类型 ('bar' 或 'scatter')
  97. marker: {
  98. color: colors, // 每个点的颜色
  99. },
  100. line: {
  101. color: this.color1, // 折线图颜色
  102. },
  103. name: "偏航误差值", // 图例名称
  104. hovertemplate:
  105. `机组:` + ` %{x} <br> ` + `偏航误差值:` + "%{y} <br> <extra></extra>",
  106. };
  107. // 创建虚拟的 trace 以便显示图例
  108. const legendTrace1 = {
  109. x: [null],
  110. y: [null],
  111. name: "(0, 3]",
  112. mode: "markers",
  113. marker: { color: "#8AC8BE", size: 10 },
  114. };
  115. const legendTrace2 = {
  116. x: [null],
  117. y: [null],
  118. name: "(3, 5]",
  119. mode: "markers",
  120. marker: { color: "#407DB3", size: 10 },
  121. };
  122. const legendTrace3 = {
  123. x: [null],
  124. y: [null],
  125. name: "(5, ∞]",
  126. mode: "markers",
  127. marker: { color: "#1B2973", size: 10 },
  128. };
  129. const layout = {
  130. title: {
  131. text: "机组静态偏航误差值分布", // 图表标题
  132. font: {
  133. size: 16, // 设置标题字体大小(默认 16)
  134. weight: "bold",
  135. },
  136. },
  137. xaxis: {
  138. title: "机组", // 横坐标标题
  139. tickmode: "array",
  140. tickvals: xData, // 设置刻度值(机组编号)
  141. ticktext: xData, // 设置刻度文本(机组编号)
  142. gridcolor: "rgb(255,255,255)",
  143. tickcolor: "rgb(255,255,255)",
  144. backgroundcolor: "#e5ecf6",
  145. },
  146. yaxis: {
  147. title: "静态偏航误差值(度)", // 纵坐标标题
  148. gridcolor: "rgb(255,255,255)",
  149. tickcolor: "rgb(255,255,255)",
  150. backgroundcolor: "#e5ecf6",
  151. },
  152. margin: {
  153. l: 50,
  154. r: 50,
  155. t: 50,
  156. b: 50,
  157. },
  158. plot_bgcolor: "#e5ecf6",
  159. gridcolor: "#fff",
  160. bgcolor: "#e5ecf6", // 设置背景颜色
  161. autosize: true, // 开启自适应
  162. showlegend: true, // 显示图例
  163. legend: {
  164. x: 1.05,
  165. y: 1,
  166. },
  167. annotations: [
  168. {
  169. x: 1.05,
  170. y: 4,
  171. xref: "paper",
  172. yref: "paper",
  173. text: "(0, 3] ",
  174. showarrow: false,
  175. font: { size: 12, color: "#8AC8BE" },
  176. },
  177. {
  178. x: 1.05,
  179. y: 3,
  180. xref: "paper",
  181. yref: "paper",
  182. text: "(3, 5] ",
  183. showarrow: false,
  184. font: { size: 12, color: "#407DB3" },
  185. },
  186. {
  187. x: 1.05,
  188. y: 2,
  189. xref: "paper",
  190. yref: "paper",
  191. text: "(5, ∞] ",
  192. showarrow: false,
  193. font: { size: 12, color: "#1B2973" },
  194. },
  195. ],
  196. };
  197. // 渲染图表
  198. Plotly.newPlot(
  199. `bar-chart-sum` + this.index,
  200. [trace, legendTrace1, legendTrace2, legendTrace3],
  201. layout,
  202. {
  203. responsive: true,
  204. modeBarButtonsToRemove: [
  205. "lasso2d", // 移除不需要的工具按钮
  206. // 移除不需要的工具按钮
  207. "lasso2d",
  208. "sendDataToCloud",
  209. "resetCameraLastSave3d",
  210. "resetCameraDefault3d",
  211. "resetCameraLastSave",
  212. "sendDataToCloud",
  213. "zoom2d", // 缩放按钮
  214. "zoom3d",
  215. "plotlylogo2D",
  216. "plotlylogo3D",
  217. ],
  218. displaylogo: false,
  219. }
  220. ).then(function (gd) {
  221. // 获取工具栏按钮
  222. const toolbar = gd.querySelector(".modebar");
  223. const buttons = toolbar.querySelectorAll(".modebar-btn");
  224. // 定义一个映射对象,方便修改按钮提示
  225. const titleMap = {
  226. "Download plot as a png": "保存图片",
  227. Autoscale: "缩放",
  228. Pan: "平移",
  229. "Zoom out": "缩小",
  230. "Zoom in": "放大",
  231. "Box Select": "选择框操作",
  232. "Lasso Select": "套索选择操作",
  233. "Reset axes": "重置操作",
  234. "Reset camera to default": "重置相机视角",
  235. "Turntable rotation": "转台式旋转",
  236. "Orbital rotation": "轨道式旋转",
  237. };
  238. // 遍历所有按钮,修改它们的 title
  239. buttons.forEach(function (button) {
  240. const dataTitle = button.getAttribute("data-title");
  241. // 如果标题匹配,修改属性值
  242. if (titleMap[dataTitle]) {
  243. button.setAttribute("data-title", titleMap[dataTitle]);
  244. }
  245. });
  246. });
  247. },
  248. // 切换图表类型
  249. toggleChartType() {
  250. this.chartType = this.chartType === "bar" ? "scatter" : "bar";
  251. this.drawChart();
  252. },
  253. // 更新图表颜色
  254. updateChartColor() {
  255. this.drawChart();
  256. },
  257. },
  258. };
  259. </script>
  260. <style scoped>
  261. /* 样式可以根据需求自定义 */
  262. </style>