feat: web font
diff --git a/package-lock.json b/package-lock.json
index 2766bfc..973455d 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -380,6 +380,12 @@
                 "vfile-message": "*"
             }
         },
+        "@types/webfontloader": {
+            "version": "1.6.33",
+            "resolved": "https://registry.npmmirror.com/@types/webfontloader/download/@types/webfontloader-1.6.33.tgz",
+            "integrity": "sha1-ze9mtTNBGTzhtNStdxcDaJ23dwg=",
+            "dev": true
+        },
         "@vitejs/plugin-vue": {
             "version": "1.9.2",
             "resolved": "https://registry.npmmirror.com/@vitejs/plugin-vue/download/@vitejs/plugin-vue-1.9.2.tgz",
@@ -4934,6 +4940,11 @@
                 "vscode-vue-languageservice": "^0.25.17"
             }
         },
+        "webfontloader": {
+            "version": "1.6.28",
+            "resolved": "https://registry.nlark.com/webfontloader/download/webfontloader-1.6.28.tgz",
+            "integrity": "sha1-23hhKSU8tujq5UwvsF+HCvZnW64="
+        },
         "which": {
             "version": "1.3.1",
             "resolved": "https://registry.npm.taobao.org/which/download/which-1.3.1.tgz?cache=0&sync_timestamp=1605134855909&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fwhich%2Fdownload%2Fwhich-1.3.1.tgz",
diff --git a/package.json b/package.json
index c79c5aa..2b55138 100644
--- a/package.json
+++ b/package.json
@@ -10,6 +10,7 @@
     "devDependencies": {
         "@babel/polyfill": "^7.12.1",
         "@types/color": "^3.0.2",
+        "@types/webfontloader": "^1.6.33",
         "@vitejs/plugin-vue": "^1.2.2",
         "@vue/compiler-sfc": "^3.0.11",
         "chalk": "^3.0.0",
@@ -30,6 +31,7 @@
         "element-plus": "^1.0.2-beta.44",
         "lodash": "^4.17.19",
         "vue": "^3.0.11",
-        "vue-i18n": "^9.1.6"
+        "vue-i18n": "^9.1.6",
+        "webfontloader": "^1.6.28"
     }
 }
diff --git a/src/App.vue b/src/App.vue
index c5d1655..3d99246 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -6,7 +6,13 @@
       </h3>
       <el-tabs type="card" v-model="activeName">
         <el-tab-pane label="样式" name="config">
-          <WConfig ref="wconfig" @change="onChange"></WConfig>
+          <WConfig
+            ref="wconfig"
+            @change="onChange"
+            @fontLoading="onFontLoading"
+            @fontLoaded="onFontLoaded"
+          >
+          </WConfig>
         </el-tab-pane>
         <el-tab-pane label="数据" name="data">
           <WData ref="wdata" @change="onChange"></WData>
@@ -39,6 +45,14 @@
   wchart.value?.run(wdata.value?.data, wconfig.value?.getConfig());
 }
 
+function onFontLoading() {
+  wchart.value?.setLoading(true);
+}
+
+function onFontLoaded() {
+  wchart.value?.setLoading(false);
+}
+
 setTimeout(() => {
   wdata.value?.setData(defaultData);
 });
diff --git a/src/components/WChart.vue b/src/components/WChart.vue
index 037d5ab..f62e6b3 100644
--- a/src/components/WChart.vue
+++ b/src/components/WChart.vue
@@ -1,5 +1,5 @@
 <template>
-  <div>
+  <div v-loading="isWebFontLoading" element-loading-text="字体加载中">
     <div class="chart" ref="chartRef">aaa</div>
   </div>
 </template>
@@ -15,9 +15,11 @@
 // });
 const chart = shallowRef<echarts.ECharts | null>(null);
 const chartRef = ref<HTMLElement | null>(null);
+const isWebFontLoading = ref(false);
 
 defineExpose({
-  run
+  run,
+  setLoading
 });
 
 type Config = {
@@ -34,6 +36,10 @@
   shape: string;
 };
 
+function setLoading(isLoading: boolean) {
+  isWebFontLoading.value = isLoading;
+}
+
 function run(data?: [], config?: Config) {
   const hues = config
     ? config.themeColors.map(
diff --git a/src/components/WConfig.vue b/src/components/WConfig.vue
index 37a11ff..33d6506 100644
--- a/src/components/WConfig.vue
+++ b/src/components/WConfig.vue
@@ -109,13 +109,19 @@
             placeholder="请选择字体"
             @change="changeFontFamily"
           >
-            <el-option
-              v-for="item in fontFamilies"
-              :key="item"
-              :label="item"
-              :value="item"
+            <el-option-group
+              v-for="group in fontFamilies"
+              :key="group.name"
+              :label="group.name"
             >
-            </el-option>
+              <el-option
+                v-for="item in group.children"
+                :key="item"
+                :label="item.name"
+                :value="item.value"
+              >
+              </el-option>
+            </el-option-group>
           </el-select>
         </el-col>
       </el-row>
@@ -212,6 +218,7 @@
 <script setup lang="ts">
 import { ref } from 'vue';
 import Color from 'color';
+import WebFont from 'webfontloader';
 
 const colorPalettes = [
   {
@@ -226,10 +233,6 @@
     bgColor: '#dbf3ff',
     themeColors: ['#4aa6d5', '#d3b16a', '#fb8500']
   },
-  // {
-  //   bgColor: '#eae2b7',
-  //   themeColors: ['#003049', '#d62828', '#f77f00', '#fcbf49']
-  // },
   {
     bgColor: '#fbffd1',
     themeColors: ['#132a13', '#90a955', '#ecf39e']
@@ -248,17 +251,65 @@
 const height = ref(90);
 const selectedMask = ref('circle');
 
+const normalizeFont = (font: string | { name: string; value: string }) => {
+  if (typeof font === 'string') {
+    return {
+      name: font,
+      value: font
+    };
+  }
+  return font;
+};
+
+const sortFont = (
+  a: { name: string; value: string },
+  b: { name: string; value: string }
+) => {
+  if (a.name < b.name) {
+    return -1;
+  }
+  if (a.name > b.name) {
+    return 1;
+  }
+  return 0;
+};
+
 const fontFamilies = [
-  'Arial',
-  'Lato',
-  'Times New Roman',
-  'Courier New',
-  'Georgia',
-  'Helvetica',
-  'Lucida Sans',
-  'Tahoma',
-  'Verdana'
+  {
+    name: '系统字体',
+    children: [
+      'Arial',
+      'Times New Roman',
+      'Courier New',
+      'Georgia',
+      { name: '宋体/华文宋体', value: 'SimSun, STSong' },
+      { name: '黑体/华文黑体', value: 'SimHei, STHeiti' },
+      { name: '微软雅黑', value: 'Microsoft YaHei' }
+    ]
+      .map(normalizeFont)
+      .sort(sortFont)
+  },
+  {
+    name: 'Google Fonts',
+    children: [
+      'Pushster',
+      'Lato',
+      'Roboto',
+      'Roboto Slab',
+      'Open Sans',
+      'Oswald',
+      'Ubuntu',
+      'Lobster',
+      { name: '马善政毛笔楷书', value: 'Ma Shan Zheng' },
+      { name: '站酷庆科黄油体', value: 'ZCOOL QingKe HuangYou' },
+      { name: '站酷小薇LOGO体', value: 'ZCOOL XiaoWei' }
+    ]
+      .map(normalizeFont)
+      .sort(sortFont)
+  }
 ];
+const webFontsLoaded: string[] = [];
+
 const masks = [
   {
     name: '椭圆',
@@ -293,7 +344,7 @@
   }
 ];
 
-const emit = defineEmits(['change']);
+const emit = defineEmits(['change', 'fontLoading', 'fontLoaded']);
 
 defineExpose({ getConfig });
 
@@ -302,6 +353,23 @@
 }, 0);
 
 function changeFontFamily() {
+  let fontFamily = selectedFontFamily.value;
+  const font = fontFamilies[1].children.find(item => item.value === fontFamily);
+  if (font && !webFontsLoaded.includes(font.value)) {
+    emit('fontLoading');
+    WebFont.load({
+      google: {
+        families: [fontFamily]
+      },
+      fontactive: () => {
+        webFontsLoaded.push(font.value);
+        emit('fontLoaded');
+        change();
+      }
+    });
+    return;
+  }
+
   change();
 }