如何在jpress上添加分类雷达统计图(二)?

上一篇文章《如何在jpress上添加分类雷达统计图(一)》中,我们完成了使用echarts展示分类雷达图的前端样式,我们继续来开发后端数据调用的工作,完成将前端写死的数据调用后端从数据库中查出来的数据。

最终效果如下图:

首先我们定义一个service接口,如下:

package com.miigua.japress.charts.service;

import io.jboot.db.model.Column;
import io.jboot.db.model.Columns;
import io.jboot.service.JbootServiceJoiner;
import io.jpress.module.article.model.Article;
import io.jpress.module.article.model.ArticleCategory;

import java.util.List;

public interface CategoryService <ArticleCategory> extends JbootServiceJoiner {
    List<io.jpress.module.article.model.ArticleCategory> getCategoryList(Columns column , String orderBy , int count , String cacheKey);
}

此接口中只有一个方法,用来做数据查询使用,其中 cacheKey 是为了做缓存而使用的。

我们来看这个service的实现类:

package com.miigua.japress.charts.provider;

import com.miigua.japress.charts.service.CategoryService;
import com.miigua.japress.charts.service.ChartsArticleService;
import io.jboot.aop.annotation.Bean;
import io.jboot.components.cache.CacheTime;
import io.jboot.components.cache.annotation.Cacheable;
import io.jboot.db.model.Column;
import io.jboot.db.model.Columns;
import io.jboot.service.JbootServiceBase;
import io.jpress.module.article.model.Article;
import io.jpress.module.article.model.ArticleCategory;

import java.util.List;

@Bean
public class CategoryProvider extends JbootServiceBase<ArticleCategory> implements CategoryService {

    @Override
    @Cacheable(name = "japress-charts", key = "catortag-#(cacheKey)", liveSeconds = 30 * CacheTime.MINUTE, nullCacheEnable = true)
    public List<ArticleCategory> getCategoryList(Columns column , String orderBy , int count , String cacheKey){
        return DAO.findListByColumns(column,orderBy,count);
    }
}

通过传入的参数查询数据库并返回,这里为了减少数据库的压力,我使用cacheKey做了缓存。

然后我们编写一个Directive用于与前端交互输出:

package com.miigua.japress.charts.directive;

import com.jfinal.aop.Inject;
import com.jfinal.template.Env;
import com.jfinal.template.io.Writer;
import com.jfinal.template.stat.Scope;
import com.miigua.japress.charts.service.CategoryService;
import io.jboot.db.model.Columns;
import io.jboot.web.directive.annotation.JFinalDirective;
import io.jboot.web.directive.base.JbootDirectiveBase;
import io.jpress.module.article.model.ArticleCategory;
import org.apache.commons.lang3.StringUtils;

import java.util.List;

@JFinalDirective("japressCategoriesOrTags")
public class CategoryDirective  extends JbootDirectiveBase {

    @Inject
    private CategoryService categoryService;

    @Override
    public void onRender(Env env, Scope scope, Writer writer) {
        String flag = getPara("flag", scope);
        Boolean containsParent = getParaToBool("containsParent", scope, false);
        String orderBy = getPara("orderBy", scope , "order_number asc");
        int count = getParaToInt("count", scope, Integer.MAX_VALUE);
        String type = getPara("type", scope, ArticleCategory.TYPE_CATEGORY);

        StringBuilder key = new StringBuilder();
        key.append(count).append("-").append(type).append("-").append(flag).append("-").append(containsParent).append("-").append(orderBy.replace(" ",""));
        Columns columns = Columns.create("type", type);
        if(StringUtils.isNotBlank(flag)){
            columns.eq("flag",flag);
        }
        if(!containsParent && type.equals(ArticleCategory.TYPE_CATEGORY)){
            columns.ne("pid",0);
        }
        List categoryList = categoryService.getCategoryList(columns, orderBy, count,key.toString());
        scope.setLocal("japressCategoriesOrTags", categoryList);
        renderBody(env, scope, writer);

    }

    @Override
    public boolean hasEnd() {
        return true;
    }
}

这个类中,我们定义了一个名为标签  japressCategoriesOrTags ,在前端我们就可以通过 #japressCategoriesOrTags() ,注意 hasEnd() 方法返回了 true ,这就要求我们前端的标签要搭配 #end 作为结束。

onRender 方法是具体的逻辑代码,这里接收前端传来的参数并调用service中的方法来做数据查询,最终将数据渲染到页面。

注意 scope.setLocal("japressCategoriesOrTags", categoryList); ,这里我们设置了一个前端可以获取到的变量,变量名为 japressCategoriesOrTags ,我们在前端就可以通过这个名字获取数据,例如我们要循环获取数据,前端调用如下:

#japressCategoriesOrTags('category','',false,10,'count desc')
#for(category : japressCategoriesOrTags)
分类名:#(category.title) , 文章数量:#(category.count)
#end
#end

在上面例子中,我们获取所有前10条子分类数据,并以分类下文章数量作为倒序来排序。

那么,接下来我们就把代码和echarts图表结合起来,这里为了调用方便,我将图表封装到了一个单独的 html 文件中,japress-charts.html,使用时我们只需要引入这个文件即可,此文件代码如下:

<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/echarts@5.2.1/dist/echarts.min.js"></script>
<script type="text/javascript">
    var face ="light";
    var color1, color2, color3, color4;
    if("light" === face){
        color1 = ["#ebedf0", "#c6e48b", "#7bc96f", "#239a3b", "#196127"];
        color2 = "#ffffff";
        color3 = "#3C4858";
        color4 = "#f9f9f9";
    }else{
        color1 = ["#ebedf0", "#c6e48b", "#7bc96f", "#239a3b", "#196127"];
        color2 = "#000";
        color3 = "#fff";
        color4 = "#212121";
    }
</script>
<!--分类雷达图-->
#define japressCategoryRadar(width,height,type,flag,containsParent,count,orderBy)
#japressCategoriesOrTags(type=type,flag=flag,containsParent=containsParent,count=count,orderBy=orderBy)
#if(japressCategoriesOrTags.size()>0)
<div id="japressCategoryRadar" style="width: #(width ?? '100%') ; height: #(height ?? '185px')"></div>
<script type="text/javascript">
    function showJapressCategoryRadar(){
        var mydata = [];
        mydata.push(#for(category : japressCategoriesOrTags) {name:"#(category.title)",value:#(category.count)}, #end);
        var max = 0;
        for (var i = 0 ; i < mydata.length ; i++){
            var d = mydata[i];
            if(d.value > max) max = d.value;
        }
        var indicatorData = [];
        var seriesData = [];
        for (var i = 0 ; i < mydata.length ; i++){
            var d = mydata[i];
            indicatorData.push({name:d.name , max:max});
            seriesData.push(d.value);
        }
        var chartDom = document.getElementById('japressCategoryRadar');
        var myChart = echarts.init(chartDom);
        var option = {
            tooltip: {},
            radar: {
                top: 0,
                name: {
                    textStyle: {
                        color: color3
                    }
                },
                indicator: indicatorData,
                center: ["50%", "50%"],
                radius: "66%"
            },
            series: [{
                type: "radar",
                color: ["#3ecf8e"],
                itemStyle: {
                    normal: {
                        areaStyle: {
                            type: "default"
                        }
                    }
                },
                data: [{
                    value: seriesData,
                    name: "文章分类数量"
                }]
            }]
        };
        option && myChart.setOption(option);
    }
    showJapressCategoryRadar();
</script>
#end
#end
#end

到这里,我们的分类雷达图插件就完成了,将后端的代码打包为jar包,拖到jpress后台安装即可使用。

最终前端模板我们只需要依据代码即可完成雷达图的展示,调用如下:

#@japressCategoryRadar('400px','250px','category','',false,10,'count desc')

以上我们便完成了在jpress上分类雷达图的展示,如果你对如何打包插件如何开发插件有疑问或者兴趣,推荐你阅读《如何从零开发一个jpress的插件》,该文章以一个简单的友情链接插件为例,全面讲解了插件的文件目录结构以及如何编写、打包、安装插件。

欢迎小伙伴留言讨论哟。

版权声明:
作者:Miigua
链接:https://www.miigua.com/article/316.html
来源:米瓜的博客
文章版权归作者所有,未经允许请勿转载。

THE END
二维码
打赏
请在后台主题设置处设置打赏图片
< <上一篇
下一篇>>