ECharts 样式与主题
本文档介绍 ECharts 中的样式设置方式,包括颜色主题、调色盘和直接样式设置。
颜色主题(Theme)
最简单的更改全局样式的方式是直接采用颜色主题(theme)。
内置主题
ECharts 5 除了一贯的默认主题外,还内置了 'dark' 主题:
javascript
var chart = echarts.init(dom, 'dark')自定义主题
可以在 主题编辑器 中编辑和下载主题。
JSON 格式主题
如果主题保存为 JSON 文件,需要加载和注册:
javascript
fetch('theme/vintage.json')
.then((r) => r.json())
.then((theme) => {
echarts.registerTheme('vintage', theme)
var chart = echarts.init(dom, 'vintage')
})UMD 格式主题
如果保存为 UMD 格式的 JS 文件,文件内部已经做了自注册,直接引入 JS 即可:
javascript
// HTML 引入 vintage.js 文件后
var chart = echarts.init(dom, 'vintage')注册主题 API
javascript
echarts.registerTheme(themeName, themeConfig)调色盘
调色盘给定了一组颜色,图形、系列会自动从其中选择颜色。可以设置全局的调色盘,也可以设置系列自己专属的调色盘。
全局调色盘
javascript
option = {
color: [
'#c23531',
'#2f4554',
'#61a0a8',
'#d48265',
'#91c7ae',
'#749f83',
'#ca8622',
'#bda29a',
'#6e7074',
'#546570',
'#c4ccd3'
],
series: [
// ...
]
}系列调色盘
javascript
option = {
series: [
{
type: 'bar',
color: [
'#dd6b66',
'#759aa0',
'#e69d87',
'#8dc1a9',
'#ea7e53'
]
},
{
type: 'pie',
color: [
'#37A2DA',
'#32C5E9',
'#67E0E3',
'#9FE6B8',
'#FFDB5C'
]
}
]
}直接样式设置
直接的样式设置是比较常用的设置方式。在 ECharts 的 option 中,很多地方可以设置 itemStyle、lineStyle、areaStyle、label 等。
itemStyle
用于设置图形元素的样式:
javascript
option = {
series: [
{
type: 'bar',
data: [10, 22, 28, 43, 49],
itemStyle: {
color: '#5470c6',
borderColor: '#91cc75',
borderWidth: 2,
borderRadius: 5,
shadowColor: 'rgba(0, 0, 0, 0.5)',
shadowBlur: 10
}
}
]
}lineStyle
用于设置线条样式:
javascript
option = {
series: [
{
type: 'line',
data: [10, 22, 28, 23, 19],
lineStyle: {
color: 'green',
width: 4,
type: 'dashed'
}
}
]
}areaStyle
用于设置区域填充样式:
javascript
option = {
series: [
{
type: 'line',
data: [10, 22, 28, 23, 19],
areaStyle: {
color: 'rgba(84, 112, 198, 0.5)'
}
}
]
}label
用于设置标签样式:
javascript
option = {
series: [
{
type: 'bar',
data: [10, 22, 28, 43, 49],
label: {
show: true,
position: 'top',
color: '#333',
fontSize: 14,
fontWeight: 'bold'
}
}
]
}高亮样式
通过 emphasis 设置鼠标悬停时的高亮样式:
javascript
option = {
series: [
{
type: 'bar',
data: [10, 22, 28, 43, 49],
emphasis: {
itemStyle: {
color: '#91cc75',
shadowBlur: 10,
shadowColor: 'rgba(0, 0, 0, 0.5)'
},
label: {
show: true,
fontSize: 16
}
}
}
]
}渐变色
ECharts 支持线性渐变和径向渐变。
线性渐变
javascript
option = {
series: [
{
type: 'bar',
data: [10, 22, 28, 43, 49],
itemStyle: {
color: {
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{ offset: 0, color: '#83bff6' },
{ offset: 0.5, color: '#188df0' },
{ offset: 1, color: '#188df0' }
]
}
}
}
]
}径向渐变
javascript
option = {
backgroundColor: {
type: 'radial',
x: 0.3,
y: 0.3,
r: 0.8,
colorStops: [
{ offset: 0, color: '#f7f8fa' },
{ offset: 1, color: '#cdd0d5' }
]
}
}纹理填充
可以使用图片作为纹理填充:
javascript
option = {
series: [
{
type: 'bar',
data: [10, 22, 28, 43, 49],
itemStyle: {
color: {
image: 'path/to/image.png',
repeat: 'repeat'
}
}
}
]
}文本样式
基本文本样式
javascript
option = {
title: {
text: '标题文本',
textStyle: {
color: '#333',
fontStyle: 'normal',
fontWeight: 'bold',
fontFamily: 'Arial',
fontSize: 18
}
}
}文本描边
javascript
option = {
series: [
{
type: 'line',
data: [10, 22, 28, 23, 19],
label: {
show: true,
textBorderColor: '#000',
textBorderWidth: 2
}
}
]
}文本阴影
javascript
option = {
series: [
{
type: 'line',
data: [10, 22, 28, 23, 19],
label: {
show: true,
textShadowColor: 'rgba(0, 0, 0, 0.5)',
textShadowBlur: 5,
textShadowOffsetX: 2,
textShadowOffsetY: 2
}
}
]
}坐标轴样式
坐标轴线样式
javascript
option = {
xAxis: {
axisLine: {
lineStyle: {
color: '#333',
width: 2
}
}
},
yAxis: {
axisLine: {
lineStyle: {
color: '#333',
width: 2
}
}
}
}分隔线样式
javascript
option = {
xAxis: {
splitLine: {
lineStyle: {
color: '#ddd',
type: 'dashed'
}
}
},
yAxis: {
splitLine: {
lineStyle: {
color: '#ddd',
type: 'dashed'
}
}
}
}刻度样式
javascript
option = {
xAxis: {
axisTick: {
lineStyle: {
color: '#333'
}
},
axisLabel: {
color: '#666',
fontSize: 12
}
}
}提示框样式
javascript
option = {
tooltip: {
backgroundColor: 'rgba(50, 50, 50, 0.7)',
borderColor: '#333',
borderWidth: 1,
padding: 10,
textStyle: {
color: '#fff',
fontSize: 14
}
}
}图例样式
javascript
option = {
legend: {
backgroundColor: '#f5f5f5',
borderColor: '#ddd',
borderWidth: 1,
borderRadius: 5,
padding: 10,
textStyle: {
color: '#333',
fontSize: 14
}
}
}深色模式适配
使用内置深色主题
javascript
var chart = echarts.init(dom, 'dark')自定义深色模式
javascript
option = {
backgroundColor: '#1a1a1a',
title: {
textStyle: {
color: '#fff'
}
},
legend: {
textStyle: {
color: '#ccc'
}
},
xAxis: {
axisLine: {
lineStyle: {
color: '#ccc'
}
},
axisLabel: {
color: '#ccc'
}
},
yAxis: {
axisLine: {
lineStyle: {
color: '#ccc'
}
},
axisLabel: {
color: '#ccc'
}
}
}动态主题切换
javascript
function toggleTheme(isDark) {
// 销毁当前实例
chart.dispose()
// 使用新主题重新初始化
chart = echarts.init(dom, isDark ? 'dark' : null)
chart.setOption(option)
}响应式布局
ECharts 图表可以自适应容器大小,实现响应式布局。
基础响应式
javascript
const chart = echarts.init(dom)
// 监听窗口大小变化
window.addEventListener('resize', () => {
chart.resize()
})使用 ResizeObserver
推荐使用 ResizeObserver 实现更精确的监听:
javascript
const chart = echarts.init(dom)
const observer = new ResizeObserver(() => {
chart.resize()
})
observer.observe(dom)
// 销毁时断开监听
// observer.disconnect()媒体查询适配
根据屏幕尺寸调整图表配置:
javascript
function getResponsiveOption() {
const width = window.innerWidth
const isMobile = width < 768
return {
grid: {
left: isMobile ? '3%' : '5%',
right: isMobile ? '3%' : '5%',
bottom: isMobile ? '15%' : '10%',
top: isMobile ? '15%' : '10%'
},
legend: {
orient: isMobile ? 'horizontal' : 'vertical',
top: isMobile ? 'top' : 'middle',
right: isMobile ? 'center' : 'right'
},
title: {
textStyle: {
fontSize: isMobile ? 14 : 18
}
},
xAxis: {
axisLabel: {
rotate: isMobile ? 45 : 0,
fontSize: isMobile ? 10 : 12
}
}
}
}
// 初始化
const chart = echarts.init(dom)
chart.setOption({
...baseOption,
...getResponsiveOption()
})
// 窗口变化时重新计算
window.addEventListener('resize', () => {
chart.setOption(getResponsiveOption())
chart.resize()
})移动端适配
javascript
option = {
// 移动端触摸交互
toolbox: {
show: true,
orient: 'vertical',
right: 10,
top: 'center'
},
// 移动端字体适配
title: {
textStyle: {
fontSize: window.innerWidth < 768 ? 14 : 18
}
},
// 移动端间距适配
grid: {
left: '3%',
right: '3%',
bottom: '10%',
top: '10%',
containLabel: true
},
// 移动端标签适配
series: [{
label: {
fontSize: window.innerWidth < 768 ? 10 : 12
}
}]
}自适应文字大小
javascript
function getAdaptiveFontSize(baseSize) {
const width = window.innerWidth
const scale = Math.min(width / 1920, 1) // 最大 1
return Math.max(baseSize * scale, 10) // 最小 10px
}
option = {
title: {
textStyle: {
fontSize: getAdaptiveFontSize(18)
}
},
xAxis: {
axisLabel: {
fontSize: getAdaptiveFontSize(12)
}
}
}容器百分比布局
html
<style>
.chart-container {
width: 100%;
height: 50vh; /* 视口高度的 50% */
min-height: 300px;
}
</style>
<div class="chart-container" id="chart"></div>
<script>
const chart = echarts.init(document.getElementById('chart'))
// 初始调整大小
chart.resize()
// 监听窗口变化
window.addEventListener('resize', () => chart.resize())
</script>响应式网格布局
多个图表的响应式布局:
html
<style>
.charts-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));
gap: 20px;
}
.chart-item {
height: 300px;
}
</style>
<div class="charts-grid">
<div class="chart-item" id="chart1"></div>
<div class="chart-item" id="chart2"></div>
<div class="chart-item" id="chart3"></div>
</div>
<script>
const charts = []
document.querySelectorAll('.chart-item').forEach(dom => {
const chart = echarts.init(dom)
chart.setOption(getOption())
charts.push(chart)
})
// 使用 ResizeObserver 监听所有图表
const observer = new ResizeObserver(() => {
charts.forEach(chart => chart.resize())
})
document.querySelectorAll('.chart-item').forEach(dom => {
observer.observe(dom)
})
</script>