123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205 |
- import {
- PropType,
- defineComponent,
- nextTick,
- onMounted,
- ref,
- toRefs,
- watch
- } from 'vue';
- import styles from '../index.module.less';
- import icons from '../icons.json';
- import { Badge, Image, Skeleton, SkeletonImage, SkeletonParagraph } from 'vant';
- import * as echarts from 'echarts';
- import { IGradeDistribution } from '../type';
- import icon_1 from '../image/icon_1.png';
- type EChartsOption = echarts.EChartsOption;
- const colors = [
- ['#94C2FD', '#5B8FF9'],
- ['#FBE031', '#F6BD16'],
- ['#93EED2', '#5AD8A6'],
- ['#F5A181', '#E8684A'],
- ['#96A9C4', '#5D7092'],
- ['#A6E6F7', '#6DC8EC'],
- ['#FFCA7D', '#FF9530'],
- ['#DBC6FF', '#B87BDD'],
- ['#D2FFC4', '#92DE97'],
- ['#94C2FD', '#5B8FF9'],
- ['#FBE031', '#F6BD16'],
- ['#93EED2', '#5AD8A6'],
- ['#F5A181', '#E8684A'],
- ['#96A9C4', '#5D7092'],
- ['#A6E6F7', '#6DC8EC'],
- ['#FFCA7D', '#FF9530'],
- ['#DBC6FF', '#B87BDD'],
- ['#D2FFC4', '#92DE97'],
- ['#94C2FD', '#5B8FF9'],
- ['#FBE031', '#F6BD16'],
- ['#93EED2', '#5AD8A6'],
- ['#F5A181', '#E8684A'],
- ['#96A9C4', '#5D7092'],
- ['#A6E6F7', '#6DC8EC'],
- ['#FFCA7D', '#FF9530'],
- ['#DBC6FF', '#B87BDD'],
- ['#D2FFC4', '#92DE97']
- ];
- export default defineComponent({
- name: 'CurrentStudent',
- props: {
- list: {
- type: Array as PropType<IGradeDistribution[]>,
- default: () => []
- }
- },
- setup(props) {
- const firstInit = ref(false);
- const echratsRef = ref();
- const { list } = toRefs(props);
- watch(
- () => list.value,
- () => {
- firstInit.value = true;
- nextTick(() => {
- handleInit();
- });
- }
- );
- let myChart: echarts.ECharts;
- const handleInit = () => {
- if (!list.value.length) return;
- if (myChart) {
- myChart.dispose();
- }
- myChart = echarts.init(echratsRef.value);
- const option: EChartsOption = {
- title: {
- text: list.value
- .reduce((total, item: IGradeDistribution) => {
- total += item.studentNum;
- return total;
- }, 0)
- .toString(),
- subtext: '在读人数',
- textAlign: 'center',
- left: '48%',
- top: '36%',
- textStyle: {
- fontSize: '22px',
- fontWeight: 'bold',
- color: '#333',
- fontFamily: 'DINAlternate-Bold, DINAlternate'
- },
- subtextStyle: {
- fontSize: '12px',
- color: '#777'
- }
- },
- tooltip: {
- trigger: 'item',
- confine: true,
- borderWidth: 0
- },
- series: [
- {
- type: 'pie',
- radius: ['40%', '62%'],
- itemStyle: {
- borderRadius: 2,
- borderColor: '#fff',
- borderWidth: 1
- },
- label: {
- show: false
- },
- labelLine: {
- show: false
- },
- avoidLabelOverlap: false,
- data: list.value.map((item: IGradeDistribution, index: number) => {
- return {
- value: item.studentNum,
- name: item.grade,
- itemStyle: {
- color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
- { offset: 0, color: colors[index][0] },
- { offset: 1, color: colors[index][1] }
- ])
- }
- };
- })
- }
- ]
- };
- option && myChart.setOption(option);
- };
- return () => (
- <div class={styles.item}>
- <div class={styles.top}>
- <Image class={styles.iconRight} src={icons.right} />
- <span>在读学员</span>
- <Image class={styles.iconLeft} src={icons.left} />
- </div>
- <div class={styles.itemTop}>
- <Image class={styles.icon} src={icons[1]} />
- <div class={styles.title}>年级分布</div>
- <div class={styles.des}>(单位:人)</div>
- </div>
- {!firstInit.value && (
- <Skeleton class={[styles.gradeContainer, styles.itemEmtry]}>
- {{
- template: () => (
- <>
- <div
- class={styles.gradeEcharts}
- style={{
- display: 'flex',
- justifyContent: 'center',
- alignItems: 'center'
- }}>
- <SkeletonImage style={{ width: '80%', height: '80%' }} />
- </div>
- <div style={{ flex: 1, marginLeft: '16px' }}>
- <SkeletonParagraph />
- <SkeletonParagraph />
- <SkeletonParagraph />
- <SkeletonParagraph />
- <SkeletonParagraph />
- </div>
- </>
- )
- }}
- </Skeleton>
- )}
- <div
- style={{ display: list.value.length ? '' : 'none' }}
- class={styles.gradeContainer}>
- <div class={styles.gradeEcharts} ref={echratsRef}></div>
- <div class={styles.tags}>
- {list.value.map((item: IGradeDistribution, i: number) => (
- <div class={styles.tag}>
- <Badge dot color={`linear-gradient(180deg, ${colors[i][0]} 0%, ${colors[i][1]} 100%)`} />
- <div class={styles.tagTitle}>{item.grade}</div>
- <span class={styles.tagNum}>{item.studentNum}</span>
- </div>
- ))}
- </div>
- </div>
- {firstInit.value && !list.value.length && (
- <div class={[styles.gradeContainer, styles.itemEmtry]}>
- <Image src={icon_1} />
- </div>
- )}
- </div>
- );
- }
- });
|