前言
在 echarts 中,动态排序柱状图是一种常用图表,可以帮助我们更好地理解数据的变化和排序规律。本文将介绍如何使用 echarts 库创建动态排序柱状图,以展示数据的变化趋势和排序情况。
完整代码
<template>
<div class="acrossStyle">
<div id="acrossChart" :style="{ width: '100%', height: '100%' }"></div>
</div>
</template>
<script>
export default {
mounted() {
const dataArr = [
{
cdate: "2000",
cname: "水蜜桃,蓝莓,猕猴桃,香蕉,美人指,杨桃,草莓",
cut: "223, 234, 345, 456, 567, 678, 789",
},
{
cdate: "2001",
cname: "水蜜桃,蓝莓,猕猴桃,香蕉,美人指,杨桃,草莓",
cut: "234, 345, 456, 567, 678, 789, 890",
},
{
cdate: "2002",
cname: "水蜜桃,蓝莓,猕猴桃,香蕉,美人指,杨桃,草莓",
cut: "245, 456, 567, 678, 789, 890, 901",
},
{
cdate: "2003",
cname: "水蜜桃,蓝莓,猕猴桃,香蕉,美人指,杨桃,草莓",
cut: "256, 567, 678, 789, 890, 901, 123",
},
{
cdate: "2004",
cname: "水蜜桃,蓝莓,猕猴桃,香蕉,美人指,杨桃,草莓",
cut: "267, 678, 789, 890, 901, 123, 234",
},
{
cdate: "2005",
cname: "水蜜桃,蓝莓,猕猴桃,香蕉,美人指,杨桃,草莓",
cut: "278, 789, 890, 901, 123, 234, 345",
},
{
cdate: "2006",
cname: "水蜜桃,蓝莓,猕猴桃,香蕉,美人指,杨桃,草莓",
cut: "289, 890, 901, 123, 234, 345, 456",
},
{
cdate: "2007",
cname: "水蜜桃,蓝莓,猕猴桃,香蕉,美人指,杨桃,草莓",
cut: "290, 901, 123, 234, 345, 456, 567",
},
{
cdate: "2008",
cname: "水蜜桃,蓝莓,猕猴桃,香蕉,美人指,杨桃,草莓",
cut: "201, 123, 234, 345, 456, 567, 678",
},
{
cdate: "2009",
cname: "水蜜桃,蓝莓,猕猴桃,香蕉,美人指,杨桃,草莓",
cut: "123, 234, 345, 456, 567, 678, 789",
},
{
cdate: "2010",
cname: "水蜜桃,蓝莓,猕猴桃,香蕉,美人指,杨桃,草莓",
cut: "234, 345, 456, 567, 678, 789, 890",
},
{
cdate: "2011",
cname: "水蜜桃,蓝莓,猕猴桃,香蕉,美人指,杨桃,草莓",
cut: "345, 456, 567, 678, 789, 890, 901",
},
];
// 处理数据
this.acrossEcharts(this.processData(dataArr));
},
methods: {
// 处理数据方法
processData(dataArr) {
return dataArr.map((data) => {
const cname = data.cname.split(",");
const cut = data.cut.split(",");
return {
cdate: data.cdate,
cname,
cut,
};
});
},
acrossEcharts(dataArr) {
// 颜色映射表
const countryColors = {
水蜜桃: "#FFC0CB",
蓝莓: "#191970",
猕猴桃: "#2E8B57",
香蕉: "#FFC107",
美人指: "#800080",
杨桃: "#D4F2E7",
草莓: "#DC143C",
};
const myChart = this.$echarts.init(
document.getElementById("acrossChart")
);
// 更新频率
const updateFrequency = 700;
// 起始年份、名称和数量
const startYear = dataArr[0].cdate;
const startName = dataArr[0].cname;
const startCut = dataArr[0].cut;
// 按照更新频率逐年渲染图表
dataArr.forEach((year, i) => {
setTimeout(() => {
updateYear(year);
}, (i + 1) * updateFrequency);
});
function updateYear(year) {
option.yAxis.data = year.cname;
option.series[0].data = year.cut;
option.graphic.elements[0].style.text = year.cdate;
myChart.setOption(option);
}
const option = {
xAxis: {
max: "dataMax", //取数据中的最大值作为最大刻度
splitLine: {
// 分隔线配置项
show: true,
},
axisLabel: {
//x轴标签配置项
formatter: (n) => Math.round(n) + "",
},
},
dataset: {
//数据集配置项,这里使用dataArr作为数据源
source: dataArr,
},
yAxis: {
type: "category", //类型,这里设置为"category"表示分类轴
inverse: true, //是否反向显示,这里设置为true表示反向显示
max: 6, //y轴的最大值,这里设置为6
data: startName, //y轴的刻度标签数据,这里使用startName作为刻度标签
axisLabel: {
//y轴标签配置项
show: true,
fontSize: 14,
},
animationDuration: 300, //动画时长 缓动效果
animationDurationUpdate: 300, //排序(柱图上升或者下降)动画完成时间
},
series: [
{
realtimeSort: true, //是否实时排序
seriesLayoutBy: "column", //数据排列方式,这里设置为"column"表示按列排列
type: "bar", //系列类型,这里设置为"bar"表示柱状图
itemStyle: {
color: function (param) {
//设置每个分类对应的柱状颜色
return countryColors[param.name];
},
},
encode: {
//数据映射配置项
x: 0, //x轴映射到数据的第0列
y: 3, //y轴映射到数据的第3列
},
label: {
//数据标签配置项
show: true, //显示数值
precision: 2, //保留小数点几位
position: "right", //居右
valueAnimation: true, //开启数值动画
fontFamily: "monospace", //字体选择
formatter: `{c}吨`, //标签格式化函数,这里使用模板字符串将数值添加单位"吨"
},
data: startCut, //数据项,这里使用startCut作为数据
},
],
animationDuration: 600, //动画时长 缓动效果
animationDurationUpdate: 600, //排序(柱图上升或者下降)动画完成时间
animationEasing: "linear", //初始动画缓动效果,这里设置为"linear",表示线性缓动
animationEasingUpdate: "linear", //数据更新时的动画缓动效果,这里设置为"linear",表示线性缓动
graphic: {
//图形元素配置项
elements: [
// 年份样式
{
type: "text",
right: 160,
bottom: 60,
style: {
text: startYear,
font: "bolder 60px monospace",
fill: "rgba(100, 100, 100, 0.25)",
},
z: 100,
},
],
},
};
myChart.setOption(option);
window.addEventListener("resize", () => {
myChart.resize();
});
},
},
};
</script>
<style scoped>
.acrossStyle {
width: 50%;
height: 50vh;
}
</style>
实现思路
以上代码就实现了一个基于 vue
和 echarts
的动态柱状图,可以根据数据源中的年份、名称和数量逐年渲染图表,并支持实时排序和动画效果。
- 首先,在
vue
组件的mounted
钩子函数中,我们将数据源dataArr
传入processData
方法进行处理,将名称和数量分别转化为数组,并将处理后的数据作为参数传入acrossEcharts
方法中; - 在
acrossEcharts
方法中,我们首先定义了一个颜色映射表countryColors
,用于将每个分类对应的柱状颜色进行设置。然后,我们使用echarts
的init
方法初始化图表,并设置了一些基本的配置项,如x
轴、y
轴、数据集、系列类型等; - 接下来,我们定义了一个
updateFrequency
变量,表示每年更新的时间间隔。然后,我们将起始年份、名称和数量分别赋值给startYear
、startName
和startCut
变量,并使用forEach
方法遍历数据源中的每一年数据,使用setTimeout
方法将每年的数据传入updateYear
方法中,并在updateFrequency
的时间间隔后进行渲染; - 在
updateYear
方法中,我们将当前年份的名称和数量分别赋值给option.yAxis.data
和option.series[0].data
,并将当前年份的年份值赋值给option.graphic.elements[0].style.text
,最后使用myChart.setOption
方法将option
配置项应用到图表中; - 在
option
配置项中,我们设置了x
轴的最大值、分隔线、标签格式化函数等,设置了y
轴的类型、反向显示、最大值、刻度标签数据等,设置了柱状图的实时排序、数据映射、标签格式化函数等,同时还设置了动画时长、缓动效果、图形元素等; - 最后,我们使用
window.addEventListener
方法监听resize
事件,当窗口大小发生变化时,调用myChart.resize
方法重新渲染图表。
实现效果