mirror of
https://github.com/soybeanjs/soybean-admin.git
synced 2025-09-18 01:36:37 +08:00
feat(hooks): add use-echarts
This commit is contained in:
parent
b43c925696
commit
726abe4208
@ -51,6 +51,7 @@
|
|||||||
"@vueuse/core": "10.7.2",
|
"@vueuse/core": "10.7.2",
|
||||||
"clipboard": "2.0.11",
|
"clipboard": "2.0.11",
|
||||||
"dayjs": "1.11.10",
|
"dayjs": "1.11.10",
|
||||||
|
"echarts": "^5.4.3",
|
||||||
"lodash-es": "4.17.21",
|
"lodash-es": "4.17.21",
|
||||||
"naive-ui": "2.37.3",
|
"naive-ui": "2.37.3",
|
||||||
"nprogress": "0.2.0",
|
"nprogress": "0.2.0",
|
||||||
|
@ -38,6 +38,9 @@ importers:
|
|||||||
dayjs:
|
dayjs:
|
||||||
specifier: 1.11.10
|
specifier: 1.11.10
|
||||||
version: 1.11.10
|
version: 1.11.10
|
||||||
|
echarts:
|
||||||
|
specifier: ^5.4.3
|
||||||
|
version: 5.4.3
|
||||||
lodash-es:
|
lodash-es:
|
||||||
specifier: 4.17.21
|
specifier: 4.17.21
|
||||||
version: 4.17.21
|
version: 4.17.21
|
||||||
@ -3541,6 +3544,13 @@ packages:
|
|||||||
resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
|
resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/echarts@5.4.3:
|
||||||
|
resolution: {integrity: sha512-mYKxLxhzy6zyTi/FaEbJMOZU1ULGEQHaeIeuMR5L+JnJTpz+YR03mnnpBhbR4+UYJAgiXgpyTVLffPAjOTLkZA==}
|
||||||
|
dependencies:
|
||||||
|
tslib: 2.3.0
|
||||||
|
zrender: 5.4.4
|
||||||
|
dev: false
|
||||||
|
|
||||||
/electron-to-chromium@1.4.637:
|
/electron-to-chromium@1.4.637:
|
||||||
resolution: {integrity: sha512-G7j3UCOukFtxVO1vWrPQUoDk3kL70mtvjc/DC/k2o7lE0wAdq+Vwp1ipagOow+BH0uVztFysLWbkM/RTIrbK3w==}
|
resolution: {integrity: sha512-G7j3UCOukFtxVO1vWrPQUoDk3kL70mtvjc/DC/k2o7lE0wAdq+Vwp1ipagOow+BH0uVztFysLWbkM/RTIrbK3w==}
|
||||||
dev: true
|
dev: true
|
||||||
@ -7979,6 +7989,10 @@ packages:
|
|||||||
typescript: 5.3.3
|
typescript: 5.3.3
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/tslib@2.3.0:
|
||||||
|
resolution: {integrity: sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/tslib@2.6.2:
|
/tslib@2.6.2:
|
||||||
resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==}
|
resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==}
|
||||||
dev: true
|
dev: true
|
||||||
@ -8855,3 +8869,9 @@ packages:
|
|||||||
resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
|
resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/zrender@5.4.4:
|
||||||
|
resolution: {integrity: sha512-0VxCNJ7AGOMCWeHVyTrGzUgrK4asT4ml9PEkeGirAkKNYXYzoPJCLvmyfdoOXcjTHPs10OZVMfD1Rwg16AZyYw==}
|
||||||
|
dependencies:
|
||||||
|
tslib: 2.3.0
|
||||||
|
dev: false
|
||||||
|
184
src/hooks/chart/use-echarts.ts
Normal file
184
src/hooks/chart/use-echarts.ts
Normal file
@ -0,0 +1,184 @@
|
|||||||
|
import { effectScope, nextTick, onScopeDispose, ref, watch } from 'vue';
|
||||||
|
import type { ComputedRef, Ref } from 'vue';
|
||||||
|
import * as echarts from 'echarts/core';
|
||||||
|
import { BarChart, GaugeChart, LineChart, PictorialBarChart, PieChart, RadarChart, ScatterChart } from 'echarts/charts';
|
||||||
|
import type {
|
||||||
|
BarSeriesOption,
|
||||||
|
GaugeSeriesOption,
|
||||||
|
LineSeriesOption,
|
||||||
|
PictorialBarSeriesOption,
|
||||||
|
PieSeriesOption,
|
||||||
|
RadarSeriesOption,
|
||||||
|
ScatterSeriesOption
|
||||||
|
} from 'echarts/charts';
|
||||||
|
import {
|
||||||
|
DatasetComponent,
|
||||||
|
GridComponent,
|
||||||
|
LegendComponent,
|
||||||
|
TitleComponent,
|
||||||
|
ToolboxComponent,
|
||||||
|
TooltipComponent,
|
||||||
|
TransformComponent
|
||||||
|
} from 'echarts/components';
|
||||||
|
import type {
|
||||||
|
DatasetComponentOption,
|
||||||
|
GridComponentOption,
|
||||||
|
LegendComponentOption,
|
||||||
|
TitleComponentOption,
|
||||||
|
ToolboxComponentOption,
|
||||||
|
TooltipComponentOption
|
||||||
|
} from 'echarts/components';
|
||||||
|
import { LabelLayout, UniversalTransition } from 'echarts/features';
|
||||||
|
import { CanvasRenderer } from 'echarts/renderers';
|
||||||
|
import { useElementSize } from '@vueuse/core';
|
||||||
|
|
||||||
|
export type ECOption = echarts.ComposeOption<
|
||||||
|
| BarSeriesOption
|
||||||
|
| LineSeriesOption
|
||||||
|
| PieSeriesOption
|
||||||
|
| ScatterSeriesOption
|
||||||
|
| PictorialBarSeriesOption
|
||||||
|
| RadarSeriesOption
|
||||||
|
| GaugeSeriesOption
|
||||||
|
| TitleComponentOption
|
||||||
|
| LegendComponentOption
|
||||||
|
| TooltipComponentOption
|
||||||
|
| GridComponentOption
|
||||||
|
| ToolboxComponentOption
|
||||||
|
| DatasetComponentOption
|
||||||
|
>;
|
||||||
|
|
||||||
|
echarts.use([
|
||||||
|
TitleComponent,
|
||||||
|
LegendComponent,
|
||||||
|
TooltipComponent,
|
||||||
|
GridComponent,
|
||||||
|
DatasetComponent,
|
||||||
|
TransformComponent,
|
||||||
|
ToolboxComponent,
|
||||||
|
BarChart,
|
||||||
|
LineChart,
|
||||||
|
PieChart,
|
||||||
|
ScatterChart,
|
||||||
|
PictorialBarChart,
|
||||||
|
RadarChart,
|
||||||
|
GaugeChart,
|
||||||
|
LabelLayout,
|
||||||
|
UniversalTransition,
|
||||||
|
CanvasRenderer
|
||||||
|
]);
|
||||||
|
|
||||||
|
interface ChartHooks {
|
||||||
|
onRender?: (chart: echarts.ECharts) => void | Promise<void>;
|
||||||
|
onDestroy?: (chart: echarts.ECharts) => void | Promise<void>;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* use echarts
|
||||||
|
*
|
||||||
|
* @param options echarts options
|
||||||
|
* @param darkMode dark mode
|
||||||
|
*/
|
||||||
|
export function useEcharts(options: ECOption, darkMode: Ref<boolean> | ComputedRef<boolean>, hooks?: ChartHooks) {
|
||||||
|
const scope = effectScope();
|
||||||
|
|
||||||
|
const domRef = ref<HTMLElement | null>(null);
|
||||||
|
|
||||||
|
const initialSize = { width: 0, height: 0 };
|
||||||
|
const { width, height } = useElementSize(domRef, initialSize);
|
||||||
|
|
||||||
|
let chart: echarts.ECharts | null = null;
|
||||||
|
|
||||||
|
function canRender() {
|
||||||
|
return initialSize.width > 0 && initialSize.height > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isRendered() {
|
||||||
|
return Boolean(domRef.value && chart);
|
||||||
|
}
|
||||||
|
|
||||||
|
function setOptions(opts: ECOption) {
|
||||||
|
if (isRendered()) {
|
||||||
|
chart?.clear();
|
||||||
|
chart?.setOption({ ...opts, backgroundColor: 'transparent' });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function render() {
|
||||||
|
if (domRef.value) {
|
||||||
|
const chartTheme = darkMode.value ? 'dark' : 'light';
|
||||||
|
|
||||||
|
await nextTick();
|
||||||
|
|
||||||
|
chart = echarts.init(domRef.value, chartTheme);
|
||||||
|
|
||||||
|
setOptions(options);
|
||||||
|
|
||||||
|
await hooks?.onRender?.(chart);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function resize() {
|
||||||
|
chart?.resize();
|
||||||
|
}
|
||||||
|
|
||||||
|
async function destroy() {
|
||||||
|
if (!chart) return;
|
||||||
|
|
||||||
|
await hooks?.onDestroy?.(chart);
|
||||||
|
chart?.dispose();
|
||||||
|
chart = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function changeTheme() {
|
||||||
|
await destroy();
|
||||||
|
await render();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* render chart by size
|
||||||
|
*
|
||||||
|
* @param w
|
||||||
|
* @param h
|
||||||
|
*/
|
||||||
|
async function renderChartBySize(w: number, h: number) {
|
||||||
|
initialSize.width = w;
|
||||||
|
initialSize.height = h;
|
||||||
|
|
||||||
|
// size is abnormal, destroy chart
|
||||||
|
if (!canRender()) {
|
||||||
|
await destroy();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// render chart
|
||||||
|
if (!isRendered()) {
|
||||||
|
await render();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// resize chart
|
||||||
|
resize();
|
||||||
|
}
|
||||||
|
|
||||||
|
scope.run(() => {
|
||||||
|
watch([width, height], ([newWidth, newHeight]) => {
|
||||||
|
renderChartBySize(newWidth, newHeight);
|
||||||
|
});
|
||||||
|
|
||||||
|
watch(darkMode, () => {
|
||||||
|
changeTheme();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
onScopeDispose(() => {
|
||||||
|
destroy();
|
||||||
|
scope.stop();
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
domRef,
|
||||||
|
setOptions
|
||||||
|
};
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user