Преглед на файлове

feat: 添加折线 柱状图

liaojiaxing преди 10 месеца
родител
ревизия
9d07faf6c4

+ 19 - 12
README.md

@@ -8,22 +8,29 @@
 ### 任务列表:
 1. 大屏管理页--完成
 2. 页面布局
-  a. 操作栏 -- 完成
-  b. 图层管理 -- 完成
-  c. 组件管理 -- 完成
-  d. 画布 -- 完成
-  e. 配置页
+  - a. 操作栏 -- 完成
+  - b. 图层管理 -- 完成
+  - c. 组件管理 -- 完成
+  - d. 画布 -- 完成
+  - e. 配置页
 3. 通用协议
 4. 画布
-  a. 缩放 -- 完成
-  b. 标尺 -- 完成
-  c. 拖拽
-  d. 吸附
-  e. 辅助线 -- 完成
-  f. 控制容器组件
+  - a. 缩放 -- 完成
+  - b. 标尺 -- 完成
+  - c. 拖拽 -- 完成
+  - d. 吸附
+  - e. 辅助线 -- 完成
+  - f. 控制容器组件 -- 完成
 5. 渲染器
 6. 属性面板
 7. 组件属性渲染表单
 8. 预览页
 9. 快捷键
-10. 操作记录
+10. 操作记录
+
+
+
+### 图表组件开发思路
+- 图表的option参数归一,提供统一的配置,便于后期做主题配置。
+- 不同的图表提供可以配置的参数,后期通过归一化处理
+- 配置的实现方式两种方式: 1、每个组件提供配置面板,2、根据配置项统一生成配置面板,通过配置项配置组件。

+ 1 - 0
package.json

@@ -17,6 +17,7 @@
     "echarts": "^5.5.0",
     "less": "^4.2.0",
     "less-loader": "^12.2.0",
+    "lodash": "^4.17.21",
     "pinia": "^2.1.7",
     "vue": "^3.4.21",
     "vue-router": "^4.3.3",

+ 3 - 0
pnpm-lock.yaml

@@ -29,6 +29,9 @@ dependencies:
   less-loader:
     specifier: ^12.2.0
     version: 12.2.0(less@4.2.0)
+  lodash:
+    specifier: ^4.17.21
+    version: 4.17.21
   pinia:
     specifier: ^2.1.7
     version: 2.1.7(typescript@5.4.5)(vue@3.4.27)

+ 4 - 0
src/components/Charts/Bar/BasicBar/index.ts

@@ -0,0 +1,4 @@
+import BasicLine from './src/index.vue';
+export default BasicLine;
+
+export { defaultPropsValue, basicLineProps } from './src/props';

+ 15 - 0
src/components/Charts/Bar/BasicBar/src/index.vue

@@ -0,0 +1,15 @@
+<template>
+  <Echarts :width="width" :height="height" :echarts-options="options"></Echarts>
+</template>
+
+<script setup lang="ts">
+import { defineProps, computed } from "vue";
+import Echarts from '@/components/Charts/Echarts.vue';
+import { basicLineProps } from "./props";
+import { omit } from 'lodash';
+
+const props = defineProps(basicLineProps);
+const options = computed(() => omit(props, ['width', 'height', ]));
+</script>
+
+<style scoped></style>

+ 106 - 0
src/components/Charts/Bar/BasicBar/src/props.ts

@@ -0,0 +1,106 @@
+import { type PropType } from 'vue';
+import { EChartsOption } from 'echarts';
+
+export const basicLineProps = {
+  width: {
+    type: Number as PropType<number>,
+    default: 400,
+  },
+  height: {
+    type: Number as PropType<number>,
+    default: 260,
+  },
+  // 标题
+  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']>,
+  },
+};
+
+export const defaultPropsValue: EChartsOption = {
+  width: 400,
+  height: 260,
+  title: {
+    text: '柱状图标题',
+    left: 'center',
+    top: 8,
+    textStyle: {
+      color: '#fff',
+      fontSize: 16
+    }
+  },
+  legend: {
+    textStyle: {
+      color: '#fff',
+    },
+    top: 32
+  },
+  grid: {
+    bottom: 34,
+    right: 20,
+    top: 60
+  },
+  backgroundColor: 'rgba(0,0,0,0.1)',
+  tooltip: {},
+  xAxis: {
+    type: 'category',
+    axisLabel: {
+      color: '#9fadbf'
+    }
+  },
+  yAxis: {
+    axisLabel: {
+      color: '#9fadbf'
+    },
+    splitLine: {
+      lineStyle: {
+        type: 'dashed',
+        color: '#36485f'
+      }
+    }
+  },
+  series: [
+    { type: 'bar', itemStyle: { color: '#1890ff' }},
+    { type: 'bar', itemStyle: { color: '#2fc25b' }}
+  ],
+  dataset: {
+    dimensions: ['serie', '系列1', '系列2'],
+    source: [
+      { serie: '轴标签A', '系列1': 43.3, '系列2': 85.8 },
+      { serie: '轴标签B', '系列1': 43.3, '系列2': 85.8 },
+      { serie: '轴标签C', '系列1': 43.3, '系列2': 85.8 },
+      { serie: '轴标签D', '系列1': 43.3, '系列2': 85.8 },
+    ],
+  }
+}

+ 54 - 0
src/components/Charts/Echarts.vue

@@ -0,0 +1,54 @@
+<!-- echarts基础组件 -->
+<template>
+  <div ref="chartRef" :style="style"></div>
+</template>
+
+<script setup lang="ts">
+import { ref, Ref, defineProps, watch, nextTick, computed } from "vue";
+import { useEcharts } from "@/hooks/useEcharts";
+import type { EChartsOption } from "echarts";
+import { throttle } from "lodash";
+import { useProjectStore } from "@/store/modules/project";
+
+const projectStore = useProjectStore();
+const props = defineProps<{
+  echartsOptions: EChartsOption;
+  width: number;
+  height: number;
+}>();
+const chartRef: Ref<null | HTMLDivElement> = ref(null);
+const { setOptions, resize } = useEcharts(chartRef as Ref<HTMLDivElement>);
+
+const style = computed(() => {
+  const { width, height } = props;
+  return {
+    width: `${width}px`,
+    height: `${height}px`,
+  };
+});
+
+watch(
+  () => [
+    props.width,
+    props.height,
+  ],
+  throttle(async () => {
+   resize();
+  }, 200),
+)
+
+watch(
+  () => props,
+  async () => {
+    await nextTick();
+    const { echartsOptions } = props;
+
+    setOptions(echartsOptions);
+  },
+  {
+    immediate: true,
+  }
+);
+</script>
+
+<style scoped></style>

+ 5 - 44
src/components/Charts/Line/BasicLine/src/index.vue

@@ -1,54 +1,15 @@
 <template>
-  <div ref="chartRef" :style="style"></div>
+  <Echarts :width="width" :height="height" :echarts-options="options"></Echarts>
 </template>
 
 <script setup lang="ts">
-import { ref, Ref, defineProps, watch, nextTick, computed } from "vue";
-import { useEcharts } from "@/hooks/useEcharts";
+import { defineProps, computed } from "vue";
+import Echarts from '@/components/Charts/Echarts.vue';
 import { basicLineProps } from "./props";
+import { omit } from 'lodash';
 
 const props = defineProps(basicLineProps);
-const chartRef: Ref<null | HTMLDivElement> = ref(null);
-const { setOptions } = useEcharts(chartRef as Ref<HTMLDivElement>);
-const style = computed(() => {
-  const { width, height } = props;
-  return {
-    width: `${width}px`,
-    height: `${height}px`,
-  };
-});
-
-watch(
-  () => props,
-  async () => {
-    await nextTick();
-    const {
-      title,
-      legend,
-      grid,
-      backgroundColor,
-      tooltip,
-      xAxis,
-      yAxis,
-      series,
-      dataset,
-    } = props;
-
-    setOptions({
-      title,
-      grid,
-      backgroundColor,
-      legend,
-      tooltip,
-      xAxis,
-      yAxis,
-      series,
-      dataset,
-    });
-  },
-  {
-    immediate: true
-  });
+const options = computed(() => omit(props, ['width', 'height', ]));
 </script>
 
 <style scoped></style>

+ 34 - 5
src/components/Charts/Line/BasicLine/src/props.ts

@@ -1,5 +1,5 @@
 import { type PropType } from 'vue';
-import { EChartsOption, color } from 'echarts';
+import { EChartsOption } from 'echarts';
 
 export const basicLineProps = {
   width: {
@@ -48,19 +48,48 @@ export const basicLineProps = {
   },
 };
 
-export const defaultPropsValue = {
+export const defaultPropsValue: EChartsOption = {
   width: 400,
   height: 260,
+  title: {
+    text: '标题',
+    left: 'center',
+    top: 8,
+    textStyle: {
+      color: '#fff',
+      fontSize: 16
+    }
+  },
   legend: {
+    textStyle: {
+      color: '#fff',
+    },
+    top: 32
+  },
+  grid: {
+    bottom: 34,
+    right: 20,
+    top: 60
   },
+  backgroundColor: 'rgba(0,0,0,0.1)',
   tooltip: {},
   xAxis: {
     type: 'category',
-    itemStyle: {
-      color: '#fff'
+    axisLabel: {
+      color: '#9fadbf'
+    }
+  },
+  yAxis: {
+    axisLabel: {
+      color: '#9fadbf'
+    },
+    splitLine: {
+      lineStyle: {
+        type: 'dashed',
+        color: '#36485f'
+      }
     }
   },
-  yAxis: {},
   series: [
     { type: 'line', itemStyle: { color: '#1890ff' }},
     { type: 'line', itemStyle: { color: '#2fc25b' }}

+ 1 - 0
src/components/index.ts

@@ -2,6 +2,7 @@
 const allComponents = {
   Title: () => import("@/components/Text/Title"),
   BasicLine: () => import("@/components/Charts/Line/BasicLine"),
+  BasicBar: () => import("@/components/Charts/Bar/BasicBar"),
 };
 
 export default allComponents;