traffic-sources.vue 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. <!-- 引用域 -->
  2. <template>
  3. <div class="visitor-trend">
  4. <div ref="chartRef" style="width: 100%; height: 300px;"></div>
  5. <div style="position: absolute;top: 20px;right: 0;">
  6. <el-select v-model="value" style="width: 84px;" @change="initChart">
  7. <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
  8. </el-select>
  9. </div>
  10. </div>
  11. </template>
  12. <script setup>
  13. import { ref, onMounted, onBeforeUnmount } from 'vue';
  14. import * as echarts from 'echarts';
  15. const value = ref('7');
  16. const options = [
  17. {
  18. value: '7',
  19. label: '7天',
  20. selected: true,
  21. },
  22. {
  23. value: '30',
  24. label: '30天',
  25. },
  26. ]
  27. const chartRef = ref(null);
  28. let chartInstance = null;
  29. // 生成随机数据
  30. const generateRandomData = () => {
  31. const categories = Array.from({ length: 6 }, (_, i) => i + 1);
  32. return categories.map(item => ({
  33. y: '192.168.3.' + item,
  34. x: Math.floor(Math.random() * 10000) + 1 // 生成1-100的随机数
  35. }));
  36. };
  37. // 初始化图表
  38. const initChart = () => {
  39. if (!chartRef.value) return;
  40. if (chartInstance) {
  41. chartInstance.dispose();
  42. }
  43. chartInstance = echarts.init(chartRef.value);
  44. const data = generateRandomData();
  45. const option = {
  46. tooltip: {
  47. trigger: 'axis',
  48. axisPointer: {
  49. type: 'shadow'
  50. },
  51. formatter: '{b}[{c}]'
  52. },
  53. grid: {
  54. left: '0%',
  55. right: '5%',
  56. bottom: '0%',
  57. containLabel: true,
  58. },
  59. xAxis: {
  60. type: 'value',
  61. boundaryGap: [0, 0.01],
  62. axisLabel: {
  63. color: 'rgba(100, 100, 100, 1)',
  64. },
  65. axisLine: {
  66. lineStyle: {
  67. color: '#999'
  68. }
  69. },
  70. splitLine: {
  71. lineStyle: {
  72. color: 'rgba(230, 230, 230, 1)',
  73. type: 'dashed',
  74. }
  75. }
  76. },
  77. yAxis: {
  78. type: 'category',
  79. data: data.map(item => item.y),
  80. axisLabel: {
  81. color: 'rgba(100, 100, 100, 1)',
  82. formatter: function(value) {
  83. return value.match(/.{1,15}/g).join('\n');;
  84. }
  85. },
  86. axisLine: {
  87. lineStyle: {
  88. color: 'rgba(230, 230, 230, 1)',
  89. }
  90. },
  91. axisTick: {
  92. alignWithLabel: true,
  93. show: false,
  94. }
  95. },
  96. series: [
  97. {
  98. name: '数值',
  99. type: 'bar',
  100. data: data.map(item => item.x),
  101. itemStyle: {
  102. color: 'rgba(22, 122, 240, 1)',
  103. borderRadius: [0, 8, 8, 0] // 右上和右下圆角
  104. },
  105. barWidth: '16',
  106. label: {
  107. show: false,
  108. // position: 'right',
  109. // formatter: '{c}'
  110. }
  111. }
  112. ]
  113. };
  114. chartInstance.setOption(option);
  115. };
  116. defineExpose({
  117. initChart
  118. });
  119. onMounted(async () => {
  120. initChart();
  121. });
  122. </script>
  123. <style lang="scss">
  124. .visitor-trend {
  125. position: relative;
  126. /* 下拉框整体样式 */
  127. .el-select__wrapper {
  128. border: 1px solid rgba(22, 122, 240, 1);
  129. }
  130. .el-select__selected-item {
  131. color: rgba(22, 122, 240, 1); /* 文字颜色 */
  132. }
  133. .el-select__caret {
  134. color: rgba(22, 122, 240, 1); /* 三角形颜色 */
  135. }
  136. }
  137. </style>