widgetLineStackChart.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480
  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. };
  115. title.subtext = optionsSetup.subText;
  116. title.subtextStyle = {
  117. color: optionsSetup.subTextColor,
  118. fontWeight: optionsSetup.subTextFontWeight,
  119. fontSize: optionsSetup.subTextFontSize
  120. };
  121. this.options.title = title;
  122. },
  123. // X轴设置
  124. setOptionsX() {
  125. const optionsSetup = this.optionsSetup;
  126. const xAxis = {
  127. type: "category",
  128. // 坐标轴是否显示
  129. show: optionsSetup.hideX,
  130. // 坐标轴名称
  131. name: optionsSetup.xName,
  132. nameTextStyle: {
  133. color: optionsSetup.xNameColor,
  134. fontSize: optionsSetup.xNameFontSize
  135. },
  136. // 轴反转
  137. inverse: optionsSetup.reversalX,
  138. axisLabel: {
  139. show: true,
  140. // 文字间隔
  141. interval: optionsSetup.textInterval,
  142. // 文字角度
  143. rotate: optionsSetup.textAngleX,
  144. textStyle: {
  145. // 坐标文字颜色
  146. color: optionsSetup.Xcolor,
  147. fontSize: optionsSetup.fontSizeX
  148. }
  149. },
  150. axisLine: {
  151. show: true,
  152. lineStyle: {
  153. color: optionsSetup.lineColorX
  154. }
  155. },
  156. splitLine: {
  157. show: optionsSetup.isShowSplitLineX,
  158. lineStyle: {
  159. color: optionsSetup.splitLineColorX
  160. }
  161. }
  162. };
  163. this.options.xAxis = xAxis;
  164. },
  165. // Y轴设置
  166. setOptionsY() {
  167. const optionsSetup = this.optionsSetup;
  168. const yAxis = {
  169. type: "value",
  170. // 坐标轴是否显示
  171. show: optionsSetup.isShowY,
  172. // 坐标轴名称
  173. name: optionsSetup.textNameY,
  174. nameTextStyle: {
  175. color: optionsSetup.NameColorY,
  176. fontSize: optionsSetup.NameFontSizeY
  177. },
  178. // y轴反转
  179. inverse: optionsSetup.reversalY,
  180. axisLabel: {
  181. show: true,
  182. // 文字角度
  183. rotate: optionsSetup.textAngleY,
  184. textStyle: {
  185. // y轴 坐标文字颜色
  186. color: optionsSetup.colorY,
  187. fontSize: optionsSetup.fontSizeY
  188. }
  189. },
  190. axisLine: {
  191. show: true,
  192. lineStyle: {
  193. color: optionsSetup.lineColorY
  194. }
  195. },
  196. splitLine: {
  197. show: optionsSetup.isShowSplitLineY,
  198. lineStyle: {
  199. color: optionsSetup.splitLineColorY
  200. }
  201. }
  202. };
  203. this.options.yAxis = yAxis;
  204. },
  205. // 获取面积
  206. getOptionArea() {
  207. const optionsSetup = this.optionsSetup;
  208. let areaStyle = [];
  209. if (optionsSetup.area) {
  210. areaStyle = {
  211. opacity: optionsSetup.areaThickness / 100
  212. }
  213. } else {
  214. areaStyle = {
  215. opacity: 0
  216. }
  217. }
  218. return areaStyle
  219. },
  220. // tooltip 提示语设置,鼠标放置显示
  221. setOptionsTooltip() {
  222. const optionsSetup = this.optionsSetup;
  223. const tooltip = {
  224. trigger: "item",
  225. show: true,
  226. textStyle: {
  227. color: optionsSetup.lineColor,
  228. fontSize: optionsSetup.tipsFontSize
  229. }
  230. };
  231. this.options.tooltip = tooltip;
  232. },
  233. // 边距设置
  234. setOptionsMargin() {
  235. const optionsSetup = this.optionsSetup;
  236. const grid = {
  237. left: optionsSetup.marginLeft,
  238. right: optionsSetup.marginRight,
  239. bottom: optionsSetup.marginBottom,
  240. top: optionsSetup.marginTop,
  241. containLabel: true
  242. };
  243. this.options.grid = grid;
  244. },
  245. // 图例操作 legend
  246. setOptionsLegend() {
  247. const optionsSetup = this.optionsSetup;
  248. const legend = this.options.legend;
  249. legend.show = optionsSetup.isShowLegend;
  250. legend.left = optionsSetup.lateralPosition;
  251. legend.top = optionsSetup.longitudinalPosition;
  252. legend.bottom =
  253. optionsSetup.longitudinalPosition;
  254. legend.orient = optionsSetup.layoutFront;
  255. legend.textStyle = {
  256. color: optionsSetup.lengedColor,
  257. fontSize: optionsSetup.lengedFontSize
  258. };
  259. legend.itemWidth = optionsSetup.lengedWidth;
  260. },
  261. // 图例名称设置
  262. setOptionsLegendName(name){
  263. const optionsSetup = this.optionsSetup;
  264. const series = this.options.series;
  265. const legendName = optionsSetup.legendName;
  266. // 图例没有手动写则显示原值,写了则显示新值
  267. if (null == legendName || legendName == '') {
  268. for (let i = 0; i < name.length; i++) {
  269. series[i].name = name[i];
  270. }
  271. this.options.legend['data'] = name;
  272. }else {
  273. const arr = legendName.split('|');
  274. for (let i = 0; i < arr.length; i++) {
  275. series[i].name = arr[i];
  276. }
  277. this.options.legend['data'] = arr
  278. }
  279. },
  280. // 图例颜色修改
  281. setOptionsColor() {
  282. const optionsCollapse = this.optionsSetup;
  283. const customColor = optionsCollapse.customColor;
  284. if (!customColor) return;
  285. const arrColor = [];
  286. for (let i = 0; i < customColor.length; i++) {
  287. arrColor.push(customColor[i].color);
  288. }
  289. this.options.color = arrColor;
  290. this.options = Object.assign({}, this.options);
  291. },
  292. // 数据解析
  293. setOptionsData() {
  294. const optionsSetup = this.optionsSetup;
  295. // 数据类型 静态 or 动态
  296. const optionsData = this.optionsData;
  297. optionsData.dataType == "staticData"
  298. ? this.staticDataFn(optionsData.staticData, optionsSetup)
  299. : this.dynamicDataFn(
  300. optionsData.dynamicData,
  301. optionsData.refreshTime,
  302. optionsSetup
  303. );
  304. },
  305. //去重
  306. setUnique(arr) {
  307. let newArr = [];
  308. arr.forEach(item => {
  309. return newArr.includes(item) ? '' : newArr.push(item);
  310. });
  311. return newArr;
  312. },
  313. //静态数据
  314. staticDataFn(val) {
  315. const optionsSetup = this.optionsSetup;
  316. //颜色
  317. const customColor = optionsSetup.customColor;
  318. const arrColor = [];
  319. for (let i = 0; i < customColor.length; i++) {
  320. arrColor.push(customColor[i].color);
  321. }
  322. //数据
  323. const series = [];
  324. let xAxisList = [];
  325. let yAxisList = [];
  326. const legendName = [];
  327. for (const i in val) {
  328. xAxisList[i] = val[i].axis;
  329. yAxisList[i] = val[i].name;
  330. }
  331. xAxisList = this.setUnique(xAxisList);
  332. yAxisList = this.setUnique(yAxisList);
  333. for (const i in yAxisList) {
  334. const data = new Array(yAxisList.length).fill(0);
  335. for (const j in xAxisList) {
  336. for (const k in val) {
  337. if (val[k].name == yAxisList[i]) {
  338. if (val[k].axis == xAxisList[j]) {
  339. data[j] = val[k].data;
  340. }
  341. }
  342. }
  343. }
  344. series.push({
  345. name: yAxisList[i],
  346. type: "line",
  347. data: data,
  348. width: optionsSetup.lineWidth,
  349. symbol: 'circle',
  350. showSymbol: optionsSetup.markPoint,
  351. symbolSize: optionsSetup.pointSize,
  352. smooth: optionsSetup.smoothCurve,
  353. // 线条
  354. lineStyle: {
  355. color: arrColor[i],
  356. width: optionsSetup.lineWidth,
  357. },
  358. //点
  359. itemStyle: {
  360. color: arrColor[i],
  361. },
  362. areaStyle: this.getOptionArea(),
  363. //标题部分
  364. label: {
  365. show: optionsSetup.isShow,
  366. position: "top",
  367. distance: 10,
  368. fontSize: optionsSetup.fontSize,
  369. color: optionsSetup.subTextColor,
  370. fontWeight: optionsSetup.fontWeight,
  371. },
  372. })
  373. legendName.push(yAxisList[i]);
  374. }
  375. this.options.series = series;
  376. if (optionsSetup.verticalShow) {
  377. this.options.xAxis.data = [];
  378. this.options.yAxis.data = xAxisList;
  379. this.options.xAxis.type = "value";
  380. this.options.yAxis.type = "category";
  381. } else {
  382. this.options.xAxis.data = xAxisList;
  383. this.options.yAxis.data = [];
  384. this.options.xAxis.type = "category";
  385. this.options.yAxis.type = "value";
  386. }
  387. this.options.legend['data'] = legendName;
  388. this.setOptionsLegendName(legendName);
  389. },
  390. // 动态数据
  391. dynamicDataFn(val, refreshTime, optionsSetup) {
  392. if (!val) return;
  393. if (this.ispreview) {
  394. this.getEchartData(val, optionsSetup);
  395. this.flagInter = setInterval(() => {
  396. this.getEchartData(val, optionsSetup);
  397. }, refreshTime);
  398. } else {
  399. this.getEchartData(val, optionsSetup);
  400. }
  401. },
  402. getEchartData(val, optionsSetup) {
  403. const data = this.queryEchartsData(val);
  404. data.then(res => {
  405. this.renderingFn(optionsSetup, res);
  406. });
  407. },
  408. renderingFn(optionsSetup, val) {
  409. //颜色
  410. const customColor = optionsSetup.customColor;
  411. const arrColor = [];
  412. for (let i = 0; i < customColor.length; i++) {
  413. arrColor.push(customColor[i].color);
  414. }
  415. // x轴
  416. if (optionsSetup.verticalShow) {
  417. this.options.xAxis.data = [];
  418. this.options.yAxis.data = val.xAxis;
  419. this.options.xAxis.type = "value";
  420. this.options.yAxis.type = "category";
  421. } else {
  422. this.options.xAxis.data = val.xAxis;
  423. this.options.yAxis.data = [];
  424. this.options.xAxis.type = "category";
  425. this.options.yAxis.type = "value";
  426. }
  427. const series = [];
  428. const legendName = [];
  429. for (const i in val.series) {
  430. if (val.series[i].type == "line") {
  431. series.push({
  432. name: val.series[i].name,
  433. type: "line",
  434. data: val.series[i].data,
  435. width: optionsSetup.lineWidth,
  436. symbol: 'circle',
  437. showSymbol: optionsSetup.markPoint,
  438. symbolSize: optionsSetup.pointSize,
  439. symbolColor: arrColor[i],
  440. smooth: optionsSetup.smoothCurve,
  441. // 线条
  442. lineStyle: {
  443. color: arrColor[i],
  444. width: optionsSetup.lineWidth,
  445. },
  446. //点
  447. itemStyle: {
  448. color: arrColor[i],
  449. },
  450. areaStyle: this.getOptionArea(),
  451. // 标题部分
  452. label: {
  453. show: optionsSetup.isShow,
  454. position: "top",
  455. distance: 10,
  456. fontSize: optionsSetup.fontSize,
  457. color: optionsSetup.subTextColor,
  458. fontWeight: optionsSetup.fontWeight,
  459. },
  460. })
  461. }
  462. legendName.push(val.series[i].name);
  463. }
  464. this.options.series = series;
  465. this.options.legend['data'] = legendName;
  466. this.setOptionsLegendName(legendName);
  467. }
  468. }
  469. };
  470. </script>
  471. <style scoped lang="scss">
  472. .echarts {
  473. width: 100%;
  474. height: 100%;
  475. overflow: hidden;
  476. }
  477. </style>