react18+ts 封装图表及词云组件
1.下载依赖包
"echarts": "^5.5.1",
"echarts-for-react": "^3.0.2",
"echarts-wordcloud": "^2.1.0",
2.创建目录结构
3.代码封装
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)