EchartsDome.vue 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. <template>
  2. <div class="echartsDome">
  3. <div class="echartsDome_title">{{ title }}</div>
  4. <div class="echartsDome_chart" ref="chartContainer"></div>
  5. </div>
  6. </template>
  7. <script>
  8. import * as echarts from "echarts";
  9. export default {
  10. name: "EchartsDome",
  11. props: {
  12. title: {
  13. type: String,
  14. default: "图表标题",
  15. },
  16. chartOption: {
  17. type: Object,
  18. default: () => ({}), // 使用函数返回默认对象
  19. },
  20. },
  21. data() {
  22. return {
  23. chartInstance: null, // 保存ECharts实例引用
  24. };
  25. },
  26. mounted() {
  27. this.$nextTick(() => {
  28. this.initChart();
  29. });
  30. },
  31. watch: {
  32. chartOption: {
  33. handler(newVal, oldVal) {
  34. // 检查是否为有效对象
  35. if (newVal && typeof newVal === "object") {
  36. this.updateChart(newVal);
  37. }
  38. },
  39. deep: true,
  40. },
  41. },
  42. methods: {
  43. initChart() {
  44. // 如果已存在实例,先销毁
  45. if (this.chartInstance) {
  46. this.chartInstance.dispose();
  47. }
  48. // 创建新实例
  49. let chartInstance = echarts.init(this.$refs.chartContainer);
  50. this.chartInstance = chartInstance;
  51. // 更新图表配置
  52. this.updateChart(this.chartOption);
  53. },
  54. updateChart(option) {
  55. // 创建新实例
  56. // 如果已存在实例,先销毁
  57. if (this.chartInstance) {
  58. this.chartInstance.dispose();
  59. }
  60. // 创建新实例
  61. let chartInstance = echarts.init(this.$refs.chartContainer);
  62. this.chartInstance = chartInstance;
  63. // 深拷贝配置,避免修改原始props
  64. const mergedOption = JSON.parse(JSON.stringify(option));
  65. // 绘制图表
  66. mergedOption.grid = {
  67. top: 80,
  68. left: 10, // 核心1:grid左侧距离容器左侧0px
  69. right: 50, // 核心2:grid右侧距离容器右侧0px
  70. bottom: 0,
  71. containLabel: true, // 关键:防止坐标轴标签超出容器(可选,根据需求添加)
  72. };
  73. if (!mergedOption.legend) {
  74. mergedOption.legend = {};
  75. }
  76. Object.assign(mergedOption.legend, {
  77. textStyle: {
  78. color: "#F2F3F5", // 字体颜色(支持十六进制、RGB、颜色名)
  79. fontSize: 14, // 可选:字体大小
  80. fontWeight: "normal", // 可选:字体粗细
  81. },
  82. });
  83. // 合并tooltip配置
  84. if (!mergedOption.tooltip) {
  85. mergedOption.tooltip = {};
  86. }
  87. Object.assign(mergedOption.tooltip, {
  88. backgroundColor: "rgba(0, 25, 50, 0.8)",
  89. borderColor: "#1E90FF",
  90. textStyle: {
  91. color: "#fff",
  92. },
  93. });
  94. chartInstance.setOption(mergedOption, true);
  95. // 添加resize事件监听
  96. window.addEventListener("resize", () => {
  97. chartInstance.resize();
  98. });
  99. },
  100. },
  101. };
  102. </script>
  103. <style scoped>
  104. .echartsDome {
  105. width: 100%;
  106. height: 100%;
  107. padding: 20px;
  108. box-sizing: border-box;
  109. }
  110. .echartsDome_title {
  111. font-size: 16px;
  112. }
  113. .echartsDome_chart {
  114. width: 100%;
  115. height: calc(100% - 40px);
  116. }
  117. </style>