需求
echarts柱状图实现数据项比较多时,就会出现数据不能完全展示问题,这里考虑将其做成轮播柱状图的方式解决。
思路
echarts并没有实现直接的参数实现轮播效果,这里我们需要通过定时函数 setInterval 来更新数据,实现了横向柱状图的轮播效果。你可以根据需要调整数据和更新频率来满足实际需求。
实现效果
这里除了实现柱状图轮播外,还实现了排序效果
实现步骤
- 定义控制变量
this.chunkedData = [];
this.chunkedXAxis = [];
this.currentIndex = 0;
this.setInterval = undefined;
- 定义初始化方法
handleData() {
const chartData = this.props.chartData;
this.chunkedData = [];
this.chunkedXAxis = [];
if (chartData && chartData.seriesData) {
let rawData = chartData.seriesData;
let xAxisData = chartData.axisData;
// 将数据切分成包含8个元素的数组
if (xAxisData.length) {
let length = xAxisData.length > 8 ? 8 : xAxisData.length;
for (let index = 0; index < length; index++) {
this.chunkedData.push(rawData[index]);
this.chunkedXAxis.push(xAxisData[index]);
}
this.currentIndex = length - 1;
}
}
}
- 启动时加载初始化方法
componentDidMount() {
this.handleData()
this.loadChart() // 这个是echarts加载方法
if (this.chunkedXAxis.length) {
// 轮播逻辑
this.setInterval = setInterval(() => {
this.currentIndex = (this.currentIndex + 1) % this.chartData.axisData.length;
this.chunkedData.shift();
this.chunkedData.push(this.chartData.seriesData[this.currentIndex])
this.chunkedXAxis.shift();
this.chunkedXAxis.push(this.chartData.axisData[this.currentIndex])
this.loadChart();
}, 8000); // 每8秒切换一次
}
}
- 需要在退出时去除轮播
componentWillUnmount() {
if (this.setInterval) {
clearInterval(this.setInterval);
}
}
完整代码
import React, { Component } from 'react'
import * as echarts from 'echarts';
export default class BarChart0 extends Component {
constructor(props) {
super(props)
this.chartData = this.props.chartData
this.updateFlag = false;
this.chunkedData = [];
this.chunkedXAxis = [];
this.currentIndex = 0;
this.setInterval = undefined;
}
componentDidMount() {
this.handleData()
this.loadChart()
if (this.chunkedXAxis.length) {
// 轮播逻辑
this.setInterval = setInterval(() => {
this.currentIndex = (this.currentIndex + 1) % this.chartData.axisData.length;
this.chunkedData.shift();
this.chunkedData.push(this.chartData.seriesData[this.currentIndex])
this.chunkedXAxis.shift();
this.chunkedXAxis.push(this.chartData.axisData[this.currentIndex])
this.loadChart();
}, 8000); // 每8秒切换一次
}
}
shouldComponentUpdate(nextProps) {
const updateFlag = nextProps.chartData ? nextProps.chartData.updateFlag : undefined;
if (this.updateFlag !== updateFlag) {
this.chartData = nextProps.chartData;
this.updateFlag = !this.updateFlag;
this.handleData();
this.loadChart()
return true;
}
return false;
}
componentWillUnmount() {
if (this.setInterval) {
clearInterval(this.setInterval);
}
}
handleData() {
const chartData = this.props.chartData;
this.chunkedData = [];
this.chunkedXAxis = [];
if (chartData && chartData.seriesData) {
let rawData = chartData.seriesData;
let xAxisData = chartData.axisData;
// 将数据切分成包含6个元素的数组
if (xAxisData.length) {
let length = xAxisData.length > 8 ? 8 : xAxisData.length;
for (let index = 0; index < length; index++) {
this.chunkedData.push(rawData[index]);
this.chunkedXAxis.push(xAxisData[index]);
}
this.currentIndex = length - 1;
}
}
}
loadChart() {
let chartData = this.chartData;
if (chartData === undefined) {
chartData = {
seriesData: [
{ name: '无数据', value: 0 },
],
}
}
let myChart = echarts.getInstanceByDom(document.getElementById(this.props.id ? this.props.id : 'barChart0'));
if (myChart == null) {
myChart = echarts.init(document.getElementById(this.props.id ? this.props.id : 'barChart0'));
}
let axisData = chartData.axisData || [];
let seriesData = chartData.seriesData || [];
let topLableSize = 14
let barWidth = 12
if (this.chunkedData) {
seriesData = this.chunkedData;
axisData = this.chunkedXAxis;
} else {
seriesData = chartData.seriesData;
axisData = chartData.axisData;
}
let option = {
grid: {
left: '5%',
top: '2%',
right: '15%',
bottom: '0%',
containLabel: true
},
xAxis: [{
show: false,
}],
yAxis: [{
inverse: true,
axisTick: 'none',
axisLine: 'none',
offset: '15',
align: 'left',
axisLabel: {
interval: 0,
color: '#ffffff',
fontSize: '12',
fontWeight: 'bold',
fontFamily: 'siyuan',
rich: {
rank: {
color: '#0AE3FF',
fontSize: topLableSize,
fontWeight: 'bold',
fontFamily: 'siyuan',
},
title: {
color: '#fff',
align: 'right',
width: barWidth < 15 ? 90 : 150,
fontSize: topLableSize,
fontWeight: 'bold',
fontFamily: 'siyuan',
}
}
},
data: axisData
}, {
inverse: true,
axisTick: 'none',
axisLine: 'none',
offset: '30',
axisLabel: {
textStyle: {
color: '#ffffff',
fontSize: '0',
}
},
data: [10, 9, 8, 7, 6]
},],
series: [{
name: '条',
type: 'bar',
yAxisIndex: 0,
//柱状图自动排序,排序自动让Y轴名字跟着数据动
realtimeSort: true,
data: seriesData,
label: {
normal: {
show: true,
position: 'right',
distance: 20,
textStyle: {
color: '#ffffff',
fontSize: topLableSize,
fontWeight: 'bold',
fontFamily: 'siyuan',
}
}
},
barWidth: barWidth,
itemStyle: {
normal: {
barBorderRadius: [0, 30, 30, 0],
color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [{
offset: 0,
color: '#0f87fa'
}, {
offset: 1,
color: '#00befe'
}]),
}
},
z: 2
},
]
};
myChart.setOption(option, true);
window.addEventListener('resize', function () {
myChart.resize();
})
}
render() {
return (
<div id={this.props.id ? this.props.id : 'barChart0'} className='base-bar-chart' style={this.props.style ? this.props.style : { width: '80%', height: '3.75rem' }} />
)
}
}
import BarChart0 from './barChart0';
<BarChart0
chartData={{
axisData: ['指标名称1', '指标名称2', '指标名称3', '指标名称4', '指标名称5', '指标名称6', '指标名称7', '指标名称8', '指标名称9'],
seriesData: [6647, 7473, 8190, 8488, 9491, 8888, 6666, 7777, 8879]
}}
id="major-eval-bar2"
style={{ width: '6rem', height: '100%' }}
/>