flask框架和echarts的结合使用二(柱状图和矩形树状图)

在上一篇文章里,我们实现了借助flask框架和echars,成功的把后台的数据转化成了前端的图表,不过,当时没有细讲柱状图的参数配置。同时,我们还没开始制作矩形树状图。

这里先回顾一下堆积柱状图的配置。

在这里,x轴作为时间维度,对数据进行分组,其类型type: 'category',传入的数据months应该是一个列表。这里还有个问题,就是生成的月份数据的顺序是乱的,想要解决这个问题,可以在初始化echarts前加上months.sort()

我们要以数组的形式向echarts中传递数据,不同月份间的数据seriesData传出的数据如下:

展开某月的数据: series用来写入数据, type:"bar"表示柱状图,写入数据data:seriesData,因为前文在处理数据的时候,我们设置了value的值value:item.value,所以在series的时候,echarts会自动读取并设置数据。

因为我们还需要了解每个月的详细情况,所以做一个鼠标划过时显示信息的效果。这里需要配置tooltip,其中trigger表示何时触发显示,我使用的axis就表示在鼠标滑过数据的轴时显示数据trigger: 'axis',这种写法一般用于柱状图、折线图等有轴的图形;还有一种写法是trigger: 'item'能在鼠标划过某个具体的内容时显示提示,可以用在散点图。

js 复制代码
axisPointer: {
    type: 'shadow',
    shadowStyle: {
        color: 'rgb(73, 94, 87,0.3)' // 设置阴影颜色
    }
}

在我们的例子中,当鼠标滑过某月的数据,会显示详细信息。axisPointer会做一个触发效果,鼠标滑过某月时,背景会做一个阴影效果进行提示,color选择背景颜色。

tooltip内可以用formatter:来自定义提示的内容,这里需要用到循环,循环的结果items代表取出一个月的数据,如果某个月的数据存在,就从data中取出我们需要的数据并一个tooltipContent接受数据,最后用return返回数据。

js 复制代码
formatter:
        function(params) {
            tooltipContent= ""
            params.forEach(function(items){
                
                if (items.value > 0){
                    console.log(items.data)
                    for (var n = 0 ; n < items.data.name.length; n++){

                        var names = items.data.name[n]
                        var ymd =  items.data.ymd[n]
                        var content = items.data.content[n]
                        console.log(names)
                        tooltipContent += "<b>" + names + ymd +content + "</b>" + '<br>';}
                }
            })
            return tooltipContent                      
        }

这是items的结果他说一个月的数据,可以看到我们需要的数据存在data中,value表示聚合后的总分,我们要排除掉没有分的月,可以用items.value做条件判断。

js 复制代码
const months = Object.keys(agg);

const seriesData = Object.values(agg).map(item => {
    return {
        name:item.name,
        time:item.time,
        ymd:item.ymd,
        content:item.content,
        value:item.value

    }
});
months.sort()
var chart = echarts.init(document.querySelector("div"))
option = {
    title: {
        text: '每月人数统计图',
        left: 'center'
    },
    legend: {
        data: ['人数']
    },
   xAxis: {
        type: 'category',
        data: months
    },
    yAxis: {
        type: 'value'

    },
    tooltip:{
        trigger: 'axis',
        axisPointer: {
            type: 'shadow',
            shadowStyle: {
                color: 'rgb(73, 94, 87,0.3)' // 设置阴影颜色
            }
        },
        formatter:
        function(params) {
            tooltipContent= ""
            params.forEach(function(items){
                
                if (items.value > 0){
                    console.log(items.data)
                    for (var n = 0 ; n < items.data.name.length; n++){

                        var names = items.data.name[n]
                        var ymd =  items.data.ymd[n]
                        var content = items.data.content[n]
                        console.log(names)
                        tooltipContent += "<b>" + names + ymd +content + "</b>" + '<br>';}


                }


            })
            return tooltipContent                      
        }
    },

    series:[{
            type:"bar",
            data:seriesData,
            itemStyle:{
                color:"rgba(237, 125,49,0.7)"
            },
        }] 

};
option && chart.setOption(option);

这里我们就完成了一个堆叠柱状图,但他其实还存在一个问题,在每个月,一位练习生可能有多条记录,但我们没有根据个人聚合数据,如果我们想细分当月每个人的分数贡献,会存在一些问题。

在制作矩形树状图的过程中,我们要根据个人来聚合数据,除了计算个人的总分外。我们要准备的数据还包括个人加分的时间、分值、加分项目,当我们的数据滑过某个人时,要能显示有关分数的详细信息。

在取得数据以后,这次,我们根据姓名对数据进行聚合。

js 复制代码
response.data.forEach(function (item) {
    var name = item.name;
    var time = item.time;
    var items = item.item;
    var score = item.score;

    var fulltime = new Date(time)
    var year = fulltime.getUTCFullYear();
    var month = fulltime.getUTCMonth() + 1;
    var day = fulltime.getUTCDay()
    var ym = year + "-" + (month < 10 ? "0" + month : month)
    var ymd = year + "-" + (month < 10 ? "0" + month : month) + "-"  + (day < 10 ? "0" + day : day)
    if (!agg.hasOwnProperty(name)) {
        agg[name] = {
            name:name,
            time: [time],
            ymd: [ymd],
            content: [items],
            scorelist: [score],
            value: score
        }
    }
    else {
            agg[name].time.push(time),
            agg[name].ymd.push(ymd),
            agg[name].content.push(items),
            agg[name].scorelist.push(score), 
            agg[name].value += score}
});

取得的结果agg如下,但我们还要把每个人都数据都存入到一个列表当中。

js 复制代码
datalist = [];
for (var name in agg) {
    var data = agg[name];
    datalist.push(data);
}

结果如下: 最后,我们可以把准备好的数据写入echarts图表,这里的type: 'treemap'表示图表类型为矩形树状图,矩形树状图不同于折线图或或柱状图,没有x轴、y轴的概念,因此不需要进行设置。

这里有几个比较重要的配置:roam: false,限制图形拖动,如果不设置,那这个矩形树状图就可以在指定区域内进行拖动,建议关闭。trigger: 'item'把触发效果设置为针对某个人触发提示效果。

是否开启拖拽漫游(移动和缩放) 是否开启拖拽漫游(移动和缩放)。可取值有:

  • false:关闭。
  • 'scale''zoom':只能够缩放。
  • 'move''pan':只能够平移。
  • true:缩放和平移均可。
js 复制代码
option = {
title: {  // 配置标题组件
    text: '个人扣分情况',
    top: 15,
    textStyle: { color: '#ed7d31' },

},

series: [{
        type: 'treemap',
        data: datalist,
        label: {
            show: true,
            trigger: 'item',
            formatter: '{b}\n -{c}', 
            fontWeight: 'bold',
            color: "#191919"
        },
        roam: false
    }],
                    tooltip: {
    trigger: 'item',
    formatter: function (params) {
        console.log(params)
        var name = params.name;
        var value = params.value;
        var months = params.data.ymd;
        var secItems = params.data.content;
        var scorelist = params.data.scorelist
        var detail = []
        for (var i = 0; i < secItems.length; i++) {
            var message = months[i] + " " + scorelist[i] + " " + secItems[i] + '</br>';
            detail.push(message)
        }
        // return name + ' (' + secItems.length + '项)' + ': -' + value;
        return name + "</br>" + detail;
    },
    // formatter: '{b}: {c}' // 提示框显示的文本格式,{b} 表示名字,{c} 表示分数
},


};
option && chart1.setOption(option);

完整代码:

html 复制代码
    <div id="treemap" style="width: 600px;height: 400px;"></div>
    <script>
       chart1 = echarts.init(document.getElementById('treemap'));
        $.ajax({
            type: "GET",
            url: "/data",
            success: function (response) {
                const agg = {}
                response.data.forEach(function (item) {
                    var name = item.name;
                    var time = item.time;
                    var items = item.item;
                    var score = item.score;

                    var fulltime = new Date(time)
                    var year = fulltime.getUTCFullYear();
                    var month = fulltime.getUTCMonth() + 1;
                    var day = fulltime.getUTCDay()
                    var ym = year + "-" + (month < 10 ? "0" + month : month)
                    var ymd = year + "-" + (month < 10 ? "0" + month : month) + "-"  + (day < 10 ? "0" + day : day)
                    if (!agg.hasOwnProperty(name)) {
                        agg[name] = {
                            name:name,
                            time: [time],
                            ymd: [ymd],
                            content: [items],
                            scorelist: [score],
                            value: score
                        }
                    }
                    else {
                            agg[name].time.push(time),
                            agg[name].ymd.push(ymd),
                            agg[name].content.push(items),
                            agg[name].scorelist.push(score), 
                            agg[name].value += score}
                });

                console.log(agg)


                datalist = [];
                for (var name in agg) {
                    var data = agg[name];
                    datalist.push(data);
                }
                console.log(datalist)

                option = {
                    title: {  // 配置标题组件
                        text: '个人扣分情况',
                        top: 15,
                        textStyle: { color: '#ed7d31' },

                    },

                    series: [{
                            type: 'treemap',
                            data: datalist,
                            label: {
                                show: true,
                                trigger: 'item',
                                formatter: '{b}\n -{c}', 
                                fontWeight: 'bold',
                                color: "#191919"
                            },
                            roam: false,
                            zzoomToNodeRatio: 1
                        }],
                                        tooltip: {
                        trigger: 'item',
                        formatter: function (params) {
                            console.log(params)
                            var name = params.name;
                            var value = params.value;
                            var months = params.data.ymd;
                            var secItems = params.data.content;
                            var scorelist = params.data.scorelist
                            var detail = []
                            for (var i = 0; i < secItems.length; i++) {
                                var message = months[i] + " " + scorelist[i] + " " + secItems[i] + '</br>';
                                detail.push(message)
                            }
                            // return name + ' (' + secItems.length + '项)' + ': -' + value;
                            return name + "</br>" + detail;
                        },
                        // formatter: '{b}: {c}' // 提示框显示的文本格式,{b} 表示名字,{c} 表示分数
                    },
                    
                    
                };
                option && chart1.setOption(option);
            }
        })
    </script>
相关推荐
别拿曾经看以后~42 分钟前
【el-form】记一例好用的el-input输入框回车调接口和el-button按钮防重点击
javascript·vue.js·elementui
川石课堂软件测试1 小时前
性能测试|docker容器下搭建JMeter+Grafana+Influxdb监控可视化平台
运维·javascript·深度学习·jmeter·docker·容器·grafana
JerryXZR1 小时前
前端开发中ES6的技术细节二
前端·javascript·es6
problc1 小时前
Flutter中文字体设置指南:打造个性化的应用体验
android·javascript·flutter
Gavin_9151 小时前
【JavaScript】模块化开发
前端·javascript·vue.js
懒大王爱吃狼2 小时前
Python教程:python枚举类定义和使用
开发语言·前端·javascript·python·python基础·python编程·python书籍
待磨的钝刨3 小时前
【格式化查看JSON文件】coco的json文件内容都在一行如何按照json格式查看
开发语言·javascript·json
前端青山8 小时前
Node.js-增强 API 安全性和性能优化
开发语言·前端·javascript·性能优化·前端框架·node.js
从兄9 小时前
vue 使用docx-preview 预览替换文档内的特定变量
javascript·vue.js·ecmascript
清灵xmf11 小时前
在 Vue 中实现与优化轮询技术
前端·javascript·vue·轮询