BarSingle.vue 8.4 KB

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