FaultAll.vue 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. <!--
  2. * @Author: your name
  3. * @Date: 2025-01-15 14:24:59
  4. * @LastEditTime: 2025-07-10 11:01:20
  5. * @LastEditors: bogon
  6. * @Description: In User Settings Edit
  7. * @FilePath: /performance-test/src/views/performance/components/chartsCom/FaultAll.vue
  8. -->
  9. <template>
  10. <div>
  11. <div ref="chart" style="width: 100%; height: 400px"></div>
  12. </div>
  13. </template>
  14. <script>
  15. import Plotly from "plotly.js-dist";
  16. export default {
  17. name: "faultAll",
  18. props: {
  19. faultTypes: {
  20. type: Array,
  21. default: [],
  22. }, // 故障类型
  23. faultCounts: {
  24. type: Array,
  25. default: [],
  26. }, // 故障次数
  27. faultDurations: {
  28. type: Array,
  29. default: [],
  30. }, // 故障时长
  31. zongFaultCsvData: {
  32. type: Array,
  33. default: [],
  34. },
  35. },
  36. watch: {
  37. zongFaultCsvData: {
  38. deep: true,
  39. handler(v) {
  40. if (v && v[0] && v[0].data) {
  41. this.faultTypes = v[0].data.map((item) => item.fault_detail);
  42. this.faultCounts = v[0].data.map((item) => item.count);
  43. this.faultDurations = v[0].data.map((item) => item.fault_time_sum);
  44. this.renderChart();
  45. }
  46. },
  47. },
  48. faultCounts: {
  49. deep: true,
  50. handler(v) {
  51. this.renderChart();
  52. },
  53. },
  54. },
  55. mounted() {
  56. this.renderChart();
  57. },
  58. methods: {
  59. renderChart() {
  60. // 故障次数的柱状图数据(左侧 Y 轴)
  61. const barTrace = {
  62. x: this.faultTypes.slice(0, 10),
  63. y: this.faultCounts.slice(0, 10),
  64. type: "bar",
  65. marker: { color: "#64ADC2" }, // 蓝色柱状图
  66. name: "故障次数",
  67. hovertemplate:
  68. `故障类型:` + ` %{x} <br> ` + `故障次数:` + "%{y} 次<br>",
  69. };
  70. // 故障时长的折线图数据(右侧 Y 轴)
  71. const lineTrace = {
  72. x: this.faultTypes.slice(0, 10),
  73. y: this.faultDurations.slice(0, 10).map((item) => item.toFixed(2)),
  74. type: "scatter",
  75. mode: "lines+markers", // 线性图 + 点标记
  76. line: { color: "#1A295D" }, // 红色折线
  77. name: "故障时长",
  78. yaxis: "y2", // 使用第二个 Y 轴(右侧)
  79. hovertemplate:
  80. `故障类型:` + ` %{x} <br> ` + `故障时长:` + "%{y} 小时 <br>",
  81. };
  82. // 布局配置,设置双 Y 轴
  83. const layout = {
  84. title: {
  85. text: "全场故障次数与时长分析Top10",
  86. font: {
  87. size: 16, // 设置标题字体大小(默认 16)
  88. weight: "bold",
  89. },
  90. },
  91. xaxis: {
  92. title: "故障类型",
  93. tickangle: 30,
  94. tickmode: "array",
  95. tickvals: this.faultTypes.slice(0, 10),
  96. tickfont: { size: 12 },
  97. gridcolor: "rgb(255,255,255)",
  98. tickcolor: "rgb(255,255,255)",
  99. backgroundcolor: "#e5ecf6",
  100. },
  101. yaxis: {
  102. title: "故障次数",
  103. titlefont: { color: "#64ADC2" },
  104. tickfont: { color: "#64ADC2" },
  105. side: "left", // 左侧的 Y 轴
  106. showline: true,
  107. linecolor: "#64ADC2",
  108. gridcolor: "rgb(255,255,255)",
  109. tickcolor: "rgb(255,255,255)",
  110. backgroundcolor: "#e5ecf6",
  111. },
  112. yaxis2: {
  113. title: "故障时长 (小时)",
  114. titlefont: { color: "#1A295D" },
  115. tickfont: { color: "#1A295D" },
  116. overlaying: "y", // 在第一个 Y 轴上方绘制
  117. side: "right", // 右侧的 Y 轴
  118. position: 1, // 调整右侧轴的位置
  119. showline: true,
  120. linecolor: "#1A295D", // 设置右侧轴线颜色
  121. },
  122. barmode: "group", // 柱状图分组
  123. plot_bgcolor: "#e5ecf6",
  124. gridcolor: "#fff",
  125. bgcolor: "#e5ecf6", // 设置背景颜色
  126. showlegend: false,
  127. // legend: {
  128. // // x: 1, // 设置 legend 水平位置
  129. // // y: 1, // 设置 legend 垂直位置
  130. // xanchor: "left", // 使图例与 x 轴对齐
  131. // yanchor: "top", // 使图例与 y 轴对齐
  132. // pad: {
  133. // r: 100, // 设置图表与 legend 之间的上间距
  134. // },
  135. // },
  136. margin: {
  137. t: 80, // 上边距
  138. b: 150, // 下边距,给 X 轴标签更多空间
  139. // r: 200, // 增加右边距,避免图例遮挡右侧 Y 轴
  140. },
  141. };
  142. // 渲染图表
  143. Plotly.newPlot(this.$refs.chart, [barTrace, lineTrace], layout, {
  144. modeBarButtonsToRemove: [
  145. // 移除不需要的工具按钮
  146. "lasso2d",
  147. "sendDataToCloud",
  148. "resetCameraLastSave3d",
  149. "resetCameraDefault3d",
  150. "resetCameraLastSave",
  151. "sendDataToCloud",
  152. "zoom2d", // 缩放按钮
  153. "zoom3d",
  154. "plotlylogo2D",
  155. "plotlylogo3D",
  156. ],
  157. displaylogo: false,
  158. responsive: true,
  159. }).then(function (gd) {
  160. // 获取工具栏按钮
  161. const toolbar = gd.querySelector(".modebar");
  162. const buttons = toolbar.querySelectorAll(".modebar-btn");
  163. // 定义一个映射对象,方便修改按钮提示
  164. const titleMap = {
  165. "Download plot as a png": "保存图片",
  166. Autoscale: "缩放",
  167. Pan: "平移",
  168. "Zoom out": "缩小",
  169. "Zoom in": "放大",
  170. "Box Select": "选择框操作",
  171. "Lasso Select": "套索选择操作",
  172. "Reset axes": "重置操作",
  173. "Reset camera to default": "重置相机视角",
  174. "Turntable rotation": "转台式旋转",
  175. "Orbital rotation": "轨道式旋转",
  176. };
  177. // 遍历所有按钮,修改它们的 title
  178. buttons.forEach(function (button) {
  179. const dataTitle = button.getAttribute("data-title");
  180. // 如果标题匹配,修改属性值
  181. if (titleMap[dataTitle]) {
  182. button.setAttribute("data-title", titleMap[dataTitle]);
  183. }
  184. });
  185. });
  186. },
  187. },
  188. };
  189. </script>
  190. <style scoped>
  191. /* 你可以根据需要添加样式 */
  192. </style>