需求:有一个统计报表,显示一个人一周的时间分布,看他的学习占比,和工作占比。鼠标移动到tooltip内容的时候,发现百分比没有显示%。需要让他显示

代码示例:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>周时间分布统计</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/echarts/5.4.2/echarts.min.js"></script>
<style>
body {
font-family: 'Menlo', 'Consolas', monospace;
}
</style>
</head>
<body>
<div id="main" style="width: 1200px;height:600px;"></div>
<script>
const chart = echarts.init(document.getElementById('main'))
// 数据配置
const dataConfig = {
days: ['周一', '周二', '周三', '周四', '周五', '周六', '周日'],
categories: ['工作', '休息', '娱乐', '学习', '社交'],
timeData: [
[8, 2, 3, 2, 1],
[9, 1, 2, 2, 2],
[7, 3, 2, 3, 1],
[8, 2, 2, 2, 2],
[7, 1, 3, 3, 2],
[4, 4, 6, 2, 4],
[3, 5, 5, 3, 4]
],
getPercentData: (typeIndex) => {
return dataConfig.timeData.map(day => {
const total = day.reduce((a, b) => a + b, 0)
return Number(((day[typeIndex] / total) * 100).toFixed(2))
})
}
}
const option = {
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow'
},
},
legend: {
data: [...dataConfig.categories, '学习占比', '工作占比'],
textStyle: {
fontSize: 14
}
},
xAxis: [{
type: 'category',
data: dataConfig.days,
axisLabel: {
fontSize: 14
}
}],
yAxis: [{
type: 'value',
name: '时间(小时)',
min: 0,
max: 24,
axisLabel: {
fontSize: 14
}
}, {
type: 'value',
name: '占比',
min: 0,
max: 100,
// 移除了Y轴标签的%符号
axisLabel: {
formatter: '{value}',
fontSize: 14
}
}],
series: [
...dataConfig.categories.map((name, idx) => ({
name,
type: 'bar',
stack: 'time',
data: dataConfig.timeData.map(day => day[idx]),
itemStyle: {
color: ['#5470C6', '#91CC75', '#FAC858', '#EE6666', '#73C0DE'][idx]
}
})), {
name: '学习占比',
type: 'line',
yAxisIndex: 1,
data: dataConfig.getPercentData(3),
symbol: 'circle',
symbolSize: 8,
itemStyle: {
color: '#EE6666'
}
}, {
name: '工作占比',
type: 'line',
yAxisIndex: 1,
data: dataConfig.getPercentData(0),
symbol: 'circle',
symbolSize: 8,
itemStyle: {
color: '#5470C6'
}
}
]
}
chart.setOption(option);
</script>
</body>
</html>
(1)自定义tooltip格式化函数
具体步骤可能包括:
- 在tooltip配置中添加formatter函数。
- 在formatter函数中遍历所有当前触发的数据点。
- 对每个数据点,判断其系列名称,如果是百分比系列,则在数值后添加%。
- 确保数值格式化正确,例如保留两位小数

代码示例:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>周时间分布统计</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/echarts/5.4.2/echarts.min.js"></script>
<style>
body { font-family: 'Menlo', 'Consolas', monospace; }
</style>
</head>
<body>
<div id="main" style="width: 1200px;height:600px;"></div>
<script>
const chart = echarts.init(document.getElementById('main'));
// 数据配置
const dataConfig = {
days: ['周一', '周二', '周三', '周四', '周五', '周六', '周日'],
categories: ['工作', '休息', '娱乐', '学习', '社交'],
timeData: [
[8, 2, 3, 2, 1],
[9, 1, 2, 2, 2],
[7, 3, 2, 3, 1],
[8, 2, 2, 2, 2],
[7, 1, 3, 3, 2],
[4, 4, 6, 2, 4],
[3, 5, 5, 3, 4]
],
getPercentData: (typeIndex) => {
return dataConfig.timeData.map(day => {
const total = day.reduce((a,b) => a + b, 0);
return Number(((day[typeIndex]/total)*100).toFixed(2));
})
}
};
const option = {
tooltip: {
trigger: 'axis',
axisPointer: { type: 'shadow' },
formatter: (params) => {
const day = params[0].axisValue;
let result = `<b>${day}</b><br>`;
// 修复点:直接使用p.value
const timeItems = params
.filter(p => p.seriesType === 'bar')
.map(p => `${p.marker} ${p.seriesName}: ${p.value}小时`); // 直接取value
const percentItems = params
.filter(p => p.seriesType === 'line')
.map(p => `${p.marker} ${p.seriesName}: ${p.value}%`);
return [...timeItems, ...percentItems].join('<br>');
}
},
legend: {
data: [...dataConfig.categories, '学习占比', '工作占比'],
textStyle: { fontSize: 14 }
},
xAxis: [{
type: 'category',
data: dataConfig.days,
axisLabel: { fontSize: 14 }
}],
yAxis: [
{
type: 'value',
name: '时间(小时)',
min: 0,
max: 24,
axisLabel: { fontSize: 14 }
},
{
type: 'value',
name: '占比',
min: 0,
max: 100,
axisLabel: {
formatter: '{value}%',
fontSize: 14
}
}
],
series: [
// 堆叠柱状图系列
...dataConfig.categories.map((name, idx) => ({
name,
type: 'bar',
stack: 'time',
data: dataConfig.timeData.map(day => day[idx]), // 数据格式为单值数组
itemStyle: {
color: ['#5470C6','#91CC75','#FAC858','#EE6666','#73C0DE'][idx]
}
})),
// 折线图系列
{
name: '学习占比',
type: 'line',
yAxisIndex: 1,
data: dataConfig.getPercentData(3),
symbol: 'circle',
symbolSize: 8,
itemStyle: { color: '#EE6666' }
},
{
name: '工作占比',
type: 'line',
yAxisIndex: 1,
data: dataConfig.getPercentData(0),
symbol: 'circle',
symbolSize: 8,
itemStyle: { color: '#5470C6' }
}
]
};
chart.setOption(option);
</script>
</body>
</html>
或者,这样并没有两端对齐,可以加一些代码实现Tooltip两端对齐
- 使用
display: table创建表格布局,设置table-layout: fixed固定列宽 - 定义两列:名称列(
name-col)120px,数值列(value-col)100px - 数值列设置
text-align: right实现右对齐

示例:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>周时间分布统计</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/echarts/5.4.2/echarts.min.js"></script>
<style>
body {
font-family: 'Menlo', 'Consolas', monospace;
}
/* Tooltip表格布局样式 */
.tooltip-table {
display: table;
table-layout: fixed;
width: 240px;
}
.tooltip-row {
display: table-row;
}
.tooltip-cell {
display: table-cell;
padding: 2px 0;
vertical-align: middle;
}
.name-col {
width: 120px;
padding-right: 10px;
}
.value-col {
width: 100px;
text-align: right;
}
</style>
</head>
<body>
<div id="main" style="width: 1200px;height:600px;"></div>
<script>
const chart = echarts.init(document.getElementById('main'));
// 数据配置
const dataConfig = {
days: ['周一', '周二', '周三', '周四', '周五', '周六', '周日'],
categories: ['工作', '休息', '娱乐', '学习', '社交'],
timeData: [
[8, 2, 3, 2, 1],
[9, 1, 2, 2, 2],
[7, 3, 2, 3, 1],
[8, 2, 2, 2, 2],
[7, 1, 3, 3, 2],
[4, 4, 6, 2, 4],
[3, 5, 5, 3, 4]
],
getPercentData: (typeIndex) => {
return dataConfig.timeData.map(day => {
const total = day.reduce((a,b) => a + b, 0);
return Number(((day[typeIndex]/total)*100).toFixed(2));
})
}
};
const option = {
tooltip: {
trigger: 'axis',
axisPointer: { type: 'shadow' },
formatter: (params) => {
const day = params[0].axisValue;
let html = `
<div class="tooltip-table">
<div class="tooltip-row">
<div class="tooltip-cell" style="font-weight:bold;padding-bottom:8px">${day}</div>
</div>
`;
// 生成数据行
params.forEach(item => {
const isPercent = item.seriesName.includes('占比');
const name = isPercent ?
item.seriesName :
`${item.seriesName}:`; // 非占比类添加全角冒号
const value = isPercent ?
`${item.value.toFixed(2)}%` :
`${item.value}小时`;
html += `
<div class="tooltip-row">
<div class="tooltip-cell name-col">
${item.marker} ${name}
</div>
<div class="tooltip-cell value-col">
${value}
</div>
</div>
`;
});
html += '</div>';
return html;
}
},
legend: {
data: [...dataConfig.categories, '学习占比', '工作占比'],
textStyle: { fontSize: 14 }
},
xAxis: [{
type: 'category',
data: dataConfig.days,
axisLabel: {
rotate: 45,
fontSize: 14
}
}],
yAxis: [
{
type: 'value',
name: '时间(小时)',
min: 0,
max: 24,
axisLabel: { fontSize: 14 }
},
{
type: 'value',
name: '占比',
min: 0,
max: 100,
axisLabel: {
formatter: '{value}%',
fontSize: 14
}
}
],
series: [
...dataConfig.categories.map((name, idx) => ({
name,
type: 'bar',
stack: 'time',
data: dataConfig.timeData.map(day => day[idx]),
itemStyle: {
color: ['#5470C6','#91CC75','#FAC858','#EE6666','#73C0DE'][idx]
}
})),
{
name: '学习占比',
type: 'line',
yAxisIndex: 1,
data: dataConfig.getPercentData(3),
symbol: 'circle',
symbolSize: 8,
itemStyle: { color: '#EE6666' }
},
{
name: '工作占比',
type: 'line',
yAxisIndex: 1,
data: dataConfig.getPercentData(0),
symbol: 'circle',
symbolSize: 8,
itemStyle: { color: '#5470C6' }
}
]
};
chart.setOption(option);
</script>
</body>
</html>
(2)valueFormatter属性
(2)ECharts的每个系列(series)可以有自己的tooltip配置,特别是valueFormatter属性,用来格式化该系列在Tooltip中的数值显示
- 柱状图系列通过
valueFormatter添加小时单位 - 折线图系列通过
valueFormatter添加%符号

代码示例:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>周时间分布统计</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/echarts/5.4.2/echarts.min.js"></script>
</head>
<body>
<div id="main" style="width: 1200px;height:600px;"></div>
<script>
const chart = echarts.init(document.getElementById('main'));
// 数据配置
const dataConfig = {
days: ['周一', '周二', '周三', '周四', '周五', '周六', '周日'],
categories: ['工作', '休息', '娱乐', '学习', '社交'],
timeData: [
[8, 2, 3, 2, 1],
[9, 1, 2, 2, 2],
[7, 3, 2, 3, 1],
[8, 2, 2, 2, 2],
[7, 1, 3, 3, 2],
[4, 4, 6, 2, 4],
[3, 5, 5, 3, 4]
],
getPercentData: (typeIndex) => {
return dataConfig.timeData.map(day => {
const total = day.reduce((a,b) => a + b, 0);
return Number(((day[typeIndex]/total)*100).toFixed(2));
})
}
};
const option = {
tooltip: {
trigger: 'axis',
axisPointer: { type: 'shadow' }
},
legend: {
data: [...dataConfig.categories, '学习占比', '工作占比']
},
xAxis: [{
type: 'category',
data: dataConfig.days,
axisLabel: { rotate: 45 }
}],
yAxis: [
{
type: 'value',
name: '时间(小时)',
min: 0,
max: 24
},
{
type: 'value',
name: '占比',
min: 0,
max: 100,
axisLabel: { formatter: '{value}%' }
}
],
series: [
// 堆叠柱状图系列
...dataConfig.categories.map((name, idx) => ({
name,
type: 'bar',
stack: 'time',
data: dataConfig.timeData.map(day => day[idx]),
tooltip: {
valueFormatter: value => `${value} 小时` // 时间格式化
},
itemStyle: {
color: ['#5470C6','#91CC75','#FAC858','#EE6666','#73C0DE'][idx]
}
})),
// 学习占比折线
{
name: '学习占比',
type: 'line',
yAxisIndex: 1,
data: dataConfig.getPercentData(3),
tooltip: {
valueFormatter: value => `${value}%` // 百分比格式化
},
symbol: 'circle',
symbolSize: 8,
itemStyle: { color: '#EE6666' }
},
// 工作占比折线
{
name: '工作占比',
type: 'line',
yAxisIndex: 1,
data: dataConfig.getPercentData(0),
tooltip: {
valueFormatter: value => `${value}%` // 百分比格式化
},
symbol: 'circle',
symbolSize: 8,
itemStyle: { color: '#5470C6' }
}
]
};
chart.setOption(option);
</script>
</body>
</html>
优化建议
-
如需更紧凑的显示,可添加全局样式:
body { font-family: 'Menlo', 'Consolas', monospace; } -
调整提示框宽度:
tooltip: { trigger: 'axis', axisPointer: { type: 'shadow' }, confine: true, // 防止溢出 extraCssText: 'width: 240px;' // 固定宽度 }
1万+

被折叠的 条评论
为什么被折叠?



