echarts-util.js 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988
  1. /**
  2. * 封装echarts 工具
  3. * Author: abner
  4. * Date: 2021-1-5 更新
  5. */
  6. let MyEcharts = {
  7. echartSet: [], // 表格集合
  8. //整理数据没有分组类型的,适合饼图
  9. EchartsDataFormate: {
  10. NoGroupFormate: function (data) {
  11. //category 的数据存储
  12. let categorys = [];
  13. //data 的数据存储
  14. let datas = [];
  15. //遍历
  16. for (let i = 0; i < data.length; i++) {
  17. categorys.push(data[i].name || "");
  18. //定义一个中间变量
  19. let temp_data = {value: data[i].value || 0, name: data[i].name || ""};
  20. datas.push(temp_data);
  21. }
  22. return {categorys: categorys, data: datas};
  23. },
  24. //整理数据有分组类型的,适合折线图、柱形图(分组,堆积)
  25. //数据格式:{group:XXX,name:XXX,value:XXX} 注意:group不填写没有图例,也无法(分组,堆积)
  26. /**
  27. * @param data : json数据<br>
  28. * @param type Array | string: 图表类型<br>
  29. * let data1 = [ <br>
  30. * { group:'类型1' , name: '1月', value: 10 }, <br>
  31. * { group:'类型2' , name: '1月', value: 15 }, <br>
  32. * { group:'类型1' , name: '2月', value: 25 }, <br>
  33. * { group:'类型2' , name: '2月', value: 12 }, <br>
  34. * { group:'类型1' , name: '3月', value: 22 }, <br>
  35. * { group:'类型2' , name: '3月', value: 12 }, <br>
  36. * ];
  37. *
  38. */
  39. GroupFormate: function (data, type) {
  40. //用于存储类型名称(图例名)
  41. let groups = [];
  42. //用于存储xAxis.data数据(x轴名称)
  43. let names = [];
  44. //存储返回series数据 (一个或者多个)
  45. let series = [];
  46. let yAxisIndex = 0;
  47. for (let i = 0; i < data.length; i++) {
  48. //判断data[i].group是否存在数租groups中
  49. if (!groups.contains(data[i].group)) {
  50. //不存在则跳进 存放
  51. groups.push(data[i].group);
  52. }
  53. //判断name数据是否存在 数组names中
  54. if (!names.contains(data[i].name)) {
  55. //不存在则跳进 存放
  56. names.push(data[i].name);
  57. }
  58. }
  59. //遍历分类
  60. for (let i = 0; i < groups.length; i++) {
  61. //定义一个series中间变量
  62. let temp_series = {};
  63. //定义data.value数据存储
  64. let temp_data = [];
  65. //定义图形类型
  66. let temp_type = type.constructor === Array ? type[i] : type;
  67. //遍历所有数据
  68. for (let j = 0; j < data.length; j++) {
  69. //遍历data.name数据
  70. for (let k = 0; k < names.length; k++) {
  71. //判断所有分类中的所有数据含name数据分开
  72. if (groups[i] == data[j].group && names[k] == data[j].name) {
  73. temp_data.push(data[j].value);
  74. //判断y轴对应的数据,如果存在yAxisIndex则使用此数据,否则使用默认值 默认:0
  75. yAxisIndex = data[j].yAxisIndex ? data[j].yAxisIndex : 0;
  76. }
  77. }
  78. }
  79. temp_series = {
  80. name: groups[i],
  81. type: temp_type === 'acrossBar' ? 'bar' : temp_type, //横向柱状图:acrossBar
  82. data: temp_data,
  83. yAxisIndex: yAxisIndex
  84. };
  85. //每个柱子或拐点对应的文字位置和颜色。echarts3是在label.normal里配置,echart4中兼容
  86. temp_series.label = {
  87. position: 'top',
  88. show: true,
  89. textStyle: {
  90. color: '#fff' //auto则根据系列色同步
  91. },
  92. formatter: function (params) { //当值为0时不显示在柱子或拐点顶部
  93. let val = params.value;
  94. return val === 0 ? '' : val;
  95. }
  96. };
  97. // 柱状图参数配置
  98. if (temp_type === 'bar') {
  99. temp_series.barMaxWidth = 24; //柱宽
  100. }
  101. // 折线图参数配置
  102. if (temp_type === 'line') {
  103. temp_series.lineStyle = {width: 4}; //线租
  104. temp_series.smooth = true; //拐点平滑
  105. }
  106. // 横向柱状图参数配置
  107. if (temp_type === 'acrossBar') {
  108. temp_series.barMaxWidth = 24; //柱宽
  109. temp_series.label = {
  110. position: 'right',
  111. show: true,
  112. textStyle: {
  113. color: 'auto' //auto则根据系列色同步
  114. }
  115. };
  116. }
  117. series.push(temp_series);
  118. }
  119. // console.log(groups)
  120. // console.log(names)
  121. // console.log(series)
  122. return {groups: groups, category: names, series: series};
  123. },
  124. /**
  125. * 雷达图数据格式化
  126. */
  127. RadarFormate: function (data, type) {
  128. //用于存储类型名称
  129. let groups = [];
  130. //用于存储data.name数据
  131. let names = [];
  132. //存储最大值数组
  133. let indicators = [];
  134. //定义data.value数据存储
  135. let temp_data = [];
  136. for (let i = 0; i < data.length; i++) {
  137. //判断data[i].group是否存在数租groups中
  138. if (!groups.contains(data[i].group)) {
  139. //不存在则跳进 存放
  140. groups.push(data[i].group);
  141. }
  142. //判断name数据是否存在 数组names中
  143. if (!names.contains(data[i].name)) {
  144. //不存在则跳进 存放
  145. names.push(data[i].name);
  146. }
  147. }
  148. for (let i = 0; i < names.length; i++) {
  149. //中
  150. let temp_maxValue = [];
  151. for (let j = 0; j < data.length; j++) {
  152. if (names[i] == data[j].name) {
  153. temp_maxValue.push(data[j].value);
  154. }
  155. }
  156. indicators.push({name: names[i], max: Number(temp_maxValue.max() * 2 / 1.5).toFixed(2)})
  157. }
  158. //遍历分类
  159. for (let i = 0; i < groups.length; i++) {
  160. //定义一个series中间变量
  161. let temp_series = {};
  162. //定义datavalue数组
  163. let dataValues = [];
  164. //遍历所有数据
  165. for (let j = 0; j < data.length; j++) {
  166. if (groups[i] == data[j].group) {
  167. dataValues.push(data[j].value);
  168. }
  169. }
  170. temp_data.push({value: dataValues, name: groups[i]});
  171. }
  172. let series = {type: type, data: temp_data};
  173. return {indicators: indicators, groups: groups, category: names, series: series};
  174. },
  175. /**
  176. * 漏斗图数据格式化
  177. */
  178. FunnelFormate: function (data, type) {
  179. //用于存储类型名称
  180. let groups = [];
  181. //用于存储data.name数据
  182. let names = [];
  183. //定义一个存放series的数组
  184. let series = [];
  185. for (let i = 0; i < data.length; i++) {
  186. //判断data[i].group是否存在数租groups中
  187. if (!groups.contains(data[i].group)) {
  188. //不存在则跳进 存放
  189. groups.push(data[i].group);
  190. }
  191. //判断name数据是否存在 数组names中
  192. if (!names.contains(data[i].name)) {
  193. //不存在则跳进 存放
  194. names.push(data[i].name);
  195. }
  196. }
  197. let width = parseInt(100 / groups.length);
  198. //遍历分类
  199. for (let i = 0; i < groups.length; i++) {
  200. //定义data.value数据存储
  201. let temp_data = [];
  202. let k = 0;
  203. //遍历所有数据
  204. for (let j = 0; j < data.length; j++) {
  205. //判断所有分类中的所有数据含name数据分开
  206. if (groups[i] == data[j].group) {
  207. k++;
  208. temp_data.push({value: k, name: data[j].name + ":" + data[j].value});
  209. }
  210. }
  211. let left = width * i;
  212. series.push({
  213. name: groups[i],
  214. type: type,
  215. sort: 'ascending',
  216. grap: 2,
  217. left: left + "%",
  218. width: width - 5 + "%",
  219. label: {
  220. normal: {
  221. show: true,
  222. position: 'inside'
  223. },
  224. emphasis: {
  225. textStyle: {
  226. fontSize: 20
  227. }
  228. }
  229. },
  230. data: temp_data
  231. });
  232. }
  233. return {groups: groups, category: names, series: series};
  234. },
  235. /**
  236. * 仪表盘图数据格式化
  237. */
  238. GaugeFormate: function (data, type) {
  239. let temp_datas = [{value: data.value, name: data.name}];
  240. let names = data.name;
  241. //判断最大值和最小值几位数
  242. maxNum = Number(parseInt(data.value)).toString().length;
  243. minNum = Number(parseInt(data.value)).toString().length;
  244. if (minNum <= 2) {
  245. min = 0;
  246. } else {
  247. //最小值
  248. min = Math.pow(10, (maxNum - 1));
  249. }
  250. //最大值
  251. max = Math.pow(10, maxNum);
  252. let series = [];
  253. series.push({
  254. name: data.group,
  255. type: type,
  256. min: min,
  257. max: max,
  258. radius: '70%',
  259. startAngle: 180,
  260. endAngle: -0,
  261. axisLine: { // 坐标轴线
  262. lineStyle: { // 属性lineStyle控制线条样式
  263. color: [[0.09, 'lime'], [0.82, '#1e90ff'], [1, '#ff4500']],
  264. width: 3,
  265. shadowColor: '#fff', //默认透明
  266. shadowBlur: 10
  267. }
  268. },
  269. axisLabel: { // 坐标轴小标记
  270. textStyle: { // 属性lineStyle控制线条样式
  271. fontWeight: 'bolder',
  272. color: '#444',
  273. shadowColor: '#fff', //默认透明
  274. shadowBlur: 10
  275. }
  276. },
  277. axisTick: { // 坐标轴小标记
  278. length: 15, // 属性length控制线长
  279. lineStyle: { // 属性lineStyle控制线条样式
  280. color: 'auto',
  281. shadowColor: '#fff', //默认透明
  282. shadowBlur: 10
  283. }
  284. },
  285. splitLine: { // 分隔线
  286. length: 25, // 属性length控制线长
  287. lineStyle: { // 属性lineStyle(详见lineStyle)控制线条样式
  288. width: 3,
  289. color: 'auto',
  290. shadowColor: '#fff', //默认透明
  291. shadowBlur: 10
  292. }
  293. },
  294. pointer: { // 分隔线
  295. shadowColor: '#fff', //默认透明
  296. shadowBlur: 5
  297. },
  298. title: {
  299. offsetCenter: ['-10%', '30%'],
  300. textStyle: { // 其余属性默认使用全局文本样式,详见TEXTSTYLE
  301. fontWeight: 'bolder',
  302. fontSize: 14,
  303. fontStyle: 'italic',
  304. color: '#',
  305. shadowColor: '#fff', //默认透明
  306. shadowBlur: 10
  307. }
  308. },
  309. detail: {
  310. backgroundColor: 'rgba(30,144,255,0.8)',
  311. borderWidth: 1,
  312. borderColor: '#fff',
  313. shadowColor: '#fff', //默认透明
  314. shadowBlur: 5,
  315. fontSize: 14,
  316. offsetCenter: ['20%', '30%'], // x, y,单位px
  317. textStyle: { // 其余属性默认使用全局文本样式,详见TEXTSTYLE
  318. fontWeight: 'bolder',
  319. color: '#fff'
  320. }
  321. },
  322. data: temp_datas
  323. });
  324. return {category: names, series: series};
  325. }
  326. },
  327. //生成图形option
  328. EchartsOption: {
  329. /**
  330. * 饼图
  331. * @param title : 标题<br>
  332. * @param subtext :副标题<br>
  333. * @param data : json 数据
  334. * @param radiusArr : array [内环百分比,外环百分比],不指定为普通饼图
  335. *
  336. */
  337. pie: function (title, subtext, data, radiusArr) {
  338. //数据格式
  339. let datas = MyEcharts.EchartsDataFormate.NoGroupFormate(data);
  340. let option = {
  341. //标题
  342. title: {
  343. text: title || "", //标题
  344. subtext: subtext || "", //副标题
  345. },
  346. //提示
  347. tooltip: {
  348. show: true,
  349. trigger: 'item',
  350. formatter: "{a} <br/>{b} : {c} ({d}%)"
  351. },
  352. //组建
  353. legend: {
  354. data: datas.categorys
  355. },
  356. series: [
  357. {
  358. name: title || "",
  359. type: 'pie', //类型
  360. radius: radiusArr || '48%', //圆的大小
  361. center: ['50%', '50%'],//位置居中
  362. data: datas.data,
  363. emphasis: { //高亮的扇区和标签样式。
  364. shadowBlur: 10,
  365. shadowOffsetX: 0,
  366. shadowColor: 'rgba(0, 0, 0, 0.5)'
  367. },
  368. labelLine: { //引导线
  369. show: false,
  370. },
  371. label: {
  372. textStyle: {
  373. color: 'auto' //改变标示文字的颜色
  374. }
  375. }
  376. }
  377. ]
  378. };
  379. return option;
  380. },
  381. /**
  382. * 柱形图
  383. * @param title : 标题<br>
  384. * @param subtext :副标题<br>
  385. * @param data : json 数据
  386. */
  387. bar: function (title, subtext, data) {
  388. let datas = MyEcharts.EchartsDataFormate.GroupFormate(data, 'bar');
  389. let option = {
  390. //标题
  391. title: {
  392. text: title || "", //标题
  393. subtext: subtext || "", //副标题
  394. },
  395. //提示
  396. tooltip: {
  397. show: true,
  398. trigger: 'axis', //散点图,饼图等无类目轴的图表中使用:'item';
  399. axisPointer: { //鼠标指向背景
  400. type: 'shadow', //'line' 直线指示器 ,'shadow' 阴影指示器 ,'none' 无指示器 ,'cross' 十字准星指示器。其实是种简写,表示启用两个正交的轴的 axisPointer。
  401. label: {
  402. show: true
  403. }
  404. },
  405. // formatter: function (params) {
  406. // return MyEcharts.resetTooltip(params);
  407. // }
  408. },
  409. // 工具条
  410. toolbox: {
  411. show: false, // 默认显示
  412. feature: {
  413. dataZoom: {
  414. yAxisIndex: 'none'
  415. },
  416. dataView: {readOnly: false},
  417. magicType: {type: ['line', 'bar']},
  418. restore: {},
  419. saveAsImage: {}
  420. }
  421. },
  422. // 数据滑竿
  423. dataZoom: [
  424. {
  425. show: false,
  426. realtime: true,
  427. },
  428. {
  429. type: 'slider',
  430. realtime: true,
  431. }
  432. ],
  433. //组建
  434. legend: {
  435. data: datas.groups.map((text) => {
  436. return {name: text, icon: 'rect'} //icon图形样式:'circle', 'rect', 'roundRect', 'triangle', 'diamond', 'pin', 'arrow'
  437. })
  438. },
  439. //水平坐标
  440. xAxis: [
  441. {
  442. name: '', //x轴单位
  443. nameTextStyle: {//x轴上方单位的颜色
  444. color: 'auto'
  445. },
  446. type: 'category',
  447. data: datas.category
  448. }
  449. ],
  450. //垂直坐标
  451. yAxis: [
  452. {
  453. name: '', //y轴单位
  454. nameTextStyle: {//y轴上方单位的颜色
  455. color: '#151515'
  456. },
  457. type: 'value'
  458. }
  459. ],
  460. //series数据
  461. series: datas.series
  462. };
  463. return option;
  464. },
  465. /**
  466. * 横向柱形图
  467. * @param title : 标题<br>
  468. * @param subtext :副标题<br>
  469. * @param data : json 数据
  470. */
  471. acrossBar: function (title, subtext, data) {
  472. let datas = MyEcharts.EchartsDataFormate.GroupFormate(data, 'acrossBar');
  473. let option = {
  474. //标题
  475. title: {
  476. text: title || "", //标题
  477. subtext: subtext || "", //副标题
  478. },
  479. //提示
  480. tooltip: {
  481. show: true,
  482. trigger: 'axis', //散点图,饼图等无类目轴的图表中使用:'item';
  483. axisPointer: { //鼠标指向背景
  484. type: 'none', //'line' 直线指示器 ,'shadow' 阴影指示器 ,'none' 无指示器 ,'cross' 十字准星指示器。其实是种简写,表示启用两个正交的轴的 axisPointer。
  485. label: {
  486. show: true
  487. }
  488. },
  489. formatter: function (params) {
  490. return MyEcharts.resetTooltip(params);
  491. }
  492. },
  493. //组建
  494. legend: {
  495. data: datas.groups.map((text) => {
  496. return {name: text, icon: 'rect'} //icon图形样式:'circle', 'rect', 'roundRect', 'triangle', 'diamond', 'pin', 'arrow'
  497. })
  498. },
  499. //水平坐标
  500. xAxis: [
  501. {
  502. name: '', //x轴单位
  503. nameTextStyle: {//x轴上方单位的颜色
  504. color: '#151515'
  505. },
  506. type: 'value'
  507. }
  508. ],
  509. //垂直坐标
  510. yAxis: [
  511. {
  512. name: '', //y轴单位
  513. nameTextStyle: {//y轴上方单位的颜色
  514. color: '#151515'
  515. },
  516. type: 'category',
  517. data: datas.category
  518. }
  519. ],
  520. //series数据
  521. series: datas.series
  522. };
  523. return option;
  524. },
  525. /**
  526. * 双y轴/混搭
  527. * @param title : string 标题
  528. * @param subtext : string 副标题
  529. * @param data : json 数据
  530. * @param type : Array 或 string,数组时需要和图例个数相对应,字符串时为统一类型 **注意:type不管为哪种类型时都需要在数据中指定yAxisIndex的值**
  531. */
  532. doubleYMixUp: function (title, subtext, data, type) {
  533. let datas = MyEcharts.EchartsDataFormate.GroupFormate(data, type);
  534. let option = {
  535. //标题
  536. title: {
  537. text: title || "", //标题
  538. subtext: subtext || "", //副标题
  539. },
  540. //提示
  541. tooltip: {
  542. show: true,
  543. trigger: 'axis', //散点图,饼图等无类目轴的图表中使用:'item';
  544. axisPointer: { //鼠标指向背景
  545. type: 'shadow', //'line' 直线指示器 ,'shadow' 阴影指示器 ,'none' 无指示器 ,'cross' 十字准星指示器。其实是种简写,表示启用两个正交的轴的 axisPointer。
  546. label: {
  547. show: true
  548. }
  549. }
  550. },
  551. //组建
  552. legend: {
  553. data: datas.groups.map((text) => {
  554. return {name: text, icon: 'rect'} //icon图形样式:'circle', 'rect', 'roundRect', 'triangle', 'diamond', 'pin', 'arrow'
  555. })
  556. },
  557. //水平坐标
  558. xAxis: [
  559. {
  560. name: '', //x轴单位
  561. type: 'category',
  562. data: datas.category,
  563. }
  564. ],
  565. //垂直坐标
  566. yAxis: [
  567. {
  568. name: '', //y轴单位
  569. type: 'value',
  570. splitLine: {
  571. show: false,
  572. }
  573. },
  574. {
  575. name: '', //右y轴单位
  576. type: 'value',
  577. splitLine: {
  578. show: false,
  579. }
  580. }
  581. ],
  582. //series数据
  583. series: datas.series
  584. };
  585. return option;
  586. },
  587. /**
  588. * 折线图
  589. * @param title : 标题<br>
  590. * @param subtext :副标题<br>
  591. * @param data : json 数据
  592. */
  593. Line: function (title, subtext, data) {
  594. let datas = MyEcharts.EchartsDataFormate.GroupFormate(data, 'line');
  595. let option = {
  596. //标题
  597. title: {
  598. text: title || "", //标题
  599. subtext: subtext || "", //副标题
  600. },
  601. //提示
  602. tooltip: {
  603. show: true,
  604. trigger: 'axis',
  605. // formatter: function (params) {
  606. // debugger
  607. // return MyEcharts.resetTooltip(params);
  608. // }
  609. },
  610. //组建
  611. legend: {
  612. data: datas.groups.map((text) => {
  613. return {name: text, icon: 'rect'} //icon图形样式:'circle', 'rect', 'roundRect', 'triangle', 'diamond', 'pin', 'arrow'
  614. })
  615. },
  616. //水平坐标
  617. xAxis: [
  618. {
  619. type: 'category',
  620. boundaryGap: false,
  621. splitLine: {
  622. show: false,
  623. },
  624. data: datas.category,
  625. }
  626. ],
  627. //垂直坐标
  628. yAxis: [
  629. {
  630. type: 'value'
  631. }
  632. ],
  633. //series数据
  634. series: datas.series
  635. };
  636. return option;
  637. },
  638. /**
  639. * 雷达图
  640. * @param title : 标题<br>
  641. * @param subtext :副标题<br>
  642. * @param data : json 数据
  643. */
  644. Radar: function (title, subtext, data) {
  645. let datas = MyEcharts.EchartsDataFormate.RadarFormate(data, 'radar');
  646. let option = {
  647. //标题
  648. title: {
  649. text: title || "", //标题
  650. subtext: subtext || "", //副标题
  651. },
  652. //提示
  653. tooltip: {
  654. show: true,
  655. },
  656. //组建
  657. legend: {
  658. data: datas.groups
  659. },
  660. radar: {
  661. name: {
  662. textStyle: {
  663. color: '#fff',
  664. backgroundColor: '#999',
  665. borderRadius: 3,
  666. padding: [3, 5]
  667. }
  668. },
  669. indicator: datas.indicators
  670. },
  671. series: datas.series
  672. };
  673. return option;
  674. },
  675. /**
  676. * 漏斗图
  677. * @param title : 标题<br>
  678. * @param subtext :副标题<br>
  679. * @param data : json 数据
  680. */
  681. Funnel: function (title, subtext, data) {
  682. let datas = MyEcharts.EchartsDataFormate.FunnelFormate(data, 'funnel');
  683. let option = {
  684. //标题
  685. title: {
  686. text: title || "", //标题
  687. subtext: subtext || "", //副标题
  688. },
  689. //提示
  690. tooltip: {
  691. show: true,
  692. trigger: 'item',
  693. formatter: "{a} <br/>{b} ({c}%)"
  694. },
  695. //组建
  696. legend: {
  697. data: datas.groups,
  698. },
  699. series: datas.series
  700. };
  701. return option;
  702. },
  703. /**
  704. * 仪表图
  705. * @param title : 标题<br>
  706. * @param subtext :副标题<br>
  707. * @param data : json 数据
  708. */
  709. Gauge: function (title, subtext, data) {
  710. let datas = MyEcharts.EchartsDataFormate.GaugeFormate(data, 'gauge');
  711. let option = {
  712. //标题
  713. title: {
  714. text: title || "", //标题
  715. subtext: subtext || "", //副标题
  716. },
  717. //提示
  718. tooltip: {
  719. show: true,
  720. formatter: "{a} <br/>{b}:{c}"
  721. },
  722. series: datas.series
  723. };
  724. return option;
  725. }
  726. },
  727. /**
  728. * 重置Tooltip样式
  729. * @param params : object tooltip函数返回值
  730. */
  731. resetTooltip: function (params) {
  732. if (params.length === 1) { //只有一组数据时
  733. let text = params[0].seriesName + '<br/>';
  734. let colorStops = params[0].color;
  735. if (typeof colorStops === 'object') { //色彩为渐变时
  736. colorStops = params[0].color.colorStops[0].color; //***待优化,此处color不一定有颜色,第一个可能为透明色
  737. }
  738. text += '<span style="display:inline-block;margin-right:5px;border-radius:50%;width:10px;height:10px;left:5px;background-color:' + colorStops + '"></span>' + params[0].axisValue + ' : ' + params[0].value + '<br/>';
  739. return text;
  740. } else { //一组 多条数据时
  741. let text = params[0].axisValue + '<br/>';
  742. params.forEach((item) => {
  743. let colorStops = item.color;
  744. if (typeof colorStops === 'object') { //色彩为渐变时
  745. colorStops = item.color.colorStops[0].color; //***待优化,此处color不一定有颜色,第一个可能为透明色
  746. }
  747. text += '<span style="display:inline-block;margin-right:5px;border-radius:50%;width:10px;height:10px;left:5px;background-color:' + colorStops + '"></span>' + item.seriesName + ' : ' + item.value + '<br/>';
  748. })
  749. return text;
  750. }
  751. },
  752. /**
  753. * @param option : option
  754. * @param echartId : 图表的id 需要加引号
  755. */
  756. initChart: function (option, echartId) {
  757. let container = eval("document.getElementById('" + echartId + "')");
  758. let myChart = echarts.init(container, myTheme);
  759. myChart.setOption(option, true); // (1图表数据: Object, 2是否不跟之前设置的option进行合并?默认为false,即合并: boolean, 3在设置完option后是否不立即更新图表?默认为false,即立即更新。: boolean)
  760. this.echartSet.push(myChart); // 存储已初始化的图表实例
  761. this.resize(); // 添加图表大小改变事件
  762. return myChart;
  763. },
  764. initChart: function (option, echartId, themeId) {
  765. let container = eval("document.getElementById('" + echartId + "')");
  766. let myChart = echarts.init(container, themeId);
  767. myChart.setOption(option, true); // (1图表数据: Object, 2是否不跟之前设置的option进行合并?默认为false,即合并: boolean, 3在设置完option后是否不立即更新图表?默认为false,即立即更新。: boolean)
  768. this.echartSet.push(myChart); // 存储已初始化的图表实例
  769. this.resize(); // 添加图表大小改变事件
  770. return myChart;
  771. },
  772. //图表大小改变事件监听
  773. resize: function () {
  774. try {
  775. window.onresize = function () {
  776. isDebounce(function () {
  777. MyEcharts.echartSet.forEach(item => {
  778. item.resize();
  779. })
  780. }, 300);
  781. }.bind(this);
  782. } catch (error) {
  783. }
  784. }
  785. };
  786. /**
  787. * 数组是否存在某数据
  788. * @param obj
  789. * @returns {Boolean}
  790. */
  791. Array.prototype.contains = function (obj) {
  792. let i = this.length;
  793. while (i--) {
  794. if (this[i] === obj) {
  795. return true;
  796. }
  797. }
  798. return false;
  799. };
  800. /**
  801. * 数组中最大值 最小值
  802. * @param array
  803. * @returns
  804. */
  805. Array.prototype.max = function () {
  806. return Math.max.apply({}, this);
  807. };
  808. Array.prototype.min = function () {
  809. return Math.min.apply({}, this);
  810. };
  811. /**
  812. * 判断是否为整数
  813. * @param obj
  814. * @returns {Boolean}
  815. */
  816. function isInteger(obj) {
  817. return obj % 1 === 0;
  818. }
  819. /**
  820. * 判断值是否包含指定字符
  821. * @param str
  822. * @returns {Boolean}
  823. */
  824. function myRegExp(str) {
  825. let patt = new RegExp(/[%|$]/)
  826. return patt.test(str);
  827. }
  828. /**防抖函数
  829. * 当持续触发事件时,一定时间段内没有再触发事件,事件处理函数才会执行一次,如果设定的时间到来之前,又一次触发了事件,就重新开始延时。
  830. * 适用于延迟时间后触发一次事件。
  831. *使用方式:isDebounce(函数名,延迟时间)();
  832. */
  833. let isTimer; // 维护一个 timer
  834. function isDebounce(fn, delay) {
  835. try {
  836. let _this = this; // 取debounce执行作用域的this
  837. let args = arguments;
  838. if (isTimer) {
  839. clearTimeout(isTimer);
  840. }
  841. isTimer = setTimeout(function () {
  842. fn.apply(_this, args); // 用apply指向调用debounce的对象,相当于_this.fn(args);
  843. }, delay);
  844. } catch (error) {
  845. console.log(error);
  846. }
  847. };
  848. /**自定义loading
  849. * 当持续触发事件时,一定时间段内没有再触发事件,事件处理函数才会执行一次,如果设定的时间到来之前,又一次触发了事件,就重新开始延时。
  850. * 适用于延迟时间后触发一次事件。
  851. *使用方式:isDebounce(函数名,延迟时间)();
  852. */
  853. function loadingNodata(api, opts) {
  854. let PI = Math.PI;
  855. opts = opts || {};
  856. opts = new echarts.util.defaults(opts, {
  857. text: 'loading', // loading显示的文字
  858. textColor: '#000', // 文字颜色
  859. fontSize: '12px', // 文字大小
  860. maskColor: 'rgba(255, 255, 255, 0.8)',
  861. showSpinner: true, // 是否显示gif动画
  862. color: '#c23531', // gif填充的颜色
  863. spinnerRadius: 10,
  864. lineWidth: 5,
  865. zlevel: 0
  866. })
  867. var group = new echarts.graphic.Group();
  868. var mask = new echarts.graphic.Rect({
  869. style: {
  870. fill: opts.maskColor
  871. },
  872. zlevel: opts.zlevel,
  873. z: 10000
  874. });
  875. group.add(mask);
  876. var font = opts.fontSize + ' sans-serif';
  877. var labelRect = new echarts.graphic.Rect({
  878. style: {
  879. fill: 'none',
  880. text: opts.text,
  881. font: font,
  882. textPosition: 'right',
  883. textDistance: 10,
  884. textFill: opts.textColor
  885. },
  886. zlevel: opts.zlevel,
  887. z: 10001
  888. });
  889. group.add(labelRect);
  890. if (opts.showSpinner) {
  891. var arc = new echarts.graphic.Arc({
  892. shape: {
  893. startAngle: -PI / 2,
  894. endAngle: -PI / 2 + 0.1,
  895. r: opts.spinnerRadius
  896. },
  897. style: {
  898. stroke: opts.color,
  899. lineCap: 'round',
  900. lineWidth: opts.lineWidth
  901. },
  902. zlevel: opts.zlevel,
  903. z: 10001
  904. });
  905. arc.animateShape(true)
  906. .when(1000, {
  907. endAngle: PI * 3 / 2
  908. })
  909. .start('circularInOut');
  910. arc.animateShape(true)
  911. .when(1000, {
  912. startAngle: PI * 3 / 2
  913. })
  914. .delay(300)
  915. .start('circularInOut');
  916. group.add(arc);
  917. }
  918. //添加计算canvas文字宽度方法
  919. api.getTextWith = function (
  920. text = '',
  921. fontStyle = '14px/1.5715 "Source Sans Pro, Helvetica Neue, Helvetica, Arial, sans-serif"', // 设置字体大小和字体
  922. ) {
  923. const canvas = document.createElement('canvas');
  924. const context = canvas.getContext('2d');
  925. context.font = fontStyle;
  926. const elem = context.measureText(text);
  927. return elem.width;
  928. }
  929. group.resize = function () {
  930. var textWidth = api.getTextWith(opts.text, font);
  931. var r = opts.showSpinner ? opts.spinnerRadius : 0;
  932. console.log("@r" + r);
  933. console.log("@showSpinner" + opts.showSpinner);
  934. // cx = (containerWidth - arcDiameter - textDistance - textWidth) / 2
  935. // textDistance needs to be calculated when both animation and text exist
  936. var cx = (api.getWidth() - r * 2 - (opts.showSpinner && textWidth ? 10 : 0) - textWidth) / 2
  937. // only show the text
  938. // - (opts.showSpinner ? 0 : textWidth / 2);
  939. var cy = api.getHeight() / 2;
  940. opts.showSpinner && arc.setShape({
  941. cx: cx,
  942. cy: cy
  943. });
  944. labelRect.setShape({
  945. x: cx - r,
  946. y: cy - r,
  947. width: r * 2,
  948. height: r * 2
  949. });
  950. mask.setShape({
  951. x: 0,
  952. y: 0,
  953. width: api.getWidth(),
  954. height: api.getHeight()
  955. });
  956. };
  957. group.resize();
  958. return group;
  959. };
  960. //向全局echarts对象注册新的loading: nodatas
  961. echarts.registerLoading("nodatas", loadingNodata);