#
Junjie
2026-02-02 d5c405aedb5ece427a36086e678114f3615cf599
#
1个文件已修改
236 ■■■■■ 已修改文件
components/EChartsLine/EChartsLine.vue 236 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
components/EChartsLine/EChartsLine.vue
@@ -1,14 +1,20 @@
<template>
  <view class="echarts-container">
    <!-- #ifdef H5 || APP-PLUS -->
  <view class="echarts-container" :style="containerStyle">
    <!-- #ifdef APP-PLUS || H5 -->
    <view 
      :id="chartId" 
      class="echarts-chart" 
      :style="chartStyle"
      :prop="chartData"
      :change:prop="echarts.updateData"
      :chartIdProp="chartId"
      :change:chartIdProp="echarts.updateId"
      :colorsProp="colors"
      :change:colorsProp="echarts.updateColors"
    ></view>
    <!-- #endif -->
    
    <!-- #ifdef MP-WEIXIN || MP-ALIPAY || MP-BAIDU || MP-TOUTIAO -->
    <!-- #ifndef APP-PLUS || H5 -->
    <view class="mp-not-supported">
      <text class="mp-text">图表组件暂不支持小程序平台</text>
    </view>
@@ -42,12 +48,16 @@
  },
  data() {
    return {
      chartId: '',
      chartInstance: null
      chartId: ''
    }
  },
  computed: {
    chartStyle() {
      const w = typeof this.width === 'number' ? `${this.width}px` : this.width
      const h = typeof this.height === 'number' ? `${this.height}px` : this.height
      return { width: w, height: h }
    },
    containerStyle() {
      const w = typeof this.width === 'number' ? `${this.width}px` : this.width
      const h = typeof this.height === 'number' ? `${this.height}px` : this.height
      return { width: w, height: h }
@@ -56,128 +66,87 @@
  created() {
    // Generate unique chart ID
    this.chartId = 'echarts-line-' + Math.random().toString(36).substr(2, 9)
  },
  mounted() {
    // Delay initialization to ensure DOM is ready
    setTimeout(() => {
      this.initChart()
    }, 100)
  },
  watch: {
    chartData: {
      handler(newData) {
        if (this.chartInstance) {
          this.updateChart(newData)
        }
      },
      deep: true
  }
}
</script>
<script module="echarts" lang="renderjs">
let myChart
let chartId = ''
let currentColors = ['#1890FF', '#F04864']
export default {
  data() {
    return {
      isLoaded: false,
      pendingData: null
    }
  },
  mounted() {
    this.initEcharts()
  },
  methods: {
    initChart() {
      // #ifdef H5
      this.initH5Chart()
      // #endif
      // #ifdef APP-PLUS
      this.initAppChart()
      // #endif
      // #ifdef MP-WEIXIN || MP-ALIPAY || MP-BAIDU || MP-TOUTIAO
      this.initMpChart()
      // #endif
    },
    initH5Chart() {
      // For H5 platform, use the existing echarts from qiun-data-charts
      this.$nextTick(() => {
        try {
          const echarts = window.echarts
          if (echarts) {
            this.createChart(echarts)
          } else {
            // Fallback: load from qiun-data-charts
            import('../../uni_modules/qiun-data-charts/static/h5/echarts.min.js').then(module => {
              const echarts = window.echarts || module.default
              this.createChart(echarts)
            }).catch(err => {
              console.error('Failed to load ECharts for H5:', err)
            })
          }
        } catch (error) {
          console.error('Error initializing H5 chart:', error)
    initEcharts() {
      if (typeof window.echarts === 'object') {
        this.isLoaded = true
        if (this.pendingData) {
          this.renderChart(this.pendingData)
        }
      })
    },
    initAppChart() {
      // For App platform
      this.$nextTick(() => {
        try {
          const echarts = window.echarts
          if (echarts) {
            this.createChart(echarts)
          } else {
            // Load from qiun-data-charts
            import('../../uni_modules/qiun-data-charts/static/app-plus/echarts.min.js').then(module => {
              const echarts = window.echarts || module.default
              this.createChart(echarts)
            }).catch(err => {
              console.error('Failed to load ECharts for App:', err)
            })
          }
        } catch (error) {
          console.error('Error initializing App chart:', error)
        }
      })
    },
    initMpChart() {
      // For mini-program platforms
      this.$nextTick(() => {
        try {
          // Use the same approach as qiun-data-charts for mini-programs
          const echarts = window.echarts
          if (echarts) {
            this.createChart(echarts)
          } else {
            console.warn('ECharts not available in mini-program environment')
          }
        } catch (error) {
          console.error('Error initializing mini-program chart:', error)
        }
      })
    },
    createChart(echarts) {
      try {
        const chartDom = document.getElementById(this.chartId)
        if (!chartDom) {
          console.error('Chart DOM element not found with ID:', this.chartId)
          return
        }
        this.chartInstance = echarts.init(chartDom, null, {
          devicePixelRatio: window.devicePixelRatio
      } else {
        // Load ECharts dynamically
        // Using the file from uni_modules which is available in the project
        const script = document.createElement('script')
        // Try to load from local static path if possible, or import
        // Since we can't easily use script src for local files in App without correct path
        // We use import() which is bundled by uni-app
        import('../../uni_modules/qiun-data-charts/static/h5/echarts.min.js').then(module => {
            window.echarts = module.default || module
            this.isLoaded = true
            if (this.pendingData) {
              this.renderChart(this.pendingData)
            }
        }).catch(err => {
            console.error('Failed to load ECharts:', err)
        })
        this.updateChart(this.chartData)
        // Handle window resize for H5
        // #ifdef H5
        window.addEventListener('resize', this.handleResize)
        // #endif
      } catch (error) {
        console.error('Error creating chart:', error)
      }
      window.addEventListener('resize', this.resize)
    },
    updateId(newValue, oldValue, ownerInstance, instance) {
      chartId = newValue
    },
    updateColors(newValue, oldValue, ownerInstance, instance) {
      if (newValue && Array.isArray(newValue)) {
        currentColors = newValue
      }
    },
    
    updateChart(data) {
      if (!this.chartInstance || !data || !data.categories || !data.series) {
        return
    updateData(newValue, oldValue, ownerInstance, instance) {
      if (!newValue) return
      if (this.isLoaded) {
        this.renderChart(newValue)
      } else {
        this.pendingData = newValue
      }
    },
    renderChart(data) {
      if (!window.echarts || !chartId) return
      const el = document.getElementById(chartId)
      if (!el) return
      if (!myChart) {
        myChart = window.echarts.init(el, null, {
          devicePixelRatio: window.devicePixelRatio
        })
      }
      
      const option = {
        color: this.colors,
        color: currentColors,
        grid: {
          top: '25%',
          left: '5%',
@@ -196,7 +165,7 @@
        },
        xAxis: {
          type: 'category',
          data: data.categories,
          data: data.categories || [],
          axisLine: {
            lineStyle: {
              color: '#CCCCCC'
@@ -231,17 +200,17 @@
            show: false
          }
        },
        series: data.series.map((serie, index) => ({
        series: (data.series || []).map((serie, index) => ({
          name: serie.name,
          type: 'line',
          data: serie.data,
          smooth: false,
          lineStyle: {
            width: 3,
            color: this.colors[index % this.colors.length]
            color: currentColors[index % currentColors.length]
          },
          itemStyle: {
            color: this.colors[index % this.colors.length]
            color: currentColors[index % currentColors.length]
          },
          symbol: 'circle',
          symbolSize: 8,
@@ -272,40 +241,27 @@
        }
      }
      
      this.chartInstance.setOption(option, true)
      myChart.setOption(option, true)
    },
    
    handleResize() {
      if (this.chartInstance) {
        this.chartInstance.resize()
      }
    },
    // Method to manually resize chart
    resize() {
      if (this.chartInstance) {
        this.chartInstance.resize()
      if (myChart) {
        myChart.resize()
      }
    }
  },
  beforeDestroy() {
    if (this.chartInstance) {
      this.chartInstance.dispose()
      this.chartInstance = null
    if (myChart) {
      myChart.dispose()
      myChart = null
    }
    // #ifdef H5
    window.removeEventListener('resize', this.handleResize)
    // #endif
    window.removeEventListener('resize', this.resize)
  }
}
</script>
<style scoped>
.echarts-container {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;