【Echarts】【ES6】柱状图/柱状叠图按照y值从高到低排序

简单粗暴地上code:

const chartOptionsGeneration = (data) => {
    const options = {
        toolbox: {
            y: 'bottom',
            feature: {
                dataView: {show: true, readOnly: false},
                restore: {show: true},
                saveAsImage: {show: true}
            }
        },
        tooltip: {
            trigger: 'axis',
            axisPointer: {           
                type: 'shadow'        
            }
        },
        legend: {
            data: []
        },
        grid: {
            left: '3%',
            right: '4%',
            bottom: '3%',
            top: '5%',
            containLabel: true
        },
        yAxis: {
            type: 'value'
        },
        xAxis: {
            type: 'category',
            // triggerEvent: true,
            // formatter: function(value) {
            //     return (value.length > 10 ? (value.slice(0,5)+"...") : value )
            // },
            axisTick: {
                alignWithLabel: true
            },
            axisLabel: {    
                interval: 0,   
                rotate: 15,
                textStyle: {
                    color: '#000',
                    fontSize: 10
                }
            },
            data: []
        }, 
        series: []

    }
    options['legend']['data'] = data['legend'];
    options['series'] = data['series']

    options['xAxis']['data'] = data['x_axis'].sort((prev, post) => { 
        // get sum of fail for the same x_axis: loop series, get data of each series item, if it contains this xaxis, get its yaxis
        // prev and post are both x_axis
        console.log(prev, post)
        const prev_y_num = data[by]['series'].reduce((total_fail, item) =>{
            return total_fail + item['data'].reduce( (fail, point) =>{ 
                if(point[0] === prev){
                    return fail + point[1]
                }else{
                    return fail;
                }
            } , 0);
        }, 0)
        const post_y_num = data['series'].reduce((total_fail, item) =>{
            return total_fail + item['data'].reduce( (fail, point) =>{ 
                if(point[0] === post){
                    return fail + point[1]
                }else{
                    return fail;
                }
            } , 0);
        }, 0)
        console.log(prev_y_num, post_y_num)
        return post_y_num - prev_y_num;
    });

    return options

}

所需的数据结构如下:

data = {
'legend': ['直接访问', '邮件营销', '联盟广告', '视频广告', '搜索引擎'],
'x_axis': ['周一', '周二', '周三', '周四', '周五', '周六', '周日'],
'series': [
        {
            name: '直接访问',
            type: 'bar',
            stack: '总量',
            label: {
                show: true,
                position: 'insideRight'
            },
            data: [['周一',320],['周三', 302]]
        },
        {
            name: '邮件营销',
            type: 'bar',
            stack: '总量',
            label: {
                show: true,
                position: 'insideRight'
            },
            data: [['周四',320],['周三', 302], ['周二',320],['周六', 302]]
        },
        {
            name: '联盟广告',
            type: 'bar',
            stack: '总量',
            label: {
                show: true,
                position: 'insideRight'
            },
            data: [['周二',320],['周一', 302], ['周三',320],['周五', 302]]
        },
        {
            name: '视频广告',
            type: 'bar',
            stack: '总量',
            label: {
                show: true,
                position: 'insideRight'
            },
            data: [['周一',320],['周三', 302], ['周二',320],['周四', 302]]
        },
        {
            name: '搜索引擎',
            type: 'bar',
            stack: '总量',
            label: {
                show: true,
                position: 'insideRight'
            },
            data: [['周五',320],['周四', 302], ['周一',320],['周三', 302]]
        }
    ]

}

 

解释一下为啥要这么做。

首先如果不做任何处理,直接使用上面的数据生成chart,会长什么样呢?

那么,如果我们想要做到按照每根柱子的高度来从高到低排序,要怎么做呢?

就是要重排xAxis中的值,根据是xAxis中每个值对应的柱子高。

那么,我们要做的就是,遍历原xAxis的值(存放于data['x_axis']),对于每一个x值,取出series中每一个元素的值数组(如data['series'][0]['data'])。这个值数组中的每个元素都是一个数组,其中第一个值是横坐标值,第二个值是在y轴上的高度,那么如果这个值数组里头包含了当前的x值,把它找出来,对应的y值加起来。

把series中的每一个元素都这么操作一遍,就能找出某个x值的柱高。

对所有的x值都操作一遍,就能找出所有x值对应的柱高。

之后就sort一下就行了。

结果:

完整的例子。copy到echarts的实例里就可以用。比如https://echarts.apache.org/examples/zh/editor.html?c=bar-y-category-stack

option = {
    tooltip: {
        trigger: 'axis',
        axisPointer: {            // 坐标轴指示器,坐标轴触发有效
            type: 'shadow'        // 默认为直线,可选为:'line' | 'shadow'
        }
    },
    legend: {
        data: ['直接访问', '邮件营销', '联盟广告', '视频广告', '搜索引擎']
    },
    grid: {
        left: '3%',
        right: '4%',
        bottom: '3%',
        containLabel: true
    },
    yAxis: {
        type: 'value'
    },
    xAxis: {
        type: 'category',
        data: ['周一', '周二', '周三', '周四', '周五', '周六', '周日']
    },
    series:  [
        {
            name: '直接访问',
            type: 'bar',
            stack: '总量',
            label: {
                show: true,
                position: 'insideRight'
            },
            data: [['周一',320],['周三', 302]]
        },
        {
            name: '邮件营销',
            type: 'bar',
            stack: '总量',
            label: {
                show: true,
                position: 'insideRight'
            },
            data: [['周四',320],['周三', 302], ['周二',320],['周六', 302]]
        },
        {
            name: '联盟广告',
            type: 'bar',
            stack: '总量',
            label: {
                show: true,
                position: 'insideRight'
            },
            data: [['周二',320],['周一', 302], ['周三',320],['周五', 302]]
        },
        {
            name: '视频广告',
            type: 'bar',
            stack: '总量',
            label: {
                show: true,
                position: 'insideRight'
            },
            data: [['周一',320],['周三', 302], ['周二',320],['周四', 302]]
        },
        {
            name: '搜索引擎',
            type: 'bar',
            stack: '总量',
            label: {
                show: true,
                position: 'insideRight'
            },
            data: [['周五',320],['周四', 302], ['周一',320],['周三', 302]]
        }
    ]

};

//为了适应echarts的实例运行环境,对code做了小小的修改。不影响大局。

    option['xAxis']['data'] = option['xAxis']['data'].sort((prev, post) => { 
        // get sum of fail for the same x_axis: loop series, get data of each series item, if it contains this xaxis, get its yaxis
        // prev and post are both x_axis
        console.log(prev, post)
        const prev_y_num = option['series'].reduce((total_fail, item) =>{
            return total_fail + item['data'].reduce( (fail, point) =>{ 
                if(point[0] === prev){
                    return fail + point[1]
                }else{
                    return fail;
                }
            } , 0);
        }, 0)
        const post_y_num = option['series'].reduce((total_fail, item) =>{
            return total_fail + item['data'].reduce( (fail, point) =>{ 
                if(point[0] === post){
                    return fail + point[1]
                }else{
                    return fail;
                }
            } , 0);
        }, 0)
        console.log(prev_y_num, post_y_num)
        return post_y_num - prev_y_num;
    });

 

 

PS:

这个例子使用了echarts的官方例子的数据(我当然不可能用公司的真实数据写博客♪(^∇^*)),但我做了小小的修改。原本的数据是这样婶儿的:

原例子中,series的data是一维数组,顺序是与yAxis中值的顺序一一对应(为啥是yAxis?因为人家的图xy跟我的例子是反过来的呀┓( ´∀` )┏),我觉得这样不太灵活,就写成了二维数组的形式。这是从折线图里来的,用二维数组来表示一个点的xy值。echats这点做得很好,很多东西都是通的,这样就可以不用太教条,合理推导就能得到我们想要的东西。

 

 

  • 5
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值