echarts-uniapp.vue 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. <template>
  2. <!-- #ifdef MP-WEIXIN || MP-TOUTIAO -->
  3. <canvas type="2d" class="echarts" :canvas-id="canvasId" :id="canvasId" @touchstart="touchStart"
  4. @touchmove="touchMove" @touchend="touchEnd" />
  5. <!-- #endif -->
  6. <!-- #ifndef MP-WEIXIN || MP-TOUTIAO -->
  7. <canvas class="echarts" :canvas-id="canvasId" :id="canvasId" @touchstart="touchStart" @touchmove="touchMove"
  8. @touchend="touchEnd" />
  9. <!-- #endif -->
  10. </template>
  11. <script>
  12. /**
  13. * echartsForUniApp echart兼容uni-app
  14. * @description echart兼容uni-app
  15. * @property {Object} option 图表数据
  16. * @property {String} canvasId 画布id
  17. * @example <echarts ref="echarts" :option="option" canvasId="echarts"></echarts>
  18. */
  19. import WxCanvas from './wx-canvas.js';
  20. import * as echarts from './echarts.min.js';
  21. var chartList = {}
  22. export default {
  23. props: {
  24. canvasId: {
  25. type: String,
  26. default: 'echarts'
  27. },
  28. option: {
  29. type: Object,
  30. default: () => {
  31. return {}
  32. }
  33. },
  34. },
  35. watch: {
  36. option(newValue, oldValue) {
  37. if(newValue.series){
  38. this.initChart(newValue)
  39. }
  40. }
  41. },
  42. data() {
  43. return {
  44. ctx:null
  45. }
  46. },
  47. mounted() {
  48. // Disable prograssive because drawImage doesn't support DOM as parameter
  49. // See https://developers.weixin.qq.com/miniprogram/dev/api/canvas/CanvasContext.drawImage.html
  50. echarts.registerPreprocessor(option => {
  51. if (option && option.series) {
  52. if (option.series.length > 0) {
  53. option.series.forEach(series => {
  54. series.progressive = 0;
  55. });
  56. } else if (typeof option.series === 'object') {
  57. option.series.progressive = 0;
  58. }
  59. }
  60. });
  61. },
  62. methods: {
  63. getCanvasAttr2d() {
  64. return new Promise((resolve, reject) => {
  65. const query = uni.createSelectorQuery().in(this)
  66. query
  67. .select('#' + this.canvasId)
  68. .fields({
  69. node: true,
  70. size: true
  71. })
  72. .exec(res => {
  73. const canvasNode = res[0].node
  74. this.canvasNode = canvasNode
  75. const canvasDpr = uni.getSystemInfoSync().pixelRatio
  76. const canvasWidth = res[0].width
  77. const canvasHeight = res[0].height
  78. this.ctx = canvasNode.getContext('2d')
  79. const canvas = new WxCanvas(this.ctx, this.canvasId, true, canvasNode)
  80. echarts.setCanvasCreator(() => {
  81. return canvas
  82. })
  83. resolve({
  84. canvas,
  85. canvasWidth,
  86. canvasHeight,
  87. canvasDpr
  88. })
  89. })
  90. });
  91. },
  92. getCanvasAttr() {
  93. return new Promise((resolve, reject) => {
  94. this.ctx = uni.createCanvasContext(this.canvasId, this);
  95. var canvas = new WxCanvas(this.ctx, this.canvasId, false);
  96. echarts.setCanvasCreator(() => {
  97. return canvas;
  98. });
  99. const canvasDpr = 1
  100. var query = uni.createSelectorQuery()
  101. // #ifndef MP-ALIPAY
  102. .in(this)
  103. // #endif
  104. query.select('#' + this.canvasId).boundingClientRect(res => {
  105. const canvasWidth = res.width
  106. const canvasHeight = res.height
  107. resolve({
  108. canvas,
  109. canvasWidth,
  110. canvasHeight,
  111. canvasDpr
  112. })
  113. }).exec();
  114. });
  115. },
  116. // #ifdef H5
  117. //H5绘制图表
  118. initChart(option) {
  119. this.ctx = uni.createCanvasContext(this.canvasId, this);
  120. chartList[this.canvasId] = echarts.init(document.getElementById(this.canvasId));
  121. chartList[this.canvasId].setOption(option?option:this.option);
  122. },
  123. //H5生成图片
  124. canvasToTempFilePath(opt) {
  125. const base64 = chartList[this.canvasId].getDataURL()
  126. opt.success && opt.success({tempFilePath:base64})
  127. },
  128. // #endif
  129. // #ifndef H5
  130. //绘制图表
  131. async initChart(option) {
  132. // #ifdef MP-WEIXIN || MP-TOUTIAO
  133. const canvasAttr = await this.getCanvasAttr2d();
  134. // #endif
  135. // #ifndef MP-WEIXIN || MP-TOUTIAO
  136. const canvasAttr = await this.getCanvasAttr();
  137. // #endif
  138. const {
  139. canvas,
  140. canvasWidth,
  141. canvasHeight,
  142. canvasDpr
  143. } = canvasAttr
  144. chartList[this.canvasId] = echarts.init(canvas, null, {
  145. width: canvasWidth,
  146. height: canvasHeight,
  147. devicePixelRatio: canvasDpr // new
  148. });
  149. canvas.setChart(chartList[this.canvasId]);
  150. chartList[this.canvasId].setOption(option?option:this.option);
  151. },
  152. //生成图片
  153. canvasToTempFilePath(opt) {
  154. // #ifdef MP-WEIXIN || MP-TOUTIAO
  155. var query = uni.createSelectorQuery()
  156. // #ifndef MP-ALIPAY
  157. .in(this)
  158. // #endif
  159. query.select('#' + this.canvasId).fields({ node: true, size: true }).exec(res => {
  160. const canvasNode = res[0].node
  161. opt.canvas = canvasNode
  162. uni.canvasToTempFilePath(opt, this)
  163. })
  164. // #endif
  165. // #ifndef MP-WEIXIN || MP-TOUTIAO
  166. if (!opt.canvasId) {
  167. opt.canvasId = this.canvasId;
  168. }
  169. this.ctx.draw(true, () => {
  170. uni.canvasToTempFilePath(opt, this);
  171. });
  172. // #endif
  173. },
  174. // #endif
  175. touchStart(e) {
  176. if (chartList[this.canvasId] && e.touches.length > 0) {
  177. var touch = e.touches[0];
  178. var handler = chartList[this.canvasId].getZr().handler;
  179. handler.dispatch('mousedown', {
  180. zrX: touch.x,
  181. zrY: touch.y
  182. });
  183. handler.dispatch('mousemove', {
  184. zrX: touch.x,
  185. zrY: touch.y
  186. });
  187. handler.processGesture(wrapTouch(e), 'start');
  188. }
  189. },
  190. touchMove(e) {
  191. if (chartList[this.canvasId] && e.touches.length > 0) {
  192. var touch = e.touches[0];
  193. var handler = chartList[this.canvasId].getZr().handler;
  194. handler.dispatch('mousemove', {
  195. zrX: touch.x,
  196. zrY: touch.y
  197. });
  198. handler.processGesture(wrapTouch(e), 'change');
  199. }
  200. },
  201. touchEnd(e) {
  202. if (chartList[this.canvasId]) {
  203. const touch = e.changedTouches ? e.changedTouches[0] : {};
  204. var handler = chartList[this.canvasId].getZr().handler;
  205. handler.dispatch('mouseup', {
  206. zrX: touch.x,
  207. zrY: touch.y
  208. });
  209. handler.dispatch('click', {
  210. zrX: touch.x,
  211. zrY: touch.y
  212. });
  213. handler.processGesture(wrapTouch(e), 'end');
  214. }
  215. }
  216. }
  217. }
  218. function wrapTouch(event) {
  219. for (let i = 0; i < event.touches.length; ++i) {
  220. const touch = event.touches[i];
  221. touch.offsetX = touch.x;
  222. touch.offsetY = touch.y;
  223. }
  224. return event;
  225. }
  226. </script>
  227. <style lang="scss" scoped>
  228. .echarts {
  229. width: 100%;
  230. height: 100%;
  231. }
  232. </style>