一键换肤(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>
相关推荐
码爸10 分钟前
flink doris批量sink
java·前端·flink
深情废杨杨11 分钟前
前端vue-父传子
前端·javascript·vue.js
J不A秃V头A1 小时前
Vue3:编写一个插件(进阶)
前端·vue.js
司篂篂2 小时前
axios二次封装
前端·javascript·vue.js
姚*鸿的博客2 小时前
pinia在vue3中的使用
前端·javascript·vue.js
宇文仲竹2 小时前
edge 插件 iframe 读取
前端·edge
Kika写代码2 小时前
【基于轻量型架构的WEB开发】【章节作业】
前端·oracle·架构
天下无贼!4 小时前
2024年最新版Vue3学习笔记
前端·vue.js·笔记·学习·vue
Jiaberrr4 小时前
JS实现树形结构数据中特定节点及其子节点显示属性设置的技巧(可用于树形节点过滤筛选)
前端·javascript·tree·树形·过滤筛选
赵啸林4 小时前
npm发布插件超级简单版
前端·npm·node.js