【ECharts不显示问题】uniapp 解决打包 安卓app打包后‌ECharts不显示的问题

507 阅读5分钟

在用uniapp多端开始时候,H5预览能出现,但是打包后不显示。也正常引入和安装依赖后,还是不显示。

ECharts 需要通过 render.js 文件来进行多端的适配工作。这个 render.js 文件会根据当前的运行环境来选择合适的渲染方式,以确保 ECharts 在不同平台下都能正常显示和交互。这意味着在打包成 APK 时,需要确保 render.js 文件能够正确地适配到 Android 平台

实践代码



<template>
  <view class="content">
    <!-- #ifdef APP-PLUS || H5 -->
    <view
      @click="echarts.onClick"
      :prop="option"
      :change:prop="echarts.updateEcharts"
      id="echarts"
      class="echarts"
    ></view>
    <!-- #endif -->
  </view>
</template>
  
  <script>
import { getExpressStatByDay } from '@/api/statistics'
import * as echarts from 'echarts'
import { watch } from 'vue'
export default {
  props: {
    deptId: {
      type: String,
      default: ''
    }
  },
  data() {
    return {
      //echart配置数据
      echartsData: {},
      option: {
        tooltip: {
          trigger: 'axis'
        },
        legend: {
          data: ['入库', '出库']
        },
        grid: {
          left: '3%',
          right: '5%',
          bottom: '3%',
          containLabel: true
        },
        xAxis: {
          type: 'category',
          boundaryGap: false, //坐标轴两边留白
          data: [],
          axisLabel: {
            //坐标轴刻度标签的相关设置。
            interval: 1, //设置为 1,表示『隔一个标签显示一个标签』
            //	margin:15,
            textStyle: {
              color: '#1B253A',
              fontStyle: 'normal',
              fontFamily: '微软雅黑',
              fontSize: 12
            },
            formatter: function (params) {
              var newParamsName = ''
              var paramsNameNumber = params.length
              var provideNumber = 5 //一行显示几个字
              var rowNumber = Math.ceil(paramsNameNumber / provideNumber)
              if (paramsNameNumber > provideNumber) {
                for (var p = 0; p < rowNumber; p++) {
                  var tempStr = ''
                  var start = p * provideNumber
                  var end = start + provideNumber
                  if (p == rowNumber - 1) {
                    tempStr = params.substring(start, paramsNameNumber)
                  } else {
                    tempStr = params.substring(start, end) + '\n'
                  }
                  newParamsName += tempStr
                }
              } else {
                newParamsName = params
              }
              return newParamsName
            }
            //rotate:50,
          },
          axisTick: {
            //坐标轴刻度相关设置。
            show: false
          },
          axisLine: {
            //坐标轴轴线相关设置
            lineStyle: {
              color: '#E5E9ED'
              // opacity:0.2
            }
          },
          splitLine: {
            //坐标轴在 grid 区域中的分隔线。
            show: true,
            lineStyle: {
              color: '#E5E9ED'
              // 	opacity:0.1
            }
          }
        },
        yAxis: [
          {
            type: 'value',
            splitNumber: 5,
            axisLabel: {
              textStyle: {
                color: '#a8aab0',
                fontStyle: 'normal',
                fontFamily: '微软雅黑',
                fontSize: 12
              }
            },
            axisLine: {
              show: false
            },
            axisTick: {
              show: false
            },
            splitLine: {
              show: true,
              lineStyle: {
                color: '#E5E9ED'
                // 	opacity:0.1
              }
            }
          }
        ],
        series: [
          {
            name: '入库',
            type: 'line',
            data: []
          },
          {
            name: '出库',
            type: 'line',

            data: []
          }
        ]
      }
    }
  },
  watch: {
    deptId: function (val) {
      console.log('部门id发生变化', val)
      this.getData()
    }
  },
  created() {

    this.getData()
  },
  methods: {
    async getData() {
      let dayList = []
      let outList = []
      let inList = []
      let weekQueryParams = {}
      
      for (let i = 8; i >= 0; i--) {
        const date = new Date()
        date.setDate(date.getDate() - i) // 计算当前日期减去i天
        const year = date.getFullYear()
        const month = String(date.getMonth() + 1).padStart(2, '0') // 月份从0开始,需要+1
        const day = String(date.getDate()).padStart(2, '0')
        if (i == 8) {
          weekQueryParams.startTime = `${year}-${month}-${day}`
        }
        if (i == 0) {
          weekQueryParams.endTime = `${year}-${month}-${day}`
        }
        dayList.push(`${month}-${day}`)
      }
      weekQueryParams.isAll = false
      const that = this
      if(this.deptId){
        weekQueryParams.deptId= this.deptId
      }else{
        delete weekQueryParams.deptId
      }
      // 请求数据接口
      await getExpressStatByDay(weekQueryParams).then((res) => {
        console.log('日期数据请求成功', res.data)
        res.data.map((item) => {
          inList.push(item.todayInboundTotal)
          outList.push(item.todayOutboundTotal)
        })
        const objData = {
          dayList,
          inList,
          outList
        }
        that.echartsData = objData
        that.changeOption()
      })
    },
    //button点击事件
    changeOption() {
      if (this.echartsData && this.echartsData.dayList && this.option.xAxis) {
        this.option.xAxis.data = this.echartsData.dayList
        this.option.series[0].data = this.echartsData.inList
        this.option.series[1].data = this.echartsData.outList
        this.option=JSON.parse (JSON.stringify(this.option))
      }
    },
    // renderjs 调用响应事件
    onViewClick(options) {
      console.log(options)
    }
  }
}
</script>
 
  <script module="echarts" lang="renderjs">
  let myChart
  
  export default {
  mounted() {
  if (typeof window.echarts === 'function') {
  this.initEcharts()
  } else {
  // 动态引入较大类库避免影响页面展示
  const script = document.createElement('script')
  // view 层的页面运行在 www 根目录,其相对路径相对于 www 计算
  script.src = 'static/echarts.min.js'
  script.onload = this.initEcharts.bind(this)
  document.head.appendChild(script)
  }
  },
  methods: {
  initEchartsData() {
      this.option = {
      tooltip: {
      trigger: "axis",
      },
      legend: {
        data: ["入库", "出库"],
      },
      grid: {
        left: "3%",
        right: "5%",
        bottom: "3%",
        containLabel: true,
      },
      xAxis: {
        type: "category",
        boundaryGap: false, //坐标轴两边留白
        data: [],
        axisLabel: {
          //坐标轴刻度标签的相关设置。
          interval: 1, //设置为 1,表示『隔一个标签显示一个标签』
          //	margin:15,
          textStyle: {
           color: "#1B253A",
           fontStyle: "normal",
           fontFamily: "微软雅黑",
           fontSize: 12,
          },
          formatter: function (params) {
          var newParamsName = "";
          var paramsNameNumber = params.length;
          var provideNumber = 5; //一行显示几个字
          var rowNumber = Math.ceil(paramsNameNumber / provideNumber);
          if (paramsNameNumber > provideNumber) {
            for (var p = 0; p < rowNumber; p++) {
              var tempStr = "";
              var start = p * provideNumber;
              var end = start + provideNumber;
              if (p == rowNumber - 1) {
                tempStr = params.substring(start, paramsNameNumber);
              } else {
                tempStr = params.substring(start, end) + "\n";
              }
              newParamsName += tempStr;
            }
          } else {
            newParamsName = params;
          }
          return newParamsName;
        },
        //rotate:50,
      },
      axisTick: {
        //坐标轴刻度相关设置。
        show: false,
      },
      axisLine: {
        //坐标轴轴线相关设置
        lineStyle: {
          color: "#E5E9ED",
          // opacity:0.2
        },
      },
      splitLine: {
        //坐标轴在 grid 区域中的分隔线。
        show: true,
        lineStyle: {
          color: "#E5E9ED",
          // 	opacity:0.1
        },
      },
      },
     yAxis: [
      {
        type: "value",
        splitNumber: 5,
        axisLabel: {
          textStyle: {
            color: "#a8aab0",
            fontStyle: "normal",
            fontFamily: "微软雅黑",
            fontSize: 12,
          },
        },
        axisLine: {
          show: false,
        },
        axisTick: {
          show: false,
        },
        splitLine: {
          show: true,
          lineStyle: {
            color: "#E5E9ED",
            // 	opacity:0.1
          },
        },
      },
      ],
      series: [
      {
        name: "入库",
        type: "line",
        itemStyle: {
          normal: {
            color: "#3A84FF",
            lineStyle: {
              color: "#3A84FF",
              width: 1,
            },
            areaStyle: {
              color: new echarts.graphic.LinearGradient(0, 1, 0, 0, [
                {
                  offset: 0,
                  color: "rgba(58,132,255,0)",
                },
                {
                  offset: 1,
                  color: "rgba(58,132,255,0.35)",
                },
              ]),
            },
          },
        },
        data:[],
      },
      {
        name: "出库",
        type: "line",
        itemStyle: {
          normal: {
            color: "rgba(255,80,124,1)",
            lineStyle: {
              color: "rgba(255,80,124,1)",
              width: 1,
            },
            areaStyle: {
              color: new echarts.graphic.LinearGradient(0, 1, 0, 0, [
                {
                  offset: 0,
                  color: "rgba(255,80,124,0)",
                },
                {
                  offset: 1,
                  color: "rgba(255,80,124,0.35)",
                },
              ]),
            },
          },
        },
        data:[],
      },
      ]
  };
  if(this.echartsData&&this.echartsData.dayList){
      this.option.xAxis.data=this.echartsData.dayList
      this.option.series[0].data = this.echartsData.inList
      this.option.series[1].data = this.echartsData.outList
  }
},
  initEcharts() {
  myChart = echarts.init(document.getElementById('echarts'))
  this.initEchartsData()
  // 观测更新的数据在 view 层可以直接访问到
  myChart.setOption(this.option)
  },
  updateEcharts(newValue, oldValue, ownerInstance, instance) {
  // 监听 service 层数据变更
  setTimeout(() => {
    console.log('层数据变更',newValue);
    
    // this.initEchartsData()
    // myChart.setOption(this.option)
    newValue.series[0].itemStyle= {
          normal: {
            color: "#3A84FF",
            lineStyle: {
              color: "#3A84FF",
              width: 1,
            },
            areaStyle: {
              color: new echarts.graphic.LinearGradient(0, 1, 0, 0, [
                {
                  offset: 0,
                  color: "rgba(58,132,255,0)",
                },
                {
                  offset: 1,
                  color: "rgba(58,132,255,0.35)",
                },
              ]),
            },
          },
        }
    newValue.series[1].itemStyle= {
              normal: {
                color: 'rgba(255,80,124,1)',
                lineStyle: {
                  color: 'rgba(255,80,124,1)',
                  width: 1
                },
                areaStyle: {
                  color: new echarts.graphic.LinearGradient(0, 1, 0, 0, [
                    {
                      offset: 0,
                      color: 'rgba(255,80,124,0)'
                    },
                    {
                      offset: 1,
                      color: 'rgba(255,80,124,0.35)'
                    }
                  ])
                }
              }
            }

    myChart.setOption(newValue)
  }, 500);

  },
  onClick(event, ownerInstance) {
  // 调用 service 层的方法
  ownerInstance.callMethod('onViewClick', {
  test: 'test'
  })
  }
  }
  }
  </script>
  
<style scoped>
.content {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}

.echarts {
  width: 100%;
  height: 300px;
}
</style>

注意

image.png

引入ECharts 依赖包,去官网下载依赖包

ECharts官网

代码解读

展示ECharts图表,展示近9天的入库和出库数据。下面为你逐步解释:

模板部分

vue

<template>
  <view class="content">
    <!-- #ifdef APP-PLUS || H5 -->
    <view
      @click="echarts.onClick"
      :prop="option"
      :change:prop="echarts.updateEcharts"
      id="echarts"
      class="echarts"
    ></view>
    <!-- #endif -->
  </view>
</template>
  • 仅在APP-PLUS或H5环境下渲染一个view组件。
  • 绑定点击事件echarts.onClick,传递option作为属性,属性变化时触发echarts.updateEcharts

脚本部分

javascript

import { getExpressStatByDay } from '@/api/statistics'
import * as echarts from 'echarts'
import { watch } from 'vue'

引入获取数据的API、ECharts库和Vue的watch函数。

组件选项

javascript

export default {
  props: {
    deptId: {
      type: String,
      default: ''
    }
  },
  data() {
    return {
      echartsData: {},
      option: {
        // 图表配置,包含tooltip、legend、grid、xAxis、yAxis、series等
      }
    }
  },
  watch: {
    deptId: function (val) {
      console.log('部门id发生变化', val)
      this.getData()
    }
  },
  created() {
    this.getData()
  },
  methods: {
    async getData() {
      // 计算近9天日期,封装请求参数
      // 调用API获取数据,处理响应并更新echartsData
      // 调用changeOption更新图表配置
    },
    changeOption() {
      // 更新option中的xAxis和series数据
      this.option=JSON.parse (JSON.stringify(this.option))
    },
    onViewClick(options) {
      console.log(options)
    }
  }
}
  • props接收deptId作为部门ID。
  • data定义echartsDataoptionoption为ECharts图表配置。
  • watch监听deptId变化,变化时调用getData
  • created钩子在组件创建后调用getData
  • getData方法计算近9天日期,封装请求参数,调用API获取数据,更新echartsData并调用changeOption
  • changeOption更新option中的xAxisseries数据。
  • onViewClick处理点击事件。

Renderjs部分

javascript

<script module="echarts" lang="renderjs">
  let myChart
  
  export default {
    mounted() {
      // 检查window.echarts是否存在,不存在则动态引入
      // 引入成功后调用Echarts
    },
    methods: {
      initEchartsData() {
        // 初始化ECharts配置,与上面的option类似
      }
    }
  }
</script>
  • mounted钩子检查window.echarts是否存在,不存在则动态引入,引入成功后调用initEcharts
  • initEchartsData初始化ECharts配置。