一键换肤(Echarts 自定义主题)

一键换肤(Echarts 自定义主题)

一、使用官方主题配置工具

官方主题配置工具:https://echarts.apache.org/zh/theme-builder.html

如果以上主题不满足使用,可以自己自定义主题

例如:修改背景、标题等,可按照设计师需求来更改

配置好之后,下载主题

有两种方式可选:JS 版本、JSON 版本,以 JSON 版本为例:

复制到项目中( theme.json ),

theme.json 文件示例:

json 复制代码
{
    "categoryAxis": {
        "axisLine": {
            "show": true,
            "lineStyle": {
                "color": "green"
            }
        },
        "axisTick": {
            "show": true,
            "lineStyle": {
                "color": "green"
            }
        },
        "axisLabel": {
            "show": true,
            "color": "green"
        } 
    },
    "valueAxis": {
        "axisLine": {
            "show": false,
            "lineStyle": {
                "color": "green"
            }
        },
        "axisLabel": {
            "show": true,
            "color": "green"
        }
    },
    "legend": {
        "textStyle": {
            "color": "green"
        }
    }
}

注册主题:

javascript 复制代码
// 引入主题
import theme from './theme.json'

// 使用echarts
import echarts from 'echarts'
echarts.registerTheme('customTheme', theme)

使用:

html 复制代码
//使用echarts
<div id="test">
	...
</div>
<script>
	let myChart = echarts.init(document.getElementById("test"),"customTheme");
	let option = {...}
	myChart.setOption(option);
</script>

完整代码:

javascript 复制代码
<template>
  <div id="main" style="width: 600px; height: 400px"></div>
</template>

<script>
import theme from "./theme.json";
import * as echarts from "echarts";

export default {
  mounted() {
    //注册主题
    echarts.registerTheme("customTheme", theme);
    //初始化使用主题
    var myChart = echarts.init(document.getElementById("main"), "customTheme"); // 使用dark 、light或无第二参数

    myChart.setOption({
      xAxis: {
        type: "category",
        data: ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
      },
      yAxis: {
        type: "value",
      },
      series: [
        {
          data: [150, 230, 224, 218, 135, 147, 260],
          type: "line",
        },
      ],
    });
  },
};
</script>

如果是多主题切换,则可以将各个主题的颜色整合在一个文件,分别注册

json 复制代码
{
    "lightTheme": {
        "categoryAxis": {
            "axisLine": {
                "show": true,
                "lineStyle": {
                    "color": "#cccccc"
                }
            },
            "axisTick": {
                "show": true,
                "lineStyle": {
                    "color": "#cccccc"
                }
            },
            "axisLabel": {
                "show": true,
                "color": "#cccccc"
            }
        },
        "valueAxis": {
            "axisLine": {
                "show": false,
                "lineStyle": {
                    "color": "#cccccc"
                }
            },
            "axisLabel": {
                "show": true,
                "color": "#cccccc"
            }
        },
        "legend": {
            "textStyle": {
                "color": "#cccccc"
            }
        }
    },
    "darkTheme": {
        "categoryAxis": {
            "axisLine": {
                "show": true,
                "lineStyle": {
                    "color": "#ffffff"
                }
            },
            "axisTick": {
                "show": true,
                "lineStyle": {
                    "color": "#ffffff"
                }
            },
            "axisLabel": {
                "show": true,
                "color": "#ffffff"
            }
        },
        "valueAxis": {
            "axisLine": {
                "show": false,
                "lineStyle": {
                    "color": "#ffffff"
                }
            },
            "axisLabel": {
                "show": true,
                "color": "#ffffff"
            }
        },
        "legend": {
            "textStyle": {
                "color": "#ffffff"
            }
        }
    }
}

这样的话,就可以对应官方示例中的这种(深色/浅色模式)
https://echarts.apache.org/examples/zh/editor.html?c=line-simple

二、上述不满足使用的情况

这是因为执行先后顺序

先使用主题色(初始化),再配置的 option,option 里的颜色覆盖了主题里的颜色。

这种情况下,我这边是用了笨办法,一个个去设置(大家如果有好的办法,可以交流下)

给 x 轴、y轴、图例、标题单独设置了 深色模式下的颜色。

定义 darkTheme.json 文件:

json 复制代码
{
    "title": {
        "textStyle": {
            "color": "rgba(255,255,255,0.6)"
        },
        "subtextStyle": {
            "color": "rgba(255,255,255,0.6)"
        }
    },
    "tooltip": {
        "backgroundColor": "rgba(5,22,38,0.9)",
        "borderColor": "rgba(5,22,38,0.9)",
        "textStyle": {
            "color": "rgba(255,255,255,0.6)"
        }
    },
    "categoryAxis": {
        "axisLine": {
            "lineStyle": {
                "color": "#CCCCCC"
            }
        }, 
        "axisTick": {
            "lineStyle": {
                "color": "#CCCCCC"
            }
        },
        "axisLabel": {
            "color": "rgba(255,255,255,0.6)"
        }
    },
    "valueAxis": {
        "axisLine": {
            "lineStyle": {
                "color": "#CCCCCC"
            }
        },
        "axisLabel": {
            "color": "rgba(255,255,255,0.6)"
        },
        "nameTextStyle": {
            "color": "rgba(255,255,255,0.6)"
        },
        "splitLine": {
            "lineStyle": {
                "color": "rgba(5,22,38,0.7)"
            }
        }
    },
    "legend": {
        "textStyle": {
            "color": "rgba(255,255,255,0.8)"
        }
    }
}

使用

js 复制代码
<script>
import { cloneDeep } from "lodash-es";
import darkTheme from "./darkTheme.json";

export default {
  props: {
    option: {
      type: Object,
      default: null,
    },
  },
  name: "ChartCustomEcharts",
  data() {
    return {
      baseChart: null,
    };
  },
  methods: {
    setOption(option = this.option) {
      if (option && this.baseChart) {
        const result = this.getThemeColors(option);
        this.baseChart.setOption(result, true);
      }
    },
    initChart() {
      this.baseChart = echarts.init(this.$refs["baseChart"]);
      this.setOption();
    },
    getThemeColors(data) {
      const option = cloneDeep(data)
      const themeType = this.themeType;

      if (themeType === "dark") {
        // 标题
        if (option.title) {
          if (option.title.subtextStyle) {
            option.title.subtextStyle.color = darkTheme.title.subtextStyle.color;
          }
        }
        // 图例
        if (option.legend) {
          if (option.legend.textStyle) {
            option.legend.textStyle.color = darkTheme.legend.textStyle.color;
          } else {
            option.legend.textStyle = darkTheme.legend.textStyle;
          }
        }
        // x轴
        if (option.xAxis) {
          if (Array.isArray(option.xAxis)) {
            option.xAxis.forEach((work) => {
              if (work.axisLabel) {
                work.axisLabel.color = darkTheme.categoryAxis.axisLabel.color;
              }
              if (work.axisLine) {
                if (work.axisLine.lineStyle) {
                  work.axisLine.lineStyle.color = darkTheme.categoryAxis.axisLine.lineStyle.color;
                } else {
                  work.axisLine.lineStyle = darkTheme.categoryAxis.axisLine.lineStyle;
                }
              }
            });
          }
        }
        // Y轴
        if (option.yAxis) {
          if (Array.isArray(option.yAxis)) {
            option.yAxis.forEach((work) => {
              if (work.axisLabel) {
                work.axisLabel.color = darkTheme.valueAxis.axisLabel.color;
              }
              if (work.axisLine) {
                if (work.axisLine.lineStyle) {
                  work.axisLine.lineStyle.color = darkTheme.valueAxis.axisLine.lineStyle.color;
                } else {
                  work.axisLine.lineStyle = darkTheme.valueAxis.axisLine.lineStyle;
                }
              }
              if(work.splitLine){
                if(work.splitLine.lineStyle){
                  work.splitLine.lineStyle.color = darkTheme.valueAxis.splitLine.lineStyle.color;
                }else{
                  work.splitLine.lineStyle = darkTheme.valueAxis.splitLine.lineStyle
                }
              }
              if (work.nameTextStyle) {
                work.nameTextStyle.color = darkTheme.valueAxis.nameTextStyle.color;
              }
            });
          }
        }
        // tooltip
        if (option.tooltip) {
          option.tooltip.backgroundColor = darkTheme.tooltip.backgroundColor;
          option.tooltip.borderColor = darkTheme.tooltip.borderColor;
          if (option.tooltip.textStyle) {
            option.tooltip.textStyle.color = darkTheme.tooltip.textStyle.color;
          } else {
            option.tooltip.textStyle = darkTheme.tooltip.textStyle;
          }
        }
      }
      return option;
    },
  },
};
</script>
相关推荐
夏河始溢1 分钟前
一七八、Node.js PM2使用介绍
前端·javascript·node.js·pm2
记忆深处的声音2 分钟前
vue2 + Element-ui 二次封装 Table 组件,打造通用业务表格
前端·vue.js·代码规范
陈随易3 分钟前
兔小巢收费引发的论坛调研Node和Deno有感
前端·后端·程序员
熊的猫17 分钟前
webpack 核心模块 — loader & plugins
前端·javascript·chrome·webpack·前端框架·node.js·ecmascript
速盾cdn24 分钟前
速盾:vue的cdn是干嘛的?
服务器·前端·网络
四喜花露水1 小时前
Vue 自定义icon组件封装SVG图标
前端·javascript·vue.js
前端Hardy1 小时前
HTML&CSS: 实现可爱的冰墩墩
前端·javascript·css·html·css3
web Rookie2 小时前
JS类型检测大全:从零基础到高级应用
开发语言·前端·javascript
Au_ust2 小时前
css:基础
前端·css
帅帅哥的兜兜2 小时前
css基础:底部固定,导航栏浮动在顶部
前端·css·css3