Skip to content

Commit

Permalink
feat(hooks): 完善useEcharts
Browse files Browse the repository at this point in the history
  • Loading branch information
chansee97 committed Jan 11, 2023
1 parent c5705f7 commit 6ef49cb
Show file tree
Hide file tree
Showing 7 changed files with 751 additions and 132 deletions.
16 changes: 16 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
"*.vue" eol=lf
"*.js" eol=lf
"*.ts" eol=lf
"*.jsx" eol=lf
"*.tsx" eol=lf
"*.cjs" eol=lf
"*.cts" eol=lf
"*.mjs" eol=lf
"*.mts" eol=lf
"*.json" eol=lf
"*.html" eol=lf
"*.css" eol=lf
"*.less" eol=lf
"*.scss" eol=lf
"*.sass" eol=lf
"*.styl" eol=lf
34 changes: 27 additions & 7 deletions src/components/common/ErrorTip.vue
Original file line number Diff line number Diff line change
@@ -1,9 +1,29 @@
<template>
<div class="flex-col-center h-800px">
<img v-if="type === '403'" src="@/assets/svg/error-403.svg" alt="" class="w-1/3" />
<img v-if="type === '404'" src="@/assets/svg/error-404.svg" alt="" class="w-1/3" />
<img v-if="type === '500'" src="@/assets/svg/error-500.svg" alt="" class="w-1/3" />
<n-button type="primary" @click="toRoot">回到首页</n-button>
<div class="flex-col-center h-full">
<img
v-if="type === '403'"
src="@/assets/svg/error-403.svg"
alt=""
class="w-1/3"
>
<img
v-if="type === '404'"
src="@/assets/svg/error-404.svg"
alt=""
class="w-1/3"
>
<img
v-if="type === '500'"
src="@/assets/svg/error-500.svg"
alt=""
class="w-1/3"
>
<n-button
type="primary"
@click="toRoot"
>
回到首页
</n-button>
</div>
</template>

Expand All @@ -12,8 +32,8 @@ import { useAppRouter } from '@/hooks';
type TipType = '403' | '404' | '500';
defineProps<{
/** 异常类型 403 404 500 */
type: TipType;
/** 异常类型 403 404 500 */
type: TipType;
}>();
const { toRoot } = useAppRouter();
</script>
Expand Down
187 changes: 122 additions & 65 deletions src/hooks/useEcharts.ts
Original file line number Diff line number Diff line change
@@ -1,87 +1,144 @@
import * as echarts from 'echarts/core';
import { nextTick, ref, onUnmounted, onMounted } from 'vue';
import { nextTick, ref, onUnmounted, watch } from 'vue';
import type { Ref } from 'vue';

import { BarChart, LineChart } from 'echarts/charts';
import { BarChart, LineChart, PieChart, RadarChart } from 'echarts/charts';
// 系列类型的定义后缀都为 SeriesOption
import type { BarSeriesOption, LineSeriesOption } from 'echarts/charts';
import type {
BarSeriesOption,
LineSeriesOption,
PieSeriesOption,
RadarSeriesOption,
} from 'echarts/charts';

import {
TitleComponent,
TooltipComponent,
GridComponent,
DatasetComponent, // 数据集组件
TransformComponent, // 内置数据转换器组件 (filter, sort)
} from 'echarts/components';
// 组件类型的定义后缀都为 ComponentOption
import type {
TitleComponentOption,
TooltipComponentOption,
GridComponentOption,
DatasetComponentOption,
TitleComponentOption,
TooltipComponentOption,
GridComponentOption,
LegendComponentOption,
DatasetComponentOption,
ToolboxComponentOption,
} from 'echarts/components';
import {
TitleComponent,
TooltipComponent,
GridComponent,
LegendComponent,
DatasetComponent, // 数据集组件
TransformComponent, // 内置数据转换器组件 (filter, sort)
ToolboxComponent,
} from 'echarts/components';

import { LabelLayout, UniversalTransition } from 'echarts/features';
import { CanvasRenderer } from 'echarts/renderers';
import { useAppStore } from '@/store';
import { useElementSize } from '@vueuse/core';

// 通过 ComposeOption 来组合出一个只有必须组件和图表的 Option 类型
export type ECOption = echarts.ComposeOption<
| BarSeriesOption
| LineSeriesOption
| TitleComponentOption
| TooltipComponentOption
| GridComponentOption
| DatasetComponentOption
| BarSeriesOption
| PieSeriesOption
| LineSeriesOption
| TitleComponentOption
| TooltipComponentOption
| GridComponentOption
| LegendComponentOption
| DatasetComponentOption
| ToolboxComponentOption
| RadarSeriesOption
>;

// 注册必须的组件
echarts.use([
TitleComponent,
TooltipComponent,
GridComponent,
DatasetComponent,
TransformComponent,
BarChart,
LineChart,
LabelLayout,
UniversalTransition,
CanvasRenderer,
TitleComponent,
TooltipComponent,
GridComponent,
LegendComponent,
DatasetComponent,
TransformComponent,
BarChart,
PieChart,
LineChart,
LabelLayout,
UniversalTransition,
CanvasRenderer,
ToolboxComponent,
RadarChart,
]);

/**
* Echarts hooks函数
* @param options - 图表配置
* @description 按需引入图表组件,没注册的组件需要先引入
*/
export function useEcharts(options: Ref<ECOption>) {
const domRef = ref<HTMLElement>();

let chart: echarts.ECharts | null = null;

async function render() {
if (domRef.value) {
chart = echarts.init(domRef.value);
update(options.value);
}
}
function isRendered() {
return Boolean(domRef.value && chart);
}
function destroy() {
chart?.dispose();
chart = null;
}

function update(updateOptions: ECOption) {
if (isRendered()) {
chart!.setOption({ ...updateOptions, backgroundColor: 'transparent' });
}
}

onMounted(async () => {
await nextTick();
render();
});
onUnmounted(() => {
destroy();
});

return {
domRef,
};
const appStore = useAppStore();

const domRef = ref<HTMLElement>();

let chart: echarts.ECharts | null = null;

const initialSize = { width: 0, height: 0 };
const { width, height } = useElementSize(domRef, initialSize);

function canRender() {
return initialSize.width > 0 && initialSize.height > 0;
}

function isRendered() {
return Boolean(domRef.value && chart);
}
async function render() {
const chartTheme = appStore.darkMode ? 'dark' : 'light';
await nextTick();
if (domRef.value) {
chart = echarts.init(domRef.value, chartTheme);
update(options.value);
}
}

function update(updateOptions: ECOption) {
if (isRendered()) {
chart!.setOption({ ...updateOptions, backgroundColor: 'transparent' });
}
}

function resize() {
chart?.resize();
}

function destroy() {
chart?.dispose();
chart = null;
}
const sizeWatch = watch([width, height], ([newWidth, newHeight]) => {
initialSize.width = newWidth;
initialSize.height = newHeight;
if (newWidth === 0 && newHeight === 0) {
// 节点被删除 将chart置为空
chart = null;
}
if (!canRender()) return;
if (isRendered()) {
resize();
} else {
render();
}
});

const OptionWatch = watch(options, (newValue) => {
console.log(newValue);
update(newValue);
});

onUnmounted(() => {
sizeWatch();
OptionWatch();
destroy();
});

return {
domRef,
};
}
3 changes: 3 additions & 0 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ async function setupApp() {
// 载入全局loading加载状态
const appLoading = createApp(AppLoading);
appLoading.mount('#appLoading');

// 创建vue实例
const app = createApp(App);
// 安装pinia全局状态库
Expand All @@ -19,5 +20,7 @@ async function setupApp() {
await setupRouter(app);
// 挂载
await app.mount('#app');
// 卸载载入动画
appLoading.unmount();
}
setupApp();
Loading

0 comments on commit 6ef49cb

Please sign in to comment.