You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

133 lines
3.9 KiB

8 months ago
  1. <template>
  2. <a-card hoverable>
  3. <template #cover>
  4. <div class="heatmap" style="border-right: rgba(0, 0, 0, 0.5);">
  5. <div ref="heat" style="height: 100%;"></div>
  6. </div>
  7. </template>
  8. </a-card>
  9. </template>
  10. <script setup lang='ts'>
  11. import { get } from '@/tools/request';
  12. import { ref, reactive, onMounted } from 'vue';
  13. import { createEcharts } from "@/hooks/intex"
  14. const heat = ref(null);
  15. function generateDates(numDays: number) {
  16. const dates = [];
  17. const currentDate = new Date();
  18. for (let i = 0; i < numDays; i++) {
  19. const date = new Date(currentDate);
  20. date.setDate(currentDate.getDate() - i);
  21. dates.push(
  22. { date: date.toISOString().split('T')[0], writCount: 0 }
  23. ); // 包含日期和评论数
  24. }
  25. return dates;
  26. }
  27. // 初始化60天的数据
  28. const data = generateDates(60);
  29. // 重新排列数据
  30. const rawData = ref<any[]>([]);
  31. const statisticList = async () => {
  32. await get("/statistics/list").then(response => {
  33. rawData.value = response.data.data
  34. rawData.value.forEach(newDataItem => {
  35. const item = newData.find((d: any) => d.date === newDataItem.date);
  36. if (item) {
  37. item.writCount = newDataItem.writCount;
  38. }
  39. });
  40. let formattedData = newData.map((item: any, index: number) => {
  41. return [index % 15, Math.floor(index / 15), item.writCount]
  42. });
  43. formattedList(formattedData)
  44. createEcharts(heat, heatMapData);
  45. })
  46. }
  47. const formattedList = (val: any) => {
  48. heatMapData.series[0].data = val
  49. }
  50. const newData = <any>[];
  51. for (let i = 0; i < 60; i += 15) {
  52. // 取出每个15天的数据,并反转顺序
  53. const chunk = data.slice(i, i + 15).reverse();
  54. newData.push(...chunk);
  55. }
  56. const heatMapData = reactive(
  57. {
  58. tooltip: {
  59. position: 'top',
  60. formatter: function (params: any) {
  61. const item = newData[params.dataIndex];
  62. if (item.writCount > 0) {
  63. return `${item.date}<br/>COMMENTS: ${item.writCount}`;
  64. } else {
  65. return `${item.date}`;
  66. }
  67. }
  68. },
  69. grid: {
  70. left: '0', // 左边距
  71. right: '0', // 右边距
  72. top: '0', // 上边距
  73. bottom: '0',
  74. },
  75. xAxis: {
  76. type: 'category',
  77. data: Array.from({ length: 15 }, (_, i) => `Col ${i + 1}`),
  78. splitArea: {
  79. show: true
  80. },
  81. show: false
  82. },
  83. yAxis: {
  84. type: 'category',
  85. data: ['Row 1', 'Row 2', 'Row 3', 'Row 4'],
  86. splitArea: {
  87. show: false
  88. },
  89. show: false
  90. },
  91. visualMap: {
  92. min: 0,
  93. max: 20,
  94. calculable: true,
  95. orient: 'horizontal',
  96. left: 'center',
  97. bottom: '15%',
  98. show: false,
  99. inRange: {
  100. color: ['rgba(182,181,178,0.01)', 'rgba(157,156,153,1)'] // 0评论是白色, 非0评论是黑色
  101. }
  102. },
  103. series: [{
  104. type: 'heatmap',
  105. data: [],
  106. itemStyle: {
  107. borderColor: 'rgb(231,229,225,0.5)', // 设置边框颜色
  108. borderWidth: 0.5, // 设置边框宽度
  109. },
  110. label: {
  111. show: false,
  112. },
  113. emphasis: {
  114. itemStyle: {
  115. shadowBlur: 10,
  116. shadowColor: 'rgba(0, 0, 0, 0.5)',
  117. borderColor: '#fff', // 鼠标悬停时的边框颜色
  118. borderWidth: 2 // 鼠标悬停时的边框宽度
  119. }
  120. }
  121. }]
  122. }
  123. )
  124. onMounted(() => {
  125. statisticList()
  126. createEcharts(heat, heatMapData);
  127. })
  128. </script>
  129. <style></style>