BarSingle.vue 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325
  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. splitLine: {
  130. lineStyle: {
  131. color: 'rgba(21,80,126,.3)',
  132. type: 'dashed', //设置网格线类型 dotted:虚线 solid:实线
  133. },
  134. // show: item.linetype == 'line' ? true : false,
  135. show: true,
  136. },
  137. showBackground: true,
  138. backgroundStyle: {
  139. color: 'rgba(205, 95, 255, 1)',
  140. },
  141. },
  142. series: []
  143. }, props.option));
  144. if (props.option) {
  145. merge(option, props.option)
  146. }
  147. watchEffect(() => {
  148. props.dataSource && option.series && initCharts();
  149. });
  150. function initDta(xData: string[], yData: number[], ymax?) {
  151. // 设置顶部和底部的值
  152. let symbolData: number[] = [], newShadowHight: number[] = []
  153. if(!ymax) ymax = Math.max(...yData)
  154. yData.forEach(() => {
  155. symbolData.push(1)
  156. newShadowHight.push(ymax)
  157. })
  158. var color = '#fff'
  159. option.xAxis.data = xData as never[]
  160. option.series = [
  161. // 底部
  162. {
  163. z: 2,
  164. type: 'pictorialBar',
  165. symbol: 'diamond',
  166. symbolOffset: ['0%', '50%'],
  167. symbolSize: [30, 12],
  168. toolltip: {
  169. show: false
  170. },
  171. itemStyle: {
  172. color: function (params) {
  173. return colors[params.dataIndex][1].color;
  174. },
  175. },
  176. data: symbolData, // [1,1,1,1,1]
  177. },
  178. // 内容区域
  179. {
  180. z: 1,
  181. type: 'bar',
  182. barWidth: 30,
  183. // name: legendData[0].name,
  184. itemStyle: {
  185. color: function (params) {
  186. return new echarts.graphic.LinearGradient(0, 0, 0, 1, [
  187. {
  188. offset: 0,
  189. // @ts-ignore
  190. color: colors[params.dataIndex][1].color,
  191. },
  192. {
  193. offset: 1,
  194. color: colors[params.dataIndex][2].color,
  195. },
  196. ]);
  197. },
  198. },
  199. label: {
  200. show: true, //开启显示
  201. position: 'top', //在上方显示
  202. // formatter: '{c}%',//显示百分号
  203. textStyle: { //数值样式
  204. // color: function (params) {
  205. // return props.fontColor.length > params ? props.fontColor[params.dataIndex] : '#fff';
  206. // },
  207. color: color,
  208. fontSize: 13//字体大小
  209. }
  210. },
  211. data: yData
  212. },
  213. // 内容的顶部
  214. {
  215. z: 3,
  216. type: 'pictorialBar',
  217. symbol: 'diamond',
  218. symbolPosition: 'end',
  219. symbolOffset: ['0%', '-50%'],
  220. symbolSize: [30, 12],
  221. toolltip: {
  222. show: false
  223. },
  224. itemStyle: {
  225. color: function (params) {
  226. color = colors[params.dataIndex][1].color
  227. return colors[params.dataIndex][0].color;
  228. },
  229. },
  230. data: yData,
  231. },
  232. // 阴影区域
  233. {
  234. z: 0,
  235. type: 'bar',
  236. barWidth: 30,
  237. barGap: "-100%",
  238. data: newShadowHight,
  239. itemStyle: {
  240. color: "#00365F66"
  241. }
  242. },
  243. // 阴影的顶部
  244. {
  245. z: 3,
  246. type: 'pictorialBar',
  247. symbol: 'diamond',
  248. symbolPosition: 'end',
  249. symbolOffset: ['0%', '-50%'],
  250. symbolSize: [30, 12],
  251. toolltip: {
  252. show: false
  253. },
  254. itemStyle: {
  255. color: "#00365F66"
  256. },
  257. data: newShadowHight,
  258. }
  259. ] as never[]
  260. }
  261. function initCharts() {
  262. //轴数据
  263. if (option.series) {
  264. const xAxisData: any[] = [];
  265. const series: any[] = [];
  266. const seriesData: any[] = [];
  267. // const legendData: { name: string, itemStyle: Object }[] = [];
  268. let ymax = 0
  269. props.xAxisData.forEach((item: any, index) => {
  270. xAxisData.push(item['key']);
  271. seriesData.push(props.dataSource[item.valueKey] || '');
  272. });
  273. for (let i = 0; i < chartsColumns.length; i++) {
  274. const item: any = chartsColumns[i]
  275. // legendData.push({
  276. // name: item.legend + (item.yname ? '(' + item.yname + ')' : ''),
  277. // itemStyle: {
  278. // color: new echarts.graphic.LinearGradient(1, 0, 0, 0, colors[i]),
  279. // },
  280. // })
  281. if (!ymax && item['ymax']) {
  282. ymax = item['ymax']
  283. }
  284. }
  285. // option.legend.data = legendData
  286. // option.series[0].data = seriesData;
  287. // option.series = series;
  288. // option.xAxis.data = xAxisData;
  289. initDta(xAxisData, seriesData)
  290. console.log('option------------->', option);
  291. setOptions(option, false);
  292. }
  293. }
  294. return { chartRef };
  295. },
  296. });
  297. </script>