react18+ts 封装图表及词云组件

发布于:2024-12-19 ⋅ 阅读:(10) ⋅ 点赞:(0)

react18+ts 封装图表及词云组件

1.下载依赖包
  "echarts": "^5.5.1",
  "echarts-for-react": "^3.0.2",
  "echarts-wordcloud": "^2.1.0",
2.创建目录结构

在这里插入图片描述

3.代码封装
  • ChartCard.tsx

在这里插入图片描述

  • Wordcloud.tsx

在这里插入图片描述

4.调用
import React, { memo, useEffect, useMemo, useRef, useState } from 'react'
import type { FC, ReactNode } from 'react'
import * as echarts from 'echarts/core'
import ChartCard from '@/components/echarts/ChartCard'
import WordCloud from '@/components/echarts/Wordcloud'

interface IProps {
  children?: ReactNode
}

const Echarts: FC<IProps> = () => {
  // * 获取当前月过去一年的年月
  const generatePastYearMonths = () => {
    const months = []
    const currentDate = new Date()
    for (let i = 0; i < 12; i++) {
      const year = currentDate.getFullYear()
      const month = currentDate.getMonth() + 1
      const formattedMonth = month < 10 ? `0${month}` : `${month}`
      const formattedDate = `${year}-${formattedMonth}`
      months.unshift(formattedDate)
      currentDate.setMonth(currentDate.getMonth() - 1) // 当前日期减去一个月
    }
    return months
  }
  const option = {
    color: ['#4387fb'],
    tooltip: {
      trigger: 'axis',
      axisPointer: { type: 'shadow' }
    },
    grid: { left: '3%', right: '4%', bottom: '3%', containLabel: true },
    legend: {
      data: [
        { name: '会员数', icon: 'roundRect' },
        { name: '会员率', itemStyle: { color: 'rgb(128, 255, 165)' } }
      ]
    },
    xAxis: [
      { type: 'category', data: generatePastYearMonths(), axisTick: { alignWithLabel: true } }
    ],
    yAxis: [
      { type: 'value', name: '会员数', axisLabel: { formatter: '{value} 人' } },
      { type: 'value', name: '会员率', axisLabel: { formatter: '{value} %' } }
    ],
    series: [
      {
        name: '会员数',
        type: 'bar',
        barWidth: '40%',
        data: [100, 52, 200, 334, 390, 330, 220, 325, 135, 267, 131, 220],
        tooltip: { valueFormatter: (value: number) => `${value}人` }
      },
      {
        name: '会员率',
        type: 'line',
        stack: 'Total',
        smooth: true,
        lineStyle: { width: 0 },
        showSymbol: false,
        yAxisIndex: 1, // 默认0 多y轴情况下 需更改
        areaStyle: {
          opacity: 0.4,
          color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
            { offset: 0, color: 'rgb(128, 255, 165)' },
            { offset: 1, color: 'rgb(1, 191, 236)' }
          ])
        },
        emphasis: { focus: 'series' },
        data: [20, 16, 28, 36, 90, 33, 27, 45, 49, 67, 89, 66],
        tooltip: { valueFormatter: (value: number) => `${value}%` }
      }
    ]
  }

  const wordCloudOption = {
    tooltip: {},
    series: [
      {
        type: 'wordCloud',
        gridSize: 2,
        sizeRange: [12, 50],
        rotationRange: [-90, 90],
        shape: 'pentagon',
        width: 600,
        height: 400,
        drawOutOfBound: true,
        textStyle: {
          color() {
            return `rgb(${[
              Math.round(Math.random() * 160),
              Math.round(Math.random() * 160),
              Math.round(Math.random() * 160)
            ].join(',')})`
          }
        },
        emphasis: {
          textStyle: {
            shadowBlur: 10,
            shadowColor: '#333'
          }
        },
        data: [
          {
            name: 'Sam S Club',
            value: 10000,
            textStyle: { color: 'black' },
            emphasis: { textStyle: { color: 'red' } }
          },
          {
            name: 'Macys',
            value: 6181
          },
          {
            name: 'Amy Schumer',
            value: 4386
          },
          {
            name: 'Jurassic World',
            value: 4055
          },
          {
            name: 'Charter Communications',
            value: 2467
          },
          {
            name: 'Chick Fil A',
            value: 2244
          },
          {
            name: 'Planet Fitness',
            value: 1898
          },
          {
            name: 'Pitch Perfect',
            value: 1484
          },
          {
            name: 'Express',
            value: 1112
          },
          {
            name: 'Home',
            value: 965
          },
          {
            name: 'Johnny Depp',
            value: 847
          },
          {
            name: 'Lena Dunham',
            value: 582
          },
          {
            name: 'Lewis Hamilton',
            value: 555
          },
          {
            name: 'KXAN',
            value: 550
          },
          {
            name: 'Mary Ellen Mark',
            value: 462
          },
          {
            name: 'Farrah Abraham',
            value: 366
          },
          {
            name: 'Rita Ora',
            value: 360
          },
          {
            name: 'Serena Williams',
            value: 282
          },
          {
            name: 'NCAA baseball tournament',
            value: 273
          },
          {
            name: 'Point Break',
            value: 265
          }
        ]
      }
    ]
  }
  return (
    <div className='chart-card-wrapper'>
      <ChartCard option={option}></ChartCard>
      <br />
      <WordCloud option={wordCloudOption}></WordCloud>
    </div>
  )
}

export default memo(Echarts)