【小程序开发填坑记】之 使用echarts在每个变量中只显示一个柱子

  • 创作背景
  • 解决思路
  • 初次尝试
  • 再次尝试
  • 结尾


创作背景

  • 本菜鸡有这样一个需求,首先是 要使用 echarts 绘制一个柱状图,其次是 根据数据所对应的分类不同,每个变量只显示一个柱子
  • 说起来挺抽象,我就用具体的数据来说明一下吧:
  • 有一个 二维数组,数据如下图所示
  • 我想根据菜品对应的喜爱人数绘制柱状图,而柱子的颜色根据菜品所属餐厅的不同而变化。

解决思路

  • 首先,图表的 legend 属性中的 data 要设置为 三个食堂构成的名称列表
  • 其次,我们要分别获得 食堂对应菜品的喜爱人数 ,不属于本食堂的菜品数量应设置为 '-'(代表数据缺失)
  • 最后,根据这些数据 生成 对应的柱状图

初次尝试

  • 说干就干!
  • 按照我的思路,我完成了这些设置,代码如下(仅有获得食堂与颜色对应关系的函数 get_map 和获得 series 的函数 get_series 还有 option,其他的设置省略):
  • get_map
function get_map() {
    let colorList = ['blue', 'orange', 'red', 'deeppink', 'yellow'];
    let legend = ['三食堂', '一食堂', '二食堂'];
    let map = {};
    for(let i = 0; i<legend.length; i++){
        let k = legend[i];
        // 判断食堂名称是否在映射字典的键中,如果没有,就添加 食堂名称与柱子颜色 的映射关系
        if(!map.hasOwnProperty(k)){
        	// 随机获取颜色的序号,根据颜色列表的长度取随机值
            let index = parseInt(Math.random()*(colorList.length-1));
            // 如果列表中该序号对应的是 undefined,就再次获得序号,直到所对应的颜色序号不为 undefined
            while(colorList[index] == undefined){
                let index = parseInt(Math.random()*(colorList.length-1));
                map[k] = colorList[index];
            }
            map[k] = colorList[index];
            // 将使用过的颜色从列表中删除
            delete colorList[index];
        }
    }
    return map;
}
  • get_series
function get_series() {
    let series = [];
    let map = get_map();
    // ex, canteen_s, x_s 的数据在我的代码中均有函数可以获取
    // 这里为了方便阅读,直接一个一个敲
    let ex = {
        '三食堂': ['我爱我的祖国', '西红柿炒鸡蛋'],
        '一食堂': ['土豆片', '肥牛'],
        '二食堂': ['辣子鸡']
    };
    let canteen_s = ['三食堂', '一食堂', '二食堂'];
    let x_s = ['我爱我的祖国', '西红柿炒鸡蛋', '土豆片', '辣子鸡', '肥牛'];
    function get_num(key){
        let s_data = [];
        for(let c = 0; c<x_s.length; c++){
        	// 如果菜品属于本食堂,就获取对应的喜爱人数,否则设为 '-'
            s_data.push(ex[key].indexOf(x_s[c])!=-1?data.fond_num[x_s[c]]:'-');
        }
        return s_data;
    }
    // 遍历餐厅名称列表,批量生成 series
    for(let i = 0; i<canteen_s.length; i++){
        let k = canteen_s[i];
        console.log('color:', map[k]);
        series.push({
            name: k,
            type: 'bar',
            data: get_num(k),
            label: {
                show: true,
                position: 'top'
            },
            itemStyle: {
                normal: {
                    color: map[k]
                }
            }
        })
    }
    return series;
}
option = {
    tooltip: {
        trigger: 'axis',
        axisPointer: {
            type: 'cross',
            crossStyle: {
                color: '#999'
            }
        }
    },
    grid: {
        x: 65
    },
    legend: {
        data: ['三食堂', '一食堂', '二食堂']
    },
    xAxis: [{
        type: 'category',
        data: ['我爱我的祖国', '西红柿炒鸡蛋', '土豆片', '辣子鸡', 'hh'],
        axisPointer: {
            type: 'shadow'
        },
        axisLabel: {
            interval: 0,
            formatter: function (params) {
                console.log('param:', params);
                var result = "";
                var len = params.length;
                var cut_len = 3;
                if (len > cut_len){
                    while(params.length > cut_len){
                        result += params.substring(0, cut_len) + '\n';
                        params = params.substring(cut_len);
                        console.log('cut:', params);
                    }
                    result += params;
                } else {
                    result = params;
                }
                return result;
            }
        }
    }],
    yAxis: [{
        type: 'value',
        name: '人数',
        min: 0,
        max: 1000,
        interval: 100,
        axisLabel: {
            formatter: '{value} 人'
        },
        fontSize: 1
    }],
    series: get_series()
}
  • 当我满怀期待地点击了运行,结果如下:
  • 有点差强人意
  • 看这状态好像是因为有三类,所以每个菜分了三个柱子,因为有的设置的是 '-' 不显示,所以就成了上图的效果
  • 但我理想中的效果应该是这样的
  • 这可怎么办呀?

再次尝试

  • 自己凭空想象肯定是没法解决问题的
  • 于是我再次查看了 echarts 官网 上的实例,发现了有一个图很符合我的需求——阶梯瀑布图
  • MpAndroidChart 开发 柱形图一个柱子显示多个数据_数据可视化


  • 示例图表就是我想要的样子, 收入支出 分别是两个颜色,一个是绿色,一个是蓝色,而且 在每个变量对应的柱子中出现绿色的地方没有出现蓝色出现蓝色的地方没有出现绿色
  • 经过与示例源码的一番对比,我发现了问题所在
  • 你可能会问:“欸小菜鸡,这个属性是干什么用的呀?”
  • 我的回答:我也说不清楚つ﹏⊂,但大概意思是将 收入支出 合为一个“对象”(这里区别于 js 中的对象,这里只是代表它们在某方面成为了一个整体,就可以达到 要么是蓝色,要么是绿色,二者只能存在一个 的目标)
  • 而我修改(在 get_series 函数批量生成 series 中添加一个属性:stack: '喜爱人数')后得到的效果图如上的理想图
  • 成功完成需求!!!