layout03UserWidgetM.vue 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. <template>
  2. <div>
  3. <div class="inner--header--wrap">
  4. <h2
  5. v-if="totalPage > 0"
  6. class="inner--component--title none--after"
  7. >
  8. 상세 현황 ({{ page }}/{{ totalPage }})
  9. </h2>
  10. <h2 v-else>
  11. 상세 현황
  12. </h2>
  13. <p class="inner--component--total">
  14. Total : <span>{{ props.totalCnt }}</span>
  15. </p>
  16. </div>
  17. <div class="inner--content df--block pt--1rem equip--conmp--wrap">
  18. <swiper
  19. :autoplay="{
  20. delay: 20000,
  21. disableOnInteraction: false,
  22. }"
  23. :loop="true"
  24. :touch-ratio="0"
  25. :space-between="spaceBetween"
  26. :slides-per-view="1"
  27. :modules="[Autoplay]"
  28. @slide-change="onSlideChange"
  29. >
  30. <swiper-slide
  31. v-for="(slide, index) in props.items"
  32. :key="`user-swiper-slide-${index}`"
  33. >
  34. <div class="user--list--contents">
  35. <ul>
  36. <li
  37. v-for="(item, idx) in slide"
  38. :key="`user-swiper-slide-item-${idx}`"
  39. :class="item.level"
  40. >
  41. <div class="headers">
  42. <div class="title">
  43. {{ item.tenantName }}
  44. </div>
  45. </div>
  46. <div class="chart--box">
  47. <Doughnut
  48. :data="item.chartData"
  49. :options="chartOptions"
  50. />
  51. <div class="current--value">
  52. {{ toRoundFix(item.curSubscriber, 0) }} / {{ toRoundFix(item.maxSubscriber, 0) }}
  53. </div>
  54. </div>
  55. <div class="current--value--ps">
  56. {{ item.perSubscriber }}<i class="unit">%</i>
  57. </div>
  58. </li>
  59. </ul>
  60. </div>
  61. </swiper-slide>
  62. </swiper>
  63. </div>
  64. </div>
  65. </template>
  66. <script setup>
  67. /***********************
  68. * import
  69. ************************/
  70. import { useI18n } from "vue-i18n"
  71. import apiUrl from '@/composables/useApi';
  72. import useAxios from '@/composables/useAxios';
  73. import useUtil from '@/composables/useUtil';
  74. import { Swiper, SwiperSlide } from 'swiper/vue';
  75. import { Autoplay } from 'swiper/modules';
  76. import 'swiper/css';
  77. import 'swiper/swiper-bundle.css'
  78. import { Doughnut } from 'vue-chartjs';
  79. import { Chart as ChartJS, Title, Tooltip, Legend, BarElement, LineController, LineElement, PointElement, ArcElement, CategoryScale, LinearScale } from 'chart.js';
  80. /***********************
  81. * plugins inject
  82. ************************/
  83. const { $toast, $log, $dayjs, $eventBus } = useNuxtApp()
  84. // props
  85. const props = defineProps({
  86. items: {
  87. type: Array,
  88. default: () => []
  89. },
  90. totalCnt: {
  91. type: Number,
  92. default: 0
  93. }
  94. })
  95. // 참조가능 데이터 설정
  96. defineExpose({})
  97. // 발신 이벤트 선언
  98. const emit = defineEmits([""]);
  99. const i18n = useI18n();
  100. ChartJS.register(Title,
  101. Tooltip,
  102. Legend,
  103. BarElement,
  104. LineController,
  105. LineElement,
  106. PointElement,
  107. CategoryScale,
  108. ArcElement,
  109. LinearScale)
  110. /***********************
  111. * data & created
  112. ************************/
  113. const page = ref(1);
  114. const totalPage = computed(() => Math.floor(props.totalCnt / 8) + (props.totalCnt % 8 == 0 ? 0 : 1))
  115. const remToPx = () => parseFloat(getComputedStyle(document.documentElement).fontSize);
  116. const spaceRem = 0.62; // 원하는 rem 값
  117. const spaceRemPx = spaceRem * remToPx();
  118. const spaceBetween = spaceRemPx;
  119. const chartOptions = {
  120. responsive: true,
  121. maintainAspectRatio: false,
  122. cutout:"75%",
  123. rotation: 270,
  124. circumference: 180,
  125. plugins: {
  126. legend: {
  127. position:'top',
  128. display: false
  129. },
  130. tooltip: {
  131. enabled:false
  132. }
  133. }
  134. }
  135. /***********************
  136. * Methods
  137. ************************/
  138. /** Slide onChang Event */
  139. function onSlideChange(swiper) {
  140. if(swiper.realIndex != page.value + 1)
  141. page.value = swiper.realIndex + 1
  142. }
  143. const toRoundFix = (data, digit) => parseFloat(data).toFixed(digit);
  144. </script>