uniapp引入echarts App端 formatter无效问题

一时失言乱红尘 2022-11-18 11:00 694阅读 0赞

前言

在开发中有时候根据需求需要添加总和之类的特殊要求,发现在web端没有问题在App端解析不了formatter 里面函数

解决方案

问题原因;需要在setOption之前手动设置,如下
封装echarts.vue组件,主要在这里面设置 formatter函数

  1. <template>
  2. <view>
  3. <view class="echarts" :prop="option" :change:prop="echarts.update"></view>
  4. </view>
  5. </template>
  6. <script>
  7. export default {
  8. name: 'Echarts',
  9. props: {
  10. option: {
  11. type: Object,
  12. required: true
  13. },
  14. numLeng:{
  15. type:Number
  16. }
  17. }
  18. }
  19. </script>
  20. <script module="echarts" lang="renderjs">
  21. export default {
  22. data() {
  23. return {
  24. chart: null
  25. }
  26. },
  27. mounted() {
  28. if (typeof window.echarts === 'object') {
  29. this.init()
  30. } else {
  31. // 动态引入类库
  32. const script = document.createElement('script')
  33. script.src = './static/echarts.js'
  34. // script.src = './static/echarts/echarts.min.js'
  35. script.onload = this.init
  36. document.head.appendChild(script)
  37. }
  38. },
  39. methods: {
  40. /**
  41. * 初始化echarts
  42. */
  43. init() {
  44. this.chart = echarts.init(this.$el)
  45. this.update(this.option)
  46. },
  47. /**
  48. * 监测数据更新
  49. * @param {Object} option
  50. */
  51. update(option) {
  52. if (this.chart) {
  53. // 因App端,回调函数无法从renderjs外传递,故在此自定义设置相关回调函数
  54. if (option) {
  55. // tooltip
  56. if (option.tooltip) {
  57. // 判断是否设置tooltip的位置
  58. if (option.tooltip.positionStatus) {
  59. option.tooltip.position = this.tooltipPosition()
  60. }
  61. // 判断是否格式化tooltip
  62. if (option.tooltip.formatterStatus) {
  63. // this.tooltipFormatter 里面的参数对应 tooltip里面自定义的名字 在这里设置 往下看
  64. option.tooltip.formatter = this.tooltipFormatter(option.tooltip.formatterUnit, option.tooltip.formatFloat2, option.tooltip.formatThousands,option.tooltip.formatFunDefeat,option.tooltip.formatFunClue)
  65. }
  66. // if (option.tooltip.formatterStatus) {
  67. // if( this.numLeng==2){
  68. // option.tooltip.formatter = this.formatFunDefeat()
  69. // }
  70. // }
  71. }
  72. }
  73. // 设置新的option
  74. this.chart.setOption(option, option.notMerge)
  75. }
  76. },
  77. /**
  78. * 设置tooltip的位置,防止超出画布
  79. */
  80. tooltipPosition() {
  81. return (point, params, dom, rect, size) => {
  82. //其中point为当前鼠标的位置,size中有两个属性:viewSize和contentSize,分别为外层div和tooltip提示框的大小
  83. let x = point[0]
  84. let y = point[1]
  85. let viewWidth = size.viewSize[0]
  86. let viewHeight = size.viewSize[1]
  87. let boxWidth = size.contentSize[0]
  88. let boxHeight = size.contentSize[1]
  89. let posX = 0 //x坐标位置
  90. let posY = 0 //y坐标位置
  91. if (x < boxWidth) { //左边放不开
  92. posX = 5
  93. } else { //左边放的下
  94. posX = x - boxWidth
  95. }
  96. if (y < boxHeight) { //上边放不开
  97. posY = 5
  98. } else { //上边放得下
  99. posY = y - boxHeight
  100. }
  101. return [posX, posY]
  102. }
  103. },
  104. /**
  105. * tooltip格式化
  106. * @param {Object} unit 数值后的单位
  107. * @param {Object} formatFloat2 是否保留两位小数
  108. * @param {Object} formatThousands 是否添加千分位
  109. */
  110. // this.numLeng==2
  111. tooltipFormatter(unit, formatFloat2, formatThousands,formatFunDefeat,formatFunClue) {
  112. return params => {
  113. let result = ''
  114. var arrTip=[]
  115. unit = unit ? unit : ''
  116. for (let i in params) {
  117. let value = ''
  118. if (params[i].data !== null) {
  119. value = params[i].data
  120. // 保留两位小数
  121. if (formatFloat2) {
  122. value = this.formatFloat2(value)
  123. }
  124. // 添加千分位
  125. if (formatThousands) {
  126. value = this.formatThousands(value)
  127. }
  128. //战败量
  129. if(formatFunDefeat){
  130. value=`<span style='color: #FFFFFF'>战败量:${params[i].value}</span> <br/>`
  131. }
  132. //线索量变化
  133. if(formatFunClue){
  134. var res = ''
  135. var sum = 0
  136. var arrTip=[]
  137. sum += params[i].value
  138. res = `${params[i].marker} <span style='color: #FFFFFF'>${params[i].seriesName} : ${params[i].value}</span> <br/>`
  139. arrTip.unshift(res)
  140. if(i==params.length-1) {
  141. res = `<span style='color: #FFFFFF'>总数 : ${sum}</span>`
  142. arrTip.push(res)
  143. }
  144. arrTip=arrTip.join().replace(/,/g,"");
  145. }
  146. }
  147. if(formatFunClue){
  148. value=arrTip
  149. }
  150. // #ifdef H5
  151. result += value
  152. // #endif
  153. // #ifdef APP-PLUS
  154. result += value
  155. // #endif
  156. }
  157. return result
  158. }
  159. },
  160. /**
  161. * 保留两位小数
  162. * @param {Object} value
  163. */
  164. formatFloat2(value) {
  165. let temp = Math.round(parseFloat(value) * 100) / 100
  166. let xsd = temp.toString().split('.')
  167. if (xsd.length === 1) {
  168. temp = (isNaN(temp) ? '0' : temp.toString()) + '.000'
  169. return temp
  170. }
  171. if (xsd.length > 1) {
  172. if (xsd[1].length < 2) {
  173. temp = temp.toString() + '0'
  174. }
  175. return temp
  176. }
  177. },
  178. /**
  179. * 添加千分位
  180. * @param {Object} value
  181. */
  182. formatThousands(value) {
  183. if (value === undefined || value === null) {
  184. value = ''
  185. }
  186. if (!isNaN(value)) {
  187. value = value + ''
  188. }
  189. let re = /\d{1,3}(?=(\d{3})+$)/g
  190. let n1 = value.replace(/^(\d+)((\.\d+)?)$/, function(s, s1, s2) {
  191. return s1.replace(re, '$&,') + s2
  192. })
  193. return n1
  194. },
  195. /**
  196. * 战败量
  197. * @param {Object} value
  198. */
  199. formatFunDefeat(data,value){
  200. console.log(data,value)
  201. let appdata=''
  202. if(this.numLeng==1){
  203. appdata= 'APP1'
  204. }else if(this.numLeng==2){
  205. appdata= '战败量:'+value
  206. }
  207. return appdata
  208. }
  209. }
  210. }
  211. </script>
  212. <style lang="scss" scoped>
  213. .echarts {
  214. width: 100%;
  215. height: 100%;
  216. }
  217. </style>

创建echartsStackCon.vue,这里是我封装的一个 堆叠图组件
echartsData:是传递过来的数据

  1. <template>
  2. <view>
  3. <view class="clueQuantity_change_title">线索量变化</view>
  4. <view class="clueQuantity_change" :style="{height: height+'rpx'}">
  5. <view class="qiun-columns" style="overflow: hidden;">
  6. <slot></slot>
  7. <view><echarts :option="optionStackFun()" :numLeng='1' :style="{height: height+'rpx'}"></echarts></view>
  8. </view>
  9. </view>
  10. </view>
  11. </template>
  12. <script>
  13. import echarts from '@/components/echarts/echarts.vue';
  14. export default {
  15. data() {
  16. return {
  17. //堆叠柱状图数据
  18. optionStack: {}, //堆叠柱状图配置
  19. color: ['#FD5757', '#FECD2F', '#7CDEBC', '#3CB3D0', '#5D9BFC'],
  20. };
  21. },
  22. props:{
  23. echartsData:{
  24. type:Object
  25. },
  26. height:{
  27. type:String,
  28. default:'420'
  29. },
  30. },
  31. watch:{
  32. echartsData(Val){
  33. return Val
  34. },
  35. },
  36. components: {
  37. echarts
  38. },
  39. computed:{
  40. level(){
  41. let levelArr=[]
  42. this.echartsData['series'].forEach((v,i)=>{
  43. levelArr.unshift(v.name)
  44. })
  45. return levelArr
  46. },
  47. },
  48. created() {
  49. },
  50. methods: {
  51. //堆叠柱状图数据
  52. optionStackFun() {
  53. console.log(this.echartsData,this.level,'-----------堆叠柱状图数据')
  54. return {
  55. tooltip: {
  56. trigger: 'axis',
  57. confine:true,
  58. axisPointer: {
  59. // 坐标轴指示器,坐标轴触发有效
  60. type: 'shadow' // 默认为直线,可选为:'line' | 'shadow'
  61. },
  62. formatterStatus:true,//开启自定义
  63. formatFunClue:'formatFunClue',//对应echarts.vue
  64. backgroundColor: '#222222',
  65. extraCssText: 'box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.16);',
  66. // formatter:function(data) {
  67. // var res = ''
  68. // var sum = 0
  69. // var arrTip=[]
  70. // data.forEach((item,index) => {
  71. // sum += item.value
  72. // res = `${item.marker} <span style='color: #FFFFFF'>${item.seriesName} : ${item.value}</span> <br/>`
  73. // arrTip.unshift(res)
  74. // if(index==data.length-1) {
  75. // res = `<span style='color: #FFFFFF'>总数 : ${sum}</span>`
  76. // arrTip.push(res)
  77. // }
  78. // })
  79. // arrTip=arrTip.join().replace(/,/g,"");
  80. // return arrTip
  81. // }
  82. },
  83. // color: this.color,
  84. legend: {
  85. data: this.level,
  86. left: 30,
  87. top:20,
  88. icon: "circle",
  89. itemGap: 20,
  90. itemWith:10,
  91. itemHeight:10
  92. },
  93. grid: {
  94. left: '3%',
  95. right: '4%',
  96. bottom: '3%',
  97. containLabel: true
  98. },
  99. xAxis: [
  100. {
  101. type: 'category',
  102. data: this.echartsData.categories,
  103. axisLine: {
  104. show: false
  105. },
  106. axisTick: {
  107. show: false
  108. }
  109. }
  110. ],
  111. yAxis: [
  112. {
  113. type: 'value',
  114. axisLabel: {
  115. show: true,
  116. interval: 'auto',
  117. // formatter: '{value} %'
  118. },
  119. show: true,
  120. axisLine: {
  121. show: false
  122. },
  123. axisTick: {
  124. show: false
  125. },
  126. splitLine: {
  127. show: false
  128. },
  129. splitLine: {
  130. lineStyle: {
  131. type: "dashed",
  132. },
  133. show: true,
  134. },
  135. }
  136. ],
  137. series: this.echartsData.series,
  138. };
  139. },
  140. },
  141. };
  142. </script>
  143. <style scoped lang="scss">
  144. .clueQuantity_change_title {
  145. font-size: 32rpx;
  146. color: #43425d;
  147. padding-left: 30rpx;
  148. background-color: #f5f6fa;
  149. width: 100%;
  150. height: 80rpx;
  151. line-height: 80rpx;
  152. font-weight: 500;
  153. }
  154. .clueQuantity_change {
  155. width: 100%;
  156. height: 440rpx;
  157. background-color: #ffffff;
  158. }
  159. </style>

echartsData数据格式

  1. {
  2. "categories": [
  3. "03/29"
  4. ],
  5. "series": [
  6. {
  7. "name": "A级",
  8. "data": [
  9. 3
  10. ],
  11. "type": "bar",
  12. "stack": "stackone",
  13. "itemStyle": {
  14. "normal": {
  15. "color": "#7CDEBC"
  16. }
  17. },
  18. "barWidth": 20
  19. },
  20. {
  21. "name": "H级",
  22. "data": [
  23. 1
  24. ],
  25. "type": "bar",
  26. "stack": "stackone",
  27. "itemStyle": {
  28. "normal": {
  29. "color": "#FECD2F"
  30. }
  31. },
  32. "barWidth": 20
  33. },
  34. {
  35. "name": "O级",
  36. "data": [
  37. 3
  38. ],
  39. "type": "bar",
  40. "stack": "stackone",
  41. "itemStyle": {
  42. "normal": {
  43. "color": "#FD5757"
  44. }
  45. },
  46. "barWidth": 20
  47. }
  48. ]
  49. }

发表评论

表情:
评论列表 (有 0 条评论,694人围观)

还没有评论,来说两句吧...

相关阅读

    相关 echarts formatter用法

    ECharts 中 formatter 是一个格式化函数,用于格式化提示框(tooltip)和图例(legend)中的文本显示。其函数接收一些参数,返回格式化后的字符串,以在图

    相关 echarts-formatter

    模板变量有 \{a\}, \{b\},\{c\},\{d\},\{e\},分别表示系列名,数据名,数据值等。 在 trigger 为 'axis' 的时候,会有多个系列的数据,