echartsUtil.ts 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313
  1. import echarts from '/@/utils/lib/echarts';
  2. import { merge } from 'lodash-es';
  3. export default class echartsUtil {
  4. option: any;
  5. type: string;
  6. constructor(option) {
  7. this.option = option;
  8. }
  9. /**
  10. * 获取数据渲染echarts图表
  11. * @param type 类型目前两种 listMonitor(实时检测对应的图表)、history(历史数据对应的图表)
  12. * @param echartsComponent echarts组件类
  13. * @param chartcolumns EnumData文件对应图表类型配置属性
  14. * @param listData 从后台获取到的数据
  15. * @param devicetype 设备类型
  16. * @param columnname 某些特定设备类型下,从后台获取到的数据中,属性名为columnname的属性值存放的是x轴的信息
  17. */
  18. initChartOption(type, chartColumns: any[] = []) {
  19. if (!this.option) {
  20. return;
  21. }
  22. const xdata = [], // 存放x轴的数据
  23. ydata = [],
  24. yAxis: any[] = [], // 存放图表y轴样式、数据
  25. colors: string[] = [], // 存放每个图表系列的颜色
  26. legends: string[] = [], // 存放每个图表系列的名字
  27. series: any[] = []; // 存放每个图表系列的样式
  28. let xAxis: any[] = [], //存放图表x轴样式、数据
  29. timeline: any = null, //
  30. grid = {},
  31. tooltip = {},
  32. dataZoom: any = null; //进度条
  33. const columns = JSON.parse(JSON.stringify(chartColumns));
  34. columns.forEach((column: any) => {
  35. const ylist = [];
  36. if (type == 'detail' || type == 'history') {
  37. column.linetype = 'line';
  38. }
  39. if (column.color) {
  40. colors.push(column.color); //获取每个图表系列的颜色
  41. }
  42. // ydata.push(ylist);
  43. /** 获取静态文件配置的图表样式信息 */
  44. if (column.legend) {
  45. legends.push(column.legend + (column.yname ? '(' + column.yname + ')' : '')); //获取每个图表系列的名字
  46. }
  47. series.push(this.getSeries(column, ylist)); //获取每个图表系列的样式
  48. if (column.seriesName || column.seriesName == undefined) {
  49. yAxis.push(this.getYAxis(column));
  50. }
  51. });
  52. /* 如果是历史记录的话需要添加进度条 */
  53. grid = this.getGrid(yAxis, type);
  54. // timeline = this.getTimeline(xdata, ydata);
  55. tooltip = this.getTooltip();
  56. // debugger;
  57. xAxis = merge(this.getXAxis(xdata, series, type), [{ ...this.option.xAxis }]);
  58. dataZoom = this.getDataZoom(type);
  59. if (this.option) {
  60. if (!this.option['tooltip']) this.option['tooltip'] = {};
  61. Object.assign(this.option['tooltip'], tooltip);
  62. // this.option['tooltip'] = tooltip;
  63. this.option['grid'] = grid;
  64. // this.option['legend'] = this.getLegend(legends);
  65. if (!this.option['legend']) this.option['legend'] = {};
  66. Object.assign(this.option['legend'], this.getLegend(legends));
  67. this.option['xAxis'] = xAxis;
  68. this.option['yAxis'] = yAxis;
  69. this.option['series'] = series;
  70. this.option['dataZoom'] = dataZoom;
  71. }
  72. }
  73. getDataZoom(type) {
  74. if (type == 'history') {
  75. return [
  76. {
  77. bottom: '0px',
  78. height: 20,
  79. start: 100,
  80. end: 0,
  81. textStyle: {
  82. color: '#ffffff',
  83. },
  84. },
  85. ];
  86. } else if (type == 'listMonitor' || type == 'detail') {
  87. return {
  88. start: 0,
  89. type: 'inside',
  90. };
  91. }
  92. return null;
  93. }
  94. getLegend(legend) {
  95. const legendObj = {
  96. textStyle: {
  97. color: '#ffffff', // 字体颜色
  98. },
  99. data: legend,
  100. top: '20',
  101. };
  102. return legendObj;
  103. }
  104. getXAxis(xdata, series, type) {
  105. let rotate = 0;
  106. const isHasBar = series.findIndex((item) => {
  107. if (item.xRotate != undefined) rotate = item.xRotate;
  108. return item.type == 'bar';
  109. });
  110. const xAxis = [
  111. {
  112. type: 'category',
  113. axisTick: {
  114. alignWithLabel: true,
  115. },
  116. axisLine: {
  117. lineStyle: {
  118. color: '#006c9d',
  119. width: 1, // 这里是为了突出显示加上的
  120. },
  121. },
  122. splitLine: { show: true, lineStyle: { color: 'rgba(21,80,126,.3)', type: 'dashed' } },
  123. axisLabel: {
  124. show: true,
  125. color: '#ffffffbb',
  126. // interval: 0,
  127. rotate: rotate,
  128. formatter: function (params) {
  129. let newParamsName = '';
  130. const paramsNameNumber = params.length;
  131. const provideNumber = 10; // 单行显示文字个数
  132. const rowNumber = Math.ceil(paramsNameNumber / provideNumber);
  133. if (paramsNameNumber > provideNumber) {
  134. for (let p = 0; p < rowNumber; p++) {
  135. let tempStr = '';
  136. const start = p * provideNumber;
  137. const end = start + provideNumber;
  138. if (p === rowNumber - 1) {
  139. tempStr = params.substring(start, paramsNameNumber);
  140. } else {
  141. tempStr = params.substring(start, end) + '\n';
  142. }
  143. newParamsName += tempStr;
  144. }
  145. } else {
  146. newParamsName = params;
  147. }
  148. return newParamsName;
  149. },
  150. },
  151. axisPointer: {
  152. type: isHasBar > -1 ? 'shadow' : 'line',
  153. shadowStyle: {
  154. color: 'rgba(0,0,0,0.1)',
  155. },
  156. },
  157. // prettier-ignore
  158. data: xdata,
  159. },
  160. ];
  161. return xAxis;
  162. }
  163. getYAxis(item) {
  164. const yAxisobj = {
  165. type: 'value',
  166. name: item.seriesName ? item.seriesName : item.legend,
  167. min: 0,
  168. max: item.ymax,
  169. position: item.yaxispos ? item.yaxispos : 'right',
  170. offset: item.yaxispos == 'right' ? (item.sort - 2) * 60 : 0,
  171. alignTicks: true,
  172. axisLine: {
  173. show: true,
  174. lineStyle: {
  175. color: '#006c9d',
  176. },
  177. },
  178. axisLabel: {
  179. show: true,
  180. color: '#ffffffcc',
  181. formatter: function (value) {
  182. if (typeof value === 'number' && /[\.]/.test(value)) {
  183. return Math.round(value * 100) / 100;
  184. } else {
  185. return value;
  186. }
  187. },
  188. },
  189. splitLine: {
  190. lineStyle: {
  191. color: 'rgba(21,80,126,.3)',
  192. type: 'dashed', //设置网格线类型 dotted:虚线 solid:实线
  193. },
  194. // show: item.linetype == 'line' ? true : false,
  195. show: true,
  196. },
  197. showBackground: true,
  198. backgroundStyle: {
  199. color: 'rgba(205, 95, 255, 1)',
  200. },
  201. };
  202. return yAxisobj;
  203. }
  204. getSeries(item, ylist) {
  205. const seriesObj = {
  206. name: item.legend + (item.yname ? '(' + item.yname + ')' : ''),
  207. type: item.linetype,
  208. yAxisIndex: item.sort - 1,
  209. barCategoryGap: '30%',
  210. showSymbol: false,
  211. data: [...ylist],
  212. barMaxWidth: '20',
  213. itemStyle: {
  214. color:
  215. item.linetype == 'bar'
  216. ? new echarts.graphic.LinearGradient(0, 0, 0, 1, [
  217. {
  218. offset: 0,
  219. color: item.color + 'ff',
  220. },
  221. {
  222. offset: 1,
  223. color: item.color + '33',
  224. },
  225. ])
  226. : item.color,
  227. borderRadius: [15, 15, 0, 0],
  228. },
  229. lineStyle: {
  230. shadowColor: '#ffffff99',
  231. shadowBlur: 3,
  232. },
  233. smooth: true,
  234. };
  235. return seriesObj;
  236. }
  237. getGrid(yAxis, type) {
  238. if (!this.option.grid) {
  239. let rightnum = 0,
  240. leftnum = 0;
  241. yAxis.forEach((item) => {
  242. if (item.position == 'right') {
  243. ++rightnum;
  244. } else if (item.position == 'left') {
  245. ++leftnum;
  246. }
  247. });
  248. const grid = {
  249. top: '60px',
  250. bottom: type == 'history' ? '40px' : '15px',
  251. right: rightnum * 30 + 20 + 'px',
  252. left: leftnum * 40 + 'px',
  253. containLabel: true,
  254. };
  255. return grid;
  256. } else {
  257. return this.option.grid;
  258. }
  259. }
  260. getTooltip() {
  261. const tooltip = {
  262. backgroundColor: '#00000005',
  263. borderColor: '#74E9FE44',
  264. extraCssText: 'backdrop-filter: blur(15px); box-shadow: 0 0 0 rgba(0, 0, 0, 0);',
  265. textStyle: {
  266. color: '#ffffff', // 字体颜色
  267. },
  268. trigger: 'axis',
  269. axisPointer: {
  270. label: {
  271. backgroundColor: 'rgba(30,120,50,0.8)',
  272. },
  273. type: 'cross',
  274. },
  275. };
  276. return tooltip;
  277. }
  278. // 分页显示数据
  279. getTimeline(xdata, ydata) {
  280. // 结合x、y轴的数据量判断是否要分页(x轴分页)ydata长度的倍数就是X轴要显示的数量n
  281. const n = Math.floor(20 / ydata.length);
  282. const size = Math.ceil(xdata.length / n); //分页数量
  283. if (size > 2) {
  284. // 设置时间轴
  285. const timeline = {
  286. axisType: 'category',
  287. // realtime: false,
  288. // loop: false,
  289. autoPlay: true,
  290. // currentIndex: 2,
  291. playInterval: 1000,
  292. // controlStyle: {
  293. // position: 'left'
  294. // },
  295. data: [],
  296. };
  297. timeline.data = Array.from(new Array(size).keys());
  298. return timeline;
  299. } else {
  300. return null;
  301. }
  302. }
  303. }