echartsUtil.ts 9.4 KB

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