dz-dust.vue 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  1. <template>
  2. <div class="dz-dust">
  3. <div ref="chartDust" class="chartDust"></div>
  4. </div>
  5. </template>
  6. <script setup lang="ts">
  7. import { ref, reactive, watch, onMounted, nextTick } from 'vue'
  8. import * as echarts from 'echarts';
  9. let props = defineProps({
  10. echartOption: {
  11. type: Object,
  12. default: () => {
  13. return {}
  14. }
  15. },
  16. paramData: {
  17. type: Array,
  18. default: () => {
  19. return []
  20. }
  21. }
  22. })
  23. //获取dom元素节点
  24. let chartDust = ref<any>();
  25. let xData = ref<any[]>([])
  26. let yData = ref<any[]>([])
  27. function getOption() {
  28. nextTick(() => {
  29. let myChart = echarts.init(chartDust.value);
  30. const offsetX = 8;
  31. const offsetY = 4;
  32. const colorList = [
  33. ['rgba(63, 124, 136, 1)', 'rgba(77, 193, 211, 1)'],
  34. ['rgba(145, 129, 47, 1)', 'rgba(211, 184, 46, 1)'],
  35. ['rgba(159, 121, 69, 1)', 'rgba(226, 173, 101, 1)'],
  36. ['rgba(163, 90, 25, 1)', 'rgba(240, 114, 4, 1)'],
  37. ['rgba(158, 13, 13, 1)', 'rgba(239, 2, 2, 1)'],
  38. ]
  39. // 绘制左侧面
  40. const CubeLeft = echarts.graphic.extendShape({
  41. shape: {
  42. x: 0,
  43. y: 0,
  44. },
  45. buildPath: function (ctx, shape) {
  46. const xAxisPoint = shape.xAxisPoint;
  47. const c0 = [shape.x, shape.y];
  48. const c1 = [shape.x - offsetX, shape.y - offsetY];
  49. const c2 = [xAxisPoint[0] - offsetX, xAxisPoint[1] - offsetY];
  50. const c3 = [xAxisPoint[0], xAxisPoint[1]];
  51. ctx.moveTo(c0[0], c0[1]).lineTo(c1[0], c1[1]).lineTo(c2[0], c2[1]).lineTo(c3[0], c3[1]).closePath();
  52. },
  53. });
  54. // 绘制右侧面
  55. const CubeRight = echarts.graphic.extendShape({
  56. shape: {
  57. x: 0,
  58. y: 0,
  59. },
  60. buildPath: function (ctx, shape) {
  61. const xAxisPoint = shape.xAxisPoint;
  62. const c1 = [shape.x, shape.y];
  63. const c2 = [xAxisPoint[0], xAxisPoint[1]];
  64. const c3 = [xAxisPoint[0] + offsetX, xAxisPoint[1] - offsetY];
  65. const c4 = [shape.x + offsetX, shape.y - offsetY];
  66. ctx.moveTo(c1[0], c1[1]).lineTo(c2[0], c2[1]).lineTo(c3[0], c3[1]).lineTo(c4[0], c4[1]).closePath();
  67. },
  68. });
  69. // 绘制顶面
  70. const CubeTop = echarts.graphic.extendShape({
  71. shape: {
  72. x: 0,
  73. y: 0,
  74. },
  75. buildPath: function (ctx, shape) {
  76. const c1 = [shape.x, shape.y];
  77. const c2 = [shape.x + offsetX, shape.y - offsetY]; //右点
  78. const c3 = [shape.x, shape.y - offsetX];
  79. const c4 = [shape.x - offsetX, shape.y - offsetY];
  80. ctx.moveTo(c1[0], c1[1]).lineTo(c2[0], c2[1]).lineTo(c3[0], c3[1]).lineTo(c4[0], c4[1]).closePath();
  81. },
  82. });
  83. // 注册三个面图形
  84. echarts.graphic.registerShape('CubeLeft', CubeLeft);
  85. echarts.graphic.registerShape('CubeRight', CubeRight);
  86. echarts.graphic.registerShape('CubeTop', CubeTop);
  87. let option = {
  88. tooltip: {
  89. trigger: 'item',
  90. },
  91. grid: {
  92. top: "12%",
  93. left: "5%",
  94. right: "5%",
  95. bottom: "5%",
  96. containLabel: true,
  97. },
  98. xAxis: {
  99. type: 'category',
  100. data: xData.value,
  101. // X
  102. axisLine: {
  103. show: true,
  104. lineStyle: {
  105. // width: 1,
  106. color: 'rgba(34, 55, 81,.7)',
  107. }
  108. },
  109. axisTick: {
  110. show: false,
  111. },
  112. axisLabel: {
  113. fontSize: 14,
  114. interval: 0,
  115. textStyle: {
  116. color: '#FFF', //更改坐标轴文字颜色
  117. fontSize: 12 //更改坐标轴文字大小
  118. }
  119. },
  120. },
  121. yAxis: {
  122. name: '',
  123. type: 'value',
  124. axisLine: {
  125. show: false,
  126. },
  127. splitLine: {
  128. show: true,
  129. lineStyle: {
  130. // type: 'dashed',
  131. color: 'rgba(34, 55, 81,.7)',
  132. },
  133. },
  134. axisTick: {
  135. show: false,
  136. },
  137. axisLabel: {
  138. fontSize: 14,
  139. textStyle: {
  140. color: '#FFF', //更改坐标轴文字颜色
  141. fontSize: 12 //更改坐标轴文字大小
  142. }
  143. },
  144. },
  145. series: [
  146. // 柱体
  147. {
  148. name: '',
  149. type: 'custom',
  150. stack: "Ad",
  151. renderItem: (params, api) => {
  152. const location = api.coord([api.value(0), api.value(1)]);
  153. return {
  154. type: 'group',
  155. x: 1,
  156. children: [
  157. {
  158. type: 'CubeLeft',
  159. shape: {
  160. api,
  161. xValue: api.value(0),
  162. yValue: api.value(1),
  163. x: location[0],
  164. y: location[1],
  165. xAxisPoint: api.coord([api.value(0), 0]),
  166. },
  167. style: {
  168. fill: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
  169. {
  170. offset: 0,
  171. color: colorList[params.dataIndex][0],
  172. },
  173. {
  174. offset: 1,
  175. color: colorList[params.dataIndex][1],
  176. },
  177. ]),
  178. },
  179. },
  180. {
  181. type: 'CubeRight',
  182. shape: {
  183. api,
  184. xValue: api.value(0),
  185. yValue: api.value(1),
  186. x: location[0],
  187. y: location[1],
  188. xAxisPoint: api.coord([api.value(0), 0]),
  189. },
  190. style: {
  191. fill: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
  192. {
  193. offset: 0,
  194. color: colorList[params.dataIndex][0],
  195. },
  196. {
  197. offset: 1,
  198. color: colorList[params.dataIndex][1],
  199. },
  200. ]),
  201. },
  202. },
  203. {
  204. type: 'CubeTop',
  205. shape: {
  206. api,
  207. xValue: api.value(0),
  208. yValue: api.value(1),
  209. x: location[0],
  210. y: location[1],
  211. xAxisPoint: api.coord([api.value(0), 0]),
  212. },
  213. style: {
  214. fill: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
  215. {
  216. offset: 0,
  217. color: colorList[params.dataIndex][0],
  218. },
  219. {
  220. offset: 1,
  221. color: colorList[params.dataIndex][1],
  222. },
  223. ]),
  224. },
  225. },
  226. ],
  227. };
  228. },
  229. data: yData.value,
  230. },
  231. {
  232. type: "bar",
  233. label: {
  234. normal: {
  235. show: true,
  236. position: "top",
  237. formatter: (e) => {
  238. return e.value + "次";
  239. },
  240. fontSize: 12,
  241. color:'#fff',
  242. offset: [0, -6],
  243. },
  244. },
  245. itemStyle: {
  246. color: "transparent",
  247. },
  248. tooltip: {},
  249. data: yData.value,
  250. },
  251. ],
  252. };
  253. myChart.setOption(option);
  254. window.onresize = function () {
  255. myChart.resize();
  256. };
  257. });
  258. }
  259. watch(() => props.paramData, (newV, oldV) => {
  260. xData.value = newV.map((el: any) => el.name)
  261. yData.value = newV.map((el: any) => el.value)
  262. getOption()
  263. }, { immediate: true })
  264. </script>
  265. <style lang="less" scoped>
  266. .dz-dust {
  267. position: relative;
  268. height: 100%;
  269. .chartDust {
  270. width: 100%;
  271. height: 100%;
  272. }
  273. }
  274. </style>