当前位置:   article > 正文

uniapp中使用echarts,通过renderjs模式封装echarts,兼容APP和H5 包括地图以及区域地图切换_uniapp echarts配置renderitem

uniapp echarts配置renderitem

项目场景:

通过uniapp编写echart  由于dom无法操作   所以一直无法显示    自己也尝试很多案例   也试了Uechart  感觉还是用原生的echart 爽   废了九牛二虎  终于整完  借鉴这位大大神的文章;我终于能用上  但是我发现地图还是不行 所以我研究了下  改了下代码  终于成功


解决方案:

1创建echart.vue    这是个组件

  1. <template>
  2. <!-- 新的:接口对其了H5 -->
  3. <view class="content" :style="{height,width}">
  4. <!-- #ifdef APP-PLUS || H5 -->
  5. <view @click="echarts.onClick" :rOption="rOption" :change:rOption="echarts.messageChanged"
  6. style="height: 100%;width: 100%;" :prop="option" :change:prop="echarts.updateEcharts" :id="canvasId"></view>
  7. <!-- #endif -->
  8. <!-- #ifndef APP-PLUS || H5 -->
  9. <canvas style="height: 100%;width: 100%;" type="2d" class="ec-canvas" :canvas-id="canvasId" :id="canvasId"
  10. :ref="canvasId" bindinit="init" @touchstart="ec.disableTouch ? '' : 'touchStart'"
  11. @touchmove="ec.disableTouch ? '' : 'touchMove'" @touchend="ec.disableTouch ? '' : 'touchEnd'"></canvas>
  12. <!-- #endif -->
  13. </view>
  14. </template>
  15. <script>
  16. class MlCanvas {
  17. constructor(ctx, canvasId, isNew, canvasNode) {
  18. this.ctx = ctx;
  19. this.canvasId = canvasId;
  20. this.chart = null;
  21. this.isNew = isNew
  22. if (isNew) {
  23. this.canvasNode = canvasNode;
  24. }
  25. this._initStyle(ctx)
  26. this._initEvent();
  27. }
  28. getContext(contextType) {
  29. if (contextType === '2d') {
  30. return this.ctx;
  31. } else {
  32. return this.ctx
  33. }
  34. }
  35. addEventListener() {
  36. }
  37. setChart(chart) {
  38. this.chart = chart;
  39. }
  40. attachEvent() {
  41. // noop
  42. }
  43. detachEvent() {
  44. // noop
  45. }
  46. _initCanvas(zrender, ctx) {
  47. console.log(zrender, ctx, 111)
  48. zrender.util.getContext = function() {
  49. return ctx;
  50. };
  51. zrender.util.$override('measureText', function(text, font) {
  52. ctx.font = font || '12px sans-serif';
  53. return ctx.measureText(text);
  54. });
  55. }
  56. _initStyle(ctx) {
  57. ctx.createRadialGradient = () => {
  58. return ctx.createCircularGradient(arguments);
  59. };
  60. }
  61. _initEvent() {
  62. this.event = {};
  63. const eventNames = [{
  64. wxName: 'touchStart',
  65. ecName: 'mousedown'
  66. }, {
  67. wxName: 'touchMove',
  68. ecName: 'mousemove'
  69. }, {
  70. wxName: 'touchEnd',
  71. ecName: 'mouseup'
  72. }, {
  73. wxName: 'touchEnd',
  74. ecName: 'click'
  75. }];
  76. eventNames.forEach(name => {
  77. this.event[name.wxName] = e => {
  78. const touch = e.touches[0];
  79. this.chart.getZr().handler.dispatch(name.ecName, {
  80. zrX: name.wxName === 'tap' ? touch.clientX : touch.x,
  81. zrY: name.wxName === 'tap' ? touch.clientY : touch.y
  82. });
  83. };
  84. });
  85. }
  86. set width(w) {
  87. if (this.canvasNode) this.canvasNode.width = w
  88. }
  89. set height(h) {
  90. if (this.canvasNode) this.canvasNode.height = h
  91. }
  92. get width() {
  93. if (this.canvasNode)
  94. return this.canvasNode.width
  95. return 0
  96. }
  97. get height() {
  98. if (this.canvasNode)
  99. return this.canvasNode.height
  100. return 0
  101. }
  102. }
  103. // #ifndef APP-PLUS || H5
  104. import * as echarts from 'echarts';
  105. // #endif
  106. let ctx;
  107. let chart;
  108. function wrapTouch(event) {
  109. for (let i = 0; i < event.touches.length; ++i) {
  110. const touch = event.touches[i];
  111. touch.offsetX = touch.x;
  112. touch.offsetY = touch.y;
  113. }
  114. return event;
  115. }
  116. export default {
  117. props: {
  118. canvasId: {
  119. type: String,
  120. default: 'ec-canvas',
  121. },
  122. ec: {
  123. type: Object,
  124. default: () => ({}),
  125. },
  126. option: {
  127. type: Object,
  128. },
  129. width: {
  130. type: String,
  131. default: '100%',
  132. },
  133. height: {
  134. type: String,
  135. default: '500rpx',
  136. },
  137. },
  138. computed: {
  139. eOption() {
  140. return JSON.stringify(this.option);
  141. },
  142. },
  143. data() {
  144. return {
  145. isUseNewCanvas: true,
  146. rOption: null,
  147. // chart: null,
  148. };
  149. },
  150. mounted() {
  151. // #ifdef APP-PLUS || H5
  152. this.$nextTick(() => {
  153. this.rOption = {
  154. canvasId: this.canvasId,
  155. ...this.option,
  156. };
  157. });
  158. // #endif
  159. // #ifndef APP-PLUS || H5
  160. this.$nextTick(() => {
  161. echarts.registerPreprocessor((option) => {
  162. if (option && option.series) {
  163. if (option.series.length > 0) {
  164. option.series.forEach((series) => {
  165. series.progressive = 0;
  166. });
  167. } else if (typeof option.series === 'object') {
  168. option.series.progressive = 0;
  169. }
  170. }
  171. });
  172. this.init();
  173. });
  174. // #endif
  175. },
  176. methods: {
  177. init(callback) {
  178. this.initByNewWay(callback);
  179. },
  180. initChart(canvas, width, height, dpr) {
  181. chart = echarts.init(canvas, null, {
  182. width: width,
  183. height: height,
  184. devicePixelRatio: dpr, // 像素
  185. });
  186. canvas.setChart(chart);
  187. chart.setOption(this.option);
  188. return chart;
  189. },
  190. initByNewWay(callback) {
  191. // version >= 2.9.0:使用新的方式初始化
  192. const query = uni.createSelectorQuery().in(this);
  193. query
  194. .select('.ec-canvas')
  195. .fields({
  196. node: true,
  197. size: true,
  198. context: true,
  199. })
  200. .exec((res) => {
  201. let targetNode;
  202. if (res[0].node) {
  203. //兼容微信小程序,2.7以上版本
  204. targetNode = res[0].node;
  205. } else {
  206. //兼容h5
  207. const parentNode = this.$refs[this.canvasId].$el;
  208. targetNode = parentNode.getElementsByTagName('canvas')[0];
  209. }
  210. const canvasDpr = uni.getSystemInfoSync().pixelRatio;
  211. // targetNode = res[0].context._context.canvas
  212. const canvasNode = targetNode;
  213. const canvasWidth = res[0].width;
  214. const canvasHeight = res[0].height;
  215. const ctx = canvasNode.getContext('2d');
  216. const canvas = new MlCanvas(ctx, this.canvasId, true, canvasNode);
  217. echarts.setCanvasCreator(() => {
  218. return canvas;
  219. });
  220. if (typeof callback === 'function') {
  221. this.chart = callback(canvas, canvasWidth, canvasHeight, canvasDpr);
  222. } else if (this.option) {
  223. this.initChart(canvas, canvasWidth, canvasHeight, canvasDpr);
  224. // this.chart = this.ec.onInit(canvas, canvasWidth, canvasHeight, canvasDpr)
  225. } else {
  226. this.triggerEvent('init', {
  227. canvas: canvas,
  228. width: canvasWidth,
  229. height: canvasHeight,
  230. dpr: canvasDpr,
  231. });
  232. }
  233. });
  234. },
  235. touchStart(e) {},
  236. setOption(option) {
  237. // #ifndef APP-PLUS || H5
  238. chart.setOption(option);
  239. // #endif
  240. // #ifdef APP-PLUS || H5
  241. this.rOption = {
  242. ...option
  243. };
  244. // #endif
  245. },
  246. touchMove(e) {},
  247. touchEnd(e) {},
  248. onViewClick(e) {},
  249. },
  250. };
  251. </script>
  252. <script module="echarts" lang="renderjs">
  253. // #ifdef APP-PLUS || H5
  254. import * as echarts from 'echarts'
  255. let myChart
  256. export default {
  257. data() {
  258. return {
  259. Coption: null,
  260. CcanvasId: null,
  261. // chart: null
  262. }
  263. },
  264. mounted() {
  265. // #ifdef APP-PLUS || H5
  266. // this.$nextTick(() => {
  267. // this.initl()
  268. // })
  269. // #endif
  270. },
  271. methods: {
  272. initl() {
  273. console.log('app&H5')
  274. },
  275. initEcharts() {
  276. myChart = echarts.init(document.getElementById(this.CcanvasId))
  277. myChart.showLoading({
  278. text: '数据加载中...',
  279. color: '#c23531',
  280. textColor: '#ffffc2',
  281. maskColor: 'rgba(255, 255, 255, 0)',
  282. });
  283. // 观测更新的数据在 view 层可以直接访问到
  284. myChart && myChart.setOption(this.Coption)
  285. },
  286. updateEcharts(newValue, oldValue, ownerInstance, instance) {
  287. if (newValue.inclass) {
  288. echarts.registerMap(newValue.inclass.name, newValue.inclass.source);
  289. }
  290. myChart = echarts.init(document.getElementById(this.CcanvasId))
  291. // 监听 service 层数据变更
  292. myChart && myChart.setOption(newValue, true)
  293. myChart && myChart.hideLoading()
  294. },
  295. onClick(event, ownerInstance) {
  296. // 调用 service 层的方法
  297. ownerInstance.callMethod('onViewClick', {
  298. test: 'test'
  299. })
  300. },
  301. messageChanged(newVal, oldVal, ins, vm) {
  302. if (newVal.canvasId) {
  303. this.CcanvasId = newVal.canvasId
  304. delete newVal.canvasId
  305. this.Coption = newVal
  306. this.initEcharts()
  307. } else {
  308. myChart = echarts.init(document.getElementById(this.CcanvasId))
  309. myChart && myChart.setOption(newVal)
  310. }
  311. }
  312. }
  313. }
  314. // #endif
  315. </script>
  316. <style scoped>
  317. .ec-canvas {
  318. width: 100%;
  319. height: 100%;
  320. }
  321. </style>

2、只需要引入此组件,传入 ehcarts 文档 option 配置,并命名 id 即可yui

  1. <mlEcharts :option="option" canvasId="mlEcharts"></mlEcharts>
  2. import mlEcharts from "@/components/echart.vue";

引入地图文件(我这是中国地图   也可以根据你的需求引入你的json文件  也可以动态引入不同省份)

import chinaData from '@/static/json/china.json';	

 在option配置中加入  以下参数

  1. inclass:{
  2. name:"china",
  3. source:chinaData
  4. }

运行  就得到地图啦  亲测H5  app有效

 这是省份地图

 写在最后:

用你们发财小手点点赞咯

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/123950
推荐阅读