mirror of
https://github.com/ecomfe/vue-echarts.git
synced 2025-08-14 19:23:28 +08:00
feat: add default style, injectable update-options & loading-options
This commit is contained in:
@ -1,13 +1,14 @@
|
||||
import typescript from "rollup-plugin-typescript2";
|
||||
import { terser } from "rollup-plugin-terser";
|
||||
import resolve from "@rollup/plugin-node-resolve";
|
||||
import postcss from "rollup-plugin-postcss";
|
||||
import dts from "rollup-plugin-dts";
|
||||
|
||||
/** @type {import('rollup').RollupOptions} */
|
||||
const options = [
|
||||
{
|
||||
input: "src/index.ts",
|
||||
plugins: [typescript()],
|
||||
plugins: [typescript(), postcss()],
|
||||
external: ["vue-demi", "echarts/core", "resize-detector"],
|
||||
output: [
|
||||
{
|
||||
@ -50,8 +51,8 @@ const options = [
|
||||
},
|
||||
{
|
||||
input: "src/all.ts",
|
||||
plugins: [resolve(), typescript()],
|
||||
external: ["vue-demi", "echarts/core"],
|
||||
plugins: [resolve(), typescript(), postcss()],
|
||||
external: ["vue", "echarts", "echarts/core"],
|
||||
output: [
|
||||
{
|
||||
file: "dist/index.umd.js",
|
||||
@ -59,7 +60,8 @@ const options = [
|
||||
name: "VueECharts",
|
||||
sourcemap: true,
|
||||
globals: {
|
||||
"vue-demi": "VueDemi",
|
||||
vue: "Vue",
|
||||
echarts: "echarts",
|
||||
"echarts/core": "echarts"
|
||||
}
|
||||
},
|
||||
@ -69,7 +71,8 @@ const options = [
|
||||
name: "VueECharts",
|
||||
sourcemap: true,
|
||||
globals: {
|
||||
"vue-demi": "VueDemi",
|
||||
vue: "Vue",
|
||||
echarts: "echarts",
|
||||
"echarts/core": "echarts"
|
||||
},
|
||||
plugins: [
|
||||
@ -84,7 +87,7 @@ const options = [
|
||||
},
|
||||
{
|
||||
input: "src/index.ts",
|
||||
plugins: [dts()],
|
||||
plugins: [postcss(), dts()],
|
||||
output: {
|
||||
file: "dist/index.d.ts",
|
||||
format: "es"
|
||||
|
@ -2,6 +2,7 @@
|
||||
import {
|
||||
defineComponent,
|
||||
ref,
|
||||
unref,
|
||||
shallowRef,
|
||||
toRefs,
|
||||
watch,
|
||||
@ -10,10 +11,17 @@ import {
|
||||
onMounted,
|
||||
onUnmounted,
|
||||
h,
|
||||
PropType
|
||||
PropType,
|
||||
watchEffect
|
||||
} from "vue-demi";
|
||||
import { init as initChart } from "echarts/core";
|
||||
import { EChartsType, OptionType } from "./types";
|
||||
import {
|
||||
EChartsType,
|
||||
InitOptions,
|
||||
Option,
|
||||
UpdateOptions,
|
||||
Theme
|
||||
} from "./types";
|
||||
import {
|
||||
usePublicAPI,
|
||||
useAutoresize,
|
||||
@ -21,37 +29,49 @@ import {
|
||||
useLoading,
|
||||
loadingProps
|
||||
} from "./composables";
|
||||
import "./style.css";
|
||||
|
||||
type InitParameters = Parameters<typeof initChart>;
|
||||
type ThemeParameter = InitParameters[1];
|
||||
type InitOptsParameter = InitParameters[2];
|
||||
export const INIT_OPTIONS_KEY = "ecInitOptions";
|
||||
export const UPDATE_OPTIONS_KEY = "ecUpdateOptions";
|
||||
export { LOADING_OPTIONS_KEY } from "./composables";
|
||||
|
||||
export default defineComponent({
|
||||
name: "echarts",
|
||||
props: {
|
||||
option: Object as PropType<OptionType>,
|
||||
option: Object as PropType<Option>,
|
||||
theme: {
|
||||
type: [Object, String] as PropType<ThemeParameter>
|
||||
type: [Object, String] as PropType<Theme>
|
||||
},
|
||||
initOptions: Object as PropType<InitOptsParameter>,
|
||||
initOptions: Object as PropType<InitOptions>,
|
||||
updateOptions: Object as PropType<UpdateOptions>,
|
||||
group: String,
|
||||
manualUpdate: Boolean,
|
||||
...autoresizeProps,
|
||||
...loadingProps
|
||||
},
|
||||
setup(props, { attrs }) {
|
||||
const defaultInitOptions = inject(
|
||||
"echartsInitOptions",
|
||||
const defaultInitOptions = inject(INIT_OPTIONS_KEY, {}) as InitOptions;
|
||||
const defaultUpdateOptions = inject(
|
||||
UPDATE_OPTIONS_KEY,
|
||||
{}
|
||||
) as InitOptsParameter;
|
||||
) as UpdateOptions;
|
||||
const root = ref<HTMLElement>();
|
||||
const chart = shallowRef<EChartsType>();
|
||||
const manualOption = shallowRef<OptionType>();
|
||||
const manualOption = shallowRef<Option>();
|
||||
const realOption = computed(
|
||||
() => manualOption.value || props.option || Object.create(null)
|
||||
);
|
||||
const realInitOptions = computed(() => ({
|
||||
...defaultInitOptions,
|
||||
...props.initOptions
|
||||
}));
|
||||
const realUpdateOptions = computed(() => ({
|
||||
...defaultUpdateOptions,
|
||||
...props.updateOptions
|
||||
}));
|
||||
const { autoresize, manualUpdate, loading, loadingOptions } = toRefs(props);
|
||||
|
||||
function init(option?: OptionType) {
|
||||
function init(option?: Option) {
|
||||
if (chart.value || !root.value) {
|
||||
return;
|
||||
}
|
||||
@ -59,7 +79,7 @@ export default defineComponent({
|
||||
const instance = (chart.value = initChart(
|
||||
root.value,
|
||||
props.theme,
|
||||
props.initOptions || defaultInitOptions
|
||||
realInitOptions.value
|
||||
));
|
||||
|
||||
if (props.group) {
|
||||
@ -67,7 +87,7 @@ export default defineComponent({
|
||||
}
|
||||
|
||||
Object.keys(attrs)
|
||||
.filter(key => key.indexOf(`on`) === 0)
|
||||
.filter(key => key.indexOf("on") === 0)
|
||||
.forEach(key => {
|
||||
const handler = attrs[key] as any;
|
||||
|
||||
@ -82,10 +102,10 @@ export default defineComponent({
|
||||
}
|
||||
});
|
||||
|
||||
instance.setOption(option || realOption.value, true);
|
||||
instance.setOption(option || realOption.value, realUpdateOptions.value);
|
||||
}
|
||||
|
||||
function setOption(option: OptionType, ...rest: any[]) {
|
||||
function setOption(option: Option, updateOptions?: UpdateOptions) {
|
||||
if (props.manualUpdate) {
|
||||
manualOption.value = option;
|
||||
}
|
||||
@ -93,7 +113,10 @@ export default defineComponent({
|
||||
if (!chart.value) {
|
||||
init(option);
|
||||
} else {
|
||||
chart.value.setOption(option, ...rest);
|
||||
chart.value.setOption(option, {
|
||||
...realUpdateOptions.value,
|
||||
...updateOptions
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -104,7 +127,6 @@ export default defineComponent({
|
||||
}
|
||||
}
|
||||
|
||||
const { autoresize, manualUpdate, loading, loadingOptions } = toRefs(props);
|
||||
let unwatchOption: (() => void) | null = null;
|
||||
watch(
|
||||
manualUpdate,
|
||||
@ -117,21 +139,14 @@ export default defineComponent({
|
||||
if (!manualUpdate) {
|
||||
unwatchOption = watch(
|
||||
() => props.option,
|
||||
(val, oldVal) => {
|
||||
if (!val) {
|
||||
option => {
|
||||
if (!option) {
|
||||
return;
|
||||
}
|
||||
if (!chart.value) {
|
||||
init();
|
||||
} else {
|
||||
// mutating `option` will lead to merging
|
||||
// replacing it with new reference will lead to not merging
|
||||
// eg.
|
||||
// `this.option = Object.assign({}, this.option, { ... })`
|
||||
// will trigger `this.chart.setOption(val, true)
|
||||
// `this.option.title.text = 'Trends'`
|
||||
// will trigger `this.chart.setOption(val, false)`
|
||||
chart.value.setOption(val, val !== oldVal);
|
||||
chart.value.setOption(option, props.updateOptions);
|
||||
}
|
||||
},
|
||||
{ deep: true }
|
||||
@ -154,14 +169,11 @@ export default defineComponent({
|
||||
}
|
||||
);
|
||||
|
||||
watch(
|
||||
() => props.group,
|
||||
group => {
|
||||
if (group && chart.value) {
|
||||
chart.value.group = group;
|
||||
watchEffect(() => {
|
||||
if (props.group && chart.value) {
|
||||
chart.value.group = props.group;
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
const publicApi = usePublicAPI(chart, init);
|
||||
|
||||
@ -177,13 +189,20 @@ export default defineComponent({
|
||||
|
||||
onUnmounted(cleanup);
|
||||
|
||||
return {
|
||||
const exposed = {
|
||||
root,
|
||||
setOption,
|
||||
...publicApi
|
||||
};
|
||||
},
|
||||
render() {
|
||||
return h("div", { ref: "root" });
|
||||
Object.defineProperty(exposed, "chart", {
|
||||
get() {
|
||||
return unref(chart);
|
||||
}
|
||||
});
|
||||
|
||||
return exposed;
|
||||
},
|
||||
render() {
|
||||
return h("div", { class: "echarts", ref: "root" });
|
||||
}
|
||||
});
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
import { Ref } from "vue-demi";
|
||||
import { EChartsType, OptionType } from "../types";
|
||||
import { EChartsType, Option } from "../types";
|
||||
|
||||
const METHOD_NAMES = [
|
||||
"getWidth",
|
||||
@ -24,7 +24,7 @@ type PublicMethods = Pick<EChartsType, MethodName>;
|
||||
|
||||
export function usePublicAPI(
|
||||
chart: Ref<EChartsType | undefined>,
|
||||
init: (option?: OptionType) => void
|
||||
init: (option?: Option) => void
|
||||
) {
|
||||
function makePublicMethod<T extends MethodName>(
|
||||
name: T
|
||||
|
@ -1,13 +1,13 @@
|
||||
import { Ref, watch } from "vue-demi";
|
||||
import { throttle } from "echarts/core";
|
||||
import { addListener, removeListener, ResizeCallback } from "resize-detector";
|
||||
import { EChartsType, OptionType } from "../types";
|
||||
import { EChartsType, Option } from "../types";
|
||||
|
||||
export function useAutoresize(
|
||||
chart: Ref<EChartsType | undefined>,
|
||||
autoresize: Ref<boolean>,
|
||||
root: Ref<HTMLElement | undefined>,
|
||||
option: Ref<OptionType>
|
||||
option: Ref<Option>
|
||||
): void {
|
||||
let resizeListener: ResizeCallback | null = null;
|
||||
let lastArea = 0;
|
||||
|
@ -1,11 +1,19 @@
|
||||
import { Ref, watchEffect } from "vue-demi";
|
||||
import { inject, computed, Ref, watchEffect } from "vue-demi";
|
||||
import { EChartsType } from "../types";
|
||||
|
||||
export const LOADING_OPTIONS_KEY = "ecLoadingOptions";
|
||||
|
||||
export function useLoading(
|
||||
chart: Ref<EChartsType | undefined>,
|
||||
loading: Ref<boolean>,
|
||||
loadingOptions?: Ref<object | undefined>
|
||||
): void {
|
||||
const defaultLoadingOptions = inject(LOADING_OPTIONS_KEY, {}) as object;
|
||||
const realLoadingOptions = computed(() => ({
|
||||
...defaultLoadingOptions,
|
||||
...loadingOptions?.value
|
||||
}));
|
||||
|
||||
watchEffect(() => {
|
||||
const instance = chart.value;
|
||||
if (!instance) {
|
||||
@ -13,7 +21,7 @@ export function useLoading(
|
||||
}
|
||||
|
||||
if (loading.value) {
|
||||
instance.showLoading(loadingOptions?.value);
|
||||
instance.showLoading(realLoadingOptions.value);
|
||||
} else {
|
||||
instance.hideLoading();
|
||||
}
|
||||
|
1
src/style.css
Normal file
1
src/style.css
Normal file
@ -0,0 +1 @@
|
||||
.echarts{width:100%;height:100%}
|
19
src/types.ts
19
src/types.ts
@ -1,5 +1,20 @@
|
||||
import { init } from "echarts/core";
|
||||
|
||||
export type EChartsType = ReturnType<typeof init>;
|
||||
type InitType = typeof init;
|
||||
export type InitParameters = Parameters<InitType>;
|
||||
export type Theme = NonNullable<InitParameters[1]>;
|
||||
export type InitOptions = NonNullable<InitParameters[2]>;
|
||||
|
||||
export type EChartsType = ReturnType<InitType>;
|
||||
type SetOptionType = EChartsType["setOption"];
|
||||
export type OptionType = Parameters<SetOptionType>[0];
|
||||
export type Option = Parameters<SetOptionType>[0];
|
||||
|
||||
// TODO: Wait for apache/echarts#14289 to ship in v5.1,
|
||||
// so that we can use SetOptionOpts directly
|
||||
export interface UpdateOptions {
|
||||
notMerge?: boolean;
|
||||
lazyUpdate?: boolean;
|
||||
silent?: boolean;
|
||||
replaceMerge?: any;
|
||||
transition?: any;
|
||||
}
|
||||
|
Reference in New Issue
Block a user