BarSingle.vue 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329
  1. <template>
  2. <div ref="chartRef" :style="{ height, width }"></div>
  3. </template>
  4. <script lang="ts">
  5. import { defineComponent, PropType, ref, Ref, reactive, watchEffect, onMounted } from 'vue';
  6. import { useECharts } from '/@/hooks/web/useECharts';
  7. import { getTableHeaderColumns } from '/@/hooks/web/useWebColumns';
  8. import { merge } from 'lodash-es';
  9. export default defineComponent({
  10. name: 'BarAndLine',
  11. props: {
  12. chartsColumns: {
  13. type: Array,
  14. default: () => [],
  15. },
  16. chartsColumnsType: {
  17. type: String,
  18. },
  19. dataSource: {
  20. type: Object,
  21. default: () => {},
  22. },
  23. xAxisData: {
  24. type: Array,
  25. default: () => [],
  26. },
  27. width: {
  28. type: String as PropType<string>,
  29. default: '100%',
  30. },
  31. height: {
  32. type: String as PropType<string>,
  33. default: '100%',
  34. },
  35. option: {
  36. type: Object,
  37. default: () => ({}),
  38. },
  39. color: {
  40. type: Array,
  41. default: () => [],
  42. },
  43. fontColor: {
  44. type: Array,
  45. default: () => [],
  46. },
  47. },
  48. setup(props) {
  49. const chartRef = ref<HTMLDivElement | null>(null);
  50. const { setOptions, echarts } = useECharts(chartRef as Ref<HTMLDivElement>);
  51. const chartData = getTableHeaderColumns(props.chartsColumnsType) || [];
  52. const chartsColumns: [] = props.chartsColumns.length > 0 ? props.chartsColumns : chartData;
  53. const colors =
  54. props.color.length > 0
  55. ? props.color
  56. : [
  57. [
  58. { offset: 0.5, color: 'rgba(14, 159, 255, 1)' },
  59. { offset: 0.6, color: 'rgba(97, 199, 252, 0.8)' },
  60. { offset: 1, color: 'rgba(97, 199, 252, 0.08)' },
  61. ],
  62. [
  63. { offset: 0.5, color: 'rgba(137, 163, 164, 1)' },
  64. { offset: 1, color: 'rgba(137, 163, 164, 0.8)' },
  65. { offset: 1, color: 'rgba(137, 163, 164, 0.08)' },
  66. ],
  67. [
  68. { offset: 0.5, color: 'rgba(44, 166, 166, 1)' },
  69. { offset: 1, color: 'rgba(44, 166, 166, 0.8)' },
  70. { offset: 1, color: 'rgba(44, 166, 166, 0.08)' },
  71. ],
  72. [
  73. { offset: 0.5, color: 'rgba(34, 66, 186, 1)' },
  74. { offset: 1, color: 'rgba(34, 66, 186, 0.8)' },
  75. { offset: 1, color: 'rgba(34, 66, 186, 0.08)' },
  76. ],
  77. [
  78. { offset: 0.5, color: 'rgba(34, 66, 186, 1)' },
  79. { offset: 1, color: 'rgba(34, 66, 186, 0.8)' },
  80. { offset: 1, color: 'rgba(34, 66, 186, 0.08)' },
  81. ],
  82. ];
  83. const option = reactive(
  84. merge(
  85. {
  86. grid: {
  87. top: '60px',
  88. bottom: 10,
  89. right: 20,
  90. left: 10,
  91. containLabel: true,
  92. },
  93. xAxis: {
  94. offset: 8,
  95. axisLine: {
  96. show: true,
  97. lineStyle: {
  98. color: '#006c9d',
  99. },
  100. },
  101. axisLabel: {
  102. color: '#ffffff',
  103. },
  104. axisTick: {
  105. show: false,
  106. },
  107. splitLine: {
  108. lineStyle: {
  109. color: 'rgba(21,80,126,.3)',
  110. type: 'dashed', //设置网格线类型 dotted:虚线 solid:实线
  111. },
  112. show: true,
  113. },
  114. showBackground: true,
  115. backgroundStyle: {
  116. color: 'rgba(205, 95, 255, 1)',
  117. },
  118. data: [],
  119. },
  120. yAxis: {
  121. type: 'value',
  122. alignTicks: true,
  123. axisLine: {
  124. show: true,
  125. lineStyle: {
  126. color: '#006c9d',
  127. },
  128. },
  129. axisLabel: {
  130. show: true,
  131. color: '#ffffff',
  132. // formatter: '{value}' + item.yname
  133. },
  134. interval: 1,
  135. min: 0,
  136. splitLine: {
  137. lineStyle: {
  138. color: 'rgba(21,80,126,.3)',
  139. type: 'dashed', //设置网格线类型 dotted:虚线 solid:实线
  140. },
  141. // show: item.linetype == 'line' ? true : false,
  142. show: true,
  143. },
  144. showBackground: true,
  145. backgroundStyle: {
  146. color: 'rgba(205, 95, 255, 1)',
  147. },
  148. },
  149. series: [],
  150. },
  151. props.option
  152. )
  153. );
  154. if (props.option) {
  155. merge(option, props.option);
  156. }
  157. watchEffect(() => {
  158. props.dataSource && option.series && initCharts();
  159. });
  160. function initDta(xData: string[], yData: number[], ymax?) {
  161. // 设置顶部和底部的值
  162. let symbolData: number[] = [],
  163. newShadowHight: number[] = [];
  164. if (!ymax) ymax = Math.max(...yData);
  165. yData.forEach(() => {
  166. symbolData.push(1);
  167. newShadowHight.push(ymax);
  168. });
  169. var color = '#fff';
  170. option.xAxis.data = xData as never[];
  171. option.series = [
  172. // 底部
  173. {
  174. z: 2,
  175. type: 'pictorialBar',
  176. symbol: 'diamond',
  177. symbolOffset: ['0%', '50%'],
  178. symbolSize: [30, 12],
  179. toolltip: {
  180. show: false,
  181. },
  182. itemStyle: {
  183. color: function (params) {
  184. return colors[params.dataIndex][1].color;
  185. },
  186. },
  187. data: symbolData, // [1,1,1,1,1]
  188. },
  189. // 内容区域
  190. {
  191. z: 1,
  192. type: 'bar',
  193. barWidth: 30,
  194. // name: legendData[0].name,
  195. itemStyle: {
  196. color: function (params) {
  197. return new echarts.graphic.LinearGradient(0, 0, 0, 1, [
  198. {
  199. offset: 0,
  200. // @ts-ignore
  201. color: colors[params.dataIndex][1].color,
  202. },
  203. {
  204. offset: 1,
  205. color: colors[params.dataIndex][2].color,
  206. },
  207. ]);
  208. },
  209. },
  210. label: {
  211. show: true, //开启显示
  212. position: 'top', //在上方显示
  213. // formatter: '{c}%',//显示百分号
  214. textStyle: {
  215. //数值样式
  216. // color: function (params) {
  217. // return props.fontColor.length > params ? props.fontColor[params.dataIndex] : '#fff';
  218. // },
  219. color: color,
  220. fontSize: 13, //字体大小
  221. },
  222. },
  223. data: yData,
  224. },
  225. // 内容的顶部
  226. {
  227. z: 3,
  228. type: 'pictorialBar',
  229. symbol: 'diamond',
  230. symbolPosition: 'end',
  231. symbolOffset: ['0%', '-50%'],
  232. symbolSize: [30, 12],
  233. toolltip: {
  234. show: false,
  235. },
  236. itemStyle: {
  237. color: function (params) {
  238. color = colors[params.dataIndex][1].color;
  239. return colors[params.dataIndex][0].color;
  240. },
  241. },
  242. data: yData,
  243. },
  244. // 阴影区域
  245. {
  246. z: 0,
  247. type: 'bar',
  248. barWidth: 30,
  249. barGap: '-100%',
  250. data: newShadowHight,
  251. itemStyle: {
  252. color: '#00365F66',
  253. },
  254. },
  255. // 阴影的顶部
  256. {
  257. z: 3,
  258. type: 'pictorialBar',
  259. symbol: 'diamond',
  260. symbolPosition: 'end',
  261. symbolOffset: ['0%', '-50%'],
  262. symbolSize: [30, 12],
  263. toolltip: {
  264. show: false,
  265. },
  266. itemStyle: {
  267. color: '#00365F66',
  268. },
  269. data: newShadowHight,
  270. },
  271. ] as never[];
  272. }
  273. function initCharts() {
  274. //轴数据
  275. if (option.series) {
  276. const xAxisData: any[] = [];
  277. const series: any[] = [];
  278. const seriesData: any[] = [];
  279. // const legendData: { name: string, itemStyle: Object }[] = [];
  280. let ymax = 0;
  281. props.xAxisData.forEach((item: any, index) => {
  282. xAxisData.push(item['key']);
  283. // seriesData.push(props.dataSource[item.valueKey] || '');
  284. seriesData.push(props.dataSource[item.valueKey]);
  285. });
  286. for (let i = 0; i < chartsColumns.length; i++) {
  287. const item: any = chartsColumns[i];
  288. // legendData.push({
  289. // name: item.legend + (item.yname ? '(' + item.yname + ')' : ''),
  290. // itemStyle: {
  291. // color: new echarts.graphic.LinearGradient(1, 0, 0, 0, colors[i]),
  292. // },
  293. // })
  294. if (!ymax && item['ymax']) {
  295. ymax = item['ymax'];
  296. }
  297. }
  298. // option.legend.data = legendData
  299. // option.series[0].data = seriesData;
  300. // option.series = series;
  301. // option.xAxis.data = xAxisData;
  302. initDta(xAxisData, seriesData);
  303. console.log('option------------->', option);
  304. setOptions(option, false);
  305. }
  306. }
  307. return { chartRef };
  308. },
  309. });
  310. </script>