本文将使用傻瓜式介绍,使用我所用的主题Sakura为例。其他主题灵活运用即可。

前排感谢matery
matery的GitHub:https://github.com/blinkfox/hexo-theme-matery

我的文章分析:http://cndrew.cn/analytics/

Attention:如果你很清楚的知道下面的步骤都是在做什么,各种文件你想放那随便放,但是如果你是小白,就跟着教程一步一步走。

首先在X:\nblog\source中新建一个文件夹analytics,用来生成文章分析的页面
在文件夹中新建一个文件index.md,文件内容为

---
title: analytics
date:
layout: analytics
---

然后下载echarts.min.js.这里给出下载链接:点我下载

然后在X:\nblog\themes\Sakura\layout中新建analytics.ejs
文件内容为

<div class="pattern-center-blank">
</div>
<div class="pattern-center ">
  <div class="pattern-attachment-img">
    <img src="https://cdn.jsdelivr.net/gh/drew233/cdn/20200303155335.webp" data-src="<%= page.photos %>" class="lazyload" onerror="imgError(this,3)" style="width: 100%; height: 100%; object-fit: cover; pointer-events: none;">
  </div>
        <style type="text/css">
                #contentss {
                    position: relative;
                    width: 800px;
                    height: 900px;
                    max-height: 1200px;
                    margin-bottom: 15px;
                    margin-top: 15px;
                    text-align: center;
                    border: 0;
                    border-radius: 10px;
                    color: rgba(0, 0, 0, .87);
                    background: #fff 50%;
                    background-size: cover;
                    box-shadow: 0 15px 35px rgba(50, 50, 93, .1), 0 5px 15px rgba(0, 0, 0, .07);
                    margin:0 auto;
                }
            </style>
  <header class="pattern-header ">
    <h1 class="entry-title">
    文章数据统计</h1>
  </header>
</div>
<div id="contentss">
<%- partial('_widget/post-charts') %>
</div>

说一下,这个ejs文件中最关键的是<%- partial('_widget/post-charts') %>,其他的都是为了迎合我的主题以及美化而已。

然后在X:\nblog\themes\Sakura\layout\_widget\中新建post-charts.ejs
文件内容为

<style type="text/css">
    #posts-chart,
    #categories-chart,
    #tags-chart {
        width: 100%;
        height: 300px;
        margin: 0.5rem auto;
        padding: 0.5rem;
    }
</style>

<div id="postCharts" class="post-charts">
    <div class="title center-align" data-aos="zoom-in-up">
    </div>
    <div class="row">
        <div class="chart col s12 m6 l4" data-aos="zoom-in-up">
            <div id="posts-chart"></div>
        </div>

        <div class="chart col s12 m6 l4" data-aos="zoom-in-up">
            <div id="categories-chart"></div>
        </div>

        <div class="chart col s12 m6 l4" data-aos="zoom-in-up">
            <div id="tags-chart"></div>
        </div>
    </div>
</div>

<script type="text/javascript" src="/js/echarts.min.js"></script>
<script>
    let postsChart = echarts.init(document.getElementById('posts-chart'));
    let categoriesChart = echarts.init(document.getElementById('categories-chart'));
    let tagsChart = echarts.init(document.getElementById('tags-chart'));

    <%
    /* calculate postsOption data. */
    var startDate = moment().subtract(1, 'years').startOf('month');
    var endDate = moment().endOf('month');

    var monthMap = new Map();
    var dayTime = 3600 * 24 * 1000;
    for (var time = startDate; time <= endDate; time += dayTime) {
        var month = moment(time).format('YYYY-MM');
        if (!monthMap.has(month)) {
            monthMap.set(month, 0);
        }
    }

    // post and count map.
    site.posts.forEach(function (post) {
        var month = post.date.format('YYYY-MM');
        if (monthMap.has(month)) {
            monthMap.set(month, monthMap.get(month) + 1);
        }
    });

    // xAxis data and yAxis data.
    var monthArr = JSON.stringify([...monthMap.keys()]);
    var monthValueArr = JSON.stringify([...monthMap.values()]);
    %>

    let postsOption = {
        title: {
            text: '文章发布统计图',
            top: 0,
            x: 'center'
        },
        tooltip: {
            trigger: 'axis'
        },
        xAxis: {
            type: 'category',
            data: <%- monthArr %>
        },
        yAxis: {
            type: 'value',
        },
        series: [
            {
                name: '<%- __("postsNumberName")  %>',
                type: 'line',
                color: ['#6772e5'],
                data: <%- monthValueArr %>,
                markPoint: {
                    symbolSize: 45,
                    color: ['#fa755a','#3ecf8e','#82d3f4'],
                    data: [{
                        type: 'max',
                        itemStyle: {color: ['#3ecf8e']},
                        name: '<%- __("maximum")  %>'
                    }, {
                        type: 'min',
                        itemStyle: {color: ['#fa755a']},
                        name: '<%- __("minimum")  %>'
                    }]
                },
                markLine: {
                    itemStyle: {color: ['#ab47bc']},
                    data: [
                        {type: 'average', name: '<%- __("average")  %>'}
                    ]
                }
            }
        ]
    };

    <%
    /* calculate categoriesOption data. */
    var categoryArr = [];
    site.categories.map(function(category) {
        categoryArr.push({'name': category.name, 'value': category.length})
    });

    var categoryArrJson = JSON.stringify(categoryArr);
    %>

    let categoriesOption = {
        title: {
            text: '文章分类统计图',
            top: 1,
            x: 'center'
        },
        tooltip: {
            trigger: 'item',
            formatter: "{a} <br/>{b} : {c} ({d}%)"
        },
        series: [
            {
                name: '<%- __("categories")  %>',
                type: 'pie',
                radius: '50%',
                color: ['#6772e5', '#ff9e0f', '#fa755a', '#3ecf8e', '#82d3f4', '#ab47bc', '#525f7f', '#f51c47', '#26A69A'],
                data: <%- categoryArrJson %>,
                itemStyle: {
                    emphasis: {
                        shadowBlur: 10,
                        shadowOffsetX: 0,
                        shadowColor: 'rgba(0, 0, 0, 0.5)'
                    }
                }
            }
        ]
    };

    <%
    /* calculate tagsOption data. */
    // get all tags name and count,then order by length desc.
    var tagArr = [];
    site.tags.map(function(tag) {
        tagArr.push({'name': tag.name, 'value': tag.length});
    });
    tagArr.sort((a, b) => {return b.value - a.value});

    // get Top 10 tags name and count.
    var tagNameArr = [];
    var tagCountArr = [];
    for (var i = 0, len = Math.min(tagArr.length, 10); i < len; i++) {
        tagNameArr.push(tagArr[i].name);
        tagCountArr.push(tagArr[i].value);
    }

    var tagNameArrJson = JSON.stringify(tagNameArr);
    var tagCountArrJson = JSON.stringify(tagCountArr);
    %>

    let tagsOption = {
        title: {
            text: 'Top10标签统计图 ',
            top: 2,
            x: 'center'
        },
        tooltip: {},
        xAxis: [
            {
                type: 'category',
                data: <%- tagNameArrJson %>
            }
        ],
        yAxis: [
            {
                type: 'value'
            }
        ],
        series: [
            {
                type: 'bar',
                color: ['#82d3f4'],
                barWidth : 18,
                data: <%- tagCountArrJson %>,
                markPoint: {
                    symbolSize: 45,
                    data: [{
                        type: 'max',
                        itemStyle: {color: ['#3ecf8e']},
                        name: '<%- __("maximum")  %>'
                    }, {
                        type: 'min',
                        itemStyle: {color: ['#fa755a']},
                        name: '<%- __("minimum")  %>'
                    }],
                },
                markLine: {
                    itemStyle: {color: ['#ab47bc']},
                    data: [
                        {type: 'average', name: '<%- __("average")  %>'}
                    ]
                }
            }
        ]
    };

    // render the charts
    postsChart.setOption(postsOption);
    categoriesChart.setOption(categoriesOption);
    tagsChart.setOption(tagsOption);
</script>

最后在主题的_config.yml文件中添加菜单栏中的analytics

统计: {path: /analytics/ , fa: fa-line-chart }

然后就可以了,效果如图: