widgetLineStackChart.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489
  1. <template>
  2. <div :style="styleObj">
  3. <v-chart :options="options" autoresize/>
  4. </div>
  5. </template>
  6. <script>
  7. export default {
  8. name: "WidgetBarStackchart",
  9. components: {},
  10. props: {
  11. value: Object,
  12. ispreview: Boolean
  13. },
  14. data() {
  15. return {
  16. options: {
  17. grid: {},
  18. legend: {
  19. textStyle: {
  20. color: "#fff"
  21. }
  22. },
  23. xAxis: {
  24. type: "category",
  25. data: [],
  26. axisLabel: {
  27. show: true,
  28. textStyle: {
  29. color: "#fff"
  30. }
  31. }
  32. },
  33. yAxis: {
  34. type: "value",
  35. data: [],
  36. axisLabel: {
  37. show: true,
  38. textStyle: {
  39. color: "#fff"
  40. }
  41. }
  42. },
  43. series: [
  44. {
  45. data: [],
  46. name: '',
  47. type: "line",
  48. barGap: "0%",
  49. itemStyle: {
  50. barBorderRadius: null
  51. }
  52. }
  53. ]
  54. },
  55. optionsStyle: {}, // 样式
  56. optionsData: {}, // 数据
  57. optionsSetup: {},
  58. flagInter: null
  59. };
  60. },
  61. computed: {
  62. styleObj() {
  63. return {
  64. position: this.ispreview ? "absolute" : "static",
  65. width: this.optionsStyle.width + "px",
  66. height: this.optionsStyle.height + "px",
  67. left: this.optionsStyle.left + "px",
  68. top: this.optionsStyle.top + "px",
  69. background: this.optionsSetup.background
  70. };
  71. }
  72. },
  73. watch: {
  74. value: {
  75. handler(val) {
  76. this.optionsStyle = val.position;
  77. this.optionsData = val.data;
  78. this.optionsCollapse = val.setup;
  79. this.optionsSetup = val.setup;
  80. this.editorOptions();
  81. },
  82. deep: true
  83. }
  84. },
  85. mounted() {
  86. this.optionsStyle = this.value.position;
  87. this.optionsData = this.value.data;
  88. this.optionsCollapse = this.value.setup;
  89. this.optionsSetup = this.value.setup;
  90. this.editorOptions();
  91. },
  92. methods: {
  93. // 修改图标options属性
  94. editorOptions() {
  95. this.setOptionsTitle();
  96. this.setOptionsX();
  97. this.setOptionsY();
  98. this.setOptionsTooltip();
  99. this.setOptionsMargin();
  100. this.setOptionsLegend();
  101. this.setOptionsData();
  102. },
  103. // 标题修改
  104. setOptionsTitle() {
  105. const optionsSetup = this.optionsSetup;
  106. const title = {};
  107. title.text = optionsSetup.titleText;
  108. title.show = optionsSetup.isNoTitle;
  109. title.left = optionsSetup.textAlign;
  110. title.textStyle = {
  111. color: optionsSetup.textColor,
  112. fontSize: optionsSetup.textFontSize,
  113. fontWeight: optionsSetup.textFontWeight,
  114. fontStyle: optionsSetup.textFontStyle,
  115. };
  116. title.subtext = optionsSetup.subText;
  117. title.subtextStyle = {
  118. color: optionsSetup.subTextColor,
  119. fontWeight: optionsSetup.subTextFontWeight,
  120. fontSize: optionsSetup.subTextFontSize,
  121. fontStyle: optionsSetup.subTextFontStyle,
  122. };
  123. this.options.title = title;
  124. },
  125. // X轴设置
  126. setOptionsX() {
  127. const optionsSetup = this.optionsSetup;
  128. const xAxis = {
  129. type: "category",
  130. // 坐标轴是否显示
  131. show: optionsSetup.hideX,
  132. // 坐标轴名称
  133. name: optionsSetup.nameX,
  134. nameTextStyle: {
  135. color: optionsSetup.nameColorX,
  136. fontSize: optionsSetup.nameFontSizeX
  137. },
  138. // 轴反转
  139. inverse: optionsSetup.reversalX,
  140. axisLabel: {
  141. show: true,
  142. // 文字间隔
  143. interval: optionsSetup.textInterval,
  144. // 文字角度
  145. rotate: optionsSetup.textAngleX,
  146. textStyle: {
  147. // 坐标文字颜色
  148. color: optionsSetup.colorX,
  149. fontSize: optionsSetup.fontSizeX
  150. }
  151. },
  152. axisLine: {
  153. show: true,
  154. lineStyle: {
  155. color: optionsSetup.lineColorX,
  156. width: optionsSetup.lineWidthX,
  157. }
  158. },
  159. splitLine: {
  160. show: optionsSetup.isShowSplitLineX,
  161. lineStyle: {
  162. color: optionsSetup.splitLineColorX,
  163. width: optionsSetup.splitLineWidthX,
  164. }
  165. }
  166. };
  167. this.options.xAxis = xAxis;
  168. },
  169. // Y轴设置
  170. setOptionsY() {
  171. const optionsSetup = this.optionsSetup;
  172. const yAxis = {
  173. type: "value",
  174. scale: optionsSetup.scale,
  175. // 均分
  176. splitNumber: optionsSetup.splitNumberY,
  177. // 坐标轴是否显示
  178. show: optionsSetup.isShowY,
  179. // 坐标轴名称
  180. name: optionsSetup.textNameY,
  181. nameTextStyle: {
  182. color: optionsSetup.nameColorY,
  183. fontSize: optionsSetup.nameFontSizeY
  184. },
  185. // 轴反转
  186. inverse: optionsSetup.reversalY,
  187. axisLabel: {
  188. show: true,
  189. // 文字角度
  190. rotate: optionsSetup.textAngleY,
  191. textStyle: {
  192. // 坐标文字颜色
  193. color: optionsSetup.colorY,
  194. fontSize: optionsSetup.fontSizeY
  195. }
  196. },
  197. axisLine: {
  198. show: true,
  199. lineStyle: {
  200. color: optionsSetup.lineColorY,
  201. width: optionsSetup.lineWidthY,
  202. }
  203. },
  204. splitLine: {
  205. show: optionsSetup.isShowSplitLineY,
  206. lineStyle: {
  207. color: optionsSetup.splitLineColorY,
  208. width: optionsSetup.splitLineWidthY,
  209. }
  210. }
  211. };
  212. this.options.yAxis = yAxis;
  213. },
  214. // 获取面积
  215. getOptionArea() {
  216. const optionsSetup = this.optionsSetup;
  217. let areaStyle = [];
  218. if (optionsSetup.area) {
  219. areaStyle = {
  220. opacity: optionsSetup.areaThickness / 100
  221. }
  222. } else {
  223. areaStyle = {
  224. opacity: 0
  225. }
  226. }
  227. return areaStyle
  228. },
  229. // tooltip 提示语设置,鼠标放置显示
  230. setOptionsTooltip() {
  231. const optionsSetup = this.optionsSetup;
  232. const tooltip = {
  233. trigger: "item",
  234. show: true,
  235. textStyle: {
  236. color: optionsSetup.tipsColor,
  237. fontSize: optionsSetup.tipsFontSize
  238. }
  239. };
  240. this.options.tooltip = tooltip;
  241. },
  242. // 边距设置
  243. setOptionsMargin() {
  244. const optionsSetup = this.optionsSetup;
  245. const grid = {
  246. left: optionsSetup.marginLeft,
  247. right: optionsSetup.marginRight,
  248. bottom: optionsSetup.marginBottom,
  249. top: optionsSetup.marginTop,
  250. containLabel: true
  251. };
  252. this.options.grid = grid;
  253. },
  254. // 图例操作 legend
  255. setOptionsLegend() {
  256. const optionsSetup = this.optionsSetup;
  257. const legend = this.options.legend;
  258. legend.show = optionsSetup.isShowLegend;
  259. legend.left = optionsSetup.lateralPosition;
  260. legend.top = optionsSetup.longitudinalPosition;
  261. legend.bottom =
  262. optionsSetup.longitudinalPosition;
  263. legend.orient = optionsSetup.layoutFront;
  264. legend.textStyle = {
  265. color: optionsSetup.legendColor,
  266. fontSize: optionsSetup.legendFontSize
  267. };
  268. legend.itemWidth = optionsSetup.legendWidth;
  269. },
  270. // 图例名称设置
  271. setOptionsLegendName(name) {
  272. const optionsSetup = this.optionsSetup;
  273. const series = this.options.series;
  274. const legendName = optionsSetup.legendName;
  275. // 图例没有手动写则显示原值,写了则显示新值
  276. if (null == legendName || legendName == '') {
  277. for (let i = 0; i < name.length; i++) {
  278. series[i].name = name[i];
  279. }
  280. this.options.legend['data'] = name;
  281. } else {
  282. const arr = legendName.split('|');
  283. for (let i = 0; i < arr.length; i++) {
  284. series[i].name = arr[i];
  285. }
  286. this.options.legend['data'] = arr
  287. }
  288. },
  289. // 图例颜色修改
  290. setOptionsColor() {
  291. const optionsCollapse = this.optionsSetup;
  292. const customColor = optionsCollapse.customColor;
  293. if (!customColor) return;
  294. const arrColor = [];
  295. for (let i = 0; i < customColor.length; i++) {
  296. arrColor.push(customColor[i].color);
  297. }
  298. this.options.color = arrColor;
  299. this.options = Object.assign({}, this.options);
  300. },
  301. // 数据解析
  302. setOptionsData() {
  303. const optionsSetup = this.optionsSetup;
  304. // 数据类型 静态 or 动态
  305. const optionsData = this.optionsData;
  306. optionsData.dataType == "staticData"
  307. ? this.staticDataFn(optionsData.staticData, optionsSetup)
  308. : this.dynamicDataFn(
  309. optionsData.dynamicData,
  310. optionsData.refreshTime,
  311. optionsSetup
  312. );
  313. },
  314. //去重
  315. setUnique(arr) {
  316. let newArr = [];
  317. arr.forEach(item => {
  318. return newArr.includes(item) ? '' : newArr.push(item);
  319. });
  320. return newArr;
  321. },
  322. //静态数据
  323. staticDataFn(val) {
  324. const optionsSetup = this.optionsSetup;
  325. //颜色
  326. const customColor = optionsSetup.customColor;
  327. const arrColor = [];
  328. for (let i = 0; i < customColor.length; i++) {
  329. arrColor.push(customColor[i].color);
  330. }
  331. //数据
  332. const series = [];
  333. let xAxisList = [];
  334. let yAxisList = [];
  335. const legendName = [];
  336. for (const i in val) {
  337. xAxisList[i] = val[i].axis;
  338. yAxisList[i] = val[i].name;
  339. }
  340. xAxisList = this.setUnique(xAxisList);
  341. yAxisList = this.setUnique(yAxisList);
  342. for (const i in yAxisList) {
  343. const data = new Array(xAxisList.length).fill(0);
  344. for (const j in xAxisList) {
  345. for (const k in val) {
  346. if (val[k].name == yAxisList[i]) {
  347. if (val[k].axis == xAxisList[j]) {
  348. data[j] = val[k].data;
  349. }
  350. }
  351. }
  352. }
  353. series.push({
  354. name: yAxisList[i],
  355. type: "line",
  356. data: data,
  357. width: optionsSetup.lineWidth,
  358. symbol: 'circle',
  359. showSymbol: optionsSetup.markPoint,
  360. symbolSize: optionsSetup.pointSize,
  361. smooth: optionsSetup.smoothCurve,
  362. // 线条
  363. lineStyle: {
  364. color: arrColor[i],
  365. width: optionsSetup.lineWidth,
  366. },
  367. //点
  368. itemStyle: {
  369. color: arrColor[i],
  370. },
  371. areaStyle: this.getOptionArea(),
  372. //标题部分
  373. label: {
  374. show: optionsSetup.isShow,
  375. position: "top",
  376. distance: 10,
  377. fontSize: optionsSetup.fontSize,
  378. color: optionsSetup.subTextColor,
  379. fontWeight: optionsSetup.fontWeight,
  380. },
  381. })
  382. legendName.push(yAxisList[i]);
  383. }
  384. this.options.series = series;
  385. if (optionsSetup.verticalShow) {
  386. this.options.xAxis.data = [];
  387. this.options.yAxis.data = xAxisList;
  388. this.options.xAxis.type = "value";
  389. this.options.yAxis.type = "category";
  390. } else {
  391. this.options.xAxis.data = xAxisList;
  392. this.options.yAxis.data = [];
  393. this.options.xAxis.type = "category";
  394. this.options.yAxis.type = "value";
  395. }
  396. this.options.legend['data'] = legendName;
  397. this.setOptionsLegendName(legendName);
  398. },
  399. // 动态数据
  400. dynamicDataFn(val, refreshTime, optionsSetup) {
  401. if (!val) return;
  402. if (this.ispreview) {
  403. this.getEchartData(val, optionsSetup);
  404. this.flagInter = setInterval(() => {
  405. this.getEchartData(val, optionsSetup);
  406. }, refreshTime);
  407. } else {
  408. this.getEchartData(val, optionsSetup);
  409. }
  410. },
  411. getEchartData(val, optionsSetup) {
  412. const data = this.queryEchartsData(val);
  413. data.then(res => {
  414. this.renderingFn(optionsSetup, res);
  415. });
  416. },
  417. renderingFn(optionsSetup, val) {
  418. //颜色
  419. const customColor = optionsSetup.customColor;
  420. const arrColor = [];
  421. for (let i = 0; i < customColor.length; i++) {
  422. arrColor.push(customColor[i].color);
  423. }
  424. // x轴
  425. if (optionsSetup.verticalShow) {
  426. this.options.xAxis.data = [];
  427. this.options.yAxis.data = val.xAxis;
  428. this.options.xAxis.type = "value";
  429. this.options.yAxis.type = "category";
  430. } else {
  431. this.options.xAxis.data = val.xAxis;
  432. this.options.yAxis.data = [];
  433. this.options.xAxis.type = "category";
  434. this.options.yAxis.type = "value";
  435. }
  436. const series = [];
  437. const legendName = [];
  438. for (const i in val.series) {
  439. if (val.series[i].type == "line") {
  440. series.push({
  441. name: val.series[i].name,
  442. type: "line",
  443. data: val.series[i].data,
  444. width: optionsSetup.lineWidth,
  445. symbol: 'circle',
  446. showSymbol: optionsSetup.markPoint,
  447. symbolSize: optionsSetup.pointSize,
  448. symbolColor: arrColor[i],
  449. smooth: optionsSetup.smoothCurve,
  450. // 线条
  451. lineStyle: {
  452. color: arrColor[i],
  453. width: optionsSetup.lineWidth,
  454. },
  455. //点
  456. itemStyle: {
  457. color: arrColor[i],
  458. },
  459. areaStyle: this.getOptionArea(),
  460. // 标题部分
  461. label: {
  462. show: optionsSetup.isShow,
  463. position: "top",
  464. distance: 10,
  465. fontSize: optionsSetup.fontSize,
  466. color: optionsSetup.subTextColor,
  467. fontWeight: optionsSetup.fontWeight,
  468. },
  469. })
  470. }
  471. legendName.push(val.series[i].name);
  472. }
  473. this.options.series = series;
  474. this.options.legend['data'] = legendName;
  475. this.setOptionsLegendName(legendName);
  476. }
  477. }
  478. };
  479. </script>
  480. <style scoped lang="scss">
  481. .echarts {
  482. width: 100%;
  483. height: 100%;
  484. overflow: hidden;
  485. }
  486. </style>