echarts自定义tooltip、legend等
一. tooltip自定义
1. 因为指标数过多,一行展示一个指标会造成高度很高,呈现效果不佳,优化成一行展现两个指标,从而减少高度
关键代码如下:
formatter: function (params) {
// 初始化一个空字符串来存储 tooltip 的内容
var tooltipContent = '';
// 对数据进行排序
const data = params.sort((a, b) => (b.value ?? 0) - (a.value ?? 0));
// 创建一个数组来存储每行的内容
var rowContents = [];
// 遍历 params 数组
data.forEach(function (item, index) {
// 拼接 series 名称、类目值和数值
const { marker, seriesName, value } = item;
const formatValue = value || value === 0 ? `${value}%` : '';
// 构建每个数据点的 HTML 内容
const cellContent = `
<div style="display:inline-block;width:50%;">
<div style="display:flex;justify-content:space-between;line-height:24px;">
<div>
${marker}
<span>${seriesName}</span>
</div>
<div>${formatValue}</div>
</div>
</div>
`;
// 如果是偶数索引或者第一个元素,则开始新的一行
if (index % 2 === 0) {
rowContents.push(cellContent);
} else {
// 否则,将当前单元格附加到前一个单元格后面
rowContents[rowContents.length - 1] += cellContent;
}
});
// 将所有行的内容连接起来
rowContents.forEach((row) => {
tooltipContent += `<div style="width:200px;">${row}</div>`;
});
return `${params[0].name}<br/>${tooltipContent}`;
},
核心知识点:
- marker属性为文字左边的图标,展示的是html字符串格式;
- index % 2 === 0是为了使一行同时具备两个指标的数据
为便于理解,可参考这个代码
const initData = [
{ id: 1, value: 11 },
{ id: 2, value: 12 },
{ id: 3, value: 13 },
{ id: 4, value: 14 },
{ id: 5, value: 15 },
];
// rowContent
// 期望得到
const getData = () => {
const resultData = [];
initData.forEach((item, index) => {
if (index % 2 === 0) {
resultData.push(item.id + '');
} else {
resultData[resultData.length - 1] = resultData[resultData.length - 1] + item.id + '';
}
});
return resultData;
};
const res = getData();
console.log(res, 'res99');
2. 如何仅仅是想更改数据的展示格式,应该怎么处理?
比如在数据的基础上加%
可以使用valueFormatter(tooltip.valueFormatter)
const formatVal = (val) => {
return val || val === 0 ? `${val}%` : '-';
};
valueFormatter: (val) => formatVal(val),
3. 如何对展示数据进行排序?
可以用order属性(tooltip.order)
order: 'valueDesc',
注意:上述例子为折线图场景,其它图形场景可能略有差异。
二. legend自定义
1. 假如legend排列想要自定义成
名称 百分比 数据 的格式,应该怎么处理?
关键代码如下:
// legend初始化赋值
legend: {
orient: 'horizontal',
bottom: '10%',
left: 'left',
icon: 'circle',
itemWidth: 10,
itemHeight: 10,
textStyle: {
rich: {
name: {
fontSize: '10px',
width: 45,
},
percentage: {
color: '#303133',
fontWeight: 700,
width: 45,
},
value: {
color: '#303133',
fontWeight: 700,
},
},
},
},
// 设置legend formatter属性,进行自定义
echartLayoutVal.value.byFeePercent.option.legend.formatter = (params) => {
const findItem = pieData.find((item) => item.name === params);
const { value, percentage } = findItem;
return `{name|${params}}{percentage|${percentage}%}{value|${value} 万元}`;
};
核心知识点:
- rich属性的使用
注意:上述例子为饼图场景,其它图形场景可能略有差异。
三. 如何保证饼图百分比总和为100
测试代码
const initData = [
{
id: null,
wufyhs: 20747.5,
datestr: null,
tm: '汽运',
},
{
id: null,
wufyhs: 137.38,
datestr: null,
tm: '空运',
},
{
id: null,
wufyhs: 1705.48,
datestr: null,
tm: '船运',
},
{
id: null,
wufyhs: 3991.72,
datestr: null,
tm: '铁路',
},
];
const getPiePercentData = (initData, key) => {
// 计算总和
const total = initData.reduce((sum, item) => {
return sum + item.wufyhs;
}, 0);
let sumPercentage = 0;
const mapData = initData.map((item, index) => {
const { wufyhs } = item;
let percentage = (wufyhs / total) * 100;
if (index !== initData.length - 1) {
percentage = Math.round(percentage); // 四舍五入到两位小数
sumPercentage += percentage;
}
return {
value: wufyhs,
name: item[key],
percentage,
};
});
// 设置最后一项的百分比
mapData[initData.length - 1].percentage = 100 - sumPercentage;
const sortData = mapData.sort((a, b) => b.percentage - a.percentage);
return sortData;
};
const getData = getPiePercentData(initData, 'tm');
console.log(getData, 'getData');
主要思路:将除最后一项前的百分比总和计算出来,最后一项百分比值赋值为100减去除最后一项前的百分比总和
此种方法可能还不是最优,有更好的思路欢迎大家指教!
四. Promise.all和Promise.allSettled
业务场景:希望一次调用多个promise接口,但是promise接口之间希望不相互影响
测试代码
const promise1 = Promise.resolve(42);
const promise2 = Promise.reject('show error');
const promise3 = Promise.resolve('Hello World');
Promise.all([promise1.catch(() => null), promise2.catch(() => null), promise3.catch(() => null)])
.then((values) => {
console.log(values); // 不会执行,因为 promise2 被拒绝了
})
.catch((error) => {
console.log(error); // 输出 'error'
});
Promise.allSettled([promise1, promise2, promise3])
.then((values) => {
console.log(values, 'values'); // 不会执行,因为 promise2 被拒绝了
})
.catch((error) => {
console.log(error, 'error'); // 输出 'error'
});
。
以上两种方法都可以达到效果
核心知识点:
- 使用 Promise.all 结合 catch:
如果任何一个 Promise 对象被拒绝(rejected),Promise.all 将立即返回一个拒绝的 Promise,并且拒绝理由(reason)是第一个被拒绝的 Promise 的拒绝理由。
使用 Promise.all 结合 catch,这种方法通过在每个 promise 后添加 .catch(() => null) 来确保即使某个 promise 被拒绝,Promise.all 也不会被拒绝,而是会将该 promise 的结果视为 null(或其他你指定的默认值
2. Promise.allSettled
可以同时处理所有 promise 的结果,无论它们是成功还是失败。
不需要额外的错误处理,因为即使某个 promise 被拒绝,Promise.allSettled 仍然会解析而不会进入 catch 块
原文地址:https://blog.csdn.net/m0_45093055/article/details/143920230
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!