创作背景
- 本菜鸡有这样一个需求,首先是 要使用 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 官网
上的实例,发现了有一个图很符合我的需求——阶梯瀑布图
- 示例图表就是我想要的样子,
收入
和支出
分别是两个颜色,一个是绿色,一个是蓝色,而且在每个变量对应的柱子中
,出现绿色的地方没有出现蓝色
,出现蓝色的地方没有出现绿色
- 经过与示例源码的一番对比,我发现了问题所在
- 你可能会问:“欸小菜鸡,这个属性是干什么用的呀?”
- 我的回答:我也说不清楚つ﹏⊂,但大概意思是将
收入
和支出
合为一个“对象”(这里区别于 js 中的对象,这里只是代表它们在某方面成为了一个整体,就可以达到要么是蓝色,要么是绿色,二者只能存在一个
的目标) - 而我修改(在
get_series
函数批量生成series
中添加一个属性:stack: '喜爱人数'
)后得到的效果图如上的理想图 - 成功完成需求!!!
结尾
以上就是我要分享的内容,因为学识尚浅,会有不足,还请各位大佬指正。
有什么问题也可在评论区留言。