Browse Source

pref: 优化打包,重构图表通用配置

liaojiaxing 1 year ago
parent
commit
90ad5fcdc6
41 changed files with 33216 additions and 15814 deletions
  1. 1 0
      babel.config.js
  2. 0 1
      components/charts/Bar/BasicBar/index.ts
  3. 85 5
      components/charts/Bar/BasicBar/src/Config.vue
  4. 0 798
      components/charts/Bar/BasicBar/src/styleFormData.ts
  5. 0 1
      components/charts/Line/BasicLine/index.ts
  6. 11 1
      components/charts/Line/BasicLine/src/Config.vue
  7. 0 798
      components/charts/Line/BasicLine/src/styleFormData.ts
  8. 0 0
      components/charts/Pie/BasicPie/index.ts
  9. 17 0
      components/charts/Pie/BasicPie/src/BasicPie.vue
  10. 73 0
      components/charts/Pie/BasicPie/src/Config.vue
  11. 119 0
      components/charts/Pie/BasicPie/src/props.ts
  12. 874 0
      components/charts/config/chartFormItemsMap.ts
  13. 141 0
      components/charts/utils/transChartOption.ts
  14. 4 1
      components/components.ts
  15. 1 1
      components/cusForm/index.ts
  16. 15 6
      components/cusForm/src/ColorScheme.vue
  17. 4 0
      components/cusForm/src/CusFormItem.vue
  18. 2 1
      components/cusForm/src/CusSlider.vue
  19. 10 10
      components/cusForm/src/FontStyle.vue
  20. 135 0
      components/cusForm/src/index.tsx
  21. 6 2
      components/cusForm/src/index.vue
  22. 22 3
      components/cusForm/src/type.ts
  23. 2 1
      components/index.ts
  24. 1 1
      lib/demo.html
  25. 0 1
      lib/shalu-dashboard-ui.css
  26. 0 19
      lib/shalu-dashboard-ui.umd.min.js
  27. 15794 7055
      lib/shalu-dashboard-ui.common.js
  28. 1 1
      lib/shalu-dashboard-ui.umd.js.map
  29. 1 0
      lib/shaluDashBoardUi.css
  30. 15798 7059
      lib/shalu-dashboard-ui.umd.js
  31. 1 1
      lib/shalu-dashboard-ui.common.js.map
  32. 38 0
      lib/shaluDashBoardUi.umd.min.js
  33. 1 1
      lib/shalu-dashboard-ui.umd.min.js.map
  34. 18 17
      package.json
  35. 26 23
      pnpm-lock.yaml
  36. 3 0
      public/index.html
  37. 1 1
      src/App.vue
  38. 0 5
      src/main.ts
  39. 1 0
      tsconfig.json
  40. 1 1
      types/index.d.ts
  41. 9 0
      typing/global.d.ts

+ 1 - 0
babel.config.js

@@ -1,3 +1,4 @@
 module.exports = {
   presets: ["@vue/cli-plugin-babel/preset"],
+  plugins: ["@vue/babel-plugin-jsx"]
 };

+ 0 - 1
components/charts/Bar/BasicBar/index.ts

@@ -9,5 +9,4 @@ BasicBar.install = (app: any) => {
 
 export default BasicBar;
 export { Config };
-export { formItems as basicBarConfigFormItems } from './src/styleFormData';
 export { defaultPropsValue, basicBarProps } from './src/props';

+ 85 - 5
components/charts/Bar/BasicBar/src/Config.vue

@@ -17,8 +17,8 @@
       </Tabs>
     </div>
 
-    <DataConfig v-if="activeTab === '1'" :dataSource="dataSource" @change="handleChange"/>
-    <CusForm v-if="activeTab === '2'" :columns="formItems"/>
+    <DataConfig v-if="activeTab === '1'" :dataSource="dataSource" @change="handleDataSourceChange"/>
+    <CusForm v-if="activeTab === '2'" :columns="formItems" @change="handleFormChange"/>
   </div>
 </template>
 
@@ -27,20 +27,100 @@ import { ref, defineProps, defineEmits } from 'vue';
 import { Tabs, TabPane } from 'ant-design-vue';
 import { DatabaseOutlined, SkinOutlined } from '@ant-design/icons-vue';
 import DataConfig from '../../../DataConfig.vue';
-import { CusForm } from '../../../../cusForm';
+import { CusForm, IFormItem } from '../../../../cusForm';
 import { basicBarProps } from './props';
-import { formItems } from './styleFormData';
+import { chartFormItemsMap } from '../../../config/chartFormItemsMap';
 
 const props = defineProps(basicBarProps);
 const activeTab = ref('1');
 const emit = defineEmits(['change']);
+const formItems = [
+  chartFormItemsMap.title,
+  chartFormItemsMap.legend,
+  // chartFormItemsMap.label,
+  {
+    ...chartFormItemsMap.series,
+    children: [
+      ...(chartFormItemsMap.serie.children as IFormItem[]),
+      {
+        label: "样式",
+        prop: "",
+        type: "divider",
+      },
+      {
+        label: "固定柱宽",
+        prop: "serieBarFixedWidth",
+        type: "radioGroup",
+        fieldProps: {
+          options: [
+            { label: "是", value: true },
+            { label: "否", value: false },
+          ],
+        },
+        defaultValue: false,
+      },
+      {
+        label: "系列间隔",
+        prop: "serieGap",
+        type: "slider",
+        defaultValue: 20,
+      },
+      {
+        label: "分类间隔",
+        prop: "categoryGap",
+        type: "slider",
+        defaultValue: 20,
+      },
+      {
+        label: "边框",
+        prop: "",
+        type: "divider",
+      },
+      {
+        label: "线宽",
+        prop: "serieBorderWidth",
+        type: "inputNumber",
+        fieldProps: {
+          addonAfter: "px",
+        },
+        defaultValue: 0,
+      },
+      {
+        label: "颜色",
+        prop: "serieBorderColor",
+        type: "colorSelect",
+        defaultValue: "#ccc",
+      },
+      {
+        label: "圆角",
+        prop: "serieBorderRadius",
+        type: "inputNumber",
+        fieldProps: {
+          addonAfter: "px",
+        },
+        defaultValue: 0,
+      },
+    ]
+  },
+  chartFormItemsMap.xAxis,
+  chartFormItemsMap.yAxis,
+  chartFormItemsMap.tooltip,
+  chartFormItemsMap.background
+]
 
-const handleChange = (data: any) => {
+const handleDataSourceChange = (data: any) => {
   emit('change', {
     ...props,
     dataSource: data,
   });
 }
+const handleFormChange = (data: any) => {
+  console.log('form change:', data);
+  emit('change', {
+    ...props,
+    ...data
+  });
+}
 </script>
 
 <style lang="less" scoped>

+ 0 - 798
components/charts/Bar/BasicBar/src/styleFormData.ts

@@ -1,798 +0,0 @@
-import { IFormItem } from "../../../../cusForm";
-
-export const formItems: IFormItem[] = [
-  {
-    label: "标题",
-    prop: "title",
-    type: "group",
-    children: [
-      {
-        label: " ",
-        prop: "showTitle",
-        type: "checkboxGroup",
-        fieldProps: {
-          options: [{ label: "标题可见", value: true }],
-        },
-        defaultValue: []
-      },
-      {
-        label: "文本",
-        prop: "titleText",
-        type: "input",
-        defaultValue: "图表标题"
-      },
-      {
-        label: "位置",
-        prop: "titlePosition",
-        type: "position",
-        defaultValue: "center"
-      },
-      {
-        label: "样式",
-        prop: "titleStyle",
-        type: "fontStyle",
-        defaultValue: {
-          size: 18,
-          bold: true,
-          italic: false,
-          underline: false,
-        }
-      },
-      {
-        label: "背景",
-        prop: "",
-        type: "divider",
-      },
-      {
-        label: "填充",
-        prop: "titleBackground",
-        type: "backgroundSelect",
-        fieldProps: {
-          filterOptions: ["image"],
-        },
-        defaultValue: {
-          type: "color",
-          color: "#fff",
-        }
-      },
-      {
-        label: "透明度",
-        prop: "titleOpacity",
-        type: "slider",
-        defaultValue: 100
-      },
-      {
-        label: "圆角",
-        prop: "titleBorderRadius",
-        type: "inputNumber",
-        fieldProps: {
-          addonAfter: "px",
-        },
-        defaultValue: 0
-      },
-    ],
-  },
-  {
-    label: "图例",
-    prop: "legend",
-    type: "group",
-    children: [
-      {
-        label: " ",
-        prop: "showLegend",
-        type: "checkboxGroup",
-        fieldProps: {
-          options: [{ label: "图例可见", value: true }],
-        },
-        defaultValue: [true]
-      },
-      {
-        label: "位置",
-        prop: "legendPosition",
-        type: "position",
-        fieldProps: {
-          type: "round",
-        },
-        defaultValue: "top"
-      },
-      {
-        label: "样式",
-        prop: "legendStyle",
-        type: "fontStyle",
-        defaultValue: {
-          size: 12,
-          bold: false,
-          italic: false,
-          underline: false,
-        }
-      },
-      {
-        label: "边框",
-        prop: "",
-        type: "divider",
-      },
-      {
-        label: "线宽",
-        prop: "legendBorderWidth",
-        type: "inputNumber",
-        fieldProps: {
-          addonAfter: "px",
-        },
-        defaultValue: 0
-      },
-      {
-        label: "颜色",
-        prop: "legendBorderColor",
-        type: "colorSelect",
-        defaultValue: "#ccc"
-      },
-      {
-        label: "圆角",
-        prop: "legendBorderRadius",
-        type: "inputNumber",
-        fieldProps: {
-          addonAfter: "px",
-        },
-        defaultValue: 0
-      },
-      {
-        label: "背景",
-        prop: "",
-        type: "divider",
-      },
-      {
-        label: "背景",
-        prop: "legendBackground",
-        type: "backgroundSelect",
-        fieldProps: {
-          filterOptions: ["image"],
-        },
-        defaultValue: {
-          type: "color",
-          color: "#fff",
-        }
-      },
-      {
-        label: "背景透明度",
-        prop: "legendBackgroudOpacity",
-        type: "slider",
-        defaultValue: 100
-      },
-      {
-        label: "背景圆角",
-        prop: "legendBackgroundRadius",
-        type: "inputNumber",
-        fieldProps: {
-          addonAfter: "px",
-        },
-        defaultValue: 0
-      },
-      {
-        label: "阴影",
-        prop: "legendShadow",
-        type: "radioGroup",
-        fieldProps: {
-          options: [
-            { label: "开启", value: true },
-            { label: "关闭", value: false },
-          ],
-        },
-        defaultValue: false
-      },
-    ],
-  },
-  {
-    label: "标签",
-    prop: "label",
-    type: "group",
-    children: [
-      {
-        label: " ",
-        prop: "showLabel",
-        type: "checkboxGroup",
-        fieldProps: {
-          options: [{ label: "标签可见", value: true }],
-        },
-        defaultValue: false
-      },
-      {
-        label: "文本",
-        prop: "labelValueType",
-        type: "checkboxGroup",
-        fieldProps: {
-          options: [
-            { label: "分类名", value: 'category' },
-            { label: "系列名", value: 'serie' },
-            { label: "数值", value: 'value' },
-            { label: "百分比", value: 'percent' },
-          ]
-        },
-        defaultValue: ['value']
-      },
-      {
-        label: "格式化",
-        prop: "labelFormatter",
-        type: "input",
-        tip: "支持字符串模板和回调函数",
-        defaultValue: "{value}"
-      },
-      {
-        label: "颜色",
-        prop: "labelColor",
-        type: "colorSelect",
-        defaultValue: "#000"
-      },
-      {
-        label: "样式",
-        prop: "labelStyle",
-        type: "fontStyle",
-        defaultValue: {
-          size: 12,
-          bold: false,
-          italic: false,
-          underline: false,
-        }
-      },
-      {
-        label: "布局",
-        prop: "",
-        type: "divider",
-      },
-      {
-        label: "位置",
-        prop: "labelPosition",
-        type: "radioGroup",
-        fieldProps: {
-          options: [
-            { label: "内部", value: "inside" },
-            { label: "外部", value: "outside" },
-            { label: "中间", value: "center" },
-          ],
-        },
-        defaultValue: "outside"
-      },
-      {
-        label: "文本方向",
-        prop: "labelDirection",
-        type: "radioGroup",
-        fieldProps: {
-          options: [
-            { label: "水平", value: "horizontal" },
-            { label: "垂直", value: "vertical" },
-          ],
-        },
-        defaultValue: "horizontal"
-      },
-      {
-        label: "边框",
-        prop: "",
-        type: "divider",
-      },
-      {
-        label: "线宽",
-        prop: "labelBorderWidth",
-        type: "inputNumber",
-        fieldProps: {
-          addonAfter: "px",
-        },
-        defaultValue: 0
-      },
-      {
-        label: "颜色",
-        prop: "labelBorderColor",
-        type: "colorSelect",
-        defaultValue: "#ccc"
-      },
-      {
-        label: "圆角",
-        prop: "labelBorderRadius",
-        type: "inputNumber",
-        fieldProps: {
-          addonAfter: "px",
-        },
-        defaultValue: 0
-      },
-    ],
-  },
-  {
-    label: "系列",
-    prop: "serie",
-    type: "group",
-    children: [
-      {
-        label: "配色",
-        prop: "colorScheme",
-        type: "colorScheme",
-        defaultValue: "custom"
-      },
-      {
-        label: "样式",
-        prop: "",
-        type: "divider",
-      },
-      {
-        label: "固定柱宽",
-        prop: "serieBarFixedWidth",
-        type: "radioGroup",
-        fieldProps: {
-          options: [
-            { label: "是", value: true },
-            { label: "否", value: false },
-          ],
-        },
-        defaultValue: false
-      },
-      {
-        label: "系列间隔",
-        prop: "serieGap",
-        type: "slider",
-        defaultValue: 20
-      },
-      {
-        label: "分类间隔",
-        prop: "categoryGap",
-        type: "slider",
-        defaultValue: 20
-      },
-      {
-        label: "边框",
-        prop: "",
-        type: "divider",
-      },
-      {
-        label: "线宽",
-        prop: "serieBorderWidth",
-        type: "inputNumber",
-        fieldProps: {
-          addonAfter: "px",
-        },
-        defaultValue: 0
-      },
-      {
-        label: "颜色",
-        prop: "serieBorderColor",
-        type: "colorSelect",
-        defaultValue: "#ccc"
-      },
-      {
-        label: "圆角",
-        prop: "serieBorderRadius",
-        type: "inputNumber",
-        fieldProps: {
-          addonAfter: "px",
-        },
-        defaultValue: 0
-      },
-    ]
-  },
-  {
-    label: "X 轴",
-    prop: "xAxis",
-    type: "group",
-    children: [
-      {
-        label: "类型",
-        prop: "xAxisType",
-        type: "select",
-        fieldProps: {
-          options: [
-            { label: "类目坐标轴", value: "category" },
-            { label: "数值坐标轴", value: "value" },
-            { label: "时间坐标轴", value: "time" },
-          ],
-        },
-        defaultValue: "category"
-      },
-      {
-        label: "轴标题",
-        prop: "xAliasShowTitle",
-        type: "radioGroup",
-        fieldProps: {
-          options: [
-            { label: "显示", value: true },
-            { label: "隐藏", value: false },
-          ],
-        },
-        defaultValue: false
-      },
-      {
-        label: "标题内容",
-        prop: "xAliasTitle",
-        type: "input",
-        defaultValue: "X 轴标题"
-      },
-      {
-        label: "标题位置",
-        prop: "xAliasPosition",
-        type: "position",
-        defaultValue: "center"
-      },
-      {
-        label: "标题样式",
-        prop: "xAliasStyle",
-        type: "fontStyle",
-        defaultValue: {
-          size: 12,
-          bold: false,
-          italic: false,
-          underline: false,
-        }
-      },
-      {
-        label: "轴线",
-        prop: "",
-        type: "divider",
-      },
-      {
-        label: "线宽",
-        prop: "xAliasLineWidth",
-        type: "inputNumber",
-        fieldProps: {
-          addonAfter: "px",
-        },
-        defaultValue: 1
-      },
-      {
-        label: "颜色",
-        prop: "xAliasLineColor",
-        type: "colorSelect",
-        defaultValue: "#ccc"
-      },
-      {
-        label: "刻度",
-        prop: "",
-        type: "divider",
-      },
-      {
-        label: "显示刻度",
-        prop: "xAliasTickShow",
-        type: "radioGroup",
-        fieldProps: {
-          options: [
-            { label: "显示", value: true },
-            { label: "隐藏", value: false },
-          ],
-        },
-        defaultValue: true
-      },
-      {
-        label: "刻度长度",
-        prop: "xAliasTickLength",
-        type: "inputNumber",
-        fieldProps: {
-          addonAfter: "px",
-        },
-        defaultValue: 5
-      },
-      {
-        label: "刻度颜色",
-        prop: "xAliasTickColor",
-        type: "colorSelect",
-        defaultValue: "#ccc"
-      },
-      {
-        label: "标签",
-        prop: "",
-        type: "divider",
-      },
-      {
-        label: "颜色",
-        prop: "xAliasLabelColor",
-        type: "colorSelect",
-        defaultValue: "#000"
-      },
-      {
-        label: "样式",
-        prop: "xAliasLabelStyle",
-        type: "fontStyle",
-        defaultValue: {
-          size: 12,
-          bold: false,
-          italic: false,
-          underline: false,
-        }
-      },
-    ]
-  },
-  {
-    label: "Y 轴",
-    prop: "yAxis",
-    type: "group",
-    children: [
-      {
-        label: "轴标题",
-        prop: "yAliasShowTitle",
-        type: "radioGroup",
-        fieldProps: {
-          options: [
-            { label: "显示", value: true },
-            { label: "隐藏", value: false },
-          ],
-        },
-        defaultValue: false
-      },
-      {
-        label: "标题内容",
-        prop: "yAliasTitle",
-        type: "input",
-        defaultValue: "Y 轴标题"
-      },
-      {
-        label: "标题位置",
-        prop: "yAliasPosition",
-        type: "position",
-        defaultValue: "center"
-      },
-      {
-        label: "标题样式",
-        prop: "yAliasStyle",
-        type: "fontStyle",
-        defaultValue: {
-          size: 12,
-          bold: false,
-          italic: false,
-          underline: false,
-        }
-      },
-      {
-        label: "轴线",
-        prop: "",
-        type: "divider",
-      },
-      {
-        label: "线宽",
-        prop: "yAliasLineWidth",
-        type: "inputNumber",
-        fieldProps: {
-          addonAfter: "px",
-        },
-        defaultValue: 1
-      },
-      {
-        label: "颜色",
-        prop: "yAliasLineColor",
-        type: "colorSelect",
-        defaultValue: "#ccc"
-      },
-      {
-        label: "刻度",
-        prop: "",
-        type: "divider",
-      },
-      {
-        label: "显示刻度",
-        prop: "yAliasTickShow",
-        type: "radioGroup",
-        fieldProps: {
-          options: [
-            { label: "显示", value: true },
-            { label: "隐藏", value: false },
-          ],
-        },
-        defaultValue: true
-      },
-      {
-        label: "刻度长度",
-        prop: "yAliasTickLength",
-        type: "inputNumber",
-        fieldProps: {
-          addonAfter: "px",
-        },
-        defaultValue: 5
-      },
-      {
-        label: "刻度颜色",
-        prop: "yAliasTickColor",
-        type: "colorSelect",
-        defaultValue: "#ccc"
-      },
-      {
-        label: "标签",
-        prop: "",
-        type: "divider",
-      },
-      {
-        label: "颜色",
-        prop: "yAliasLabelColor",
-        type: "colorSelect",
-        defaultValue: "#000"
-      },
-      {
-        label: "样式",
-        prop: "yAliasLabelStyle",
-        type: "fontStyle",
-        defaultValue: {
-          size: 12,
-          bold: false,
-          italic: false,
-          underline: false,
-        }
-      },
-    ]
-  },
-  {
-    label: "提示",
-    prop: "tooltip",
-    type: "group",
-    children: [
-      {
-        label: " ",
-        prop: "showTooltip",
-        type: "checkboxGroup",
-        fieldProps: {
-          options: [
-            { label: "提示可见", value: true },
-          ],
-        },
-        defaultValue: [true]
-      },
-      {
-        label: "文本",
-        prop: "tooltipValueType",
-        type: "checkboxGroup",
-        fieldProps: {
-          options: [
-            { label: "分类名", value: 'category' },
-            { label: "系列名", value: 'serie' },
-            { label: "数值", value: 'value' },
-            { label: "百分比", value: 'percent' },
-          ]
-        },
-        defaultValue: ['value']
-      },
-      {
-        label: "格式化",
-        prop: "tooltipFormatter",
-        type: "input",
-        tip: "支持字符串模板和回调函数",
-        defaultValue: "{value}"
-      },
-      {
-        label: "样式",
-        prop: "tooltipStyle",
-        type: "fontStyle",
-        defaultValue: {
-          size: 12,
-          bold: false,
-          italic: false,
-          underline: false,
-        }
-      },
-      {
-        label: "边框",
-        prop: "",
-        type: "divider",
-      },
-      {
-        label: "线宽",
-        prop: "tooltipBorderWidth",
-        type: "inputNumber",
-        fieldProps: {
-          addonAfter: "px",
-        },
-        defaultValue: 1
-      },
-      {
-        label: "颜色",
-        prop: "tooltipBorderColor",
-        type: "colorSelect",
-        defaultValue: "#ccc"
-      },
-      {
-        label: "圆角",
-        prop: "tooltipBorderRadius",
-        type: "inputNumber",
-        fieldProps: {
-          addonAfter: "px",
-        },
-        defaultValue: 0
-      },
-      {
-        label: "背景",
-        prop: "",
-        type: "divider",
-      },
-      {
-        label: "填充",
-        prop: "tooltipBackground",
-        type: "backgroundSelect",
-        fieldProps: {
-          filterOptions: ["image"],
-        },
-        defaultValue: {
-          type: "color",
-          color: "#fff",
-        }
-      },
-      {
-        label: "背景透明度",
-        prop: "tooltipBackgroudOpacity",
-        type: "slider",
-        defaultValue: 100
-      },
-      {
-        label: "阴影",
-        prop: "tooltipShadow",
-        type: "radioGroup",
-        fieldProps: {
-          options: [
-            { label: "开启", value: true },
-            { label: "关闭", value: false },
-          ],
-        },
-        defaultValue: false
-      },
-    ]
-  },
-  {
-    label: "背景",
-    prop: "background",
-    type: "group",
-    children: [
-      {
-        label: "边框",
-        prop: "",
-        type: "divider",
-      },
-      {
-        label: "线宽",
-        prop: "backgroundBorderWidth",
-        type: "inputNumber",
-        fieldProps: {
-          addonAfter: "px",
-        },
-        defaultValue: 0
-      },
-      {
-        label: "颜色",
-        prop: "backgroundBorderColor",
-        type: "colorSelect",
-        defaultValue: "#ccc"
-      },
-      {
-        label: "圆角",
-        prop: "backgroundBorderRadius",
-        type: "inputNumber",
-        fieldProps: {
-          addonAfter: "px",
-        },
-        defaultValue: 0
-      },
-      {
-        label: "背景",
-        prop: "",
-        type: "divider",
-      },
-      {
-        label: "填充",
-        prop: "backgroundBackground",
-        type: "backgroundSelect",
-        fieldProps: {
-          filterOptions: ["image"],
-        },
-        defaultValue: {
-          type: "color",
-          color: "#fff",
-        }
-      },
-      {
-        label: "背景透明度",
-        prop: "backgroundBackgroudOpacity",
-        type: "slider",
-        defaultValue: 100
-      },
-      {
-        label: "阴影",
-        prop: "backgroundShadow",
-        type: "radioGroup",
-        fieldProps: {
-          options: [
-            { label: "开启", value: true },
-            { label: "关闭", value: false },
-          ],
-        },
-        defaultValue: false
-      },
-    ]
-  }
-];

+ 0 - 1
components/charts/Line/BasicLine/index.ts

@@ -8,5 +8,4 @@ BasicLine.install = (app: any) => {
 };
 export default BasicLine;
 export { Config };
-export { formItems as basicLineConfigFormItems } from './src/styleFormData';
 export { defaultPropsValue, basicLineProps } from './src/props';

+ 11 - 1
components/charts/Line/BasicLine/src/Config.vue

@@ -29,11 +29,21 @@ import { DatabaseOutlined, SkinOutlined } from '@ant-design/icons-vue';
 import DataConfig from '../../../DataConfig.vue';
 import { CusForm } from '../../../../cusForm';
 import { basicLineProps } from './props';
-import { formItems } from './styleFormData';
+import { chartFormItemsMap } from '../../../config/chartFormItemsMap';
 
 const props = defineProps(basicLineProps);
 const activeTab = ref('1');
 const emit = defineEmits(['change']);
+const formItems = [
+  chartFormItemsMap.title,
+  chartFormItemsMap.legend,
+  // chartFormItemsMap.label,
+  chartFormItemsMap.series,
+  chartFormItemsMap.xAxis,
+  chartFormItemsMap.yAxis,
+  chartFormItemsMap.tooltip,
+  chartFormItemsMap.background
+]
 
 const handleChange = (data: any) => {
   emit('change', {

+ 0 - 798
components/charts/Line/BasicLine/src/styleFormData.ts

@@ -1,798 +0,0 @@
-import { IFormItem } from "../../../../cusForm";
-
-export const formItems: IFormItem[] = [
-  {
-    label: "标题",
-    prop: "title",
-    type: "group",
-    children: [
-      {
-        label: " ",
-        prop: "showTitle",
-        type: "checkboxGroup",
-        fieldProps: {
-          options: [{ label: "标题可见", value: true }],
-        },
-        defaultValue: []
-      },
-      {
-        label: "文本",
-        prop: "titleText",
-        type: "input",
-        defaultValue: "图表标题"
-      },
-      {
-        label: "位置",
-        prop: "titlePosition",
-        type: "position",
-        defaultValue: "center"
-      },
-      {
-        label: "样式",
-        prop: "titleStyle",
-        type: "fontStyle",
-        defaultValue: {
-          size: 18,
-          bold: true,
-          italic: false,
-          underline: false,
-        }
-      },
-      {
-        label: "背景",
-        prop: "",
-        type: "divider",
-      },
-      {
-        label: "填充",
-        prop: "titleBackground",
-        type: "backgroundSelect",
-        fieldProps: {
-          filterOptions: ["image"],
-        },
-        defaultValue: {
-          type: "color",
-          color: "#fff",
-        }
-      },
-      {
-        label: "透明度",
-        prop: "titleOpacity",
-        type: "slider",
-        defaultValue: 100
-      },
-      {
-        label: "圆角",
-        prop: "titleBorderRadius",
-        type: "inputNumber",
-        fieldProps: {
-          addonAfter: "px",
-        },
-        defaultValue: 0
-      },
-    ],
-  },
-  {
-    label: "图例",
-    prop: "legend",
-    type: "group",
-    children: [
-      {
-        label: " ",
-        prop: "showLegend",
-        type: "checkboxGroup",
-        fieldProps: {
-          options: [{ label: "图例可见", value: true }],
-        },
-        defaultValue: [true]
-      },
-      {
-        label: "位置",
-        prop: "legendPosition",
-        type: "position",
-        fieldProps: {
-          type: "round",
-        },
-        defaultValue: "top"
-      },
-      {
-        label: "样式",
-        prop: "legendStyle",
-        type: "fontStyle",
-        defaultValue: {
-          size: 12,
-          bold: false,
-          italic: false,
-          underline: false,
-        }
-      },
-      {
-        label: "边框",
-        prop: "",
-        type: "divider",
-      },
-      {
-        label: "线宽",
-        prop: "legendBorderWidth",
-        type: "inputNumber",
-        fieldProps: {
-          addonAfter: "px",
-        },
-        defaultValue: 0
-      },
-      {
-        label: "颜色",
-        prop: "legendBorderColor",
-        type: "colorSelect",
-        defaultValue: "#ccc"
-      },
-      {
-        label: "圆角",
-        prop: "legendBorderRadius",
-        type: "inputNumber",
-        fieldProps: {
-          addonAfter: "px",
-        },
-        defaultValue: 0
-      },
-      {
-        label: "背景",
-        prop: "",
-        type: "divider",
-      },
-      {
-        label: "背景",
-        prop: "legendBackground",
-        type: "backgroundSelect",
-        fieldProps: {
-          filterOptions: ["image"],
-        },
-        defaultValue: {
-          type: "color",
-          color: "#fff",
-        }
-      },
-      {
-        label: "背景透明度",
-        prop: "legendBackgroudOpacity",
-        type: "slider",
-        defaultValue: 100
-      },
-      {
-        label: "背景圆角",
-        prop: "legendBackgroundRadius",
-        type: "inputNumber",
-        fieldProps: {
-          addonAfter: "px",
-        },
-        defaultValue: 0
-      },
-      {
-        label: "阴影",
-        prop: "legendShadow",
-        type: "radioGroup",
-        fieldProps: {
-          options: [
-            { label: "开启", value: true },
-            { label: "关闭", value: false },
-          ],
-        },
-        defaultValue: false
-      },
-    ],
-  },
-  {
-    label: "标签",
-    prop: "label",
-    type: "group",
-    children: [
-      {
-        label: " ",
-        prop: "showLabel",
-        type: "checkboxGroup",
-        fieldProps: {
-          options: [{ label: "标签可见", value: true }],
-        },
-        defaultValue: false
-      },
-      {
-        label: "文本",
-        prop: "labelValueType",
-        type: "checkboxGroup",
-        fieldProps: {
-          options: [
-            { label: "分类名", value: 'category' },
-            { label: "系列名", value: 'serie' },
-            { label: "数值", value: 'value' },
-            { label: "百分比", value: 'percent' },
-          ]
-        },
-        defaultValue: ['value']
-      },
-      {
-        label: "格式化",
-        prop: "labelFormatter",
-        type: "input",
-        tip: "支持字符串模板和回调函数",
-        defaultValue: "{value}"
-      },
-      {
-        label: "颜色",
-        prop: "labelColor",
-        type: "colorSelect",
-        defaultValue: "#000"
-      },
-      {
-        label: "样式",
-        prop: "labelStyle",
-        type: "fontStyle",
-        defaultValue: {
-          size: 12,
-          bold: false,
-          italic: false,
-          underline: false,
-        }
-      },
-      {
-        label: "布局",
-        prop: "",
-        type: "divider",
-      },
-      {
-        label: "位置",
-        prop: "labelPosition",
-        type: "radioGroup",
-        fieldProps: {
-          options: [
-            { label: "内部", value: "inside" },
-            { label: "外部", value: "outside" },
-            { label: "中间", value: "center" },
-          ],
-        },
-        defaultValue: "outside"
-      },
-      {
-        label: "文本方向",
-        prop: "labelDirection",
-        type: "radioGroup",
-        fieldProps: {
-          options: [
-            { label: "水平", value: "horizontal" },
-            { label: "垂直", value: "vertical" },
-          ],
-        },
-        defaultValue: "horizontal"
-      },
-      {
-        label: "边框",
-        prop: "",
-        type: "divider",
-      },
-      {
-        label: "线宽",
-        prop: "labelBorderWidth",
-        type: "inputNumber",
-        fieldProps: {
-          addonAfter: "px",
-        },
-        defaultValue: 0
-      },
-      {
-        label: "颜色",
-        prop: "labelBorderColor",
-        type: "colorSelect",
-        defaultValue: "#ccc"
-      },
-      {
-        label: "圆角",
-        prop: "labelBorderRadius",
-        type: "inputNumber",
-        fieldProps: {
-          addonAfter: "px",
-        },
-        defaultValue: 0
-      },
-    ],
-  },
-  {
-    label: "系列",
-    prop: "serie",
-    type: "group",
-    children: [
-      {
-        label: "配色",
-        prop: "colorScheme",
-        type: "colorScheme",
-        defaultValue: "custom"
-      },
-      {
-        label: "样式",
-        prop: "",
-        type: "divider",
-      },
-      {
-        label: "固定柱宽",
-        prop: "serieBarFixedWidth",
-        type: "radioGroup",
-        fieldProps: {
-          options: [
-            { label: "是", value: true },
-            { label: "否", value: false },
-          ],
-        },
-        defaultValue: false
-      },
-      {
-        label: "系列间隔",
-        prop: "serieGap",
-        type: "slider",
-        defaultValue: 20
-      },
-      {
-        label: "分类间隔",
-        prop: "categoryGap",
-        type: "slider",
-        defaultValue: 20
-      },
-      {
-        label: "边框",
-        prop: "",
-        type: "divider",
-      },
-      {
-        label: "线宽",
-        prop: "serieBorderWidth",
-        type: "inputNumber",
-        fieldProps: {
-          addonAfter: "px",
-        },
-        defaultValue: 0
-      },
-      {
-        label: "颜色",
-        prop: "serieBorderColor",
-        type: "colorSelect",
-        defaultValue: "#ccc"
-      },
-      {
-        label: "圆角",
-        prop: "serieBorderRadius",
-        type: "inputNumber",
-        fieldProps: {
-          addonAfter: "px",
-        },
-        defaultValue: 0
-      },
-    ]
-  },
-  {
-    label: "X 轴",
-    prop: "xAxis",
-    type: "group",
-    children: [
-      {
-        label: "类型",
-        prop: "xAxisType",
-        type: "select",
-        fieldProps: {
-          options: [
-            { label: "类目坐标轴", value: "category" },
-            { label: "数值坐标轴", value: "value" },
-            { label: "时间坐标轴", value: "time" },
-          ],
-        },
-        defaultValue: "category"
-      },
-      {
-        label: "轴标题",
-        prop: "xAliasShowTitle",
-        type: "radioGroup",
-        fieldProps: {
-          options: [
-            { label: "显示", value: true },
-            { label: "隐藏", value: false },
-          ],
-        },
-        defaultValue: false
-      },
-      {
-        label: "标题内容",
-        prop: "xAliasTitle",
-        type: "input",
-        defaultValue: "X 轴标题"
-      },
-      {
-        label: "标题位置",
-        prop: "xAliasPosition",
-        type: "position",
-        defaultValue: "center"
-      },
-      {
-        label: "标题样式",
-        prop: "xAliasStyle",
-        type: "fontStyle",
-        defaultValue: {
-          size: 12,
-          bold: false,
-          italic: false,
-          underline: false,
-        }
-      },
-      {
-        label: "轴线",
-        prop: "",
-        type: "divider",
-      },
-      {
-        label: "线宽",
-        prop: "xAliasLineWidth",
-        type: "inputNumber",
-        fieldProps: {
-          addonAfter: "px",
-        },
-        defaultValue: 1
-      },
-      {
-        label: "颜色",
-        prop: "xAliasLineColor",
-        type: "colorSelect",
-        defaultValue: "#ccc"
-      },
-      {
-        label: "刻度",
-        prop: "",
-        type: "divider",
-      },
-      {
-        label: "显示刻度",
-        prop: "xAliasTickShow",
-        type: "radioGroup",
-        fieldProps: {
-          options: [
-            { label: "显示", value: true },
-            { label: "隐藏", value: false },
-          ],
-        },
-        defaultValue: true
-      },
-      {
-        label: "刻度长度",
-        prop: "xAliasTickLength",
-        type: "inputNumber",
-        fieldProps: {
-          addonAfter: "px",
-        },
-        defaultValue: 5
-      },
-      {
-        label: "刻度颜色",
-        prop: "xAliasTickColor",
-        type: "colorSelect",
-        defaultValue: "#ccc"
-      },
-      {
-        label: "标签",
-        prop: "",
-        type: "divider",
-      },
-      {
-        label: "颜色",
-        prop: "xAliasLabelColor",
-        type: "colorSelect",
-        defaultValue: "#000"
-      },
-      {
-        label: "样式",
-        prop: "xAliasLabelStyle",
-        type: "fontStyle",
-        defaultValue: {
-          size: 12,
-          bold: false,
-          italic: false,
-          underline: false,
-        }
-      },
-    ]
-  },
-  {
-    label: "Y 轴",
-    prop: "yAxis",
-    type: "group",
-    children: [
-      {
-        label: "轴标题",
-        prop: "yAliasShowTitle",
-        type: "radioGroup",
-        fieldProps: {
-          options: [
-            { label: "显示", value: true },
-            { label: "隐藏", value: false },
-          ],
-        },
-        defaultValue: false
-      },
-      {
-        label: "标题内容",
-        prop: "yAliasTitle",
-        type: "input",
-        defaultValue: "Y 轴标题"
-      },
-      {
-        label: "标题位置",
-        prop: "yAliasPosition",
-        type: "position",
-        defaultValue: "center"
-      },
-      {
-        label: "标题样式",
-        prop: "yAliasStyle",
-        type: "fontStyle",
-        defaultValue: {
-          size: 12,
-          bold: false,
-          italic: false,
-          underline: false,
-        }
-      },
-      {
-        label: "轴线",
-        prop: "",
-        type: "divider",
-      },
-      {
-        label: "线宽",
-        prop: "yAliasLineWidth",
-        type: "inputNumber",
-        fieldProps: {
-          addonAfter: "px",
-        },
-        defaultValue: 1
-      },
-      {
-        label: "颜色",
-        prop: "yAliasLineColor",
-        type: "colorSelect",
-        defaultValue: "#ccc"
-      },
-      {
-        label: "刻度",
-        prop: "",
-        type: "divider",
-      },
-      {
-        label: "显示刻度",
-        prop: "yAliasTickShow",
-        type: "radioGroup",
-        fieldProps: {
-          options: [
-            { label: "显示", value: true },
-            { label: "隐藏", value: false },
-          ],
-        },
-        defaultValue: true
-      },
-      {
-        label: "刻度长度",
-        prop: "yAliasTickLength",
-        type: "inputNumber",
-        fieldProps: {
-          addonAfter: "px",
-        },
-        defaultValue: 5
-      },
-      {
-        label: "刻度颜色",
-        prop: "yAliasTickColor",
-        type: "colorSelect",
-        defaultValue: "#ccc"
-      },
-      {
-        label: "标签",
-        prop: "",
-        type: "divider",
-      },
-      {
-        label: "颜色",
-        prop: "yAliasLabelColor",
-        type: "colorSelect",
-        defaultValue: "#000"
-      },
-      {
-        label: "样式",
-        prop: "yAliasLabelStyle",
-        type: "fontStyle",
-        defaultValue: {
-          size: 12,
-          bold: false,
-          italic: false,
-          underline: false,
-        }
-      },
-    ]
-  },
-  {
-    label: "提示",
-    prop: "tooltip",
-    type: "group",
-    children: [
-      {
-        label: " ",
-        prop: "showTooltip",
-        type: "checkboxGroup",
-        fieldProps: {
-          options: [
-            { label: "提示可见", value: true },
-          ],
-        },
-        defaultValue: [true]
-      },
-      {
-        label: "文本",
-        prop: "tooltipValueType",
-        type: "checkboxGroup",
-        fieldProps: {
-          options: [
-            { label: "分类名", value: 'category' },
-            { label: "系列名", value: 'serie' },
-            { label: "数值", value: 'value' },
-            { label: "百分比", value: 'percent' },
-          ]
-        },
-        defaultValue: ['value']
-      },
-      {
-        label: "格式化",
-        prop: "tooltipFormatter",
-        type: "input",
-        tip: "支持字符串模板和回调函数",
-        defaultValue: "{value}"
-      },
-      {
-        label: "样式",
-        prop: "tooltipStyle",
-        type: "fontStyle",
-        defaultValue: {
-          size: 12,
-          bold: false,
-          italic: false,
-          underline: false,
-        }
-      },
-      {
-        label: "边框",
-        prop: "",
-        type: "divider",
-      },
-      {
-        label: "线宽",
-        prop: "tooltipBorderWidth",
-        type: "inputNumber",
-        fieldProps: {
-          addonAfter: "px",
-        },
-        defaultValue: 1
-      },
-      {
-        label: "颜色",
-        prop: "tooltipBorderColor",
-        type: "colorSelect",
-        defaultValue: "#ccc"
-      },
-      {
-        label: "圆角",
-        prop: "tooltipBorderRadius",
-        type: "inputNumber",
-        fieldProps: {
-          addonAfter: "px",
-        },
-        defaultValue: 0
-      },
-      {
-        label: "背景",
-        prop: "",
-        type: "divider",
-      },
-      {
-        label: "填充",
-        prop: "tooltipBackground",
-        type: "backgroundSelect",
-        fieldProps: {
-          filterOptions: ["image"],
-        },
-        defaultValue: {
-          type: "color",
-          color: "#fff",
-        }
-      },
-      {
-        label: "背景透明度",
-        prop: "tooltipBackgroudOpacity",
-        type: "slider",
-        defaultValue: 100
-      },
-      {
-        label: "阴影",
-        prop: "tooltipShadow",
-        type: "radioGroup",
-        fieldProps: {
-          options: [
-            { label: "开启", value: true },
-            { label: "关闭", value: false },
-          ],
-        },
-        defaultValue: false
-      },
-    ]
-  },
-  {
-    label: "背景",
-    prop: "background",
-    type: "group",
-    children: [
-      {
-        label: "边框",
-        prop: "",
-        type: "divider",
-      },
-      {
-        label: "线宽",
-        prop: "backgroundBorderWidth",
-        type: "inputNumber",
-        fieldProps: {
-          addonAfter: "px",
-        },
-        defaultValue: 0
-      },
-      {
-        label: "颜色",
-        prop: "backgroundBorderColor",
-        type: "colorSelect",
-        defaultValue: "#ccc"
-      },
-      {
-        label: "圆角",
-        prop: "backgroundBorderRadius",
-        type: "inputNumber",
-        fieldProps: {
-          addonAfter: "px",
-        },
-        defaultValue: 0
-      },
-      {
-        label: "背景",
-        prop: "",
-        type: "divider",
-      },
-      {
-        label: "填充",
-        prop: "backgroundBackground",
-        type: "backgroundSelect",
-        fieldProps: {
-          filterOptions: ["image"],
-        },
-        defaultValue: {
-          type: "color",
-          color: "#fff",
-        }
-      },
-      {
-        label: "背景透明度",
-        prop: "backgroundBackgroudOpacity",
-        type: "slider",
-        defaultValue: 100
-      },
-      {
-        label: "阴影",
-        prop: "backgroundShadow",
-        type: "radioGroup",
-        fieldProps: {
-          options: [
-            { label: "开启", value: true },
-            { label: "关闭", value: false },
-          ],
-        },
-        defaultValue: false
-      },
-    ]
-  }
-];

+ 0 - 0
components/charts/Pie/BasicPie/index.ts


+ 17 - 0
components/charts/Pie/BasicPie/src/BasicPie.vue

@@ -0,0 +1,17 @@
+<template>
+  <Charts :width="width" :height="height" :echarts-options="options" :loading="loading"></Charts>
+</template>
+
+<script setup lang="ts" name="fmDashboardBasicBar">
+import { defineProps } from 'vue';
+import Charts from '../../../Charts.vue';
+import { basicBarProps } from "./props";
+import { useChartOptions } from "../../../hooks/useChartOptions";
+
+const props = defineProps(basicBarProps);
+
+const { options, loading } = useChartOptions(props);
+
+</script>
+
+<style scoped></style>

+ 73 - 0
components/charts/Pie/BasicPie/src/Config.vue

@@ -0,0 +1,73 @@
+<template>
+  <div class="chart-config">
+    <div class="config-tab">
+      <Tabs v-model:activeKey="activeTab" size="small" centered>
+        <TabPane key="1">
+          <template #tab>
+            <DatabaseOutlined />
+            <span>数据设置</span>
+          </template>
+        </TabPane>
+        <TabPane key="2">
+          <template #tab>
+            <SkinOutlined />
+            <span>样式设置</span>
+          </template>
+        </TabPane>
+      </Tabs>
+    </div>
+
+    <DataConfig v-if="activeTab === '1'" :dataSource="dataSource" @change="handleDataSourceChange"/>
+    <CusForm v-if="activeTab === '2'" :columns="formItems" @change="handleFormChange"/>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { ref, defineProps, defineEmits } from 'vue';
+import { Tabs, TabPane } from 'ant-design-vue';
+import { DatabaseOutlined, SkinOutlined } from '@ant-design/icons-vue';
+import DataConfig from '../../../DataConfig.vue';
+import { CusForm, IFormItem } from '../../../../cusForm';
+import { basicBarProps } from './props';
+import { chartFormItemsMap } from '../../../config/chartFormItemsMap';
+
+const props = defineProps(basicBarProps);
+const activeTab = ref('1');
+const emit = defineEmits(['change']);
+const formItems = [
+  chartFormItemsMap.title,
+  chartFormItemsMap.legend,
+  // chartFormItemsMap.label,
+  {
+    ...chartFormItemsMap.series,
+    children: [
+      ...(chartFormItemsMap.serie.children as IFormItem[]),
+    ]
+  },
+  chartFormItemsMap.xAxis,
+  chartFormItemsMap.yAxis,
+  chartFormItemsMap.tooltip,
+  chartFormItemsMap.background
+]
+
+const handleDataSourceChange = (data: any) => {
+  emit('change', {
+    ...props,
+    dataSource: data,
+  });
+}
+const handleFormChange = (data: any) => {
+  console.log('form change:', data);
+  emit('change', {
+    ...props,
+    ...data
+  });
+}
+</script>
+
+<style lang="less" scoped>
+.config-tab {
+  text-align: center;
+  margin-bottom: 12px;
+}
+</style>

+ 119 - 0
components/charts/Pie/BasicPie/src/props.ts

@@ -0,0 +1,119 @@
+import { type PropType } from "vue";
+import { EChartsOption } from "echarts";
+import { getNormalizedChart, dataSource } from "../../../utils";
+import { DataSourceType } from "../../../chartEnum";
+
+export const basicBarProps = {
+  width: {
+    type: Number as PropType<number>,
+    default: 400,
+  },
+  height: {
+    type: Number as PropType<number>,
+    default: 260,
+  },
+  dataSource,
+  // 标题
+  title: {
+    type: Object as PropType<EChartsOption["title"]>,
+  },
+  // 图例
+  legend: {
+    type: Object as PropType<EChartsOption["legend"]>,
+  },
+  // 背景
+  backgroundColor: {
+    type: String as PropType<string>,
+  },
+  // 边框
+  grid: {
+    type: Object as PropType<EChartsOption["grid"]>,
+  },
+  // 提示框
+  tooltip: {
+    type: Object as PropType<EChartsOption["tooltip"]>,
+  },
+  // x轴数据
+  xAxis: {
+    type: Object as PropType<EChartsOption["xAxis"]>,
+  },
+  // y轴数据
+  yAxis: {
+    type: Object as PropType<EChartsOption["yAxis"]>,
+  },
+  // 折线
+  series: {
+    type: Array as PropType<EChartsOption["series"]>,
+  },
+  // 数据集
+  dataset: {
+    type: Object as PropType<EChartsOption["dataset"]>,
+  },
+  // color
+  color: {
+    type: Object as PropType<EChartsOption["color"]>
+  }
+};
+
+const chartOptions = getNormalizedChart({
+  title: {
+    text: "柱状图标题",
+  },
+  xAxis: {
+    data: ['轴标签A', '轴标签B', '轴标签C', '轴标签D']
+  },
+})
+
+export const defaultPropsValue: EChartsOption = {
+  // 组件容器默认属性
+  container: {
+    props: {
+      width: 400,
+      height: 260,
+    },
+  },
+  // 图表默认属性
+  props: {
+    // 数据源
+    dataSource: {
+      sourceType: DataSourceType.STATIC,
+      data: {
+        xData: ['轴标签A', '轴标签B', '轴标签C', '轴标签D'],
+        series: [
+          {
+            type: 'bar',
+            name: '系列1',
+            data: [89.3, 92.1, 94.4, 85.4]
+          },
+          {
+            type: 'bar',
+            name: '系列2',
+            data: [95.8, 89.4, 91.2, 76.9]
+          },
+        ]
+      },
+      url: location.origin + "/mock/api/get/example/bar",
+      method: "POST",
+      params: {},
+      headers: {},
+      refreshTime: 0,
+      dataProcess: `
+        (res) => {
+          // 取出列表
+          const data = res.data;
+          // x轴数据
+          const xData = data.map((item) => item.name); 
+          // 系列数据
+          const series = [
+            { type: 'bar', name: '价格', data: data.map(item => item.price) },
+            { type: 'bar', name: '总量', data: data.map(item => item.count) },
+          ];
+
+          // 返回图表数据
+          return { xData, series };
+        }
+      `
+    },
+    ...chartOptions
+  },
+};

+ 874 - 0
components/charts/config/chartFormItemsMap.ts

@@ -0,0 +1,874 @@
+import { IFormItem } from "../../cusForm";
+/**
+ * 用于快速配置图表配置项 
+ * 
+ * prop: option的路径
+ * format:转换数据
+ * 
+ * */
+export const chartFormItemsMap: Record<string, IFormItem> = {
+  /* 标题 */
+  title: {
+    label: "标题",
+    prop: "title",
+    type: "group",
+    children: [
+      {
+        label: " ",
+        prop: "title.show",
+        type: "checkboxGroup",
+        fieldProps: {
+          options: [{ label: "标题可见", value: true }],
+        },
+        defaultValue: [],
+        format: (formatModel, value) => {
+          formatModel.value['title.show'] = value.length ? [true] : [];
+        }
+      },
+      {
+        type: "dependency",
+        label: "",
+        prop: "",
+        name: ["title.show"],
+        children: (model) => {
+          return model['title.show'].length
+            ? [
+                {
+                  label: "文本",
+                  prop: "title.text",
+                  type: "input",
+                  defaultValue: "图表标题",
+                },
+                {
+                  label: "位置",
+                  prop: "title.left",
+                  type: "position",
+                  defaultValue: "center",
+                },
+                {
+                  label: "样式",
+                  prop: "title.textStyle",
+                  type: "fontStyle",
+                  defaultValue: {
+                    size: 18,
+                    bold: true,
+                    italic: false,
+                  },
+                  format: (formatModel, value) => {
+                    formatModel.value['title.textStyle'] = {
+                      color: value.color,
+                      fontSize: value.size,
+                      fontWeight: value.bold ? "bold" : "normal",
+                      fontStyle: value.italic ? "italic" : "normal",
+                    };
+                  }
+                },
+                {
+                  label: "背景",
+                  prop: "",
+                  type: "divider",
+                },
+                {
+                  label: "填充",
+                  prop: "title.backgroundColor",
+                  type: "backgroundSelect",
+                  fieldProps: {
+                    filterOptions: ["image"],
+                  },
+                  defaultValue: {
+                    type: "color",
+                    color: "#fff",
+                  },
+                  format: (formatModel, value) => {
+                    formatModel.value['title.backgroundColor'] = value.color;
+                  }
+                },
+                {
+                  label: "圆角",
+                  prop: "title.borderRadius",
+                  type: "inputNumber",
+                  fieldProps: {
+                    addonAfter: "px",
+                  },
+                  defaultValue: 0,
+                },
+              ]
+            : [];
+        },
+      },
+    ],
+  },
+  /* 图例 */
+  legend: {
+    label: "图例",
+    prop: "legend",
+    type: "group",
+    children: [
+      {
+        label: " ",
+        prop: "legend.show",
+        type: "checkboxGroup",
+        fieldProps: {
+          options: [{ label: "图例可见", value: true }],
+        },
+        defaultValue: [true],
+        format: (formatModel, value) => {
+          formatModel.value['legend.show'] = value.length ? [true] : [];
+        }
+      },
+      {
+        type: "dependency",
+        label: "",
+        prop: "",
+        name: ["legend.show"],
+        children: (model) => {
+          return model['legend.show'].length
+            ? [
+                {
+                  label: "位置",
+                  prop: "legend.position",
+                  type: "position",
+                  fieldProps: {
+                    type: "round",
+                  },
+                  defaultValue: "top",
+                },
+                {
+                  label: "样式",
+                  prop: "legend.textStyle",
+                  type: "fontStyle",
+                  defaultValue: {
+                    size: 12,
+                    bold: false,
+                    italic: false,
+                  },
+                  format: (formatModel, value) => {
+                    formatModel.value['legend.textStyle'] = {
+                      color: value.color,
+                      fontSize: value.size,
+                      fontWeight: value.bold ? "bold" : "normal",
+                      fontStyle: value.italic ? "italic" : "normal",
+                    };
+                  }
+                },
+                {
+                  label: "边框",
+                  prop: "",
+                  type: "divider",
+                },
+                {
+                  label: "线宽",
+                  prop: "legend.borderWidth",
+                  type: "inputNumber",
+                  fieldProps: {
+                    addonAfter: "px",
+                  },
+                  defaultValue: 0,
+                },
+                {
+                  label: "颜色",
+                  prop: "legend.borderColor",
+                  type: "colorSelect",
+                  defaultValue: "#ccc",
+                },
+                {
+                  label: "圆角",
+                  prop: "legend.borderRadius",
+                  type: "inputNumber",
+                  fieldProps: {
+                    addonAfter: "px",
+                  },
+                  defaultValue: 0,
+                },
+                {
+                  label: "背景",
+                  prop: "",
+                  type: "divider",
+                },
+                {
+                  label: "背景",
+                  prop: "legend.backgroundColor",
+                  type: "backgroundSelect",
+                  fieldProps: {
+                    filterOptions: ["image"],
+                  },
+                  defaultValue: {
+                    type: "color",
+                    color: "#fff",
+                  },
+                  format: (formatModel, value) => {
+                    formatModel.value['legend.backgroundColor'] = value.color;
+                  }
+                },
+                {
+                  label: "阴影",
+                  prop: "legend.shadowBlur",
+                  type: "radioGroup",
+                  fieldProps: {
+                    options: [
+                      { label: "开启", value: true },
+                      { label: "关闭", value: false },
+                    ],
+                  },
+                  defaultValue: false,
+                  format: (formatModel, value) => {
+                    formatModel.value['legend.shadowBlur'] = value ? 10 : 0;
+                    formatModel.value['legend.shadowColor'] = "#000";
+                  }
+                },
+              ]
+            : [];
+        },
+      },
+    ],
+  },
+  /* 系列 */
+  series: {
+    label: "系列",
+    prop: "series.color",
+    type: "group",
+    children: [
+      {
+        label: "配色",
+        prop: "colorScheme",
+        type: "colorScheme",
+        defaultValue: "",
+      },
+    ],
+  },
+  /* X轴 */
+  xAxis: {
+    label: "X 轴",
+    prop: "xAxis",
+    type: "group",
+    children: [
+      {
+        label: "类型",
+        prop: "xAxis.type",
+        type: "select",
+        fieldProps: {
+          options: [
+            { label: "类目坐标轴", value: "category" },
+            { label: "数值坐标轴", value: "value" },
+            { label: "时间坐标轴", value: "time" },
+          ],
+        },
+        defaultValue: "category",
+      },
+      {
+        label: " ",
+        prop: "xAxis.showName",
+        type: "checkboxGroup",
+        fieldProps: {
+          options: [
+            { label: "显示轴标题", value: true },
+          ],
+        },
+        defaultValue: [true],
+        format: (formatModel, value) => {
+          formatModel.value['xAxis.showName'] = value.length ? [true] : [];
+        }
+      },
+      {
+        label: "",
+        prop: "",
+        type: "dependency",
+        name: ["xAxis.showName"],
+        children: (model) => {
+          return model['xAxis.showName'].length ? [
+            {
+              label: "标题内容",
+              prop: "xAxis.name",
+              type: "input",
+              defaultValue: "X 轴标题",
+              format: (formatModel, value) => {
+                if(formatModel.value['xAxis.showName']) {
+                  formatModel.value['xAxis.name'] = value;
+                  formatModel.value['grid.bottom'] = 40;
+                } else {
+                  formatModel.value['xAxis.name'] = "";
+                  formatModel.value['grid.bottom'] = 20;
+                }
+              }
+            },
+            {
+              label: "标题位置",
+              prop: "xAxis.nameLocation",
+              type: "position",
+              defaultValue: "center",
+              format: (formatModel, value: 'left' | 'center' | 'right') => {
+                const p = {
+                  left: "start",
+                  center: "middle",
+                  right: "end",
+                }
+                formatModel.value['xAxis.nameLocation'] = value ? p[value] : 'middle';
+              }
+            },
+            {
+              label: "标题样式",
+              prop: "xAxis.nameTextStyle",
+              type: "fontStyle",
+              defaultValue: {
+                size: 12,
+                bold: false,
+                italic: false
+              },
+              format: (formatModel, value) => {
+                formatModel.value['xAxis.nameTextStyle'] = {
+                  color: value.color,
+                  fontSize: value.size,
+                  fontWeight: value.bold ? "bold" : "normal",
+                  fontStyle: value.italic ? "italic" : "normal",
+                };
+              }
+            },
+          ] : []
+        }
+      },
+      {
+        label: "轴线",
+        prop: "",
+        type: "divider",
+      },
+      {
+        label: "线宽",
+        prop: "xAxis.axisLine.width",
+        type: "inputNumber",
+        fieldProps: {
+          addonAfter: "px",
+        },
+        defaultValue: 1,
+      },
+      {
+        label: "颜色",
+        prop: "xAxis.axisLine.color",
+        type: "colorSelect",
+        defaultValue: "#ccc",
+      },
+      {
+        label: "刻度",
+        prop: "",
+        type: "divider",
+      },
+      {
+        label: " ",
+        prop: "xAxis.axisTick.show",
+        type: "checkboxGroup",
+        fieldProps: {
+          options: [
+            { label: "显示刻度", value: true },
+          ],
+        },
+        defaultValue: [true],
+        format: (formatModel, value) => {
+          formatModel.value['xAxis.axisTick.show'] = value.length ? true : false;
+        }
+      },
+      {
+        label: "",
+        prop: "",
+        type: "dependency",
+        name: ["xAxis.axisTick.show"],
+        children: (model) => {
+          return model['xAxis.axisTick.show'].length ? [
+            {
+              label: "刻度宽度",
+              prop: "xAxis.axisTick.lineStyle.width",
+              type: "inputNumber",
+              fieldProps: {
+                addonAfter: "px",
+              },
+              defaultValue: 5,
+            },
+            {
+              label: "刻度颜色",
+              prop: "xAxis.axisTick.lineStyle.color",
+              type: "colorSelect",
+              defaultValue: "#ccc",
+            },
+          ] : []
+        }
+      },
+      {
+        label: "标签",
+        prop: "",
+        type: "divider",
+      },
+      {
+        label: "颜色",
+        prop: "xAxis.axisLabel.color",
+        type: "colorSelect",
+        defaultValue: "#000",
+      },
+      {
+        label: "样式",
+        prop: "xAxis.axisLabel",
+        type: "fontStyle",
+        defaultValue: {
+          size: 12,
+          bold: false,
+          italic: false
+        },
+        format: (formatModel, value) => {
+          formatModel.value['xAxis.axisLabel.color'] = value.color;
+          formatModel.value['xAxis.axisLabel.fontSize'] = value.size;
+          formatModel.value['xAxis.axisLabel.fontWeight'] = value.bold ? "bold" : "normal";
+          formatModel.value['xAxis.axisLabel.fontStyle'] = value.italic ? "italic" : "normal"; 
+        }
+      },
+    ],
+  },
+  /* Y 轴 */
+  yAxis: {
+    label: "Y 轴",
+    prop: "yAxis",
+    type: "group",
+    children: [
+      {
+        label: " ",
+        prop: "yAliasShowTitle",
+        type: "checkboxGroup",
+        fieldProps: {
+          options: [
+            { label: "显示轴标题", value: true },
+          ],
+        },
+        defaultValue: [],
+      },
+      {
+        label: "",
+        prop: "",
+        type: "dependency",
+        name: ["yAliasShowTitle"],
+        children: ({ yAliasShowTitle }) => {
+          return yAliasShowTitle.length
+            ? [
+                {
+                  label: "标题内容",
+                  prop: "yAliasTitle",
+                  type: "input",
+                  defaultValue: "Y 轴标题",
+                },
+                {
+                  label: "标题位置",
+                  prop: "yAliasPosition",
+                  type: "position",
+                  defaultValue: "center",
+                },
+                {
+                  label: "标题样式",
+                  prop: "yAliasStyle",
+                  type: "fontStyle",
+                  defaultValue: {
+                    size: 12,
+                    bold: false,
+                    italic: false,
+                  },
+                },
+              ]
+            : [];
+        },
+      },
+      {
+        label: "轴线",
+        prop: "",
+        type: "divider",
+      },
+      {
+        label: "线宽",
+        prop: "yAliasLineWidth",
+        type: "inputNumber",
+        fieldProps: {
+          addonAfter: "px",
+        },
+        defaultValue: 1,
+      },
+      {
+        label: "颜色",
+        prop: "yAliasLineColor",
+        type: "colorSelect",
+        defaultValue: "#ccc",
+      },
+      {
+        label: "刻度",
+        prop: "",
+        type: "divider",
+      },
+      {
+        label: " ",
+        prop: "yAliasTickShow",
+        type: "checkboxGroup",
+        fieldProps: {
+          options: [
+            { label: "显示刻度", value: true },
+          ],
+        },
+        defaultValue: [true],
+      },
+      {
+        label: "",
+        prop: "",
+        type: "dependency",
+        name: ['yAliasTickShow'],
+        children: ({ yAliasTickShow }) => {
+          return yAliasTickShow.length ? [
+            {
+              label: "刻度长度",
+              prop: "yAliasTickLength",
+              type: "inputNumber",
+              fieldProps: {
+                addonAfter: "px",
+              },
+              defaultValue: 5,
+            },
+            {
+              label: "刻度颜色",
+              prop: "yAliasTickColor",
+              type: "colorSelect",
+              defaultValue: "#ccc",
+            },
+          ] : []
+        }
+      },
+      {
+        label: "标签",
+        prop: "",
+        type: "divider",
+      },
+      {
+        label: "颜色",
+        prop: "yAliasLabelColor",
+        type: "colorSelect",
+        defaultValue: "#000",
+      },
+      {
+        label: "样式",
+        prop: "yAliasLabelStyle",
+        type: "fontStyle",
+        defaultValue: {
+          size: 12,
+          bold: false,
+          italic: false
+        },
+      },
+    ],
+  },
+  /* 提示 */
+  tooltip: {
+    label: "提示",
+    prop: "tooltip",
+    type: "group",
+    children: [
+      {
+        label: " ",
+        prop: "showTooltip",
+        type: "checkboxGroup",
+        fieldProps: {
+          options: [{ label: "提示可见", value: true }],
+        },
+        defaultValue: [true],
+      },
+      {
+        label: "",
+        prop: "",
+        type: "dependency",
+        name: ["showTooltip"],
+        children: ({ showTooltip }) => {
+          return showTooltip.length
+            ? [
+                {
+                  label: "文本",
+                  prop: "tooltipValueType",
+                  type: "checkboxGroup",
+                  fieldProps: {
+                    options: [
+                      { label: "分类名", value: "category" },
+                      { label: "系列名", value: "serie" },
+                      { label: "数值", value: "value" },
+                      { label: "百分比", value: "percent" },
+                    ],
+                  },
+                  defaultValue: ["value"],
+                },
+                {
+                  label: "格式化",
+                  prop: "tooltipFormatter",
+                  type: "input",
+                  tip: "支持字符串模板和回调函数",
+                  defaultValue: "{value}",
+                },
+                {
+                  label: "样式",
+                  prop: "tooltipStyle",
+                  type: "fontStyle",
+                  defaultValue: {
+                    size: 12,
+                    bold: false,
+                    italic: false,
+                  },
+                },
+                {
+                  label: "边框",
+                  prop: "",
+                  type: "divider",
+                },
+                {
+                  label: "线宽",
+                  prop: "tooltipBorderWidth",
+                  type: "inputNumber",
+                  fieldProps: {
+                    addonAfter: "px",
+                  },
+                  defaultValue: 1,
+                },
+                {
+                  label: "颜色",
+                  prop: "tooltipBorderColor",
+                  type: "colorSelect",
+                  defaultValue: "#ccc",
+                },
+                {
+                  label: "圆角",
+                  prop: "tooltipBorderRadius",
+                  type: "inputNumber",
+                  fieldProps: {
+                    addonAfter: "px",
+                  },
+                  defaultValue: 0,
+                },
+                {
+                  label: "背景",
+                  prop: "",
+                  type: "divider",
+                },
+                {
+                  label: "填充",
+                  prop: "tooltipBackground",
+                  type: "backgroundSelect",
+                  fieldProps: {
+                    filterOptions: ["image"],
+                  },
+                  defaultValue: {
+                    type: "color",
+                    color: "#fff",
+                  },
+                },
+                {
+                  label: "背景透明度",
+                  prop: "tooltipBackgroudOpacity",
+                  type: "slider",
+                  defaultValue: 100,
+                },
+                {
+                  label: "阴影",
+                  prop: "tooltipShadow",
+                  type: "radioGroup",
+                  fieldProps: {
+                    options: [
+                      { label: "开启", value: true },
+                      { label: "关闭", value: false },
+                    ],
+                  },
+                  defaultValue: false,
+                },
+              ]
+            : [];
+        },
+      },
+    ],
+  },
+  /* 背景 */
+  background: {
+    label: "背景",
+    prop: "background",
+    type: "group",
+    children: [
+      {
+        label: "边框",
+        prop: "",
+        type: "divider",
+      },
+      {
+        label: "线宽",
+        prop: "backgroundBorderWidth",
+        type: "inputNumber",
+        fieldProps: {
+          addonAfter: "px",
+        },
+        defaultValue: 0,
+      },
+      {
+        label: "颜色",
+        prop: "backgroundBorderColor",
+        type: "colorSelect",
+        defaultValue: "#ccc",
+      },
+      {
+        label: "圆角",
+        prop: "backgroundBorderRadius",
+        type: "inputNumber",
+        fieldProps: {
+          addonAfter: "px",
+        },
+        defaultValue: 0,
+      },
+      {
+        label: "背景",
+        prop: "",
+        type: "divider",
+      },
+      {
+        label: "填充",
+        prop: "backgroundBackground",
+        type: "backgroundSelect",
+        fieldProps: {
+          filterOptions: ["image"],
+        },
+        defaultValue: {
+          type: "color",
+          color: "#fff",
+        },
+      },
+      {
+        label: "背景透明度",
+        prop: "backgroundBackgroudOpacity",
+        type: "slider",
+        defaultValue: 100,
+      },
+      {
+        label: "阴影",
+        prop: "backgroundShadow",
+        type: "radioGroup",
+        fieldProps: {
+          options: [
+            { label: "开启", value: true },
+            { label: "关闭", value: false },
+          ],
+        },
+        defaultValue: false,
+      },
+    ],
+  },
+};
+
+/* 标签配置在每个系列下,获取标签配置 */
+export const getLabelFormItems = () => {
+  return {
+    label: "标签",
+    prop: "label",
+    type: "group",
+    children: [
+      {
+        label: " ",
+        prop: "showLabel",
+        type: "checkboxGroup",
+        fieldProps: {
+          options: [{ label: "标签可见", value: true }],
+        },
+        defaultValue: [],
+      },
+      {
+        label: "",
+        prop: "",
+        type: "dependency",
+        name: ["showLabel"],
+        children: ({ showLabel }) => {
+          return showLabel.length
+            ? [
+                {
+                  label: "文本",
+                  prop: "labelValueType",
+                  type: "checkboxGroup",
+                  fieldProps: {
+                    options: [
+                      { label: "分类名", value: "name" },
+                      { label: "系列名", value: "seriesType" },
+                      { label: "数值", value: "value" },
+                      // { label: "百分比", value: "percent" },
+                    ],
+                  },
+                  defaultValue: ["value"],
+                },
+                {
+                  label: "颜色",
+                  prop: "labelColor",
+                  type: "colorSelect",
+                  defaultValue: "#000",
+                },
+                {
+                  label: "样式",
+                  prop: "labelStyle",
+                  type: "fontStyle",
+                  defaultValue: {
+                    size: 12,
+                    bold: false,
+                    italic: false,
+                  },
+                },
+                {
+                  label: "布局",
+                  prop: "",
+                  type: "divider",
+                },
+                {
+                  label: "位置",
+                  prop: "labelPosition",
+                  type: "radioGroup",
+                  fieldProps: {
+                    options: [
+                      { label: "内部", value: "insideTop" },
+                      { label: "外部", value: "top" },
+                      { label: "中间", value: "inside" },
+                    ],
+                  },
+                  defaultValue: "insideTop",
+                },
+                {
+                  label: "文本方向",
+                  prop: "labelDirection",
+                  type: "radioGroup",
+                  fieldProps: {
+                    options: [
+                      { label: "水平", value: "horizontal" },
+                      { label: "垂直", value: "vertical" },
+                    ],
+                  },
+                  defaultValue: "horizontal",
+                },
+                {
+                  label: "边框",
+                  prop: "",
+                  type: "divider",
+                },
+                {
+                  label: "线宽",
+                  prop: "labelBorderWidth",
+                  type: "inputNumber",
+                  fieldProps: {
+                    addonAfter: "px",
+                  },
+                  defaultValue: 0,
+                },
+                {
+                  label: "颜色",
+                  prop: "labelBorderColor",
+                  type: "colorSelect",
+                  defaultValue: "#ccc",
+                },
+                {
+                  label: "圆角",
+                  prop: "labelBorderRadius",
+                  type: "inputNumber",
+                  fieldProps: {
+                    addonAfter: "px",
+                  },
+                  defaultValue: 0,
+                },
+              ]
+            : [];
+        },
+      },
+    ],
+  }
+}

+ 141 - 0
components/charts/utils/transChartOption.ts

@@ -0,0 +1,141 @@
+// import { EChartsOption } from "echarts";
+// import { isArray } from "element-plus/es/utils";
+// import { set } from "lodash";
+
+// /* 配置表单 转 echartsOption */
+// export const config2Option = (config: Record<string, any>) => {
+//   const option: EChartsOption = {};
+
+//   option.grid = {};
+//   // 标题
+//   option.title = {};
+//   option.title.show = isArray(config.showTitle)
+//     ? !!config.showTitle?.[0]
+//     : !!config.showTitle;
+//   option.title.text = `title|${config.titleText}`;
+//   option.title.left = config.titlePosition;
+//   option.title.textStyle = {
+//     rich: {
+//       title: {
+//         color: config.titleStyle.color,
+//         fontSize: config.titleStyle.size,
+//         fontWeight: config.titleStyle.bold ? "bold" : "normal",
+//         fontStyle: config.titleStyle.italic ? "italic" : "normal",
+//       },
+//     },
+//   };
+//   option.title.backgroundColor = config.titleBackground.color;
+//   option.title.textStyle.opacity = config.titleOpacity / 100;
+//   option.title.borderRadius = config.titleBorderRadius;
+
+//   // 图例
+//   option.legend = {};
+//   option.legend.show = isArray(config.showLegend)
+//     ? !!config.showLegend?.[0]
+//     : !!config.showLegend;
+//   switch (config.legendPosition) {
+//     case "top":
+//       option.legend.top = 0;
+//       option.legend.left = "center";
+//       break;
+//     case "bottom":
+//       option.legend.bottom = 0;
+//       option.legend.left = "center";
+//       break;
+//     case "left":
+//       option.legend.orient = "vertical";
+//       option.legend.left = 0;
+//       option.legend.top = "middle";
+//       break;
+//     case "right":
+//       option.legend.orient = "vertical";
+//       option.legend.right = 0;
+//       option.legend.top = "middle";
+//       break;
+//   }
+//   option.legend.formatter = `{legendTitle|{name}}`;
+//   option.legend.textStyle = {
+//     rich: {
+//       legendTitle: {
+//         color: config.legendStyle.color,
+//         fontSize: config.legendStyle.size,
+//         fontWeight: config.legendStyle.bold ? "bold" : "normal",
+//         fontStyle: config.legendStyle.italic ? "italic" : "normal",
+//       },
+//     },
+//   };
+//   option.legend.borderWidth = config.legendBorderWidth;
+//   option.legend.borderColor = config.legendBorderColor;
+//   option.legend.borderRadius = config.legendBorderRadius;
+//   option.legend.backgroundColor = config.legendBackground.color;
+//   if (config.legendShadow) {
+//     option.legend.shadowBlur = 10;
+//     option.legend.shadowColor = "rgba(0, 0, 0, 0.5)";
+//     option.legend.shadowOffsetX = 0;
+//     option.legend.shadowOffsetY = 0;
+//   }
+
+//   // 标签
+//   // TODO 标签加入到series中
+//   const optionLabel: Record<string, any> = {};
+//   optionLabel.show = isArray(config.showLabel)
+//     ? !!config.showLabel?.[0]
+//     : !!config.showLabel;
+//   optionLabel.formatter = (res: any) => {
+//     let str: string = "";
+//     (config.labelValueType || []).forEach((key: string) => {
+//       str += res[key] + " ";
+//     });
+
+//     return `{labelTitle|{${str}}}`;
+//   };
+//   optionLabel.color = config.labelColor;
+//   optionLabel.rich = {
+//     labelTitle: {
+//       color: config.labelColor,
+//       fontSize: config.labelStyle.size,
+//       fontWeight: config.labelStyle.bold ? "bold" : "normal",
+//       fontStyle: config.labelStyle.italic ? "italic" : "normal",
+//     },
+//   };
+//   optionLabel.position = config.labelPosition;
+//   optionLabel.rotate = config.labelDirection === "vertical" ? 90 : 0;
+//   optionLabel.borderWidth = config.labelBorderWidth;
+//   optionLabel.borderColor = config.labelBorderColor;
+//   optionLabel.borderRadius = config.labelBorderRadius;
+
+//   // 系列--暂时只配置颜色方案,其他配置组件内部处理
+//   option.series = {};
+//   option.series.color = config.colorScheme;
+
+//   // X 轴
+//   option.xAxis = {};
+//   option.xAxis.type = config.xAxisType;
+//   if (config.xAliasShowTitle && config.xAliasTitle) {
+//     option.xAxis.name = config.xAliasTitle;
+//     option.grid.bottom = 40; // 给标题留出空间
+//   }
+//   let positionMap = {
+//     left: "start",
+//     center: "middle",
+//     right: "end",
+//   };
+//   type Position = "start" | "middle" | "end";
+//   option.xAxis.nameLocation = (
+//     config.xAliasPosition
+//       ? positionMap[config.xAliasPosition as "left" | "center" | "right"]
+//       : "middle"
+//   ) as Position;
+//   option.xAxis.nameTextStyle = {
+//     color: config.xAliasStyle.color,
+//     fontSize: config.xAliasStyle.size,
+//     fontWeight: config.xAliasStyle.bold ? "bold" : "normal",
+//     fontStyle: config.xAliasStyle.italic ? "italic" : "normal",
+//   }
+//   set(option, 'xAxias.axisLine.lineStyle.width', config.xAxisLineWidth);
+//   set(option, 'xAxias.axisLine.lineStyle.color', config.xAxisLineColor);
+//   set(option, 'xAxias.axisLine.axisTick.color', config.xAxisTickColor);
+// };
+
+// /* echartsOption 转 配置表单 */
+// export const option2Config = (option: EChartsOption) => {};

+ 4 - 1
components/components.ts

@@ -1,7 +1,7 @@
 export const asyncComponentAll = {
   Title: () => import('./text/Title'),
   BasicLine: () => import('./charts/Line/BasicLine'),
-  BasicBar: () => import('./charts/Bar/BasicBar/src/BasicBar.vue'),
+  BasicBar: () => import('./charts/Bar/BasicBar'),
 }
 
 export { DataSourceType } from './charts/chartEnum';
@@ -26,6 +26,9 @@ export {
   basicBarProps as BasicBarProps
 } from './charts/Bar/BasicBar';
 
+export type { IFormItem } from './cusForm';
+export { CusForm } from './cusForm';
+
 export const components = {
   BasicLine,
   BasicBar,

+ 1 - 1
components/cusForm/index.ts

@@ -1,4 +1,4 @@
-import CusForm from './src/index.vue';
+import CusForm from './src/index';
 import type { IFormItem } from './src/type';
 
 export {

+ 15 - 6
components/cusForm/src/ColorScheme.vue

@@ -25,27 +25,36 @@
         :key="index"
         :style="{background: color}"
       ></span>
-      <span class="color-block cus-btn"><PlusOutlined /></span>
+      <span class="color-block cus-btn" @click="handleAddColor"><PlusOutlined /></span>
     </div>
   </div>
 </template>
 
 <script setup lang="ts">
-import { ref } from "vue";
+import { ref, defineProps, defineEmits } from "vue";
 import { Select, SelectOption } from "ant-design-vue";
 import { PlusOutlined } from "@ant-design/icons-vue";
-import { colorPreset } from "@/config/colorDefaultConfig";
+import { colorPreset } from "../../charts/config";
 
-const value = ref<string[]>(colorPreset[0].color);
+const props = defineProps({
+  value: {
+    type: Array,
+    default: () => [],
+  },
+});
+const emit = defineEmits(["update:value"]);
 const colorType = ref<string>(colorPreset[0].color.join(","));
 
 const changeColorType = (val: string) => {
   if (val === "custom") {
-    value.value = [];
+    // emit("update:value", []);
   } else {
-    value.value = val.split(",");
+    emit("update:value", val.split(","));
   }
 };
+const handleAddColor = () => {
+  console.log('add color...');
+};
 </script>
 
 <style lang="less" scoped>

+ 4 - 0
components/cusForm/src/CusFormItem.vue

@@ -25,6 +25,9 @@
     <template v-else-if="item.type === 'colorSelect'">
       <ColorSelect v-model:value="model"  v-bind="item?.fieldProps"/>
     </template>
+    <template v-else-if="item.type === 'colorScheme'">
+      <ColorScheme v-model:value="model"  v-bind="item?.fieldProps"/>
+    </template>
     <template v-else-if="item.type === 'radioGroup'">
       <RadioGroup v-model:value="model" size="small" v-bind="item?.fieldProps">
       </RadioGroup>
@@ -68,6 +71,7 @@ import { InfoCircleOutlined } from "@ant-design/icons-vue";
 
 import BackgroundSelect from "./BackgroundSelect.vue";
 import ColorSelect from "./ColorSelect.vue";
+import ColorScheme from "./ColorScheme.vue";
 import Position from "./Position.vue";
 import FontStyle from "./FontStyle.vue";
 import CusSlider from "./CusSlider.vue";

+ 2 - 1
components/cusForm/src/CusSlider.vue

@@ -21,7 +21,8 @@ defineEmits(["update:value"]);
     flex: 1;
   }
   .ant-input-number-group-wrapper {
-    flex: 15%;
+    flex: 12%;
+    margin-left: 8px;
   }
 }
 </style>

+ 10 - 10
components/cusForm/src/FontStyle.vue

@@ -6,9 +6,9 @@
     <span class="cus-btn" :class="{ 'active-btn': italic }"
       ><ItalicOutlined @click="handleItalic"
     /></span>
-    <span class="cus-btn" :class="{ 'active-btn': underline }"
+    <!-- <span class="cus-btn" :class="{ 'active-btn': underline }"
       ><UnderlineOutlined @click="handleUnderline"
-    /></span>
+    /></span> -->
     <InputNumber
       size="small"
       :value="size"
@@ -28,7 +28,7 @@ import { defineProps, defineEmits, ref } from "vue";
 import {
   BoldOutlined,
   ItalicOutlined,
-  UnderlineOutlined,
+  // UnderlineOutlined,
 } from "@ant-design/icons-vue";
 import { InputNumber } from "ant-design-vue";
 
@@ -37,7 +37,7 @@ const props = defineProps<{
     size: number;
     bold: boolean;
     italic: boolean;
-    underline: boolean;
+    // underline: boolean;
   };
 }>();
 
@@ -45,7 +45,7 @@ const emit = defineEmits(["update:value"]);
 
 const bold = ref(props.value?.bold);
 const italic = ref(props.value?.italic);
-const underline = ref(props.value?.underline);
+// const underline = ref(props.value?.underline);
 const size = ref(props.value?.size);
 
 const handleUpdate = () => {
@@ -53,7 +53,7 @@ const handleUpdate = () => {
     size: size.value,
     bold: bold.value,
     italic: italic.value,
-    underline: underline.value,
+    // underline: underline.value,
   });
 };
 
@@ -65,10 +65,10 @@ const handleItalic = () => {
   italic.value = !italic.value;
   handleUpdate();
 };
-const handleUnderline = () => {
-  underline.value = !underline.value;
-  handleUpdate();
-};
+// const handleUnderline = () => {
+//   underline.value = !underline.value;
+//   handleUpdate();
+// };
 const handleChange = (val: number) => {
   size.value = val;
   handleUpdate();

+ 135 - 0
components/cusForm/src/index.tsx

@@ -0,0 +1,135 @@
+import type { IFormItem, ChildrenFn } from "./type";
+import type { FormInstance } from "ant-design-vue";
+import { ref, computed, watch, defineComponent } from "vue";
+import { Form, Collapse, CollapsePanel } from "ant-design-vue";
+import CusFormItem from "./CusFormItem.vue";
+import { pick } from "lodash";
+
+export default defineComponent({
+  props: {
+    columns: {
+      type: Array as () => IFormItem[],
+      default: () => [],
+    },
+    formModel: {
+      type: Object as () => Record<string, any>,
+      default: () => ({}),
+    },
+  },
+  emits: ["change"],
+  setup(props, { emit }) {
+    const formModel = ref<Record<string, any>>({});
+    const formRef = ref<FormInstance>();
+    // 记录被格式化的数据
+    // const formatFormModel = ref<Record<string, any>>({});
+
+    const formItems = computed(() => {
+      return props.columns.map((item) => {
+        return {
+          ...item,
+          rules: item.rules || [],
+        };
+      });
+    });
+
+    const setFormModel = (columns: IFormItem[]) => {
+      columns?.forEach((item) => {
+        // 设置表单初始值
+        if (item.type === "group") {
+          setFormModel(item.children as IFormItem[]);
+        } else if (item.type === "dependency") {
+          const list = (item.children as ChildrenFn)?.(
+            pick(formModel.value, item.name || []),
+            formModel
+          );
+          setFormModel(list);
+        } else {
+          if (item.type === "divider") return;
+          formModel.value[item.prop] = item?.defaultValue;
+        }
+      });
+    };
+
+    watch(
+      () => formItems.value,
+      (val) => {
+        if (val) setFormModel(val);
+      },
+      { immediate: true }
+    );
+
+    watch(
+      () => formModel.value,
+      (val) => {
+        emit("change", val);
+      },
+      { deep: true, immediate: true }
+    );
+
+    /* 单个表单项 */
+    const getItem = (child: IFormItem) => {
+      switch (child.type) {
+        case "dependency": {
+          const list = (child.children as ChildrenFn)?.(
+            pick(formModel.value, child.name || []),
+            formModel
+          );
+          if (list) setFormModel(list);
+          return getFormItems(list);
+        }
+        case "group": {
+          return getGroupItem(child);
+        }
+        default: {
+          return (
+            <CusFormItem
+              key={child.prop}
+              item={child}
+              modelValue={formModel.value[child.prop]}
+              onUpdate:modelValue={(val: any) => {
+                formModel.value[child.prop] = val;
+              }}
+            />
+          );
+        }
+      }
+    };
+    /* 分组 */
+    const getGroupItem = (item: IFormItem) => {
+      return (
+        <Collapse>
+          <CollapsePanel key={item.prop} header={item.label}>
+            {(item.children as IFormItem[])?.map((child) => {
+              return getItem(child);
+            })}
+          </CollapsePanel>
+        </Collapse>
+      );
+    };
+
+    /* 获取表单项 */
+    const getFormItems = (formItemList: IFormItem[]): any => {
+      return formItemList.map((item) => {
+        switch (item.type) {
+          case "group":
+            return getGroupItem(item);
+          default:
+            return getItem(item);
+        }
+      });
+    };
+
+    return () => (
+      <Form
+        model={formModel}
+        colon={false}
+        label-col={{ span: 8 }}
+        ref={formRef}
+        layout="horizontal"
+        size="small"
+      >
+        {getFormItems(formItems.value)}
+      </Form>
+    );
+  },
+});

+ 6 - 2
components/cusForm/src/index.vue

@@ -8,6 +8,10 @@
     size="small"
   >
     <template v-for="item in formItems" :key="item.prop">
+      <!-- 联动 -->
+      <template v-if="item.type === 'dependency'">
+        
+      </template>
       <!-- 分组 -->
       <Collapse v-if="item.type === 'group'">
         <CollapsePanel :key="item.prop" :header="item.label">
@@ -20,7 +24,7 @@
   </Form>
 </template>
 
-<script setup lang="ts">
+<script setup lang="tsx">
 import type { IFormItem } from "./type";
 import type { FormInstance } from "ant-design-vue";
 import {
@@ -65,7 +69,7 @@ watch(
         // 设置表单初始值
         if (item.type === "group") {
           const children = item.children || [];
-          children.forEach((child) => {
+          (children as IFormItem[]).forEach((child) => {
             if(item.type === 'divider') return;
             formModel.value[child.prop] = child?.defaultValue;
           });

+ 22 - 3
components/cusForm/src/type.ts

@@ -1,5 +1,6 @@
-import { VNode } from "vue";
+import type { VNode, Reactive, Ref } from "vue";
 
+export type ChildrenFn = ((names: Record<string, any>, model: Reactive<any>) => IFormItem[]);
 export interface IFormItem {
   label: string;
   icon?: string;
@@ -39,14 +40,32 @@ export interface IFormItem {
     | "slider"
     // 分割线
     | "divider"
+    // 联动
+    | 'dependency'
   rules?: any[];
   defaultValue?: any;
   // 分组表单项
-  children?: IFormItem[];
+  children?: IFormItem[] | ChildrenFn;
   // 组件属性
   fieldProps?: any;
   // 自定义渲染
   render?: (form: any) => VNode;
   // 提示内容
   tip?: string;
-}
+  // 联动表单字段名
+  name?: string[]; 
+  // 格式化数据
+  format?: (formatModel: Ref<Record<string, any>>, value: any) => void;
+}
+
+
+/**
+ * 联动表单
+ * type: 'dependency',
+ * name: ['name1', 'name2'], // 用户需要监听变化的字段
+ * // 动态返回children
+ * children: ({name1, name2}) => {
+ *  ...处理逻辑
+ *  return [...其他表单项]
+ * }
+ *  */

+ 2 - 1
components/index.ts

@@ -2,11 +2,12 @@ import type { App } from 'vue';
 import { components } from './components';
 export * from './components';
 
+export type ComponentType = keyof typeof components;
 export const install = function (app: App) {
   Object.keys(components).forEach(key => {
     const component = components[key as keyof typeof components] as { install?: (app: App<any>) => any };
     if (component?.install) {
-      console.log('install', key);
+      console.log('注册组件:', key);
       app.use(component as any);
     }
   });

+ 1 - 1
lib/demo.html

@@ -1 +1 @@
-<!doctype html><meta charset="utf-8"><title>shalu-dashboard-ui demo</title><script src="./shalu-dashboard-ui.umd.js"></script><link rel="stylesheet" href="./shalu-dashboard-ui.css"><script>console.log(window['shalu-dashboard-ui'])</script>
+<!doctype html><meta charset="utf-8"><title>shaluDashBoardUi demo</title><script src="./shaluDashBoardUi.umd.js"></script><link rel="stylesheet" href="./shaluDashBoardUi.css"><script>console.log(shaluDashBoardUi)</script>

File diff suppressed because it is too large
+ 0 - 1
lib/shalu-dashboard-ui.css


File diff suppressed because it is too large
+ 0 - 19
lib/shalu-dashboard-ui.umd.min.js


File diff suppressed because it is too large
+ 15794 - 7055
lib/shalu-dashboard-ui.common.js


File diff suppressed because it is too large
+ 1 - 1
lib/shalu-dashboard-ui.umd.js.map


File diff suppressed because it is too large
+ 1 - 0
lib/shaluDashBoardUi.css


File diff suppressed because it is too large
+ 15798 - 7059
lib/shalu-dashboard-ui.umd.js


File diff suppressed because it is too large
+ 1 - 1
lib/shalu-dashboard-ui.common.js.map


File diff suppressed because it is too large
+ 38 - 0
lib/shaluDashBoardUi.umd.min.js


File diff suppressed because it is too large
+ 1 - 1
lib/shalu-dashboard-ui.umd.min.js.map


+ 18 - 17
package.json

@@ -1,23 +1,29 @@
 {
   "name": "shalu-dashboard-ui",
-  "version": "0.1.0",
+  "version": "1.0.0",
   "private": true,
   "scripts": {
     "serve": "vue-cli-service serve",
-    "build": "vue-cli-service build --target lib --dest lib index.js",
+    "build": "vue-cli-service build --target lib --name shaluDashBoardUi --dest lib index.js --inline-vue",
     "test:unit": "vue-cli-service test:unit",
     "lint": "vue-cli-service lint"
   },
   "dependencies": {
-    "core-js": "^3.8.3",
+    "@types/lodash-es": "^4.17.12",
     "@vueuse/core": "^10.11.0",
+    "core-js": "^3.8.3",
     "echarts": "^5.5.1",
     "lodash": "^4.17.21"
   },
   "devDependencies": {
+    "@ant-design/icons-vue": "^7.0.1",
+    "@codemirror/lang-javascript": "^6.2.2",
+    "@codemirror/lang-json": "^6.0.1",
+    "@codemirror/theme-one-dark": "^6.1.2",
     "@types/jest": "^27.0.1",
     "@typescript-eslint/eslint-plugin": "^5.4.0",
     "@typescript-eslint/parser": "^5.4.0",
+    "@vue/babel-plugin-jsx": "^1.2.2",
     "@vue/cli-plugin-babel": "~5.0.0",
     "@vue/cli-plugin-eslint": "~5.0.0",
     "@vue/cli-plugin-typescript": "~5.0.0",
@@ -26,27 +32,23 @@
     "@vue/eslint-config-typescript": "^9.1.0",
     "@vue/test-utils": "^2.0.0-0",
     "@vue/vue3-jest": "^27.0.0-alpha.1",
+    "ant-design-vue": "^4.2.3",
     "babel-jest": "^27.0.6",
+    "css-loader": "^7.1.2",
+    "element-plus": "^2.7.6",
     "eslint": "^7.32.0",
     "eslint-config-prettier": "^8.3.0",
     "eslint-plugin-prettier": "^4.0.0",
     "eslint-plugin-vue": "^8.0.3",
     "jest": "^27.0.5",
-    "lint-staged": "^11.1.2",
-    "prettier": "^2.4.1",
-    "ts-jest": "^27.0.4",
-    "typescript": "~4.5.5",
-    "@ant-design/icons-vue": "^7.0.1",
-    "@codemirror/lang-javascript": "^6.2.2",
-    "@codemirror/lang-json": "^6.0.1",
-    "@codemirror/theme-one-dark": "^6.1.2",
-    "ant-design-vue": "^4.2.3",
-    "css-loader": "^7.1.2",
-    "element-plus": "^2.7.6",
     "js-beautify": "^1.15.1",
     "less-loader": "^12.2.0",
+    "lint-staged": "^11.1.2",
+    "prettier": "^2.4.1",
     "progress-bar-webpack-plugin": "^2.1.0",
     "style-loader": "^4.0.0",
+    "ts-jest": "^27.0.4",
+    "typescript": "~4.5.5",
     "vue": "^3.2.13",
     "vue-codemirror": "^6.1.1",
     "vue-hooks-plus": "^2.2.0",
@@ -69,7 +71,7 @@
       "ecmaVersion": 2020
     },
     "rules": {
-      "vue/multi-word-component-names":"off"
+      "vue/multi-word-component-names": "off"
     },
     "overrides": [
       {
@@ -92,8 +94,7 @@
   "jest": {
     "preset": "@vue/cli-plugin-unit-jest/presets/typescript-and-babel"
   },
-  "gitHooks": {
-  },
+  "gitHooks": {},
   "lint-staged": {
     "*.{js,jsx,vue,ts,tsx}": "vue-cli-service lint"
   }

+ 26 - 23
pnpm-lock.yaml

@@ -5,6 +5,9 @@ settings:
   excludeLinksFromLockfile: false
 
 dependencies:
+  '@types/lodash-es':
+    specifier: ^4.17.12
+    version: 4.17.12
   '@vueuse/core':
     specifier: ^10.11.0
     version: 10.11.0(vue@3.4.31)
@@ -40,6 +43,9 @@ devDependencies:
   '@typescript-eslint/parser':
     specifier: ^5.4.0
     version: 5.62.0(eslint@7.32.0)(typescript@4.5.5)
+  '@vue/babel-plugin-jsx':
+    specifier: ^1.2.2
+    version: 1.2.2(@babel/core@7.24.7)
   '@vue/cli-plugin-babel':
     specifier: ~5.0.0
     version: 5.0.8(@vue/cli-service@5.0.8)(core-js@3.37.1)(vue@3.4.31)(webpack-cli@5.1.4)
@@ -1509,7 +1515,7 @@ packages:
     resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==}
     dev: true
 
-  /@codemirror/autocomplete@6.16.3(@codemirror/language@6.10.2)(@codemirror/state@6.4.1)(@codemirror/view@6.28.2)(@lezer/common@1.2.1):
+  /@codemirror/autocomplete@6.16.3(@codemirror/language@6.10.2)(@codemirror/state@6.4.1)(@codemirror/view@6.28.3)(@lezer/common@1.2.1):
     resolution: {integrity: sha512-Vl/tIeRVVUCRDuOG48lttBasNQu8usGgXQawBXI7WJAiUDSFOfzflmEsZFZo48mAvAaa4FZ/4/yLLxFtdJaKYA==}
     peerDependencies:
       '@codemirror/language': ^6.0.0
@@ -1519,7 +1525,7 @@ packages:
     dependencies:
       '@codemirror/language': 6.10.2
       '@codemirror/state': 6.4.1
-      '@codemirror/view': 6.28.2
+      '@codemirror/view': 6.28.3
       '@lezer/common': 1.2.1
     dev: true
 
@@ -1528,18 +1534,18 @@ packages:
     dependencies:
       '@codemirror/language': 6.10.2
       '@codemirror/state': 6.4.1
-      '@codemirror/view': 6.28.2
+      '@codemirror/view': 6.28.3
       '@lezer/common': 1.2.1
     dev: true
 
   /@codemirror/lang-javascript@6.2.2:
     resolution: {integrity: sha512-VGQfY+FCc285AhWuwjYxQyUQcYurWlxdKYT4bqwr3Twnd5wP5WSeu52t4tvvuWmljT4EmgEgZCqSieokhtY8hg==}
     dependencies:
-      '@codemirror/autocomplete': 6.16.3(@codemirror/language@6.10.2)(@codemirror/state@6.4.1)(@codemirror/view@6.28.2)(@lezer/common@1.2.1)
+      '@codemirror/autocomplete': 6.16.3(@codemirror/language@6.10.2)(@codemirror/state@6.4.1)(@codemirror/view@6.28.3)(@lezer/common@1.2.1)
       '@codemirror/language': 6.10.2
       '@codemirror/lint': 6.8.1
       '@codemirror/state': 6.4.1
-      '@codemirror/view': 6.28.2
+      '@codemirror/view': 6.28.3
       '@lezer/common': 1.2.1
       '@lezer/javascript': 1.4.17
     dev: true
@@ -1555,7 +1561,7 @@ packages:
     resolution: {integrity: sha512-kgbTYTo0Au6dCSc/TFy7fK3fpJmgHDv1sG1KNQKJXVi+xBTEeBPY/M30YXiU6mMXeH+YIDLsbrT4ZwNRdtF+SA==}
     dependencies:
       '@codemirror/state': 6.4.1
-      '@codemirror/view': 6.28.2
+      '@codemirror/view': 6.28.3
       '@lezer/common': 1.2.1
       '@lezer/highlight': 1.2.0
       '@lezer/lr': 1.4.1
@@ -1566,7 +1572,7 @@ packages:
     resolution: {integrity: sha512-IZ0Y7S4/bpaunwggW2jYqwLuHj0QtESf5xcROewY6+lDNwZ/NzvR4t+vpYgg9m7V8UXLPYqG+lu3DF470E5Oxg==}
     dependencies:
       '@codemirror/state': 6.4.1
-      '@codemirror/view': 6.28.2
+      '@codemirror/view': 6.28.3
       crelt: 1.0.6
     dev: true
 
@@ -1574,7 +1580,7 @@ packages:
     resolution: {integrity: sha512-rpMgcsh7o0GuCDUXKPvww+muLA1pDJaFrpq/CCHtpQJYz8xopu4D1hPcKRoDD0YlF8gZaqTNIRa4VRBWyhyy7Q==}
     dependencies:
       '@codemirror/state': 6.4.1
-      '@codemirror/view': 6.28.2
+      '@codemirror/view': 6.28.3
       crelt: 1.0.6
     dev: true
 
@@ -1587,12 +1593,12 @@ packages:
     dependencies:
       '@codemirror/language': 6.10.2
       '@codemirror/state': 6.4.1
-      '@codemirror/view': 6.28.2
+      '@codemirror/view': 6.28.3
       '@lezer/highlight': 1.2.0
     dev: true
 
-  /@codemirror/view@6.28.2:
-    resolution: {integrity: sha512-A3DmyVfjgPsGIjiJqM/zvODUAPQdQl3ci0ghehYNnbt5x+o76xq+dL5+mMBuysDXnI3kapgOkoeJ0sbtL/3qPw==}
+  /@codemirror/view@6.28.3:
+    resolution: {integrity: sha512-QVqP+ko078/h9yrW+u5grX3rQhC+BkGKADRrlDaJznfPngJOv5zObiVf0+SgAWhL/Yt0nvZ+10rO3L+gU5IbFw==}
     dependencies:
       '@codemirror/state': 6.4.1
       style-mod: 4.1.2
@@ -2321,11 +2327,9 @@ packages:
     resolution: {integrity: sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==}
     dependencies:
       '@types/lodash': 4.17.6
-    dev: true
 
   /@types/lodash@4.17.6:
     resolution: {integrity: sha512-OpXEVoCKSS3lQqjx9GGGOapBeuW5eUboYHRlHP9urXPX25IKZ6AnP5ZRxtVf63iieUbsHxLn8NQ5Nlftc6yzAA==}
-    dev: true
 
   /@types/mime@1.3.5:
     resolution: {integrity: sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==}
@@ -4016,7 +4020,7 @@ packages:
     hasBin: true
     dependencies:
       caniuse-lite: 1.0.30001639
-      electron-to-chromium: 1.4.815
+      electron-to-chromium: 1.4.816
       node-releases: 2.0.14
       update-browserslist-db: 1.0.16(browserslist@4.23.1)
     dev: true
@@ -4272,13 +4276,13 @@ packages:
   /codemirror@6.0.1(@lezer/common@1.2.1):
     resolution: {integrity: sha512-J8j+nZ+CdWmIeFIGXEFbFPtpiYacFMDR8GlHK3IyHQJMCaVRfGx9NT+Hxivv1ckLWPvNdZqndbr/7lVhrf/Svg==}
     dependencies:
-      '@codemirror/autocomplete': 6.16.3(@codemirror/language@6.10.2)(@codemirror/state@6.4.1)(@codemirror/view@6.28.2)(@lezer/common@1.2.1)
+      '@codemirror/autocomplete': 6.16.3(@codemirror/language@6.10.2)(@codemirror/state@6.4.1)(@codemirror/view@6.28.3)(@lezer/common@1.2.1)
       '@codemirror/commands': 6.6.0
       '@codemirror/language': 6.10.2
       '@codemirror/lint': 6.8.1
       '@codemirror/search': 6.5.6
       '@codemirror/state': 6.4.1
-      '@codemirror/view': 6.28.2
+      '@codemirror/view': 6.28.3
     transitivePeerDependencies:
       - '@lezer/common'
     dev: true
@@ -5181,8 +5185,8 @@ packages:
     resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==}
     dev: true
 
-  /electron-to-chromium@1.4.815:
-    resolution: {integrity: sha512-OvpTT2ItpOXJL7IGcYakRjHCt8L5GrrN/wHCQsRB4PQa1X9fe+X9oen245mIId7s14xvArCGSTIq644yPUKKLg==}
+  /electron-to-chromium@1.4.816:
+    resolution: {integrity: sha512-EKH5X5oqC6hLmiS7/vYtZHZFTNdhsYG5NVPRN6Yn0kQHNBlT59+xSM8HBy66P5fxWpKgZbPqb+diC64ng295Jw==}
     dev: true
 
   /element-plus@2.7.6(vue@3.4.31):
@@ -8660,7 +8664,6 @@ packages:
     resolution: {integrity: sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==}
     engines: {node: '>=10.13.0'}
     hasBin: true
-    requiresBuild: true
     dev: true
 
   /pretty-error@4.0.0:
@@ -8782,8 +8785,8 @@ packages:
       side-channel: 1.0.6
     dev: true
 
-  /qs@6.12.1:
-    resolution: {integrity: sha512-zWmv4RSuB9r2mYQw3zxQuHWeU+42aKi1wWig/j4ele4ygELZ7PEO6MM7rim9oAQH2A5MWfsAVf/jPvTPgCbvUQ==}
+  /qs@6.12.2:
+    resolution: {integrity: sha512-x+NLUpx9SYrcwXtX7ob1gnkSems4i/mGZX5SlYxwIau6RrUSODO89TR/XDGGpn5RPWSYIB+aSfuSlV5+CmbTBg==}
     engines: {node: '>=0.6'}
     dependencies:
       side-channel: 1.0.6
@@ -10114,7 +10117,7 @@ packages:
       '@codemirror/commands': 6.6.0
       '@codemirror/language': 6.10.2
       '@codemirror/state': 6.4.1
-      '@codemirror/view': 6.28.2
+      '@codemirror/view': 6.28.3
       codemirror: 6.0.1(@lezer/common@1.2.1)
       vue: 3.4.31(typescript@4.5.5)
     dev: true
@@ -10164,7 +10167,7 @@ packages:
       '@vue/devtools-api': 6.6.3
       js-cookie: 3.0.5
       lodash: 4.17.21
-      qs: 6.12.1
+      qs: 6.12.2
       query-string: 7.1.3
       screenfull: 5.2.0
       vue: 3.4.31(typescript@4.5.5)

+ 3 - 0
public/index.html

@@ -6,6 +6,7 @@
     <meta name="viewport" content="width=device-width,initial-scale=1.0">
     <link rel="icon" href="<%= BASE_URL %>favicon.ico">
     <title><%= htmlWebpackPlugin.options.title %></title>
+    
   </head>
   <body>
     <noscript>
@@ -14,4 +15,6 @@
     <div id="app"></div>
     <!-- built files will be auto injected -->
   </body>
+  <script src="./shalu-dashboard-ui.umd.js"></script>
+  <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
 </html>

+ 1 - 1
src/App.vue

@@ -4,7 +4,7 @@
 </template>
 
 <script lang="ts">
-import { defineComponent } from "vue";
+import { defineComponent, defineAsyncComponent } from "vue";
 
 export default defineComponent({
   name: "App",

+ 0 - 5
src/main.ts

@@ -1,10 +1,5 @@
 import { createApp } from "vue";
 import App from "./App.vue";
-import shaluDashboard from "../components/index"
-
 
 const app = createApp(App)
-
-app.use(shaluDashboard)
-
 app.mount("#app");

+ 1 - 0
tsconfig.json

@@ -4,6 +4,7 @@
     "module": "esnext",
     "strict": true,
     "jsx": "preserve",
+    "jsxImportSource": "vue",
     "moduleResolution": "node",
     "skipLibCheck": true,
     "esModuleInterop": true,

+ 1 - 1
types/index.d.ts

@@ -1 +1 @@
-declare module 'lodash';
+declare type Recordable<T = any> = Record<string, T>;

+ 9 - 0
typing/global.d.ts

@@ -0,0 +1,9 @@
+/* eslint-disable @typescript-eslint/consistent-type-imports */
+declare module 'vue' {
+  export interface GlobalComponents {
+    BasicBar: typeof import('../components')['BasicBar'];
+    BasicLine: typeof import('../components')['BasicLine'];
+    Title: typeof import('../components')['Title'];
+  }
+}
+export {};