归档页贡献图
什么是归档页贡献图?您可以在导航栏 功能页 -> 归档页 点击查看。
安装 Echarts 依赖
首先需要安装 Echarts 依赖,根据您项目的包管理器选择安装方式:
sh
pnpm add -D echarts
sh
yarn add -D echarts
sh
npm add -D echarts
创建贡献图组件
在 .vitepress/theme/components
目录下创建 ContributeChart.vue
文件,并添加以下代码:
vue
<script setup lang="ts" name="ContributeChart">
import * as echarts from "echarts";
import { ref, watch, nextTick, computed, useTemplateRef } from "vue";
import { useData } from "vitepress";
import { formatDate, usePosts } from "vitepress-theme-teek";
const { isDark } = useData();
const posts = usePosts();
// 今天
const today = formatDate(new Date(), "yyyy-MM-dd");
// 获取前一年的时间
const beforeOnYear = formatDate(new Date(new Date().getTime() - 365 * 24 * 60 * 60 * 1000), "yyyy-MM-dd");
// 贡献图数据
const contributeList = computed(() => {
const contributeObject = ref({});
posts.value.sortPostsByDate.forEach(item => {
if (!item.date) return;
const date = item.date.substring(0, 10);
if (contributeObject.value[date]) contributeObject.value[date]++;
else contributeObject.value[date] = 1;
});
const contributeDays = Object.keys(contributeObject.value);
return contributeDays.map((item: string) => [item, contributeObject.value[item]]).reverse();
});
const chartRef = useTemplateRef("chartRef");
const contributeChart = ref();
// Echarts 配置项
const option = {
tooltip: {
formatter: function (params) {
return `${params.value[0]} <br/> ${params.value[1]} 篇文章`;
},
},
visualMap: {
show: false,
min: 0,
max: 5,
inRange: {
color: ["#ebedf0", "#c6e48b", "#7bc96f", "#239a3b", "#196127", "#196127"],
},
},
calendar: {
left: "center",
itemStyle: {
color: "#ebedf0",
borderWidth: 5,
borderColor: "#fff",
shadowBlur: 0,
},
cellSize: [20, 20],
range: [beforeOnYear, today],
splitLine: true,
dayLabel: {
firstDay: 7,
nameMap: "ZH",
color: "#3c3c43",
},
monthLabel: {
color: "#3c3c43",
},
yearLabel: {
show: true,
position: "right",
},
silent: {
show: false,
},
},
series: {
type: "heatmap",
coordinateSystem: "calendar",
data: [],
},
};
// 渲染贡献图
const renderChart = (data: any) => {
option.calendar.itemStyle.borderColor = isDark.value ? "#1b1b1f" : "#fff";
option.calendar.itemStyle.color = isDark.value ? "#787878" : "#ebedf0";
if (contributeChart.value) echarts.dispose(contributeChart.value);
if (chartRef.value) contributeChart.value = echarts.init(chartRef.value);
option.series.data = data;
contributeChart.value?.setOption(option);
};
watch(
contributeList,
async newValue => {
await nextTick();
renderChart(newValue);
},
{ immediate: true }
);
watch(isDark, () => {
renderChart(contributeList.value);
});
</script>
<template>
<div class="contribute__chart">
<div class="chart__box" ref="chartRef"></div>
</div>
</template>
<style>
.tk-article-page.tk-archives {
width: 1220px;
}
.tk-archives .contribute__chart {
width: 100%;
height: 260px;
}
.tk-archives .contribute__chart .chart__box {
margin: auto;
width: 100%;
height: 100%;
}
</style>
组件默认时间是近两年,且颜色已在代码里体现,您可以自行修改为你喜欢的风格。
使用贡献图组件
在 .vitepress/theme/index.ts
中通过 Teek 提供的归档页顶部插槽插入贡献图组件。
ts
import Teek from "vitepress-theme-teek";
import ContributeChart from "./components/ContributeChart.vue";
import { h } from "vue";
export default {
extends: Teek,
Layout: () =>
h(Teek.Layout, null, {
"teek-archives-top-before": () => h(ContributeChart),
}),
};