lineAndChildLine.vue 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. <template>
  2. <div>
  3. <!-- 图表控制面板 总图-->
  4. <div style="display: flex; align-items: center">
  5. <el-select
  6. size="small"
  7. v-model="color1"
  8. @change="updateChartColor"
  9. placeholder="选择配色方案"
  10. style="width: 200px"
  11. >
  12. <el-option
  13. v-for="(scheme, index) in colorSchemes"
  14. :key="index"
  15. :label="scheme.label"
  16. :value="scheme.colors"
  17. :style="getOptionStyle(scheme.colors)"
  18. ></el-option>
  19. </el-select>
  20. <div>
  21. <el-button size="small" @click="toggleChartType">
  22. 切换为{{ chartType === "line" ? "面积图" : "折线图" }}
  23. </el-button>
  24. </div>
  25. </div>
  26. <!-- 图表容器 -->
  27. <div
  28. v-loading="loading"
  29. :id="`bar-chart${index}`"
  30. style="width: 100%; height: 400px"
  31. >
  32. <el-empty v-if="isError" description="请求失败"></el-empty>
  33. </div>
  34. </div>
  35. </template>
  36. <script>
  37. import { nextTick } from "vue"; // 导入 nextTick
  38. import Plotly from "plotly.js-dist";
  39. import axios from "axios";
  40. import { colorSchemesLine } from "@/views/overview/js/colors";
  41. import { myMixin } from "@/mixins/chartRequestMixin"; // 假设你需要的 mixin
  42. export default {
  43. props: {
  44. fileAddr: {
  45. type: String,
  46. default: "",
  47. },
  48. index: {
  49. type: String,
  50. default() {
  51. return "0";
  52. },
  53. },
  54. },
  55. mixins: [myMixin],
  56. data() {
  57. return {
  58. chartData: {},
  59. chartType: "line", // 默认图表类型是折线图
  60. color1: [], // 默认颜色
  61. // 配色方案列表(每个方案是一个颜色数组)
  62. colorSchemes: [...colorSchemesLine],
  63. loading: false,
  64. isError: false,
  65. colors: [
  66. "#636EFA",
  67. "#EF553B",
  68. "#00CC96",
  69. "#AB63FA",
  70. "#FFA15A",
  71. "#19D3F3",
  72. "#FF6692",
  73. "#B6E880",
  74. "#FF97FF",
  75. "#FECB52",
  76. "#636EFB",
  77. "#EF553C",
  78. "#00CC97",
  79. "#AB63FB",
  80. "#FFA15B",
  81. "#19D3F4",
  82. "#FF6693",
  83. "#B6E881",
  84. "#FF97FE",
  85. "#FECB51",
  86. "#1F77B4",
  87. "#FF7F0E",
  88. "#2CA02C",
  89. "#D62728",
  90. "#9467BD",
  91. "#8C564B",
  92. "#E377C2",
  93. "#7F7F7F",
  94. "#BCBD22",
  95. "#17BECF",
  96. "#1A55F2",
  97. "#FF5733",
  98. "#33FF57",
  99. "#3375FF",
  100. "#FF33A6",
  101. "#57FF33",
  102. "#3380FF",
  103. "#FF8033",
  104. "#57FF80",
  105. "#8033FF",
  106. "#FF3380",
  107. "#FFD733",
  108. ],
  109. };
  110. },
  111. mounted() {
  112. if (this.fileAddr) {
  113. this.getData();
  114. }
  115. },
  116. methods: {
  117. // 获取数据
  118. async getData() {
  119. if (this.fileAddr !== "") {
  120. try {
  121. this.loading = true;
  122. this.cancelToken = axios.CancelToken.source();
  123. const resultChartsData = await axios.get(this.fileAddr, {
  124. cancelToken: this.cancelToken.token,
  125. });
  126. this.chartData = resultChartsData.data;
  127. // 使用 nextTick 来确保 DOM 渲染完成后绘制图表
  128. nextTick(() => {
  129. this.drawChart();
  130. this.isError = false;
  131. this.loading = false;
  132. });
  133. } catch (error) {
  134. console.error("Error loading data:", error);
  135. this.isError = true;
  136. this.loading = false;
  137. }
  138. }
  139. },
  140. // 绘制图表
  141. drawChart() {
  142. const data = [];
  143. console.log(this.chartData, "this.chartData");
  144. this.chartData &&
  145. this.chartData.data &&
  146. this.chartData.data.forEach((turbine, index) => {
  147. // 判断图表类型,根据类型调整绘制方式
  148. const chartConfig = {
  149. x: turbine.xData, // X 数据
  150. y: turbine.yData, // Y 数据
  151. name: turbine.engineName, // 使用机组名称
  152. line: {
  153. color:
  154. this.color1.length > 0
  155. ? this.color1[index % this.color1.length]
  156. : this.colors[index % this.colors.length], // 为每个机组分配不同的颜色
  157. },
  158. marker: {
  159. color:
  160. this.color1.length > 0
  161. ? this.color1[index % this.color1.length]
  162. : this.colors[index % this.colors.length], // 为每个机组分配不同的颜色
  163. },
  164. };
  165. if (this.chartType === "line") {
  166. chartConfig.mode = "lines"; // 如果是折线图
  167. chartConfig.fill = "none";
  168. } else if (this.chartType === "bar") {
  169. // chartConfig.type = "bar"; // 如果是柱状图
  170. chartConfig.fill = "tonexty";
  171. }
  172. data.push(chartConfig);
  173. });
  174. const layout = {
  175. title: this.chartData.title,
  176. xaxis: {
  177. title: this.chartData.xaixs || "X轴", // 横坐标标题
  178. },
  179. yaxis: {
  180. title: this.chartData.yaixs || "Y轴", // 纵坐标标题
  181. },
  182. margin: {
  183. l: 50,
  184. r: 50,
  185. t: 50,
  186. b: 50,
  187. },
  188. autosize: true, // 开启自适应
  189. barmode: this.chartType === "bar" ? "stack" : "group", // 如果是柱状图则启用堆叠
  190. };
  191. if (
  192. this.chartData.contract_Cp_curve_yData &&
  193. this.chartData.contract_Cp_curve_yData.length > 0
  194. ) {
  195. data.push({
  196. x: this.chartData.contract_Cp_curve_xData,
  197. y: this.chartData.contract_Cp_curve_yData,
  198. mode: "lines+markers",
  199. name: "合同功率曲线",
  200. line: {
  201. color: "red",
  202. width: 1, // 设置线条的宽度为1
  203. },
  204. marker: { color: "red", size: 4 },
  205. });
  206. }
  207. // 使用 Plotly.react 来更新图表
  208. Plotly.react(`bar-chart${this.index}`, data, layout, {
  209. responsive: true,
  210. });
  211. },
  212. // 切换图表类型
  213. toggleChartType() {
  214. this.chartType = this.chartType === "line" ? "bar" : "line"; // 切换图表类型
  215. this.drawChart(); // 重新绘制图表
  216. },
  217. // 更新图表颜色
  218. updateChartColor() {
  219. this.drawChart(); // 更新颜色后重新绘制图表
  220. },
  221. // 根据配色方案设置每个选项的样式
  222. getOptionStyle(scheme) {
  223. return {
  224. background: `linear-gradient(to right, ${scheme.join(", ")})`,
  225. color: "#fff",
  226. height: "30px",
  227. lineHeight: "30px",
  228. borderRadius: "4px",
  229. };
  230. },
  231. },
  232. };
  233. </script>
  234. <style scoped>
  235. /* 样式可以根据需求自定义 */
  236. </style>