echart是我们经常使用的页面展示插件,漂亮精美。
页面是靠数据驱动的。以柱状图标签旋转为例,介绍一下生成数据的思路。
此图x轴为一个数组,这里是2012~2016五个年费,每一年又有4项及对应数值,其option为:
option = {
legend: {
data: ['Forest', 'Steppe', 'Desert', 'Wetland']
},
xAxis: [
{
type: 'category',
data: ['2012', '2013', '2014', '2015', '2016']
}
],
series: [
{
name: 'Forest',
data: [320, 332, 301, 334, 390]
},
{
name: 'Steppe',
data: [220, 182, 191, 234, 290]
},
{
name: 'Desert',
data: [150, 232, 201, 154, 190]
},
{
name: 'Wetland',
data: [98, 77, 101, 99, 40]
}
]
};
数据对应关系如图
后端准备数据的代码
这是数据库中的数据,每个批次,不一定会有所有人的数据,但后端可以补0返给前端,下面是对应的serviceImpl类的代码:
public ExpenseStaticsVo getServedFigures(ExpenseVo expenseVo) {
List<ExpenseVo> list = personalExpensesMapper.selectExpenseFigures(expenseVo);
List<String> batches = list.stream().map(ExpenseVo::getBatch).distinct().sorted().collect(Collectors.toList());
List<String> realNames = list.stream().map(ExpenseVo::getRealName).distinct().sorted().collect(Collectors.toList());
List<String> result = new ArrayList<>();
for (String batch : batches) {
StringBuilder sb = new StringBuilder();
List<ExpenseVo> vos = list.stream().filter(item -> item.getBatch().equals(batch)).collect(Collectors.toList());
for (String realName : realNames) {
List<ExpenseVo> collect = vos.stream().filter(item -> item.getRealName().equals(realName)).collect(Collectors.toList());
if (collect.isEmpty())
sb.append("0,");
else
sb.append(collect.get(0).getExpense()/100.0).append(",");
}
sb.deleteCharAt(sb.length() - 1);
result.add(sb.toString());
}
ExpenseStaticsVo res = new ExpenseStaticsVo();
//将List转换为不带方括号的字符串,
res.setBatches(String.join(",", batches));
res.setEmployees(String.join(",", realNames));
res.setExpenses(result);
return res;
}
前端准备数据的代码
后端准备数据,返回的数据很简洁。
但是有稍微有点不够灵活,有时希望把人员作为x轴,有时又希望把批次作为x轴,如果后端把数据加工好,前端反而难以处理。我们也可以把数据库查出来的数据,放到前端来处理,代码为:
const genSeriesData = (data) => {
// 批次数组,去重
let batches = data.map(el => el.batch).filter((item, index, self) => self.indexOf(item) === index)
// 人员数组,去重
let users = data.map(el => el.realName).filter((item, index, self) => self.indexOf(item) === index)
let seriesData = []
users.forEach(user => {
// 过滤出当前人员的数据
let userData = data.filter(item => item.realName === user)
let userSeriesData = []
// 遍历批次数组,将每个批次对应的数据取出,
// 然后将数据放入对应的seriesData数组中
batches.forEach(batch => {
let one = userData.filter(item => item.batch === batch)
let expense = one.length === 0 ? 0 : one[0].expense
userSeriesData.push(expense)
})
let userSeriesItem = {
name: user,
type: 'bar',
barGap: 0,
emphasis: { focus: 'series' },
label: { show: true, position: 'insideBottom' },
data: userSeriesData
}
seriesData.push(userSeriesItem)
})
}
小结
以上贴出来的都是主要的代码块,朋友们自己还需要摸索一下,这里主要提及的还是思路。