mirror of
https://github.com/ecomfe/vue-echarts.git
synced 2025-10-28 19:43:37 +08:00
feat: vue-echarts-next first version
This commit is contained in:
9
.editorconfig
Normal file
9
.editorconfig
Normal file
@ -0,0 +1,9 @@
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
1
.eslintignore
Normal file
1
.eslintignore
Normal file
@ -0,0 +1 @@
|
||||
dist
|
||||
3035
package-lock.json
generated
3035
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
25
package.json
25
package.json
@ -1,17 +1,22 @@
|
||||
{
|
||||
"name": "vue-echarts-next",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"serve": "vue-cli-service serve",
|
||||
"build": "vue-cli-service build",
|
||||
"build:demo": "vue-cli-service build",
|
||||
"build": "rollup -c rollup.config.js",
|
||||
"lint": "vue-cli-service lint"
|
||||
},
|
||||
"main": "dist/index.cjs.min.js",
|
||||
"module": "dist/index.esm.min.js",
|
||||
"unpkg": "dist/index.umd.min.js",
|
||||
"jsdelivr": "dist/index.umd.min.js",
|
||||
"dependencies": {
|
||||
"core-js": "^3.6.5",
|
||||
"vue": "^3.0.0"
|
||||
"resize-detector": "^0.2.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@rollup/plugin-node-resolve": "^11.1.1",
|
||||
"@typescript-eslint/eslint-plugin": "^2.33.0",
|
||||
"@typescript-eslint/parser": "^2.33.0",
|
||||
"@vue/cli-plugin-babel": "~4.5.0",
|
||||
@ -19,12 +24,24 @@
|
||||
"@vue/cli-plugin-typescript": "~4.5.0",
|
||||
"@vue/cli-service": "~4.5.0",
|
||||
"@vue/compiler-sfc": "^3.0.0",
|
||||
"@vue/composition-api": "^1.0.0-rc.1",
|
||||
"@vue/eslint-config-prettier": "^6.0.0",
|
||||
"@vue/eslint-config-typescript": "^5.0.2",
|
||||
"echarts": "^5.0.2",
|
||||
"eslint": "^6.7.2",
|
||||
"eslint-plugin-prettier": "^3.1.3",
|
||||
"eslint-plugin-vue": "^7.0.0-0",
|
||||
"postcss": "^8.2.5",
|
||||
"prettier": "^1.19.1",
|
||||
"typescript": "~3.9.3"
|
||||
"rollup": "^2.38.5",
|
||||
"rollup-plugin-postcss": "^4.0.0",
|
||||
"rollup-plugin-terser": "^7.0.2",
|
||||
"rollup-plugin-typescript2": "^0.29.0",
|
||||
"typescript": "^4.1.3",
|
||||
"vue": "npm:vue@^3.0.5"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"echarts": "^5.0.2",
|
||||
"vue": "^2.6.11 || ^3.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
98
rollup.config.js
Normal file
98
rollup.config.js
Normal file
@ -0,0 +1,98 @@
|
||||
import typescript from "rollup-plugin-typescript2";
|
||||
import { terser } from "rollup-plugin-terser";
|
||||
import postcss from "rollup-plugin-postcss";
|
||||
import resolve from "@rollup/plugin-node-resolve";
|
||||
|
||||
/** @type {import('rollup').RollupOptions} */
|
||||
const options = [
|
||||
{
|
||||
plugins: [
|
||||
typescript({
|
||||
useTsconfigDeclarationDir: true
|
||||
}),
|
||||
postcss()
|
||||
],
|
||||
external: ["vue", "echarts/core", "resize-detector"],
|
||||
input: "src/index.ts",
|
||||
output: [
|
||||
{
|
||||
file: "dist/index.esm.js",
|
||||
format: "es",
|
||||
sourcemap: true
|
||||
},
|
||||
{
|
||||
file: "dist/index.esm.min.js",
|
||||
format: "es",
|
||||
sourcemap: true,
|
||||
plugins: [
|
||||
terser({
|
||||
format: {
|
||||
comments: false
|
||||
}
|
||||
})
|
||||
]
|
||||
},
|
||||
{
|
||||
file: "dist/index.cjs.js",
|
||||
format: "cjs",
|
||||
exports: "default",
|
||||
sourcemap: true
|
||||
},
|
||||
{
|
||||
file: "dist/index.cjs.min.js",
|
||||
format: "cjs",
|
||||
exports: "default",
|
||||
sourcemap: true,
|
||||
plugins: [
|
||||
terser({
|
||||
format: {
|
||||
comments: false
|
||||
}
|
||||
})
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
plugins: [
|
||||
resolve(),
|
||||
typescript({
|
||||
useTsconfigDeclarationDir: true
|
||||
}),
|
||||
postcss()
|
||||
],
|
||||
external: ["vue", "echarts/core"],
|
||||
input: "src/all.ts",
|
||||
output: [
|
||||
{
|
||||
file: "dist/index.umd.js",
|
||||
format: "umd",
|
||||
name: "VueECharts",
|
||||
sourcemap: true,
|
||||
globals: {
|
||||
vue: "Vue",
|
||||
"echarts/core": "echarts"
|
||||
}
|
||||
},
|
||||
{
|
||||
file: "dist/index.umd.min.js",
|
||||
format: "umd",
|
||||
name: "VueECharts",
|
||||
sourcemap: true,
|
||||
globals: {
|
||||
vue: "Vue",
|
||||
"echarts/core": "echarts"
|
||||
},
|
||||
plugins: [
|
||||
terser({
|
||||
format: {
|
||||
comments: false
|
||||
}
|
||||
})
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
export default options;
|
||||
0
src/shims-vue.d.ts → shims-vue.d.ts
vendored
0
src/shims-vue.d.ts → shims-vue.d.ts
vendored
27
src/App.vue
27
src/App.vue
@ -1,27 +0,0 @@
|
||||
<template>
|
||||
<img alt="Vue logo" src="./assets/logo.png" />
|
||||
<HelloWorld msg="Welcome to Your Vue.js + TypeScript App" />
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from "vue";
|
||||
import HelloWorld from "./components/HelloWorld.vue";
|
||||
|
||||
export default defineComponent({
|
||||
name: "App",
|
||||
components: {
|
||||
HelloWorld
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style>
|
||||
#app {
|
||||
font-family: Avenir, Helvetica, Arial, sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
text-align: center;
|
||||
color: #2c3e50;
|
||||
margin-top: 60px;
|
||||
}
|
||||
</style>
|
||||
195
src/ECharts.ts
Normal file
195
src/ECharts.ts
Normal file
@ -0,0 +1,195 @@
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
import {
|
||||
defineComponent,
|
||||
ref,
|
||||
shallowRef,
|
||||
toRefs,
|
||||
watch,
|
||||
computed,
|
||||
inject,
|
||||
onMounted,
|
||||
onUnmounted,
|
||||
h,
|
||||
PropType
|
||||
} from "vue";
|
||||
import { init as initChart } from "echarts/core";
|
||||
import { EChartsType, OptionType } from "@/types";
|
||||
import {
|
||||
usePublicAPI,
|
||||
useAutoresize,
|
||||
autoresizeProps,
|
||||
useLoading,
|
||||
loadingProps
|
||||
} from "./composables";
|
||||
import "./style.css";
|
||||
|
||||
type InitParameters = Parameters<typeof initChart>;
|
||||
type ThemeParameter = InitParameters[1];
|
||||
type InitOptsParameter = InitParameters[2];
|
||||
|
||||
export default defineComponent({
|
||||
name: "echarts",
|
||||
props: {
|
||||
options: Object as PropType<OptionType>,
|
||||
theme: {
|
||||
type: [Object, String] as PropType<ThemeParameter>
|
||||
},
|
||||
initOptions: Object as PropType<InitOptsParameter>,
|
||||
group: String,
|
||||
manualUpdate: Boolean,
|
||||
...autoresizeProps,
|
||||
...loadingProps
|
||||
},
|
||||
setup(props, { attrs }) {
|
||||
const defaultInitOptions = inject(
|
||||
"echartsInitOptions",
|
||||
{}
|
||||
) as InitOptsParameter;
|
||||
const root = ref<HTMLElement>();
|
||||
const chart = shallowRef<EChartsType>();
|
||||
const manualOptions = shallowRef<OptionType>();
|
||||
const realOptions = computed(
|
||||
() => manualOptions.value || props.options || Object.create(null)
|
||||
);
|
||||
|
||||
function init(options?: OptionType) {
|
||||
if (chart.value || !root.value) {
|
||||
return;
|
||||
}
|
||||
|
||||
const instance = (chart.value = initChart(
|
||||
root.value,
|
||||
props.theme,
|
||||
props.initOptions || defaultInitOptions
|
||||
));
|
||||
|
||||
if (props.group) {
|
||||
instance.group = props.group;
|
||||
}
|
||||
|
||||
Object.keys(attrs)
|
||||
.filter(key => key.indexOf(`on`) === 0)
|
||||
.forEach(key => {
|
||||
const handler = attrs[key] as any;
|
||||
|
||||
if (!handler) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (key.indexOf("onZr:") === 0) {
|
||||
instance.getZr().on(key.slice(5).toLowerCase(), handler);
|
||||
} else {
|
||||
instance.on(key.slice(2).toLowerCase(), handler);
|
||||
}
|
||||
});
|
||||
|
||||
instance.setOption(options || realOptions.value, true);
|
||||
}
|
||||
|
||||
function mergeOptions(options: OptionType, ...rest: any[]) {
|
||||
if (props.manualUpdate) {
|
||||
manualOptions.value = options;
|
||||
}
|
||||
|
||||
if (!chart.value) {
|
||||
init(options);
|
||||
} else {
|
||||
chart.value.setOption(options, ...rest);
|
||||
}
|
||||
}
|
||||
|
||||
function cleanup() {
|
||||
if (chart.value) {
|
||||
chart.value.dispose();
|
||||
chart.value = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
const {
|
||||
theme,
|
||||
initOptions,
|
||||
group,
|
||||
autoresize,
|
||||
manualUpdate,
|
||||
loading,
|
||||
loadingOptions
|
||||
} = toRefs(props);
|
||||
let unwatchOptions: (() => void) | null = null;
|
||||
watch(
|
||||
manualUpdate,
|
||||
manualUpdate => {
|
||||
if (typeof unwatchOptions === "function") {
|
||||
unwatchOptions();
|
||||
unwatchOptions = null;
|
||||
}
|
||||
|
||||
if (!manualUpdate) {
|
||||
unwatchOptions = watch(
|
||||
() => props.options,
|
||||
(val, oldVal) => {
|
||||
if (!val) {
|
||||
return;
|
||||
}
|
||||
if (!chart.value) {
|
||||
init();
|
||||
} else {
|
||||
// mutating `options` will lead to merging
|
||||
// replacing it with new reference will lead to not merging
|
||||
// eg.
|
||||
// `this.options = Object.assign({}, this.options, { ... })`
|
||||
// will trigger `this.chart.setOption(val, true)
|
||||
// `this.options.title.text = 'Trends'`
|
||||
// will trigger `this.chart.setOption(val, false)`
|
||||
chart.value.setOption(val, val !== oldVal);
|
||||
}
|
||||
},
|
||||
{ deep: true }
|
||||
);
|
||||
}
|
||||
},
|
||||
{
|
||||
immediate: true
|
||||
}
|
||||
);
|
||||
|
||||
watch([theme, initOptions], () => {
|
||||
cleanup();
|
||||
init();
|
||||
});
|
||||
|
||||
watch(
|
||||
() => group,
|
||||
group => {
|
||||
if (group && group.value && chart.value) {
|
||||
chart.value.group = group.value;
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
const publicApi = usePublicAPI(chart, init);
|
||||
|
||||
useLoading(chart, loading, loadingOptions);
|
||||
|
||||
useAutoresize(chart, autoresize, root, realOptions);
|
||||
|
||||
onMounted(() => {
|
||||
if (props.options) {
|
||||
init();
|
||||
}
|
||||
});
|
||||
|
||||
onUnmounted(cleanup);
|
||||
|
||||
return {
|
||||
root,
|
||||
mergeOptions,
|
||||
...publicApi
|
||||
};
|
||||
},
|
||||
render() {
|
||||
return h("div", {
|
||||
ref: "root",
|
||||
class: "echarts"
|
||||
});
|
||||
}
|
||||
});
|
||||
3
src/all.ts
Normal file
3
src/all.ts
Normal file
@ -0,0 +1,3 @@
|
||||
import "echarts";
|
||||
|
||||
export { default } from "./ECharts";
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 6.7 KiB |
@ -1,124 +0,0 @@
|
||||
<template>
|
||||
<div class="hello">
|
||||
<h1>{{ msg }}</h1>
|
||||
<p>
|
||||
For a guide and recipes on how to configure / customize this project,<br />
|
||||
check out the
|
||||
<a href="https://cli.vuejs.org" target="_blank" rel="noopener"
|
||||
>vue-cli documentation</a
|
||||
>.
|
||||
</p>
|
||||
<h3>Installed CLI Plugins</h3>
|
||||
<ul>
|
||||
<li>
|
||||
<a
|
||||
href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-babel"
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
>babel</a
|
||||
>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-typescript"
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
>typescript</a
|
||||
>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-eslint"
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
>eslint</a
|
||||
>
|
||||
</li>
|
||||
</ul>
|
||||
<h3>Essential Links</h3>
|
||||
<ul>
|
||||
<li>
|
||||
<a href="https://vuejs.org" target="_blank" rel="noopener">Core Docs</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://forum.vuejs.org" target="_blank" rel="noopener"
|
||||
>Forum</a
|
||||
>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://chat.vuejs.org" target="_blank" rel="noopener"
|
||||
>Community Chat</a
|
||||
>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://twitter.com/vuejs" target="_blank" rel="noopener"
|
||||
>Twitter</a
|
||||
>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://news.vuejs.org" target="_blank" rel="noopener">News</a>
|
||||
</li>
|
||||
</ul>
|
||||
<h3>Ecosystem</h3>
|
||||
<ul>
|
||||
<li>
|
||||
<a href="https://router.vuejs.org" target="_blank" rel="noopener"
|
||||
>vue-router</a
|
||||
>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://vuex.vuejs.org" target="_blank" rel="noopener">vuex</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
href="https://github.com/vuejs/vue-devtools#vue-devtools"
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
>vue-devtools</a
|
||||
>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://vue-loader.vuejs.org" target="_blank" rel="noopener"
|
||||
>vue-loader</a
|
||||
>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
href="https://github.com/vuejs/awesome-vue"
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
>awesome-vue</a
|
||||
>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from "vue";
|
||||
|
||||
export default defineComponent({
|
||||
name: "HelloWorld",
|
||||
props: {
|
||||
msg: String
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
||||
<style scoped>
|
||||
h3 {
|
||||
margin: 40px 0 0;
|
||||
}
|
||||
ul {
|
||||
list-style-type: none;
|
||||
padding: 0;
|
||||
}
|
||||
li {
|
||||
display: inline-block;
|
||||
margin: 0 10px;
|
||||
}
|
||||
a {
|
||||
color: #42b983;
|
||||
}
|
||||
</style>
|
||||
54
src/composables/api.ts
Normal file
54
src/composables/api.ts
Normal file
@ -0,0 +1,54 @@
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
import { Ref } from "vue";
|
||||
import { EChartsType, OptionType } from "@/types";
|
||||
|
||||
const METHOD_NAMES = [
|
||||
"getWidth",
|
||||
"getHeight",
|
||||
"getDom",
|
||||
"getOption",
|
||||
"resize",
|
||||
"dispatchAction",
|
||||
"convertToPixel",
|
||||
"convertFromPixel",
|
||||
"getDataURL",
|
||||
"getConnectedDataURL",
|
||||
"appendData",
|
||||
"clear",
|
||||
"isDisposed",
|
||||
"dispose"
|
||||
] as const;
|
||||
type MethodName = typeof METHOD_NAMES[number];
|
||||
|
||||
type PublicMethods = Pick<EChartsType, MethodName>;
|
||||
|
||||
export function usePublicAPI(
|
||||
chart: Ref<EChartsType | undefined>,
|
||||
init: (options?: OptionType) => void
|
||||
) {
|
||||
function makePublicMethod<T extends MethodName>(
|
||||
name: T
|
||||
): (...args: Parameters<EChartsType[T]>) => ReturnType<EChartsType[T]> {
|
||||
return (...args) => {
|
||||
if (!chart.value) {
|
||||
init();
|
||||
}
|
||||
|
||||
if (!chart.value) {
|
||||
throw new Error("ECharts is not initialized yet.");
|
||||
}
|
||||
return (chart.value[name] as any).apply(chart.value, args);
|
||||
};
|
||||
}
|
||||
|
||||
function makePublicMethods(): PublicMethods {
|
||||
const methods = Object.create(null);
|
||||
METHOD_NAMES.forEach(name => {
|
||||
methods[name] = makePublicMethod(name);
|
||||
});
|
||||
|
||||
return methods as PublicMethods;
|
||||
}
|
||||
|
||||
return makePublicMethods();
|
||||
}
|
||||
50
src/composables/autoresize.ts
Normal file
50
src/composables/autoresize.ts
Normal file
@ -0,0 +1,50 @@
|
||||
import { Ref, watch } from "vue";
|
||||
import { addListener, removeListener, ResizeCallback } from "resize-detector";
|
||||
import { EChartsType, OptionsType } from "@/types";
|
||||
|
||||
export function useAutoresize(
|
||||
chart: Ref<EChartsType | undefined>,
|
||||
autoresize: Ref<boolean>,
|
||||
root: Ref<HTMLElement | undefined>,
|
||||
options: Ref<OptionsType>
|
||||
): void {
|
||||
let resizeListener: ResizeCallback | null = null;
|
||||
let lastArea = 0;
|
||||
|
||||
function getArea() {
|
||||
const el = root.value;
|
||||
if (!el) {
|
||||
return 0;
|
||||
}
|
||||
return el.offsetWidth * el.offsetHeight;
|
||||
}
|
||||
|
||||
watch([root, chart, autoresize], ([root, chart, autoresize], _, cleanup) => {
|
||||
if (root && chart && autoresize) {
|
||||
lastArea = getArea();
|
||||
resizeListener = () => {
|
||||
if (lastArea === 0) {
|
||||
chart.setOption(Object.create(null), true);
|
||||
chart.resize();
|
||||
chart.setOption(options.value, true);
|
||||
} else {
|
||||
chart.resize();
|
||||
}
|
||||
lastArea = getArea();
|
||||
};
|
||||
|
||||
addListener(root, resizeListener);
|
||||
}
|
||||
|
||||
cleanup(() => {
|
||||
if (resizeListener && root) {
|
||||
lastArea = 0;
|
||||
removeListener(root, resizeListener);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
export const autoresizeProps = {
|
||||
autoresize: Boolean
|
||||
};
|
||||
3
src/composables/index.ts
Normal file
3
src/composables/index.ts
Normal file
@ -0,0 +1,3 @@
|
||||
export * from "./api";
|
||||
export * from "./autoresize";
|
||||
export * from "./loading";
|
||||
41
src/composables/loading.ts
Normal file
41
src/composables/loading.ts
Normal file
@ -0,0 +1,41 @@
|
||||
import { Ref, PropType, watchEffect } from "vue";
|
||||
import { EChartsType } from "@/types";
|
||||
|
||||
export interface LoadingOptions {
|
||||
text?: string;
|
||||
color?: string;
|
||||
textColor?: string;
|
||||
maskColor?: string;
|
||||
zlevel?: number;
|
||||
fontSize?: number;
|
||||
showSpinner?: boolean;
|
||||
spinnerRadius?: number;
|
||||
lineWidth?: number;
|
||||
fontWeight?: string | number;
|
||||
fontStyle?: string;
|
||||
fontFamily?: string;
|
||||
}
|
||||
|
||||
export function useLoading(
|
||||
chart: Ref<EChartsType | undefined>,
|
||||
loading: Ref<boolean>,
|
||||
loadingOptions?: Ref<LoadingOptions | undefined>
|
||||
): void {
|
||||
watchEffect(() => {
|
||||
const instance = chart.value;
|
||||
if (!instance) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (loading.value) {
|
||||
instance.showLoading(loadingOptions?.value);
|
||||
} else {
|
||||
instance.hideLoading();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export const loadingProps = {
|
||||
loading: Boolean,
|
||||
loadingOptions: Object as PropType<LoadingOptions>
|
||||
};
|
||||
154
src/demo/App.vue
Normal file
154
src/demo/App.vue
Normal file
@ -0,0 +1,154 @@
|
||||
<template>
|
||||
<article>
|
||||
<div class="settings">
|
||||
<label><input type="checkbox" v-model="autoresize" /> Autoresize</label>
|
||||
<label
|
||||
><input type="checkbox" v-model="defaultTheme" /> Default theme</label
|
||||
>
|
||||
<label><input type="checkbox" v-model="loading" /> Loading</label>
|
||||
<label><input type="checkbox" v-model="useSvg" /> Use SVG</label>
|
||||
<label><input type="checkbox" v-model="useRef" /> Use ref data</label>
|
||||
<button @click="mutate" :disabled="useRef">Mutate data</button>
|
||||
<button @click="set" :disabled="!useRef">Set data</button>
|
||||
<button @click="mutateLoadingOptions" :disabled="!loading">
|
||||
Mutate loading options
|
||||
</button>
|
||||
</div>
|
||||
<v-chart
|
||||
style="width: 100%; height: 400px"
|
||||
ref="foo"
|
||||
:autoresize="autoresize"
|
||||
:options="realOptions"
|
||||
:loading="loading"
|
||||
:loading-options="loadingOptions"
|
||||
:theme="defaultTheme ? null : 'dark'"
|
||||
:init-options="initOptions"
|
||||
@click="log('echarts')"
|
||||
@zr:click="log('zr')"
|
||||
/>
|
||||
</article>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { computed, defineComponent, reactive, ref } from "vue";
|
||||
import VChart from "../ECharts";
|
||||
import * as echarts from "echarts/core";
|
||||
import { GridComponent } from "echarts/components";
|
||||
import { LineChart } from "echarts/charts";
|
||||
import { CanvasRenderer, SVGRenderer } from "echarts/renderers";
|
||||
|
||||
echarts.use([GridComponent, LineChart, CanvasRenderer, SVGRenderer]);
|
||||
|
||||
export default defineComponent({
|
||||
name: "App",
|
||||
components: {
|
||||
VChart
|
||||
},
|
||||
setup() {
|
||||
const foo = ref();
|
||||
const options = reactive({
|
||||
xAxis: {
|
||||
type: "category",
|
||||
data: ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]
|
||||
},
|
||||
yAxis: {
|
||||
type: "value"
|
||||
},
|
||||
series: [
|
||||
{
|
||||
data: [150, 230, 224, 218, 135, 147, 260],
|
||||
type: "line"
|
||||
}
|
||||
]
|
||||
});
|
||||
const optionsRef = ref({
|
||||
xAxis: {
|
||||
type: "category",
|
||||
data: ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]
|
||||
},
|
||||
yAxis: {
|
||||
type: "value"
|
||||
},
|
||||
series: [
|
||||
{
|
||||
data: [233, 128, 184, 302, 208, 287, 212],
|
||||
type: "line"
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
const loadingOptions = reactive({
|
||||
text: "正在加载..."
|
||||
});
|
||||
|
||||
const autoresize = ref<boolean>(true);
|
||||
const defaultTheme = ref<boolean>(true);
|
||||
const useSvg = ref<boolean>(false);
|
||||
const useRef = ref<boolean>(false);
|
||||
const loading = ref<boolean>(false);
|
||||
const initOptions = computed(() => ({
|
||||
renderer: useSvg.value ? "svg" : "canvas"
|
||||
}));
|
||||
const realOptions = computed(() =>
|
||||
useRef.value ? optionsRef.value : options
|
||||
);
|
||||
|
||||
function mutate() {
|
||||
options.series[0].data = [150, 230, 224, 218, 135, 147, 260].map(
|
||||
val => val + Math.round(50 * Math.random())
|
||||
);
|
||||
}
|
||||
|
||||
function set() {
|
||||
optionsRef.value = {
|
||||
xAxis: {
|
||||
type: "category",
|
||||
data: ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]
|
||||
},
|
||||
yAxis: {
|
||||
type: "value"
|
||||
},
|
||||
series: [
|
||||
{
|
||||
data: [
|
||||
233 + Math.round(50 * Math.random()),
|
||||
128 + Math.round(50 * Math.random()),
|
||||
184 + Math.round(50 * Math.random()),
|
||||
302 + Math.round(50 * Math.random()),
|
||||
208 + Math.round(50 * Math.random()),
|
||||
287 + Math.round(50 * Math.random()),
|
||||
212 + Math.round(50 * Math.random())
|
||||
],
|
||||
type: "line"
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
|
||||
function mutateLoadingOptions() {
|
||||
loadingOptions.text += ".";
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
function log(...args: any[]) {
|
||||
console.log(...args);
|
||||
}
|
||||
|
||||
return {
|
||||
realOptions,
|
||||
autoresize,
|
||||
defaultTheme,
|
||||
useSvg,
|
||||
useRef,
|
||||
initOptions,
|
||||
mutate,
|
||||
set,
|
||||
loading,
|
||||
loadingOptions,
|
||||
mutateLoadingOptions,
|
||||
foo,
|
||||
log
|
||||
};
|
||||
}
|
||||
});
|
||||
</script>
|
||||
1
src/index.ts
Normal file
1
src/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export { default } from "./ECharts";
|
||||
4
src/style.css
Normal file
4
src/style.css
Normal file
@ -0,0 +1,4 @@
|
||||
.echarts {
|
||||
width: 400px;
|
||||
height: 300px;
|
||||
}
|
||||
5
src/types.ts
Normal file
5
src/types.ts
Normal file
@ -0,0 +1,5 @@
|
||||
import { init } from "echarts/core";
|
||||
|
||||
export type EChartsType = ReturnType<typeof init>;
|
||||
type SetOptionType = EChartsType["setOption"];
|
||||
export type OptionType = Parameters<SetOptionType>[0];
|
||||
@ -1,39 +1,32 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "esnext",
|
||||
"module": "esnext",
|
||||
"target": "ES5",
|
||||
"module": "ESNext",
|
||||
"strict": true,
|
||||
"jsx": "preserve",
|
||||
"importHelpers": true,
|
||||
"moduleResolution": "node",
|
||||
"removeComments": true,
|
||||
"skipLibCheck": true,
|
||||
"esModuleInterop": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"sourceMap": true,
|
||||
"baseUrl": ".",
|
||||
"types": [
|
||||
"webpack-env"
|
||||
],
|
||||
"types": ["webpack-env"],
|
||||
"paths": {
|
||||
"@/*": [
|
||||
"src/*"
|
||||
]
|
||||
"@/*": ["src/*"]
|
||||
},
|
||||
"lib": [
|
||||
"esnext",
|
||||
"dom",
|
||||
"dom.iterable",
|
||||
"scripthost"
|
||||
]
|
||||
"lib": ["ESNext", "DOM", "DOM.Iterable", "ScriptHost"],
|
||||
// "declaration": true,
|
||||
// "declarationDir": "dist"
|
||||
},
|
||||
"include": [
|
||||
"src/**/*.ts",
|
||||
"src/**/*.tsx",
|
||||
"src/**/*.vue",
|
||||
"tests/**/*.ts",
|
||||
"tests/**/*.tsx"
|
||||
"shims-vue.d.ts",
|
||||
"src/demo/**/*.ts",
|
||||
"src/demo/**/*.vue"
|
||||
],
|
||||
"exclude": [
|
||||
"node_modules"
|
||||
]
|
||||
"exclude": ["node_modules"]
|
||||
}
|
||||
|
||||
10
vue.config.js
Normal file
10
vue.config.js
Normal file
@ -0,0 +1,10 @@
|
||||
module.exports = {
|
||||
outputDir: "demo",
|
||||
transpileDependencies: ["resize-detector"],
|
||||
chainWebpack: config => {
|
||||
config
|
||||
.entry("app")
|
||||
.clear()
|
||||
.add("./src/demo/main.ts");
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user