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 typescript from "rollup-plugin-typescript2";
|
||||||
import { terser } from "rollup-plugin-terser";
|
import { terser } from "rollup-plugin-terser";
|
||||||
import resolve from "@rollup/plugin-node-resolve";
|
import resolve from "@rollup/plugin-node-resolve";
|
||||||
|
import postcss from "rollup-plugin-postcss";
|
||||||
import dts from "rollup-plugin-dts";
|
import dts from "rollup-plugin-dts";
|
||||||
|
|
||||||
/** @type {import('rollup').RollupOptions} */
|
/** @type {import('rollup').RollupOptions} */
|
||||||
const options = [
|
const options = [
|
||||||
{
|
{
|
||||||
input: "src/index.ts",
|
input: "src/index.ts",
|
||||||
plugins: [typescript()],
|
plugins: [typescript(), postcss()],
|
||||||
external: ["vue-demi", "echarts/core", "resize-detector"],
|
external: ["vue-demi", "echarts/core", "resize-detector"],
|
||||||
output: [
|
output: [
|
||||||
{
|
{
|
||||||
@ -50,8 +51,8 @@ const options = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
input: "src/all.ts",
|
input: "src/all.ts",
|
||||||
plugins: [resolve(), typescript()],
|
plugins: [resolve(), typescript(), postcss()],
|
||||||
external: ["vue-demi", "echarts/core"],
|
external: ["vue", "echarts", "echarts/core"],
|
||||||
output: [
|
output: [
|
||||||
{
|
{
|
||||||
file: "dist/index.umd.js",
|
file: "dist/index.umd.js",
|
||||||
@ -59,7 +60,8 @@ const options = [
|
|||||||
name: "VueECharts",
|
name: "VueECharts",
|
||||||
sourcemap: true,
|
sourcemap: true,
|
||||||
globals: {
|
globals: {
|
||||||
"vue-demi": "VueDemi",
|
vue: "Vue",
|
||||||
|
echarts: "echarts",
|
||||||
"echarts/core": "echarts"
|
"echarts/core": "echarts"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -69,7 +71,8 @@ const options = [
|
|||||||
name: "VueECharts",
|
name: "VueECharts",
|
||||||
sourcemap: true,
|
sourcemap: true,
|
||||||
globals: {
|
globals: {
|
||||||
"vue-demi": "VueDemi",
|
vue: "Vue",
|
||||||
|
echarts: "echarts",
|
||||||
"echarts/core": "echarts"
|
"echarts/core": "echarts"
|
||||||
},
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
@ -84,7 +87,7 @@ const options = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
input: "src/index.ts",
|
input: "src/index.ts",
|
||||||
plugins: [dts()],
|
plugins: [postcss(), dts()],
|
||||||
output: {
|
output: {
|
||||||
file: "dist/index.d.ts",
|
file: "dist/index.d.ts",
|
||||||
format: "es"
|
format: "es"
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
import {
|
import {
|
||||||
defineComponent,
|
defineComponent,
|
||||||
ref,
|
ref,
|
||||||
|
unref,
|
||||||
shallowRef,
|
shallowRef,
|
||||||
toRefs,
|
toRefs,
|
||||||
watch,
|
watch,
|
||||||
@ -10,10 +11,17 @@ import {
|
|||||||
onMounted,
|
onMounted,
|
||||||
onUnmounted,
|
onUnmounted,
|
||||||
h,
|
h,
|
||||||
PropType
|
PropType,
|
||||||
|
watchEffect
|
||||||
} from "vue-demi";
|
} from "vue-demi";
|
||||||
import { init as initChart } from "echarts/core";
|
import { init as initChart } from "echarts/core";
|
||||||
import { EChartsType, OptionType } from "./types";
|
import {
|
||||||
|
EChartsType,
|
||||||
|
InitOptions,
|
||||||
|
Option,
|
||||||
|
UpdateOptions,
|
||||||
|
Theme
|
||||||
|
} from "./types";
|
||||||
import {
|
import {
|
||||||
usePublicAPI,
|
usePublicAPI,
|
||||||
useAutoresize,
|
useAutoresize,
|
||||||
@ -21,37 +29,49 @@ import {
|
|||||||
useLoading,
|
useLoading,
|
||||||
loadingProps
|
loadingProps
|
||||||
} from "./composables";
|
} from "./composables";
|
||||||
|
import "./style.css";
|
||||||
|
|
||||||
type InitParameters = Parameters<typeof initChart>;
|
export const INIT_OPTIONS_KEY = "ecInitOptions";
|
||||||
type ThemeParameter = InitParameters[1];
|
export const UPDATE_OPTIONS_KEY = "ecUpdateOptions";
|
||||||
type InitOptsParameter = InitParameters[2];
|
export { LOADING_OPTIONS_KEY } from "./composables";
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: "echarts",
|
name: "echarts",
|
||||||
props: {
|
props: {
|
||||||
option: Object as PropType<OptionType>,
|
option: Object as PropType<Option>,
|
||||||
theme: {
|
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,
|
group: String,
|
||||||
manualUpdate: Boolean,
|
manualUpdate: Boolean,
|
||||||
...autoresizeProps,
|
...autoresizeProps,
|
||||||
...loadingProps
|
...loadingProps
|
||||||
},
|
},
|
||||||
setup(props, { attrs }) {
|
setup(props, { attrs }) {
|
||||||
const defaultInitOptions = inject(
|
const defaultInitOptions = inject(INIT_OPTIONS_KEY, {}) as InitOptions;
|
||||||
"echartsInitOptions",
|
const defaultUpdateOptions = inject(
|
||||||
|
UPDATE_OPTIONS_KEY,
|
||||||
{}
|
{}
|
||||||
) as InitOptsParameter;
|
) as UpdateOptions;
|
||||||
const root = ref<HTMLElement>();
|
const root = ref<HTMLElement>();
|
||||||
const chart = shallowRef<EChartsType>();
|
const chart = shallowRef<EChartsType>();
|
||||||
const manualOption = shallowRef<OptionType>();
|
const manualOption = shallowRef<Option>();
|
||||||
const realOption = computed(
|
const realOption = computed(
|
||||||
() => manualOption.value || props.option || Object.create(null)
|
() => 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) {
|
if (chart.value || !root.value) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -59,7 +79,7 @@ export default defineComponent({
|
|||||||
const instance = (chart.value = initChart(
|
const instance = (chart.value = initChart(
|
||||||
root.value,
|
root.value,
|
||||||
props.theme,
|
props.theme,
|
||||||
props.initOptions || defaultInitOptions
|
realInitOptions.value
|
||||||
));
|
));
|
||||||
|
|
||||||
if (props.group) {
|
if (props.group) {
|
||||||
@ -67,7 +87,7 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
|
|
||||||
Object.keys(attrs)
|
Object.keys(attrs)
|
||||||
.filter(key => key.indexOf(`on`) === 0)
|
.filter(key => key.indexOf("on") === 0)
|
||||||
.forEach(key => {
|
.forEach(key => {
|
||||||
const handler = attrs[key] as any;
|
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) {
|
if (props.manualUpdate) {
|
||||||
manualOption.value = option;
|
manualOption.value = option;
|
||||||
}
|
}
|
||||||
@ -93,7 +113,10 @@ export default defineComponent({
|
|||||||
if (!chart.value) {
|
if (!chart.value) {
|
||||||
init(option);
|
init(option);
|
||||||
} else {
|
} 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;
|
let unwatchOption: (() => void) | null = null;
|
||||||
watch(
|
watch(
|
||||||
manualUpdate,
|
manualUpdate,
|
||||||
@ -117,21 +139,14 @@ export default defineComponent({
|
|||||||
if (!manualUpdate) {
|
if (!manualUpdate) {
|
||||||
unwatchOption = watch(
|
unwatchOption = watch(
|
||||||
() => props.option,
|
() => props.option,
|
||||||
(val, oldVal) => {
|
option => {
|
||||||
if (!val) {
|
if (!option) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!chart.value) {
|
if (!chart.value) {
|
||||||
init();
|
init();
|
||||||
} else {
|
} else {
|
||||||
// mutating `option` will lead to merging
|
chart.value.setOption(option, props.updateOptions);
|
||||||
// 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);
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ deep: true }
|
{ deep: true }
|
||||||
@ -154,14 +169,11 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
watch(
|
watchEffect(() => {
|
||||||
() => props.group,
|
if (props.group && chart.value) {
|
||||||
group => {
|
chart.value.group = props.group;
|
||||||
if (group && chart.value) {
|
|
||||||
chart.value.group = group;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
);
|
});
|
||||||
|
|
||||||
const publicApi = usePublicAPI(chart, init);
|
const publicApi = usePublicAPI(chart, init);
|
||||||
|
|
||||||
@ -177,13 +189,20 @@ export default defineComponent({
|
|||||||
|
|
||||||
onUnmounted(cleanup);
|
onUnmounted(cleanup);
|
||||||
|
|
||||||
return {
|
const exposed = {
|
||||||
root,
|
root,
|
||||||
setOption,
|
setOption,
|
||||||
...publicApi
|
...publicApi
|
||||||
};
|
};
|
||||||
|
Object.defineProperty(exposed, "chart", {
|
||||||
|
get() {
|
||||||
|
return unref(chart);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return exposed;
|
||||||
},
|
},
|
||||||
render() {
|
render() {
|
||||||
return h("div", { ref: "root" });
|
return h("div", { class: "echarts", ref: "root" });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
import { Ref } from "vue-demi";
|
import { Ref } from "vue-demi";
|
||||||
import { EChartsType, OptionType } from "../types";
|
import { EChartsType, Option } from "../types";
|
||||||
|
|
||||||
const METHOD_NAMES = [
|
const METHOD_NAMES = [
|
||||||
"getWidth",
|
"getWidth",
|
||||||
@ -24,7 +24,7 @@ type PublicMethods = Pick<EChartsType, MethodName>;
|
|||||||
|
|
||||||
export function usePublicAPI(
|
export function usePublicAPI(
|
||||||
chart: Ref<EChartsType | undefined>,
|
chart: Ref<EChartsType | undefined>,
|
||||||
init: (option?: OptionType) => void
|
init: (option?: Option) => void
|
||||||
) {
|
) {
|
||||||
function makePublicMethod<T extends MethodName>(
|
function makePublicMethod<T extends MethodName>(
|
||||||
name: T
|
name: T
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
import { Ref, watch } from "vue-demi";
|
import { Ref, watch } from "vue-demi";
|
||||||
import { throttle } from "echarts/core";
|
import { throttle } from "echarts/core";
|
||||||
import { addListener, removeListener, ResizeCallback } from "resize-detector";
|
import { addListener, removeListener, ResizeCallback } from "resize-detector";
|
||||||
import { EChartsType, OptionType } from "../types";
|
import { EChartsType, Option } from "../types";
|
||||||
|
|
||||||
export function useAutoresize(
|
export function useAutoresize(
|
||||||
chart: Ref<EChartsType | undefined>,
|
chart: Ref<EChartsType | undefined>,
|
||||||
autoresize: Ref<boolean>,
|
autoresize: Ref<boolean>,
|
||||||
root: Ref<HTMLElement | undefined>,
|
root: Ref<HTMLElement | undefined>,
|
||||||
option: Ref<OptionType>
|
option: Ref<Option>
|
||||||
): void {
|
): void {
|
||||||
let resizeListener: ResizeCallback | null = null;
|
let resizeListener: ResizeCallback | null = null;
|
||||||
let lastArea = 0;
|
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";
|
import { EChartsType } from "../types";
|
||||||
|
|
||||||
|
export const LOADING_OPTIONS_KEY = "ecLoadingOptions";
|
||||||
|
|
||||||
export function useLoading(
|
export function useLoading(
|
||||||
chart: Ref<EChartsType | undefined>,
|
chart: Ref<EChartsType | undefined>,
|
||||||
loading: Ref<boolean>,
|
loading: Ref<boolean>,
|
||||||
loadingOptions?: Ref<object | undefined>
|
loadingOptions?: Ref<object | undefined>
|
||||||
): void {
|
): void {
|
||||||
|
const defaultLoadingOptions = inject(LOADING_OPTIONS_KEY, {}) as object;
|
||||||
|
const realLoadingOptions = computed(() => ({
|
||||||
|
...defaultLoadingOptions,
|
||||||
|
...loadingOptions?.value
|
||||||
|
}));
|
||||||
|
|
||||||
watchEffect(() => {
|
watchEffect(() => {
|
||||||
const instance = chart.value;
|
const instance = chart.value;
|
||||||
if (!instance) {
|
if (!instance) {
|
||||||
@ -13,7 +21,7 @@ export function useLoading(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (loading.value) {
|
if (loading.value) {
|
||||||
instance.showLoading(loadingOptions?.value);
|
instance.showLoading(realLoadingOptions.value);
|
||||||
} else {
|
} else {
|
||||||
instance.hideLoading();
|
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";
|
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"];
|
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