qiun-data-charts.vue 46 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427
  1. <!--
  2. * qiun-data-charts 秋云高性能跨全端图表组件 v2.0.0-20210419
  3. * Copyright (c) 2021 QIUN® 秋云 https://www.ucharts.cn All rights reserved.
  4. * Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
  5. * 复制使用请保留本段注释,感谢支持开源!
  6. * 为方便更多开发者使用,如有更好的建议请提交码云 Pull Requests !
  7. *
  8. * uCharts®官方网站
  9. * https://www.uCharts.cn
  10. *
  11. * 开源地址:
  12. * https://gitee.com/uCharts/uCharts
  13. *
  14. * uni-app插件市场地址:
  15. * http://ext.dcloud.net.cn/plugin?id=271
  16. *
  17. -->
  18. <template>
  19. <view class="chartsview" :id="'ChartBoxId'+cid">
  20. <view v-if="mixinDatacomLoading">
  21. <!-- 自定义加载状态,请改这里 -->
  22. <qiun-loading :loadingType="loadingType" />
  23. </view>
  24. <view v-if="mixinDatacomErrorMessage && errorShow" @tap="reloading">
  25. <!-- 自定义错误提示,请改这里 -->
  26. <qiun-error :errorMessage="errorMessage" />
  27. </view>
  28. <!-- APP和H5采用renderjs渲染图表 -->
  29. <!-- #ifdef APP-VUE || H5 -->
  30. <block v-if="echarts">
  31. <view
  32. :style="{ background: background }"
  33. style="width: 100%;height: 100%;"
  34. :data-directory="directory"
  35. :id="'EC'+cid"
  36. :prop="echartsOpts"
  37. :change:prop="rdcharts.ecinit"
  38. :resize="echartsResize"
  39. :change:resize="rdcharts.ecresize"
  40. v-show="showchart"
  41. />
  42. </block>
  43. <block v-else>
  44. <view
  45. @tap="rdcharts.tap"
  46. @mousemove="rdcharts.mouseMove"
  47. @mousedown="rdcharts.mouseDown"
  48. @mouseup="rdcharts.mouseUp"
  49. @touchstart="rdcharts.touchStart"
  50. @touchmove="rdcharts.touchMove"
  51. @touchend="rdcharts.touchEnd"
  52. :id="'UC'+cid"
  53. :prop="uchartsOpts"
  54. :change:prop="rdcharts.ucinit"
  55. >
  56. <canvas
  57. :id="cid"
  58. :canvasId="cid"
  59. :style="{ width: cWidth + 'px', height: cHeight + 'px', background: background }"
  60. :disable-scroll="disableScroll"
  61. @error="_error"
  62. v-if="showchart"
  63. />
  64. </view>
  65. </block>
  66. <!-- #endif -->
  67. <!-- 支付宝小程序 -->
  68. <!-- #ifdef MP-ALIPAY -->
  69. <block v-if="ontouch">
  70. <canvas
  71. :id="cid"
  72. :canvasId="cid"
  73. :width="cWidth * pixel"
  74. :height="cHeight * pixel"
  75. :style="{ width: cWidth + 'px', height: cHeight + 'px', background: background }"
  76. :disable-scroll="disScroll"
  77. @tap="_tap"
  78. @touchstart="_touchStart"
  79. @touchmove="_touchMove"
  80. @touchend="_touchEnd"
  81. @error="_error"
  82. v-if="showchart"
  83. />
  84. </block>
  85. <block v-if="!ontouch">
  86. <canvas
  87. :id="cid"
  88. :canvasId="cid"
  89. :width="cWidth * pixel"
  90. :height="cHeight * pixel"
  91. :style="{ width: cWidth + 'px', height: cHeight + 'px', background: background }"
  92. :disable-scroll="disScroll"
  93. @tap="_tap"
  94. @error="_error"
  95. v-if="showchart"
  96. />
  97. </block>
  98. <!-- #endif -->
  99. <!-- 其他小程序通过vue渲染图表 -->
  100. <!-- #ifdef MP-360 || MP-BAIDU || MP-QQ || MP-TOUTIAO || MP-WEIXIN -->
  101. <block v-if="type2d">
  102. <view v-if="ontouch" @tap="_tap">
  103. <canvas
  104. :id="cid"
  105. :canvasId="cid"
  106. :style="{ width: cWidth + 'px', height: cHeight + 'px', background: background }"
  107. type="2d"
  108. :disable-scroll="disScroll"
  109. @touchstart="_touchStart"
  110. @touchmove="_touchMove"
  111. @touchend="_touchEnd"
  112. @error="_error"
  113. v-show="showchart"
  114. />
  115. </view>
  116. <view v-if="!ontouch" @tap="_tap">
  117. <canvas
  118. :id="cid"
  119. :canvasId="cid"
  120. :style="{ width: cWidth + 'px', height: cHeight + 'px', background: background }"
  121. type="2d"
  122. :disable-scroll="disScroll"
  123. @error="_error"
  124. v-show="showchart"
  125. />
  126. </view>
  127. </block>
  128. <block v-if="!type2d">
  129. <view v-if="ontouch" @tap="_tap">
  130. <canvas
  131. :id="cid"
  132. :canvasId="cid"
  133. :style="{ width: cWidth + 'px', height: cHeight + 'px', background: background }"
  134. @touchstart="_touchStart"
  135. @touchmove="_touchMove"
  136. @touchend="_touchEnd"
  137. :disable-scroll="disScroll"
  138. @error="_error"
  139. v-if="showchart"
  140. />
  141. </view>
  142. <view v-if="!ontouch" >
  143. <canvas
  144. :id="cid"
  145. :canvasId="cid"
  146. :style="{ width: cWidth + 'px', height: cHeight + 'px', background: background }"
  147. :disable-scroll="disScroll"
  148. @tap="_tap"
  149. @error="_error"
  150. v-if="showchart"
  151. />
  152. </view>
  153. </block>
  154. <!-- #endif -->
  155. </view>
  156. </template>
  157. <script>
  158. import uChartsMp from '@/components/u-charts/u-charts-v2.0.0.js';
  159. import cfu from '@/components/u-charts/config-ucharts.js';
  160. // #ifdef APP-VUE || H5
  161. import cfe from '@/components/u-charts/config-echarts.js';
  162. // #endif
  163. function deepCloneAssign(origin = {}, ...args) {
  164. for (let i in args) {
  165. for (let key in args[i]) {
  166. if (args[i].hasOwnProperty(key)) {
  167. origin[key] = args[i][key] && typeof args[i][key] === 'object' ? deepCloneAssign(Array.isArray(args[i][key]) ? [] : {}, origin[key], args[i][key]) : args[i][key];
  168. }
  169. }
  170. }
  171. return origin;
  172. }
  173. function formatterAssign(args,formatter) {
  174. for (let key in args) {
  175. if(typeof args[key] === 'object'){
  176. formatterAssign(args[key],formatter)
  177. }else if(key === 'format' && typeof args[key] === 'string'){
  178. args['formatter'] = formatter[args[key]] ? formatter[args[key]] : undefined;
  179. }
  180. }
  181. return args;
  182. }
  183. // 时间转换函数,为了匹配uniClinetDB读取出的时间与categories不同
  184. function getFormatDate(date) {
  185. var seperator = "-";
  186. var year = date.getFullYear();
  187. var month = date.getMonth() + 1;
  188. var strDate = date.getDate();
  189. if (month >= 1 && month <= 9) {
  190. month = "0" + month;
  191. }
  192. if (strDate >= 0 && strDate <= 9) {
  193. strDate = "0" + strDate;
  194. }
  195. var currentdate = year + seperator + month + seperator + strDate;
  196. return currentdate;
  197. }
  198. var lastMoveTime = null;
  199. export default {
  200. name: 'qiun-data-charts',
  201. mixins: [uniCloud.mixinDatacom],
  202. props: {
  203. type: {
  204. type: String,
  205. default: null
  206. },
  207. canvasId: {
  208. type: String,
  209. default: 'uchartsid'
  210. },
  211. canvas2d: {
  212. type: Boolean,
  213. default: false
  214. },
  215. background: {
  216. type: String,
  217. default: 'none'
  218. },
  219. animation: {
  220. type: Boolean,
  221. default: true
  222. },
  223. chartData: {
  224. type: Object,
  225. default() {
  226. return {
  227. categories: [],
  228. series: []
  229. };
  230. }
  231. },
  232. opts: {
  233. type: Object,
  234. default() {
  235. return {};
  236. }
  237. },
  238. eopts: {
  239. type: Object,
  240. default() {
  241. return {};
  242. }
  243. },
  244. loadingType: {
  245. type: Number,
  246. default: 2
  247. },
  248. errorShow: {
  249. type: Boolean,
  250. default: true
  251. },
  252. errorMessage: {
  253. type: String,
  254. default: null
  255. },
  256. inScrollView: {
  257. type: Boolean,
  258. default: false
  259. },
  260. reshow: {
  261. type: Boolean,
  262. default: false
  263. },
  264. reload: {
  265. type: Boolean,
  266. default: false
  267. },
  268. disableScroll: {
  269. type: Boolean,
  270. default: false
  271. },
  272. ontap: {
  273. type: Boolean,
  274. default: true
  275. },
  276. ontouch: {
  277. type: Boolean,
  278. default: false
  279. },
  280. onmouse: {
  281. type: Boolean,
  282. default: true
  283. },
  284. onmovetip: {
  285. type: Boolean,
  286. default: false
  287. },
  288. echartsH5: {
  289. type: Boolean,
  290. default: false
  291. },
  292. echartsApp: {
  293. type: Boolean,
  294. default: false
  295. },
  296. tooltipShow: {
  297. type: Boolean,
  298. default: true
  299. },
  300. tooltipFormat: {
  301. type: String,
  302. default: undefined
  303. },
  304. tooltipCustom: {
  305. default: undefined
  306. },
  307. startDate: {
  308. type: String,
  309. default: undefined
  310. },
  311. endDate: {
  312. type: String,
  313. default: undefined
  314. },
  315. textEnum: {
  316. type: Array,
  317. default () {
  318. return []
  319. }
  320. },
  321. groupEnum: {
  322. type: Array,
  323. default () {
  324. return []
  325. }
  326. },
  327. pageScrollTop: {
  328. type: Number,
  329. default: 0
  330. },
  331. directory: {
  332. type: String,
  333. default: '/'
  334. }
  335. },
  336. data() {
  337. return {
  338. cid: 'uchartsid',
  339. inWx: false,
  340. inAli: false,
  341. inTt:false,
  342. inBd:false,
  343. inH5: false,
  344. inApp: false,
  345. type2d: true,
  346. disScroll: false,
  347. pixel: 1,
  348. cWidth: 375,
  349. cHeight: 250,
  350. showchart: false,
  351. echarts: false,
  352. echartsResize:false,
  353. uchartsOpts: {},
  354. echartsOpts: {},
  355. drawData:{},
  356. lastDrawTime:null,
  357. };
  358. },
  359. created(){
  360. this.cid = this.canvasId
  361. if (this.canvasId == 'uchartsid' || this.canvasId == '') {
  362. let t = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
  363. let len = t.length
  364. let id = ''
  365. for (let i = 0; i < 32; i++) {
  366. id += t.charAt(Math.floor(Math.random() * len))
  367. }
  368. this.cid = id
  369. }
  370. // #ifdef MP-WEIXIN || MP-QQ
  371. this.inWx = true;
  372. if (this.canvas2d === false) {
  373. this.type2d = false;
  374. }else{
  375. this.pixel = uni.getSystemInfoSync().pixelRatio;
  376. if (this.canvasId === 'uchartsid' || this.canvasId == '') {
  377. console.log('[uCharts]:开启canvas2d模式,必须指定canvasId,否则会出现偶尔获取不到dom节点的问题!');
  378. }
  379. }
  380. // #endif
  381. //非微信小程序端强制关闭canvas2d模式
  382. // #ifndef MP-WEIXIN || MP-QQ
  383. this.type2d = false;
  384. // #endif
  385. // #ifdef MP-ALIPAY
  386. this.inAli = true;
  387. this.pixel = uni.getSystemInfoSync().pixelRatio;
  388. // #endif
  389. // #ifdef MP-BAIDU
  390. this.inBd = true;
  391. // #endif
  392. // #ifdef MP-TOUTIAO
  393. this.inTt = true;
  394. // #endif
  395. this.disScroll = this.disableScroll;
  396. },
  397. mounted() {
  398. // #ifdef APP-VUE
  399. this.inApp = true;
  400. if (this.echartsApp === true) {
  401. this.echarts = true;
  402. }
  403. // #endif
  404. // #ifdef APP-NVUE
  405. this.inApp = true;
  406. this.mixinDatacomLoading = false
  407. this.mixinDatacomErrorMessage = "暂不支持NVUE"
  408. // #endif
  409. // #ifdef H5
  410. this.inH5 = true;
  411. if (this.echartsH5 === true) {
  412. this.echarts = true;
  413. }
  414. // #endif
  415. this.$nextTick(()=>{
  416. this.beforeInit();
  417. })
  418. // #ifndef MP-ALIPAY || MP-BAIDU || MP-TOUTIAO
  419. uni.onWindowResize(res => {
  420. if (this.mixinDatacomLoading == true) {
  421. return;
  422. }
  423. let errmsg = this.mixinDatacomErrorMessage
  424. if(errmsg !== null && errmsg !== 'null' && errmsg !== ''){
  425. return;
  426. }
  427. setTimeout(() => {
  428. if(this.echarts){
  429. this.echartsResize = !this.echartsResize
  430. }else{
  431. this.resizeHandler()
  432. }
  433. }, 200);
  434. });
  435. // #endif
  436. },
  437. destroyed(){
  438. if(this.echarts === true){
  439. delete cfe.option[this.cid]
  440. delete cfe.instance[this.cid]
  441. }else{
  442. delete cfu.option[this.cid]
  443. delete cfu.instance[this.cid]
  444. }
  445. // #ifndef MP-ALIPAY || MP-BAIDU || MP-TOUTIAO
  446. uni.offWindowResize(()=>{})
  447. // #endif
  448. },
  449. watch: {
  450. chartDataProps: {
  451. handler(val, oldval) {
  452. if (typeof val === 'object') {
  453. if (JSON.stringify(val) !== JSON.stringify(oldval)) {
  454. if (val.series && val.series.length > 0) {
  455. this.beforeInit();
  456. }else{
  457. this.mixinDatacomLoading = true;
  458. this.showchart = false;
  459. this.mixinDatacomErrorMessage = null;
  460. }
  461. }
  462. } else {
  463. this.mixinDatacomLoading = false;
  464. this.showchart = false;
  465. this.mixinDatacomErrorMessage = '参数错误:chartData数据类型错误';
  466. }
  467. },
  468. immediate: false,
  469. deep: true
  470. },
  471. localdata:{
  472. handler(val, oldval) {
  473. if (JSON.stringify(val) !== JSON.stringify(oldval)) {
  474. if (val.length > 0) {
  475. this.beforeInit();
  476. }else{
  477. this.mixinDatacomLoading = true;
  478. this.showchart = false;
  479. this.mixinDatacomErrorMessage = null;
  480. }
  481. }
  482. },
  483. immediate: false,
  484. deep: true
  485. },
  486. optsProps: {
  487. handler(val, oldval) {
  488. if (typeof val === 'object') {
  489. if (JSON.stringify(val) !== JSON.stringify(oldval) && this.echarts === false) {
  490. this.checkData(this.drawData);
  491. }
  492. } else {
  493. this.mixinDatacomLoading = false;
  494. this.showchart = false;
  495. this.mixinDatacomErrorMessage = '参数错误:opts数据类型错误';
  496. }
  497. },
  498. immediate: false,
  499. deep: true
  500. },
  501. eoptsProps: {
  502. handler(val, oldval) {
  503. if (typeof val === 'object') {
  504. if (JSON.stringify(val) !== JSON.stringify(oldval) && this.echarts === true) {
  505. this.checkData(this.drawData);
  506. }
  507. } else {
  508. this.mixinDatacomLoading = false;
  509. this.showchart = false;
  510. this.mixinDatacomErrorMessage = '参数错误:eopts数据类型错误';
  511. }
  512. },
  513. immediate: false,
  514. deep: true
  515. },
  516. reshow(val, oldval) {
  517. if (val === true && this.mixinDatacomLoading === false) {
  518. setTimeout(() => {
  519. this.showchart = true;
  520. this.mixinDatacomErrorMessage = null;
  521. this.echartsResize = !this.echartsResize;
  522. this.checkData(this.drawData);
  523. }, 200);
  524. }
  525. },
  526. reload(val, oldval) {
  527. if (val === true) {
  528. this.showchart = false;
  529. this.mixinDatacomErrorMessage = null;
  530. this.reloading();
  531. }
  532. },
  533. mixinDatacomErrorMessage(val, oldval) {
  534. if (val) {
  535. this.emitMsg({name: 'error', params: {type:"error", errorShow: this.errorShow, msg: val, id: this.cid}});
  536. if(this.errorShow){
  537. console.log('[秋云图表组件]' + val);
  538. }
  539. }
  540. },
  541. errorMessage(val, oldval) {
  542. if (val && this.errorShow && val !== null && val !== 'null' && val !== '') {
  543. this.showchart = false;
  544. this.mixinDatacomLoading = false;
  545. this.mixinDatacomErrorMessage = val;
  546. } else {
  547. this.showchart = false;
  548. this.mixinDatacomErrorMessage = null;
  549. this.reloading();
  550. }
  551. }
  552. },
  553. computed: {
  554. optsProps() {
  555. return JSON.parse(JSON.stringify(this.opts));
  556. },
  557. eoptsProps() {
  558. return JSON.parse(JSON.stringify(this.eopts));
  559. },
  560. chartDataProps() {
  561. return JSON.parse(JSON.stringify(this.chartData));
  562. },
  563. },
  564. methods: {
  565. beforeInit(){
  566. this.mixinDatacomErrorMessage = null;
  567. if (typeof this.chartData === 'object' && this.chartData != null && this.chartData.series !== undefined && this.chartData.series.length > 0) {
  568. this.mixinDatacomLoading = true;
  569. //拷贝一下chartData,为了opts变更后统一数据来源
  570. this.drawData = deepCloneAssign({}, this.chartData);
  571. this.checkData(this.chartData);
  572. }else if(this.localdata.length>0){
  573. this.mixinDatacomLoading = true;
  574. this.localdataInit(this.localdata);
  575. }else if(this.collection !== ''){
  576. this.mixinDatacomLoading = false;
  577. this.getCloudData();
  578. }else{
  579. this.mixinDatacomLoading = true;
  580. }
  581. },
  582. localdataInit(resdata){
  583. //替换enum类型为正确的描述
  584. if(this.groupEnum.length>0){
  585. for (let i = 0; i < resdata.length; i++) {
  586. for (let j = 0; j < this.groupEnum.length; j++) {
  587. if(resdata[i].group === this.groupEnum[j].value){
  588. resdata[i].group = this.groupEnum[j].text
  589. }
  590. }
  591. }
  592. }
  593. if(this.textEnum.length>0){
  594. for (let i = 0; i < resdata.length; i++) {
  595. for (let j = 0; j < this.textEnum.length; j++) {
  596. if(resdata[i].text === this.textEnum[j].value){
  597. resdata[i].text = this.textEnum[j].text
  598. }
  599. }
  600. }
  601. }
  602. let needCategories = false;
  603. let tmpData = {categories:[], series:[]}
  604. let tmpcategories = []
  605. let tmpseries = [];
  606. //拼接categories
  607. if(this.echarts === true){
  608. needCategories = cfe.categories.includes(this.type)
  609. }else{
  610. needCategories = cfu.categories.includes(this.type)
  611. }
  612. if(needCategories === true){
  613. //如果props中的chartData带有categories,则优先使用chartData的categories
  614. if(this.chartData && this.chartData.categories && this.chartData.categories.length>0){
  615. tmpcategories = this.chartData.categories
  616. }else{
  617. //如果是日期类型的数据,不管是本地数据还是云数据,都按起止日期自动拼接categories
  618. if(this.startDate && this.endDate){
  619. let idate = new Date(this.startDate)
  620. let edate = new Date(this.endDate)
  621. while (idate <= edate) {
  622. tmpcategories.push(getFormatDate(idate))
  623. idate = idate.setDate(idate.getDate() + 1)
  624. idate = new Date(idate)
  625. }
  626. //否则从结果中去重并拼接categories
  627. }else{
  628. let tempckey = {};
  629. resdata.map(function(item, index) {
  630. if (item.text != undefined && !tempckey[item.text]) {
  631. tmpcategories.push(item.text)
  632. tempckey[item.text] = true
  633. }
  634. });
  635. }
  636. }
  637. tmpData.categories = tmpcategories
  638. }
  639. //拼接series
  640. let tempskey = {};
  641. resdata.map(function(item, index) {
  642. if (item.group != undefined && !tempskey[item.group]) {
  643. tmpseries.push({ name: item.group, data: [] });
  644. tempskey[item.group] = true;
  645. }
  646. });
  647. //如果没有获取到分组名称(可能是带categories的数据,也可能是不带的饼图类)
  648. if (tmpseries.length == 0) {
  649. tmpseries = [{ name: '默认分组', data: [] }];
  650. //如果是需要categories的图表类型
  651. if(needCategories === true){
  652. for (let j = 0; j < tmpcategories.length; j++) {
  653. let seriesdata = 0;
  654. for (let i = 0; i < resdata.length; i++) {
  655. if (resdata[i].text == tmpcategories[j]) {
  656. seriesdata = resdata[i].value;
  657. }
  658. }
  659. tmpseries[0].data.push(seriesdata);
  660. }
  661. //如果是饼图类的图表类型
  662. }else{
  663. for (let i = 0; i < resdata.length; i++) {
  664. tmpseries[0].data.push({"name": resdata[i].text,"value": resdata[i].value});
  665. }
  666. }
  667. //如果有分组名
  668. } else {
  669. for (let k = 0; k < tmpseries.length; k++) {
  670. //如果有categories
  671. if (tmpcategories.length > 0) {
  672. for (let j = 0; j < tmpcategories.length; j++) {
  673. let seriesdata = 0;
  674. for (let i = 0; i < resdata.length; i++) {
  675. if (tmpseries[k].name == resdata[i].group && resdata[i].text == tmpcategories[j]) {
  676. seriesdata = resdata[i].value;
  677. }
  678. }
  679. tmpseries[k].data.push(seriesdata);
  680. }
  681. //如果传了group而没有传text,即没有categories(正常情况下这种数据是不符合数据要求规范的)
  682. } else {
  683. for (let i = 0; i < resdata.length; i++) {
  684. if (tmpseries[k].name == resdata[i].group) {
  685. tmpseries[k].data.push(resdata[i].value);
  686. }
  687. }
  688. }
  689. }
  690. }
  691. tmpData.series = tmpseries
  692. //拷贝一下chartData,为了opts变更后统一数据来源
  693. this.drawData = deepCloneAssign({}, tmpData);
  694. this.checkData(tmpData)
  695. },
  696. reloading() {
  697. this.showchart = false;
  698. this.mixinDatacomErrorMessage = null;
  699. if (this.collection !== '') {
  700. this.mixinDatacomLoading = false;
  701. this.onMixinDatacomPropsChange(true);
  702. } else {
  703. this.beforeInit();
  704. }
  705. },
  706. checkData(anyData) {
  707. let cid = this.cid
  708. //复位opts或eopts
  709. if(this.echarts === true){
  710. if (this.type && cfe.type.includes(this.type)) {
  711. cfe.option[cid] = deepCloneAssign({}, cfe[this.type], this.eopts);
  712. }else{
  713. cfe.option[cid] = deepCloneAssign({}, this.eopts);
  714. }
  715. cfe.option[cid].id = cid;
  716. }else{
  717. if (this.type && cfu.type.includes(this.type)) {
  718. cfu.option[cid] = deepCloneAssign({}, cfu[this.type], this.opts);
  719. cfu.option[cid].canvasId = cid;
  720. } else {
  721. this.mixinDatacomLoading = false;
  722. this.showchart = false;
  723. this.mixinDatacomErrorMessage = '参数错误:props参数中type类型不正确';
  724. }
  725. }
  726. //挂载categories和series
  727. let newData = deepCloneAssign({}, anyData);
  728. if (newData.series !== undefined && newData.series.length > 0) {
  729. this.mixinDatacomErrorMessage = null;
  730. if (this.echarts === true) {
  731. if(cfe.option[cid].xAxis && cfe.option[cid].xAxis.type && cfe.option[cid].xAxis.type === 'category'){
  732. cfe.option[cid].xAxis.data = newData.categories
  733. }
  734. if(cfe.option[cid].yAxis && cfe.option[cid].yAxis.type && cfe.option[cid].yAxis.type === 'category'){
  735. cfe.option[cid].yAxis.data = newData.categories
  736. }
  737. cfe.option[cid].series = []
  738. for (var i = 0; i < newData.series.length; i++) {
  739. cfe.option[cid].seriesTemplate = cfe.option[cid].seriesTemplate ? cfe.option[cid].seriesTemplate : {}
  740. let Template = deepCloneAssign({},cfe.option[cid].seriesTemplate,newData.series[i])
  741. cfe.option[cid].series.push(Template)
  742. }
  743. this.$nextTick(()=>{
  744. this.init()
  745. })
  746. }else{
  747. cfu.option[cid].categories = newData.categories;
  748. cfu.option[cid].series = newData.series;
  749. this.$nextTick(()=>{
  750. this.init()
  751. })
  752. }
  753. }
  754. },
  755. resizeHandler() {
  756. //渲染防抖
  757. let currTime = Date.now();
  758. let lastDrawTime = this.lastDrawTime?this.lastDrawTime:currTime-3000;
  759. let duration = currTime - lastDrawTime;
  760. if (duration < 1000) return;
  761. let chartdom = uni
  762. .createSelectorQuery()
  763. // #ifndef MP-ALIPAY
  764. .in(this)
  765. // #endif
  766. .select('#ChartBoxId'+this.cid)
  767. .boundingClientRect(data => {
  768. this.showchart = true;
  769. if (data.width > 0 && data.height > 0) {
  770. if (data.width !== this.cWidth || data.height !== this.cHeight) {
  771. this.checkData(this.drawData)
  772. }
  773. }
  774. })
  775. .exec();
  776. },
  777. getCloudData() {
  778. if (this.mixinDatacomLoading == true) {
  779. return;
  780. }
  781. this.mixinDatacomLoading = true;
  782. this.mixinDatacomGet()
  783. .then(res => {
  784. this.mixinDatacomResData = res.result.data;
  785. this.localdataInit(this.mixinDatacomResData);
  786. })
  787. .catch(err => {
  788. this.mixinDatacomLoading = false;
  789. this.showchart = false;
  790. this.mixinDatacomErrorMessage = '请求错误:' + err;
  791. });
  792. },
  793. onMixinDatacomPropsChange(needReset, changed) {
  794. if (needReset == true && this.collection !== '') {
  795. this.showchart = false;
  796. this.mixinDatacomErrorMessage = null;
  797. this._clearChart();
  798. this.getCloudData();
  799. }
  800. },
  801. _clearChart() {
  802. let cid = this.cid
  803. if (this.echrts !== true) {
  804. const ctx = uni.createCanvasContext(cid, this);
  805. ctx.clearRect(0, 0, this.cWidth, this.cHeight);
  806. ctx.draw();
  807. }
  808. },
  809. init() {
  810. let cid = this.cid
  811. let chartdom = uni
  812. .createSelectorQuery()
  813. // #ifndef MP-ALIPAY
  814. .in(this)
  815. // #endif
  816. .select('#ChartBoxId'+cid)
  817. .boundingClientRect(data => {
  818. if (data.width > 0 && data.height > 0) {
  819. this.lastDrawTime = Date.now();
  820. this.cWidth = data.width;
  821. this.cHeight = data.height;
  822. if(this.echarts !== true){
  823. cfu.option[cid].background = this.background == 'none' ? '#FFFFFF' : this.background;
  824. cfu.option[cid].canvas2d = this.type2d;
  825. cfu.option[cid].pixelRatio = this.pixel;
  826. cfu.option[cid].animation = this.animation;
  827. cfu.option[cid].width = data.width * this.pixel;
  828. cfu.option[cid].height = data.height * this.pixel;
  829. cfu.option[cid].ontap = this.ontap;
  830. cfu.option[cid].ontouch = this.ontouch;
  831. cfu.option[cid].onmouse = this.onmouse;
  832. cfu.option[cid].onmovetip = this.onmovetip;
  833. cfu.option[cid].tooltipShow = this.tooltipShow;
  834. cfu.option[cid].tooltipFormat = this.tooltipFormat;
  835. cfu.option[cid].tooltipCustom = this.tooltipCustom;
  836. cfu.option[cid].inScrollView = this.inScrollView;
  837. cfu.option[cid].lastDrawTime = this.lastDrawTime;
  838. }
  839. //如果是H5或者App端,采用renderjs渲染图表
  840. if (this.inH5 || this.inApp) {
  841. if (this.echarts == true) {
  842. this.mixinDatacomLoading = false;
  843. this.showchart = true;
  844. cfe.option[cid].ontap = this.ontap;
  845. cfe.option[cid].onmouse = this.onmouse;
  846. cfe.option[cid].tooltipShow = this.tooltipShow;
  847. cfe.option[cid].tooltipFormat = this.tooltipFormat;
  848. cfe.option[cid].tooltipCustom = this.tooltipCustom;
  849. cfe.option[cid].lastDrawTime = this.lastDrawTime;
  850. cfe.option[cid].rotateLock = cfe.option[cid].rotate;
  851. this.echartsOpts = deepCloneAssign({}, cfe.option[cid]);
  852. } else {
  853. cfu.option[cid].rotateLock = cfu.option[cid].rotate;
  854. this.mixinDatacomLoading = false;
  855. this.showchart = true;
  856. this.uchartsOpts = deepCloneAssign({}, cfu.option[cid]);
  857. }
  858. //如果是小程序端,采用uCharts渲染
  859. } else {
  860. cfu.option[cid] = formatterAssign(cfu.option[cid],cfu.formatter)
  861. this.mixinDatacomErrorMessage = null;
  862. this.mixinDatacomLoading = false;
  863. this.showchart = true;
  864. this.$nextTick(()=>{
  865. if (this.type2d === true) {
  866. const query = uni.createSelectorQuery().in(this)
  867. query
  868. .select('#' + cid)
  869. .fields({ node: true, size: true })
  870. .exec(res => {
  871. if (res[0]) {
  872. const canvas = res[0].node;
  873. const ctx = canvas.getContext('2d');
  874. cfu.option[cid].context = ctx;
  875. canvas.width = data.width * this.pixel;
  876. canvas.height = data.height * this.pixel;
  877. canvas._width = data.width * this.pixel;
  878. canvas._height = data.height * this.pixel;
  879. cfu.option[cid].rotateLock = cfu.option[cid].rotate;
  880. this._newChart(cid);
  881. } else {
  882. this.showchart = false;
  883. this.mixinDatacomErrorMessage = '参数错误:开启2d模式后,未获取到dom节点,canvas-id:' + cid;
  884. }
  885. });
  886. } else {
  887. if(this.inAli){
  888. cfu.option[cid].rotateLock = cfu.option[cid].rotate;
  889. }
  890. cfu.option[cid].context = uni.createCanvasContext(cid, this);
  891. this._newChart(cid);
  892. }
  893. })
  894. }
  895. } else {
  896. this.mixinDatacomLoading = false;
  897. this.showchart = false;
  898. if (this.reshow == true) {
  899. this.mixinDatacomErrorMessage = '布局错误:未获取到父元素宽高尺寸!canvas-id:' + cid;
  900. }
  901. }
  902. })
  903. .exec();
  904. },
  905. saveImage(){
  906. uni.canvasToTempFilePath({
  907. canvasId: this.cid,
  908. success: res=>{
  909. //#ifdef H5
  910. var a = document.createElement("a");
  911. a.href = res.tempFilePath;
  912. a.download = this.cid;
  913. a.target = '_blank'
  914. a.click();
  915. //#endif
  916. //#ifndef H5
  917. uni.saveImageToPhotosAlbum({
  918. filePath: res.tempFilePath,
  919. success: function () {
  920. this.$util.showToast({
  921. title: '保存成功'
  922. });
  923. }
  924. });
  925. //#endif
  926. }
  927. },this);
  928. },
  929. // #ifndef APP-VUE || H5
  930. _newChart(cid) {
  931. if (this.mixinDatacomLoading == true) {
  932. return;
  933. }
  934. this.showchart = true;
  935. cfu.instance[cid] = new uChartsMp(cfu.option[cid]);
  936. cfu.instance[cid].addEventListener('renderComplete', () => {
  937. this.emitMsg({name: 'complete', params: {type:"complete", complete: true, id: cid}});
  938. cfu.instance[cid].delEventListener('renderComplete')
  939. });
  940. cfu.instance[cid].addEventListener('scrollLeft', () => {
  941. this.emitMsg({name: 'scrollLeft', params: {type:"scrollLeft", scrollLeft: true, id: cid}});
  942. });
  943. cfu.instance[cid].addEventListener('scrollRight', () => {
  944. this.emitMsg({name: 'scrollRight', params: {type:"scrollRight", scrollRight: true, id: cid}});
  945. });
  946. },
  947. _tooltipDefault(item, category, index, opts) {
  948. if (category) {
  949. let data = item.data
  950. if(typeof item.data === "object"){
  951. data = item.data.value
  952. }
  953. return category + ' ' + item.name + ':' + data;
  954. } else {
  955. if (item.properties !== undefined) {
  956. return item.properties.name;
  957. } else {
  958. return item.name + ':' + item.data;
  959. }
  960. }
  961. },
  962. _showTooltip(e) {
  963. let cid = this.cid
  964. let tc = cfu.option[cid].tooltipCustom
  965. if (tc && tc !== undefined && tc !== null) {
  966. let offset = undefined;
  967. if (tc.x >= 0 && tc.y >= 0) {
  968. offset = { x: tc.x, y: tc.y + 10 };
  969. }
  970. cfu.instance[cid].showToolTip(e, {
  971. index: tc.index,
  972. offset: offset,
  973. textList: tc.textList,
  974. formatter: (item, category, index, opts) => {
  975. if (typeof cfu.option[cid].tooltipFormat === 'string' && cfu.formatter[cfu.option[cid].tooltipFormat]) {
  976. return cfu.formatter[cfu.option[cid].tooltipFormat](item, category, index, opts);
  977. } else {
  978. return this._tooltipDefault(item, category, index, opts);
  979. }
  980. }
  981. });
  982. } else {
  983. cfu.instance[cid].showToolTip(e, {
  984. formatter: (item, category, index, opts) => {
  985. if (typeof cfu.option[cid].tooltipFormat === 'string' && cfu.formatter[cfu.option[cid].tooltipFormat]) {
  986. return cfu.formatter[cfu.option[cid].tooltipFormat](item, category, index, opts);
  987. } else {
  988. return this._tooltipDefault(item, category, index, opts);
  989. }
  990. }
  991. });
  992. }
  993. },
  994. _tap(e,move) {
  995. let cid = this.cid
  996. let currentIndex = null;
  997. let legendIndex = null;
  998. if (this.inScrollView === true || this.inAli) {
  999. let chartdom = uni
  1000. .createSelectorQuery()
  1001. // #ifndef MP-ALIPAY
  1002. .in(this)
  1003. .select('#ChartBoxId'+cid)
  1004. // #endif
  1005. // #ifdef MP-ALIPAY
  1006. .select('#'+this.cid)
  1007. // #endif
  1008. .boundingClientRect(data => {
  1009. e.changedTouches=[];
  1010. if (this.inAli) {
  1011. e.changedTouches.unshift({ x: e.detail.pageX - data.left, y: e.detail.pageY - data.top});
  1012. }else{
  1013. e.changedTouches.unshift({ x: e.detail.x - data.left, y: e.detail.y - data.top - this.pageScrollTop});
  1014. }
  1015. if(move){
  1016. if (this.tooltipShow === true) {
  1017. this._showTooltip(e);
  1018. }
  1019. }else{
  1020. currentIndex = cfu.instance[cid].getCurrentDataIndex(e);
  1021. legendIndex = cfu.instance[cid].getLegendDataIndex(e);
  1022. cfu.instance[cid].touchLegend(e);
  1023. if (this.tooltipShow === true) {
  1024. this._showTooltip(e);
  1025. }
  1026. this.emitMsg({name: 'getIndex', params: { type:"getIndex", event:{ x: e.detail.x - data.left, y: e.detail.y - data.top }, currentIndex: currentIndex, legendIndex: legendIndex, id: cid}});
  1027. }
  1028. })
  1029. .exec();
  1030. } else {
  1031. if(move){
  1032. if (this.tooltipShow === true) {
  1033. this._showTooltip(e);
  1034. }
  1035. }else{
  1036. e.changedTouches=[];
  1037. e.changedTouches.unshift({ x: e.detail.x - e.currentTarget.offsetLeft, y: e.detail.y - e.currentTarget.offsetTop });
  1038. currentIndex = cfu.instance[cid].getCurrentDataIndex(e);
  1039. legendIndex = cfu.instance[cid].getLegendDataIndex(e);
  1040. cfu.instance[cid].touchLegend(e);
  1041. if (this.tooltipShow === true) {
  1042. this._showTooltip(e);
  1043. }
  1044. this.emitMsg({name: 'getIndex', params: {type:"getIndex", event:{ x: e.detail.x, y: e.detail.y - e.currentTarget.offsetTop }, currentIndex: currentIndex, legendIndex: legendIndex, id: cid}});
  1045. }
  1046. }
  1047. },
  1048. _touchStart(e) {
  1049. let cid = this.cid
  1050. lastMoveTime=Date.now();
  1051. if(cfu.option[cid].enableScroll === true){
  1052. cfu.instance[cid].scrollStart(e);
  1053. }
  1054. this.emitMsg({name:'getTouchStart', params:{type:"touchStart", event:e.changedTouches[0], id:cid}});
  1055. },
  1056. _touchMove(e) {
  1057. let cid = this.cid
  1058. let currMoveTime = Date.now();
  1059. let duration = currMoveTime - lastMoveTime;
  1060. if (duration < Math.floor(1000 / 60)) return;//每秒60帧
  1061. lastMoveTime = currMoveTime;
  1062. if(cfu.option[cid].enableScroll === true){
  1063. cfu.instance[cid].scroll(e);
  1064. }
  1065. this.emitMsg({name: 'getTouchMove', params: {type:"touchMove", event:e.changedTouches[0], id: cid}});
  1066. if(this.ontap === true && cfu.option[cid].enableScroll === false && this.onmovetip === true){
  1067. this._tap(e,true)
  1068. }
  1069. },
  1070. _touchEnd(e) {
  1071. let cid = this.cid
  1072. if(cfu.option[cid].enableScroll === true){
  1073. cfu.instance[cid].scrollEnd(e);
  1074. }
  1075. this.emitMsg({name:'getTouchEnd', params:{type:"touchEnd", event:e.changedTouches[0], id:cid}});
  1076. if(this.ontap === true && cfu.option[cid].enableScroll === false && this.onmovetip === true){
  1077. this._tap(e,true)
  1078. }
  1079. },
  1080. // #endif
  1081. _error(e) {
  1082. this.mixinDatacomErrorMessage = e.detail.errMsg;
  1083. },
  1084. emitMsg(msg) {
  1085. this.$emit(msg.name, msg.params);
  1086. },
  1087. getRenderType() {
  1088. //防止如果开启echarts且父元素为v-if的情况renderjs监听不到prop变化的问题
  1089. if(this.echarts===true && this.mixinDatacomLoading===false){
  1090. this.beforeInit()
  1091. }
  1092. },
  1093. toJSON(){
  1094. return this
  1095. }
  1096. }
  1097. };
  1098. </script>
  1099. <!-- #ifdef APP-VUE || H5 -->
  1100. <script module="rdcharts" lang="renderjs">
  1101. import uChartsRD from '@/components/u-charts/u-charts-v2.0.0.js';
  1102. import cfu from '@/components/u-charts/config-ucharts.js';
  1103. import cfe from '@/components/u-charts/config-echarts.js';
  1104. var that = {};
  1105. var rootdom = null;
  1106. function rdformatterAssign(args,formatter) {
  1107. for (let key in args) {
  1108. if(typeof args[key] === 'object'){
  1109. rdformatterAssign(args[key],formatter)
  1110. }else if(key === 'format' && typeof args[key] === 'string'){
  1111. args['formatter'] = formatter[args[key]] ? formatter[args[key]] : undefined;
  1112. }
  1113. }
  1114. return args;
  1115. }
  1116. export default {
  1117. data() {
  1118. return {
  1119. rid:null
  1120. }
  1121. },
  1122. mounted() {
  1123. rootdom = {top:0,left:0}
  1124. // #ifdef H5
  1125. let dm = document.querySelectorAll('uni-main')[0]
  1126. if(dm === undefined){
  1127. dm = document.querySelectorAll('uni-page-wrapper')[0]
  1128. }
  1129. rootdom = {top:dm.offsetTop,left:dm.offsetLeft}
  1130. // #endif
  1131. setTimeout(()=>{
  1132. if(this.rid === null){
  1133. this.$ownerInstance.callMethod('getRenderType')
  1134. }
  1135. },200)
  1136. },
  1137. destroyed(){
  1138. delete cfu.option[this.rid]
  1139. delete cfu.instance[this.rid]
  1140. delete cfe.option[this.rid]
  1141. delete cfe.instance[this.rid]
  1142. },
  1143. methods: {
  1144. //==============以下是ECharts的方法====================
  1145. ecinit(newVal, oldVal, owner, instance){
  1146. let cid = JSON.parse(JSON.stringify(newVal.id))
  1147. this.rid = cid
  1148. that[cid] = this.$ownerInstance
  1149. cfe.option[cid] = JSON.parse(JSON.stringify(newVal))
  1150. if (typeof window.echarts === 'object') {
  1151. this.newEChart()
  1152. }else{
  1153. const script = document.createElement('script')
  1154. // #ifdef APP-VUE
  1155. script.src = './static/app-plus/echarts.min.js'
  1156. // #endif
  1157. // #ifdef H5
  1158. const rooturl = window.location.origin
  1159. const directory = instance.getDataset().directory
  1160. script.src = rooturl + directory + 'static/h5/echarts.min.js'
  1161. // #endif
  1162. script.onload = this.newEChart
  1163. document.head.appendChild(script)
  1164. }
  1165. },
  1166. ecresize(newVal, oldVal, owner, instance){
  1167. if(cfe.instance[this.rid]){
  1168. cfe.instance[this.rid].resize()
  1169. }
  1170. },
  1171. newEChart(){
  1172. let cid = this.rid
  1173. if(cfe.instance[cid] === undefined){
  1174. cfe.instance[cid] = echarts.init(that[cid].$el.children[0])
  1175. //ontap开启后才触发click事件
  1176. if(cfe.option[cid].ontap === true){
  1177. cfe.instance[cid].on('click', resdata => {
  1178. let event = JSON.parse(JSON.stringify({
  1179. x:resdata.event.offsetX,y:resdata.event.offsetY
  1180. }))
  1181. that[cid].callMethod('emitMsg',{name:"getIndex", params:{type:"getIndex", event:event, currentIndex:resdata.dataIndex, value:resdata.data, seriesName: resdata.seriesName,id:cid}})
  1182. })
  1183. }
  1184. this.updataEChart(cid,cfe.option[cid])
  1185. }else{
  1186. this.updataEChart(cid,cfe.option[cid])
  1187. }
  1188. },
  1189. updataEChart(cid,option){
  1190. //替换option内format属性为formatter的预定义方法
  1191. option = rdformatterAssign(option,cfe.formatter)
  1192. if(option.tooltip){
  1193. option.tooltip.show = option.tooltipShow?true:false;
  1194. option.tooltip.position = this.tooltipPosition()
  1195. //tooltipFormat方法,替换组件的tooltipFormat为config-echarts.js内对应的方法
  1196. if (typeof option.tooltipFormat === 'string' && cfe.formatter[option.tooltipFormat]) {
  1197. option.tooltip.formatter = option.tooltip.formatter ? option.tooltip.formatter : cfe.formatter[option.tooltipFormat]
  1198. }
  1199. }
  1200. // 颜色渐变添加的方法
  1201. if (option.series) {
  1202. for (let i in option.series) {
  1203. let linearGradient = option.series[i].linearGradient
  1204. if (linearGradient) {
  1205. option.series[i].color = new echarts.graphic.LinearGradient(linearGradient[0],linearGradient[1],linearGradient[2],linearGradient[3],linearGradient[4])
  1206. }
  1207. }
  1208. }
  1209. cfe.instance[cid].setOption(option, option.notMerge)
  1210. cfe.instance[cid].on('finished', function(){
  1211. that[cid].callMethod('emitMsg',{name:"complete",params:{type:"complete",complete:true,id:cid}})
  1212. if(cfe.instance[cid]){
  1213. cfe.instance[cid].off('finished')
  1214. }
  1215. })
  1216. },
  1217. tooltipPosition(){
  1218. return (point, params, dom, rect, size) => {
  1219. let x = point[0]
  1220. let y = point[1]
  1221. let viewWidth = size.viewSize[0]
  1222. let viewHeight = size.viewSize[1]
  1223. let boxWidth = size.contentSize[0]
  1224. let boxHeight = size.contentSize[1]
  1225. let posX = x + 30
  1226. let posY = y + 30
  1227. if (posX + boxWidth > viewWidth) {
  1228. posX = x - boxWidth - 30
  1229. }
  1230. if (posY + boxHeight > viewHeight) {
  1231. posY = y - boxHeight - 30
  1232. }
  1233. return [posX, posY]
  1234. }
  1235. },
  1236. //==============以下是uCharts的方法====================
  1237. ucinit(newVal, oldVal, owner, instance){
  1238. let cid = JSON.parse(JSON.stringify(newVal.canvasId))
  1239. this.rid = cid
  1240. that[cid] = this.$ownerInstance
  1241. cfu.option[cid] = JSON.parse(JSON.stringify(newVal))
  1242. cfu.option[cid] = rdformatterAssign(cfu.option[cid],cfu.formatter)
  1243. let canvasdom = document.getElementById(cid)
  1244. if(canvasdom && canvasdom.children[0]){
  1245. cfu.option[cid].context = canvasdom.children[0].getContext("2d")
  1246. this.newUChart()
  1247. }
  1248. },
  1249. newUChart() {
  1250. let cid = this.rid
  1251. cfu.instance[cid] = new uChartsRD(cfu.option[cid])
  1252. cfu.instance[cid].addEventListener('renderComplete', () => {
  1253. that[cid].callMethod('emitMsg',{name:"complete",params:{type:"complete",complete:true,id:cid}})
  1254. cfu.instance[cid].delEventListener('renderComplete')
  1255. });
  1256. cfu.instance[cid].addEventListener('scrollLeft', () => {
  1257. that[cid].callMethod('emitMsg',{name:"scrollLeft",params:{type:"scrollLeft",scrollLeft:true,id:cid}})
  1258. });
  1259. cfu.instance[cid].addEventListener('scrollRight', () => {
  1260. that[cid].callMethod('emitMsg',{name:"scrollRight",params:{type:"scrollRight",scrollRight:true,id:cid}})
  1261. });
  1262. },
  1263. tooltipDefault(item, category, index, opts) {
  1264. if (category) {
  1265. let data = item.data
  1266. if(typeof item.data === "object"){
  1267. data = item.data.value
  1268. }
  1269. return category + ' ' + item.name + ':' + data;
  1270. } else {
  1271. if (item.properties !== undefined) {
  1272. return item.properties.name;
  1273. } else {
  1274. return item.name + ':' + item.data;
  1275. }
  1276. }
  1277. },
  1278. showTooltip(e,cid) {
  1279. let tc = cfu.option[cid].tooltipCustom
  1280. if (tc && tc !== undefined && tc !== null) {
  1281. let offset = undefined;
  1282. if (tc.x >= 0 && tc.y >= 0) {
  1283. offset = { x: tc.x, y: tc.y + 10 };
  1284. }
  1285. cfu.instance[cid].showToolTip(e, {
  1286. index: tc.index,
  1287. offset: offset,
  1288. textList: tc.textList,
  1289. formatter: (item, category, index, opts) => {
  1290. if (typeof cfu.option[cid].tooltipFormat === 'string' && cfu.formatter[cfu.option[cid].tooltipFormat]) {
  1291. return cfu.formatter[cfu.option[cid].tooltipFormat](item, category, index, opts);
  1292. } else {
  1293. return this.tooltipDefault(item, category, index, opts);
  1294. }
  1295. }
  1296. });
  1297. } else {
  1298. cfu.instance[cid].showToolTip(e, {
  1299. formatter: (item, category, index, opts) => {
  1300. if (typeof cfu.option[cid].tooltipFormat === 'string' && cfu.formatter[cfu.option[cid].tooltipFormat]) {
  1301. return cfu.formatter[cfu.option[cid].tooltipFormat](item, category, index, opts);
  1302. } else {
  1303. return this.tooltipDefault(item, category, index, opts);
  1304. }
  1305. }
  1306. });
  1307. }
  1308. },
  1309. tap(e) {
  1310. let cid = this.rid
  1311. let ontap = cfu.option[cid].ontap
  1312. let tooltipShow = cfu.option[cid].tooltipShow
  1313. if(ontap == false) return;
  1314. let currentIndex=null
  1315. let legendIndex=null
  1316. let rchartdom = document.getElementById('UC'+cid).getBoundingClientRect()
  1317. let tmpe = {}
  1318. if(e.detail.x){//tap或者click的事件
  1319. tmpe = { x: e.detail.x - rchartdom.left, y:e.detail.y - rchartdom.top + rootdom.top}
  1320. }else{//mouse的事件
  1321. tmpe = { x: e.clientX - rchartdom.left, y:e.clientY - rchartdom.top + rootdom.top}
  1322. }
  1323. e.changedTouches.unshift(tmpe)
  1324. currentIndex=cfu.instance[cid].getCurrentDataIndex(e)
  1325. legendIndex=cfu.instance[cid].getLegendDataIndex(e)
  1326. cfu.instance[cid].touchLegend(e)
  1327. if(tooltipShow==true){
  1328. this.showTooltip(e,cid)
  1329. }
  1330. that[cid].callMethod('emitMsg',{name:"getIndex",params:{type:"getIndex",event:tmpe,currentIndex:currentIndex,legendIndex:legendIndex,id:cid}})
  1331. },
  1332. touchStart(e) {
  1333. let cid = this.rid
  1334. let ontouch = cfu.option[cid].ontouch
  1335. if(ontouch == false) return;
  1336. cfu.instance[cid].scrollStart(e)
  1337. that[cid].callMethod('emitMsg',{name:"getTouchStart",params:{type:"touchStart",event:e.changedTouches[0],id:cid}})
  1338. },
  1339. touchMove(e) {
  1340. let cid = this.rid
  1341. let ontouch = cfu.option[cid].ontouch
  1342. if(ontouch == false) return;
  1343. cfu.instance[cid].scroll(e)
  1344. that[cid].callMethod('emitMsg',{name:"getTouchMove",params:{type:"touchMove",event:e.changedTouches[0],id:cid}})
  1345. if(cfu.option[cid].ontap === true && cfu.option[cid].enableScroll === false && cfu.option[cid].onmovetip === true){
  1346. let rchartdom = document.getElementById('UC'+cid).getBoundingClientRect()
  1347. let tmpe = { x: e.changedTouches[0].clientX - rchartdom.left, y:e.changedTouches[0].clientY - rchartdom.top + rootdom.top}
  1348. e.changedTouches.unshift(tmpe)
  1349. if(cfu.option[cid].tooltipShow === true){
  1350. this.showTooltip(e,cid)
  1351. }
  1352. }
  1353. },
  1354. touchEnd(e) {
  1355. let cid = this.rid
  1356. let ontouch = cfu.option[cid].ontouch
  1357. if(ontouch == false) return;
  1358. cfu.instance[cid].scrollEnd(e)
  1359. that[cid].callMethod('emitMsg',{name:"getTouchEnd",params:{type:"touchEnd",event:e.changedTouches[0],id:cid}})
  1360. },
  1361. mouseDown(e) {
  1362. let cid = this.rid
  1363. let onmouse = cfu.option[cid].onmouse
  1364. if(onmouse == false) return;
  1365. let rchartdom = document.getElementById('UC'+cid).getBoundingClientRect()
  1366. let tmpe = {}
  1367. tmpe = { x: e.clientX - rchartdom.left, y:e.clientY - rchartdom.top + rootdom.top}
  1368. e.changedTouches.unshift(tmpe)
  1369. cfu.instance[cid].scrollStart(e)
  1370. cfu.option[cid].mousedown=true;
  1371. that[cid].callMethod('emitMsg',{name:"getTouchStart",params:{type:"mouseDown",event:tmpe,id:cid}})
  1372. },
  1373. mouseMove(e) {
  1374. let cid = this.rid
  1375. let onmouse = cfu.option[cid].onmouse
  1376. let tooltipShow = cfu.option[cid].tooltipShow
  1377. if(onmouse == false) return;
  1378. let rchartdom = document.getElementById('UC'+cid).getBoundingClientRect()
  1379. let tmpe = {}
  1380. tmpe = { x: e.clientX - rchartdom.left, y:e.clientY - rchartdom.top + rootdom.top}
  1381. e.changedTouches.unshift(tmpe)
  1382. if(cfu.option[cid].mousedown){
  1383. cfu.instance[cid].scroll(e)
  1384. that[cid].callMethod('emitMsg',{name:"getTouchMove",params:{type:"mouseMove",event:tmpe,id:cid}})
  1385. }else if(cfu.instance[cid]){
  1386. if(tooltipShow==true){
  1387. this.showTooltip(e,cid)
  1388. }
  1389. }
  1390. },
  1391. mouseUp(e) {
  1392. let cid = this.rid
  1393. let onmouse = cfu.option[cid].onmouse
  1394. if(onmouse == false) return;
  1395. let rchartdom = document.getElementById('UC'+cid).getBoundingClientRect()
  1396. let tmpe = {}
  1397. tmpe = { x: e.clientX - rchartdom.left, y:e.clientY - rchartdom.top + rootdom.top}
  1398. e.changedTouches.unshift(tmpe)
  1399. cfu.instance[cid].scrollEnd(e)
  1400. cfu.option[cid].mousedown=false;
  1401. that[cid].callMethod('emitMsg',{name:"getTouchEnd",params:{type:"mouseUp",event:tmpe,id:cid}})
  1402. },
  1403. }
  1404. }
  1405. </script>
  1406. <!-- #endif -->
  1407. <style scoped>
  1408. .chartsview {
  1409. width: 100%;
  1410. height: 100%;
  1411. display: flex;
  1412. flex: 1;
  1413. justify-content: center;
  1414. align-items: center;
  1415. }
  1416. </style>