0. 前言
柱状图
(Bar Chart),也称为条形图,是一种常用的数据可视化图表,用于展示不同类别的数据量。 它通过水平或垂直的条形来表示数据的大小,条形的长度或高度与它们所代表的值成比例。
有许多JavaScript库可以帮助你快速创建柱状图,其中一些流行的包括: Chart.js
、D3.js
、Highcharts
、ECharts
等。
今天,我们将从0开始,基于Vue3,仅使用CSS3动画来实现一个最基础的柱状图。
1. 数据生成
1-1. 类型定义
ts
interface BarItem {
id: string; // ID
title: string; // 标题
val: number; // 数值
}
interface BarChartItem extends BarItem {
percent: string; // 整体占比
}
1-2. 计算占比
ts
import { random, maxBy } from 'lodash-es';
// 数据列表
const barItems: Ref<BarItem[]> = ref([])
// 自动计算百分比
const barChartItems = computed<BarChartItem[]>(() => {
// 最大值
const maxItem = maxBy(barItems.value, item => item.val)
if (!maxItem) return []
return barItems.value.map(item => {
return {
percent: (item.val / maxItem?.val * 100).toFixed(1),
...item,
}
})
})
使用数据项中的最大值作为基准,计算所有项的百分比。此百分比将用于后续展示柱状图的高度。
1-3. 添加、删除数据
ts
import { random, maxBy, times } from 'lodash-es';
// 添加一项数据
const addItem = () => {
barItems.value.push({
id: useId(),
title: `${curIdx.value++}-${faker.commerce.department()}`,
val: random(1, 200)
})
}
// 删除一项
const delItem = () => {
const idx = random(0, barItems.value.length - 1)
barItems.value.splice(idx, 1)
}
// 随机增加数值
const addVal = () => {
barItems.value.forEach((item) => {
item.val = Math.max(1, item.val + random(-50, 50))
})
}
onMounted(() => {
// 初始化默认添加5项数据
times(5, addItem)
})
addItem
:添加一项数据项,并生成1-200的随机值;同时这里我们使用faker
来生成一个公司部门名称作为标题。delItem
: 随机删除一条数据。addVal
:为每个数据项随机增加-50到50的数据值,来模拟数据值变化的效果。页面初始化
:默认添加5项数据
2. 页面结构
2-1. 数据操作
html
<n-button-group>
<n-button @click="addItem">添加一项</n-button>
<n-button @click="delItem">删除一项</n-button>
<n-button @click="addVal">添加随机值</n-button>
</n-button-group>
添加操作按钮,手动调整柱状图数据。
2-2. 柱状图
html
<TransitionGroup name="list" tag="section" class="flex flex-row h-500px self-center gap-x-5">
<div v-for="item in barChartItems" :key="item.id" class="flex flex-col h-full w-60px">
<section class="flex-1 relative flex flex-col-reverse items-center">
<div class="w-full transition transition-height transition-duration-500 bg-[#5771c0]" :style="{ height: `${item.percent}%` }"></div>
<span class="text-[#333] font-bold text-base text-center">{{ item.val }}</span>
</section>
<span class="mt-3 text-[#333] font-bold text-center text-base">{{ item.title }}</span>
</div>
</TransitionGroup>
使用v-for
循环生成柱状图数据项,并制定柱状图颜色; 这里使用了Unocss
的transition transition-height transition-duration-500
来设置柱状图高度变化时的transition
动效。
2-3. transition
css
.list-move, /* 对移动中的元素应用的过渡 */
.list-enter-active,
.list-leave-active {
transition: all 0.5s ease;
}
.list-enter-from,
.list-leave-to {
opacity: 0;
transform: translateY(30px);
}
.list-leave-active {
position: absolute;
}
使用Vue
自带的组件TransitionGroup组件为柱状图元素在增加或删除时,添加过度动效。
3. 最终效果
最后我们运行一下,查看最终效果:
以上全部代码已经分享到Gitee上,如有所需,欢迎自取。