遇到的echarts样式问题合集
一 样式问题
二 渲染问题
-------------------------------------样式问题-------------------------------------
1 柱状图弹窗渲染有问题
改正版
代码 : tooltip-formatter (按照旧的写法会报错 , 报错如下 , )
const saleOption = {
title: {
text: '销售总金额(元)/月',
left: 'left',
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow',
},
// 按照旧的写法来,会报错
// formatter: function (params) {
// console.log('params', params);
// if (params[0].data == '0.00') {
// return '暂无数据';
// } else {
// return params[0].name + '月' + '<br/>' + params[0].value.toFixed(2) + '元';
// }
// },
formatter: function (params) {
console.log('params', params);
if (typeof params[0].data === 'string' && params[0].data === '0.00') {
return '暂无数据';
} else if (typeof params[0].value === 'number') {
return params[0].name + '月' + '<br/>' + params[0].value.toFixed(2) + '元';
} else if (typeof params[0].value === 'string') {
const valueAsNumber = parseFloat(params[0].value);
if (isNaN(valueAsNumber)) {
return '数据异常';
} else {
return params[0].name + '月' + '<br/>' + valueAsNumber.toFixed(2) + '元';
}
} else {
return '数据格式错误';
}
},
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true,
},
xAxis: [
{
type: 'category',
data: xAxisData,
axisTick: {
alignWithLabel: true,
},
axisLabel: {
interval: 0, // 强制显示所有标签
formatter: function (value, index) {
// 仅显示 1、3、5、7、9、11 月的标签
if ((index + 1) % 2 !== 0) {
return value + '月';
} else {
return '';
}
},
},
},
],
yAxis: [
{
type: 'value',
splitLine: {
show: false, // 取消 y 轴的横线
},
},
],
series: [
{
name: 'Direct',
type: 'bar',
barWidth: '60%',
data: seriesData,
itemStyle: {
color: '#d48ca0',
},
},
],
};
2 饼图鼠标选中往内弹(额外加了鼠标选中) 和 往外弹 (series-radius)
var data = [
{ value: 1048, name: '火车' },
{ value: 848, name: '汽车' },
{ value: 605, name: '公交' },
{ value: 500, name: '自驾' }
]
const colors = [
{
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{
offset: 0,
color: '#7BA9E5'
},
{
offset: 1,
color: '#4570C6'
}
]
},
....... // 颜色不是重点 , 就不多展示了
]
const option = {
color: colors,
series: [
{
type: 'pie',
radius: ['50%', '25%'], // 第一个参数控制圆的大小;第二个参数控制圆往内外弹;这样的话圆是往里弹
// radius: ['30%', '60%'], // 第二参数大于50%,往外弹
center: ['50%', '40%'],
roseType: 'area',
itemStyle: {
borderRadius: 8 // 饼图外圆的圆滑程度
},
labelLine: {
// 取消echarts往外指出的小横线
length: 70, //线的长短
length2: 10 //折线的长短
},
emphasis: {
// 添加鼠标悬停或选中的强调样式
itemStyle: {
shadowBlur: 10,
borderWidth: 2,
borderColor: '#fff' // 可自定义边框颜色
},
label: {
// 如果需要增强文字效果也可以在这里配置
},
radius: ['90%', '35%'] // 例如增加外圈半径,如果需要只对外圈做高亮,可以尝试使用选中态的radius调整
},
data: data
}
]
}
2 取消饼图中往外指出的小横线 (series-labelLine)
<script>
// 创建饼图实例
let chart = echarts.init(document.getElementById('chart'))
// 配置选项和数据
let options = {
title: {
...
},
legend: {
...
series: [
{
name: '访问来源',
type: 'pie',
radius: ['50%', '70%'], // 饼图变成环形图
data: [
...
],
itemStyle: {
...
},
labelLine: { // 取消echarts往外指出的小横线
length: 0,
length2: 0 // 默认线是往里指的 , 要给这俩个设置值
}
}
]
}
// 使用配置项和数据渲染图表
chart.setOption(options)
</script>
3 饼图弹窗样式更改 (tooltip-formatter)
以上是默认效果 , 以下是更改效果
const option = {
title: {
text: '老师业绩分布TOP10',
left: 'left',
},
tooltip: {
trigger: 'item',
formatter: function (params) {
return `<div style="display: flex; align-items: center;">
<div style="width: 10px; height: 10px; border-radius: 50%; background-color: ${params.color}; margin-right: 10px;"></div>
<span style="color: ${params.color}">老师名称</span> : ${params.name}。 <br/>
</div>
<div style="display: flex; align-items: center;">
<div style="width: 10px; height: 10px; border-radius: 50%; background-color: ${params.color}; margin-right: 10px;"></div>
<span style="color: ${params.color}">老师业绩</span> : ${params.value}。
</div>`;
},
},
legend: {
orient: 'horizontal', // 将 orient 设置为 'horizontal'
top: '5%', // 调整 top 属性的值,控制图例位置
},
series: [
{
name: 'Access From',
type: 'pie',
radius: '50%',
data: seriesData,
emphasis: {
itemStyle: {
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: 'rgba(0, 0, 0, 0.5)',
},
},
labelLine: {
show: false,
},
label: {
// 添加label属性,在formatter函数中获取price和ratio
formatter: function (params) {
const { price, ratio } = data[params.dataIndex];
return `${params.name} ${(ratio * 100).toFixed(2)}%`;
},
},
},
],
};
4 在饼图中间位置添加不同样式的文本
<script>
// 创建饼图实例
let chart = echarts.init(document.getElementById('chart'))
// 配置选项和数据
let options = {
title: {
text: '{firstTitle|一级标题}\n{secondTitle|二级标题}',
top: 'center',
left: 'center',
textStyle: {
fontSize: 24,
rich: { // 用rich属性实现
firstTitle: {
fontSize: 24,
color: '#000'
},
secondTitle: {
fontSize: 16,
color: '#333',
padding: [4, 0, 0, 0]
}
}
}
},
legend: {
icon: 'circle',
// 让图例和文本在同一水平线
textStyle: {
fontFamily: 'serif'
},
inactiveBorderColor: '#fff' // 当图例关闭时icon保持大小不变
},
series: [
{
name: '访问来源',
type: 'pie',
// radius: '50%', // 饼图
radius: ['50%', '70%'], // 饼图变成环形图
data: [
{ value: 335, name: 'aaa' },
{ value: 310, name: 'bbb' },
{ value: 234, name: 'ccc' },
{ value: 135, name: 'ddd' },
{ value: 1548, name: 'eee' }
],
itemStyle: {
borderColor: '#fff',
borderWidth: 2
}
}
]
}
// 使用配置项和数据渲染图表
chart.setOption(options)
</script>
5 饼图图例和文本未在同一水平线
<script>
// 创建饼图实例
let chart = echarts.init(document.getElementById('chart'))
// 配置选项和数据
let options = {
legend: {
icon: 'circle',
// 更改字体实现图例和文本在同一水平线
textStyle: {
fontFamily: 'serif'
},
},
series: [
{
name: '访问来源',
type: 'pie',
radius: '50%',
data: [
{ value: 335, name: 'aaa' },
{ value: 310, name: 'bbb' },
{ value: 234, name: 'ccc' },
{ value: 135, name: 'ddd' },
{ value: 1548, name: 'eee' }
]
}
]
}
// 使用配置项和数据渲染图表
chart.setOption(options)
</script>
-----------------------------------渲染问题合集--------------------------------
1 react中 可以拿到后台返回的数据 , 却不能正常展示echarts图 , 可能是后台返回的数据不是数字类型
问题: 明明有数据,就是不显示
解决: 将value转为数字类型 parseFloat()
const teachers = (data) => {
const seriesData = data.map((item) => ({
name: item.teacher_name,
value: parseFloat(item.price), // 转为数字类型
}));
console.log('seriesData', seriesData);
const option = {
title: {
text: '老师业绩分布TOP10',
left: 'left',
},
tooltip: {
trigger: 'item',
formatter: function (params) {
return `<div style="display: flex; align-items: center;">
<div style="width: 10px; height: 10px; border-radius: 50%; background-color: ${params.color}; margin-right: 10px;"></div>
<span style="color: ${params.color}">老师名称</span> : ${params.name}。 <br/>
</div>
<div style="display: flex; align-items: center;">
<div style="width: 10px; height: 10px; border-radius: 50%; background-color: ${params.color}; margin-right: 10px;"></div>
<span style="color: ${params.color}">老师业绩</span> : ${params.value} 元。
</div>`;
},
},
legend: {
orient: 'vertical', // 将图例位置纵向展示
top: '5%', // 调整 top 属性的值,控制图例位置
itemStyle: {
color: seriesData.length === 0 ? '#d3d3d3' : 'auto', // 根据seriesData的长度设置图例颜色
},
},
series: [
{
name: '暂无数据',
type: 'pie',
radius: '50%',
data: seriesData,
emphasis: {
itemStyle: {
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: 'rgba(211, 211, 211)',
},
},
labelLine: {
show: false,
},
label: {
// 添加label属性,在formatter函数中获取price和ratio
formatter: function (params) {
const { price, ratio } = data[params.dataIndex];
return `${params.name} ${(ratio * 100).toFixed(2)}%`;
},
},
},
],
};
const teacherEchart = echarts.init(document.getElementById('teacherPerformance'));
teacherEchart.setOption(option);
};
1 react中 出现经典错误 Uncaught (in promise) Error: Initialize failed: invalid dom.
const initAllEcharts = async () => {
const data = await salesStatistics();
let { salesAmount, teacher, book, order_num, buy_num, average, income } = data;
setType(data.type);
// 添加延迟来等待DOM元素准备就绪
await new Promise((resolve) => setTimeout(resolve, 100));
console.log('type', type);
if (data.type === 2) {
sale(salesAmount);
books(book);
} else if (data.type === 1) {
sale(salesAmount);
teachers(teacher);
}
setTabArr([
{ name: '预计总收入', value: income },
{ name: '总订单数', value: order_num },
{ name: '总购买人数', value: buy_num },
{ name: '平均客单价', value: average },
]);
};
useEffect(() => {
initAllEcharts();
}, []);
2 vue3项目中echarts报错
报错如下 ,且目前出现了内存泄漏,页面出现卡死状况
<template>
<div class="echartsBox">
<div
id="myEcharts"
:style="{
width: '900px',
height: '300px',
position: 'absolute',
left: '35%'
}"
></div>
</div>
</template>
<script setup>
import { reactive, onMounted, onUnmounted } from 'vue'
import * as echarts from 'echarts'
let chartInstance = null
onMounted(() => {
initChart()
})
function initChart () {
const chartDom = document.getElementById('myEcharts')
let chartInstance = echarts.init(chartDom)
// 把配置和数据放这里
chartInstance.setOption({ //具体内容可去echarts官网随便copy一份看效果 })
window.onresize = function () {
//自适应大小
chartInstance.resize()
}
// onUnmounted(() => { 这是原来的销毁echarts,会产生内存泄漏,导致页面卡死,因在组件销毁之前chartInstance还没被赋值呢
// chartInstance.dispose()
// })
onUnmounted(() => {
if (chartInstance) {
chartInstance.dispose()
}
})
</script>
3 如果出现以下报错 , 可以将onMounted()和onUnmounted()的代码放在script标签的最下方
3 设置点击事件让echarts数据显示 , 会报以下的警告(警告内容: [ECharts] There is a chart instance already initialized on the dom.) , 因为在初始化图表之前,已存在一个相同 DOM 实例 , 所以需要在初始化之前销毁echarts实例
解决方法
const chartData = ref([0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) // 初始化echarts数据为0
function initChart () {
const chartDom = document.getElementById('myEcharts')
if (chartInstance) {
// 在初始化图表之前,可能已经存在一个使用相同 DOM 元素的图表实例 , 会报警告"[ECharts] There is a chart instance already initialized on the dom."
chartInstance.dispose()
}
chartInstance = echarts.init(chartDom)
var myColor = [
'#eb2100',
'#eb3600',
'#d0570e',
'#d0a00e',
'#34da62',
'#00e9db',
'#00c0e9',
'#0096f3',
'#33CCFF',
'#33FFCC'
]
// 把配置和数据放这里 这些是echarts的具体数据和上述问题关系不大
chartInstance.setOption({
backgroundColor: '#0e2147',
grid: {
left: '11%',
top: '12%',
right: '0%',
bottom: '8%',
containLabel: true
},
xAxis: [
{
show: false
}
],
yAxis: [
{
axisTick: 'none',
axisLine: 'none',
offset: '27',
axisLabel: {
color: '#ffffff',
fontSize: '16'
},
data: [
'南昌转运中心',
'广州转运中心',
'杭州转运中心',
'宁夏转运中心',
'兰州转运中心',
'南宁转运中心',
'长沙转运中心',
'武汉转运中心',
'合肥转运中心',
'贵州转运中心'
]
},
{
axisTick: 'none',
axisLine: 'none',
axisLabel: {
color: '#ffffff',
fontSize: '16'
},
data: ['10', '9', '8', '7', '6', '5', '4', '3', '2', '1']
},
{
name: '分拨延误TOP 10',
nameGap: '50',
nameTextStyle: {
color: '#ffffff',
fontSize: '16'
},
axisLine: {
lineStyle: {
color: 'rgba(0,0,0,0)'
}
},
data: []
}
],
series: [
{
name: '条',
type: 'bar',
yAxisIndex: 0,
data: chartData.value,
label: {
show: true,
position: 'right',
color: '#ffffff',
fontSize: '16'
},
barWidth: 12,
itemStyle: {
color: function (params) {
var num = myColor.length
return myColor[params.dataIndex % num]
}
},
z: 2
},
{
name: '白框',
type: 'bar',
yAxisIndex: 1,
barGap: '-100%',
data: [99, 99.5, 99.5, 99.5, 99.5, 99.5, 99.5, 99.5, 99.5, 99.5],
barWidth: 20,
itemStyle: {
color: '#0e2147',
borderRadius: 5
},
z: 1
},
{
name: '外框',
type: 'bar',
yAxisIndex: 2,
barGap: '-100%',
data: [100, 100, 100, 100, 100, 100, 100, 100, 100, 100],
barWidth: 10,
itemStyle: {
color: function (params) {
var num = myColor.length
return myColor[params.dataIndex % num]
},
borderRadius: 5
},
z: 0
},
{
name: '外圆',
type: 'scatter',
emphasis: false,
data: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
yAxisIndex: 2,
symbolSize: 10,
itemStyle: {
color: function (params) {
var num = myColor.length
return myColor[params.dataIndex % num]
},
opacity: 1
},
z: 2
}
]
})
window.onresize = function () {
//自适应大小
chartInstance.resize()
}
}
const onSubmit = () => { // 这里是点击事件,点击改变echarts的数据
chartData.value = [4, 13, 25, 29, 38, 44, 50, 52, 60, 72]
initChart()
}
onMounted(() => {
initChart()
})
onUnmounted(() => {
if (chartInstance) {
chartInstance.dispose()
}
})