fix bug and WEcharts.vue

master
管理员 10 months ago
parent a4dd16682c
commit d1fb3008a5

@ -66,7 +66,7 @@ instance.interceptors.response.use(function (response) {
if (response.data.code != 200) {
ElMessage.error(response.data.msg || response.data.message);
if(response.data.code == 401) {
let authStore = AuthStore();
let authStore = useAuthStore();
authStore.logout();
useRouter().push({path:'/login', query: { to: encodeURIComponent(useRoute().fullPath) }});
}

@ -0,0 +1,238 @@
<template>
<div class="WEcharts" ref="WEchartsRef">
</div>
</template>
<script setup>
import * as echarts from 'echarts';
import { useElementSize, useThrottleFn } from '@vueuse/core';
import { useTemplateRef, watch, onMounted } from 'vue';
import { unit, objectMerge, deepClone } from '@/util';
const props = defineProps({
option: {
type: Object,
default: {}
},
useDefault: {
type: Boolean,
default: true
},
colors: {
type: Array,
default: ['#e74c3c', '#f39c12', '#2ed573', '#e056fd', '#833471']
},
color: {
type: String,
default: "#FFFA"
},
excludes: {
type: Array,
default: ['fontSize']
},
});
const emit = defineEmits(['resize', 'load']);
const root = useTemplateRef('WEchartsRef');
let chart = null;
let optionGlobal = null;
const { width, height } = useElementSize(root);
const getDefaultOption = () => ({
color: props.colors,
tooltip: {
trigger: 'axis',
textStyle: {
fontSize: '.85em',
}
},
legend: {
// data: [],
top: '1em',
textStyle: {
color: props.color,
fontSize: '.9em',
}
},
grid: {
top: '3.5em',
left: '1em',
right: '1em',
bottom: '1em',
containLabel: true,
},
xAxis: {
type: 'category',
boundaryGap: false,
// data: [],
axisLine: {
lineStyle: {
color: props.color
},
},
axisLabel: {
color: props.color,
fontSize: '.8em'
},
},
yAxis: {
type: 'value',
axisLine: {
lineStyle: {
color: props.color,
}
},
axisLabel: {
color: props.color,
fontSize: '.8em'
},
splitLine: {
show: true,
lineStyle: {
color: '#FFF2',
}
}
},
// series: []
});
const setPxArray = (array, px) => {
for (let i = 0; i < array.length; i++) {
if (Array.isArray(array[i])) {
setPxArray(array[i], px);
} else if (typeof array[i] === 'object') {
setPx(array[i], px);
} else if (typeof array[i] === 'string') {
if (/^.*\dem$/.test(array[i])) {
try {
array[i] = (parseFloat(array[i]) * px) || 0;
} catch (e) { }
}
}
}
}
const setPx = (option, px) => {
for (let key of Object.keys(option)) {
if (props.excludes.includes(key)) {
continue;
}
if (Array.isArray(option[key])) {
setPxArray(option[key], px);
} else if (typeof option[key] === 'object') {
setPx(option[key], px)
} else if (typeof option[key] === 'string') {
if (/^.*\dem$/.test(option[key])) {
try {
option[key] = (parseFloat(option[key]) * px) || 0;
} catch (e) { }
}
}
}
}
const resize = (px) => {
if (!chart) {
return;
}
let option = null;
if (props.useDefault) {
option = objectMerge(getDefaultOption(), props.option);
} else {
option = deepClone(props.option);
}
setPx(option, px);
try {
delete option.series;
delete option.legend.data;
delete option.xAxis.data;
delete option.yAxis.data;
} catch (e) { }
chart.setOption(option);
}
onMounted(async () => {
chart = echarts.init(root.value, 'light', {
renderer: 'svg'
});
let px = unit.em2px(root, 1);
resize(px);
emit('load', { chart, setOption,px});
})
const doResize = useThrottleFn(() => {
if (!chart) {
return;
}
chart.resize({
width: width.value, // 使
height: height.value, // 使
silent: false, //
});
let px = unit.em2px(root, 1);
resize(px);
emit('resize', { chart, setOption, px });
}, 500, true);
watch(() => width.value * 10000 + height.value, doResize);
const setTitles = (titiles) => {
setOption({ legend: { data: titiles } });
}
const setX = (x) => {
setOption({ xAxis: { data: x } });
}
const setY = (y) => {
setOption({ yAxis: { data: y } });
}
const setSeries = (series) => {
setOption({ series });
}
const setOption = (option) => {
if (!chart) {
return;
}
chart.setOption(option);
doResize();
}
defineExpose({
chart,
setOption,
el: root,
setTitles,
setX,
setY,
setSeries,
setData: setSeries
});
</script>
<style lang="scss" scoped>
@layer {
.WEcharts {
width: 100%;
height: 100%;
overflow: hidden;
}
}
</style>

@ -251,50 +251,51 @@ codeRef.setCode('new code');//设置代码
<w-code language="html">
{{ `
<div
style="display: grid; grid-template-columns: repeat(10, 5em); grid-template-rows: 5em; gap: 1em; margin-bottom: 1em;">
<w-effect-light>
<div style="height: 100%; width: 100%; background-color: var(--w-main);"></div>
</w-effect-light>
<div
style="display: grid; grid-template-columns: repeat(10, 5em); grid-template-rows: 5em; gap: 1em; margin-bottom: 1em;">
<w-effect-light>
<div style="height: 100%; width: 100%; background-color: var(--w-main);"></div>
</w-effect-light>
<w-effect-light style="--time:3s; --filter: brightness(150%);">
<div style="height: 100%; width: 100%; background-color: var(--w-main);"></div>
</w-effect-light>
<w-effect-light style="--time:3s; --filter: brightness(150%);">
<div style="height: 100%; width: 100%; background-color: var(--w-main);"></div>
</w-effect-light>
<w-effect-light style="--time:5s; --filter: hue-rotate(360deg); background-color: var(--w-main);">
</w-effect-light>
<w-effect-light style="--time:5s; --filter: hue-rotate(360deg); background-color: var(--w-main);">
</w-effect-light>
<w-effect-breathing>
<div style="height: 100%; width: 100%; background-color: var(--w-main);"></div>
</w-effect-breathing>
<w-effect-breathing>
<div style="height: 100%; width: 100%; background-color: var(--w-main);"></div>
</w-effect-breathing>
<div class="w-breathing" style="background-color: var(--w-main);"></div>
<div class="w-breathing" style="background-color: var(--w-main);"></div>
<div class="w-breathing"
style="background-color: var(--w-main); --time:2s; --filter: brightness(70%) opacity(0); --transform: skew(-5deg) scale(1.2);">
</div>
<div class="w-breathing"
style="background-color: var(--w-main); --time:2s; --filter: brightness(70%) opacity(0); --transform: skew(-5deg) scale(1.2);">
</div>
<div class="w-breathing w-flex"
style="background-color: var(--w-main); --time:3s;--filter:none;--transform:none; --data-num: .3; --data-num-to: 1; box-shadow: 0 0 calc(2em * var(--data-num)) #000;">
<div style="height: 3em; width: calc(3em * var(--data-num)); background-color: #FFF3; border-radius: 100%;">
<div class="w-breathing w-flex"
style="background-color: var(--w-main); --time:3s;--filter:none;--transform:none; --data-num: .3; --data-num-to: 1; box-shadow: 0 0 calc(2em * var(--data-num)) #000;">
<div
style="height: 3em; width: calc(3em * var(--data-num)); background-color: #FFF3; border-radius: 100%;">
</div>
</div>
</div>
</div>
<w-effect-light :style="{ 'animation-play-state': am ? 'running' : 'paused' }"
style="--filter: brightness(150%); --time:2s; ">
<div
style="height: 5em; width: 5em; background-color: var(--w-main); border-radius: 1em; margin-bottom: .5em;">
</div>
</w-effect-light>
<el-button @click="am = !am;">\{\{ am ? '暂停' : '播放' \}\}</el-button>` }}
<w-effect-light :style="{ 'animation-play-state': am ? 'running' : 'paused' }"
style="--filter: brightness(150%); --time:2s; ">
<div
style="height: 5em; width: 5em; background-color: var(--w-main); border-radius: 1em; margin-bottom: .5em;">
</div>
</w-effect-light>
<el-button @click="am = !am;">\{\{ am ? '暂停' : '播放' \}\}</el-button>` }}
</w-code>
<h2>干扰动画效果</h2>
<w-effect-noise :am="am1" style="--time:5s;">
<div style="height: 5em; width: 5em; background-color: var(--w-main); border-radius: 10em;"></div>
</w-effect-noise>
<el-button @click="am1 = !am1;">{{ am1 ? '暂停' : '播放' }}</el-button>
<h2>加载动画效果</h2>
@ -424,6 +425,66 @@ const emRef3 = proxy.$refs.emRef3;
</w-code>
</el-tab-pane>
<el-tab-pane label="echarts">
<h2>图表组件</h2>
<h3>自适应,可使用em</h3>
<div style="width: 80em; height: 20em; resize: both; background-color: #0002; overflow: auto;">
<w-echarts ref="echartsRef" :option="{
grid: {
top: '3.5em',
left: '5em',
right: '1em',
bottom: '2em'
}
}" @resize="resize" />
</div>
<el-button
@click="proxy.$refs.echartsRef.setTitles(['标题标题标题一', '标题二']);">setTitles(['标题标题标题一','标题二'])</el-button>
<el-button @click="proxy.$refs.echartsRef.setX(['11', '22', '33']);">setX(['11','22','33'])</el-button>
<el-button disabled>setY()</el-button>
<el-button @click="proxy.$refs.echartsRef.setSeries([{
name: '标题标题标题一',
data: [Math.random() * 10, Math.random() * 10, Math.random() * 10],
type: 'line',
smooth: true,
}, {
name: '标题二',
data: [Math.random() * 10, Math.random() * 10, Math.random() * 10],
type: 'line',
areaStyle:{},
smooth: true,
}]);">setSeries([{},{}])</el-button>
<h3>方法</h3>
<ol style="margin: 1em 3em;">
<li>setTitles : option.legend.data = [....] </li>
<li>setX: option.xAxis.data = [...]</li>
<li>setY: option.yAxis.data = [...]</li>
<li>setSeries: option.series = [...]; 别名: setData</li>
<li>setOption: chart?.setOption;</li>
<li>chart: echarts的实例</li>
<li>el: 组件的Element引用</li>
</ol>
<h3>属性</h3>
<ol style="margin: 1em 3em;">
<li>option : echarts的配置,在只允许使用Number的地方可以使用'XXXem',会根据当前字段大小自动转换为Number</li>
<li>useDefault: option是否合并组件里的默认配置</li>
<li>colors: 默认配置中的调色盘(option.color),默认: ['#e74c3c', '#f39c12', '#2ed573', '#e056fd', '#833471']</li>
<li>color: 默认配置中的主色,文字颜色,坐标颜色, 默认: #FFFA</li>
<li>excludes: 默认配置中不进行em转px操作的属性名,默认: ['fontSize']</li>
</ol>
<h3>事件</h3>
<ol style="margin: 1em 3em;">
<li>resize: 组件尺寸发生变化事件,事件参数 {chart,setOption,px},px为1em的单位大小</li>
<li>load: 组件初始化加载完成事件,事件参数 {chart,setOption,px},px为1em的单位大小</li>
</ol>
</el-tab-pane>
</el-tabs>
@ -456,9 +517,17 @@ const switchValue = ref(true);
const am = ref(true);
const am1 = ref(true);
const resize = ({ chart, px, setOption }) => {
setOption({ legend: { itemGap: chart.getOption().series.reduce((i, item) => Math.max(i, item.name.length), 1) * px } });
}
</script>
<style lang="scss" scoped>
h2 {
margin: 2em 0 1em;
}
h3 {
margin: 1em 0 .5em;
}
</style>

@ -51,3 +51,27 @@ export function deepClone(source) {
})
return targetObj
}
/**
* Merges two objects, giving the last one precedence
* @param {Object} target
* @param {(Object|Array)} source
* @returns {Object}
*/
export function objectMerge(target, source) {
if (typeof target !== 'object') {
target = {}
}
if (Array.isArray(source)) {
return source.slice()
}
Object.keys(source).forEach(property => {
const sourceProperty = source[property]
if (typeof sourceProperty === 'object') {
target[property] = objectMerge(target[property], sourceProperty)
} else {
target[property] = sourceProperty
}
})
return target
}
Loading…
Cancel
Save