Commit 841aaffb authored by hucy's avatar hucy

feat:动态配置的echar图表轮播图

parent 96ed2a72
......@@ -2,10 +2,17 @@
* 轮播图
-->
<script setup lang="ts">
import { ref, onMounted, onBeforeUnmount, watch } from 'vue';
import {
ref,
reactive,
onMounted,
onBeforeUnmount,
watch,
nextTick,
markRaw,
} from 'vue';
import { isEmpty } from 'src/common/utils';
// import * as echarts from 'echarts';
// type EChartsOption = echarts.EChartsOption;
import * as echarts from 'echarts';
interface Props {
itemKey: string;
......@@ -21,10 +28,18 @@ const props = withDefaults(defineProps<Props>(), {
navigation: false,
});
const DOM_PIE_KEY = 'chart-pie-dom-';
const pointActive = ref<any>(1);
const lastIndex = ref(0);
const timer = ref<any>(null);
const state = reactive({
// vue3中使用proxy的方式监听响应式,chart会被在vue内部转换成响应式对象,从而在resize 的时候获取不到
// markRaw 标记一个对象,使其永远不会再成为响应式对象
domMap: markRaw(new Map()),
});
watch(
() => props.list,
() => {
......@@ -42,17 +57,88 @@ onBeforeUnmount(() => {
// list改变
function listChange() {
console.log('listChange', props.list);
// console.log('listChange=', props.list);
offTimer(); // 清除定时器
if (isEmpty(props.list)) {
resetIndex();
state.domMap.clear();
} else {
// 如果当前下标 > list长度,则下标重新开始
if (pointActive.value > props.list.length) {
resetIndex();
}
nextTick(() => {
const domMap = new Map();
props.list.map((item: any) => {
const id = `${DOM_PIE_KEY}${item[props.itemKey]}`;
const hasDom = state.domMap.has(id);
const dom: any = hasDom
? state.domMap.get(id).dom
: document.getElementById(id);
const option = item.option || null;
let myChart: any;
const condition = pointActive.value === item[props.itemKey];
if (hasDom) {
if (state.domMap.get(id).myChart) {
myChart = state.domMap.get(id).myChart;
} else {
if (condition) {
myChart = echarts.init(dom);
} else {
myChart = null;
}
}
} else {
if (condition) {
myChart = echarts.init(dom);
} else {
myChart = null;
}
}
if (condition && option) {
// console.log('设置了', myChart);
myChart.resize();
myChart.clear();
myChart.setOption(option);
}
const val = {
dom,
option,
id,
myChart,
};
if (state.domMap) domMap.set(id, val);
return val;
});
if (state.domMap.size < domMap.size) {
for (const [key, value] of domMap) {
if (state.domMap.has(key)) {
state.domMap.set(key, domMap.get(key));
} else {
state.domMap.set(key, value);
}
}
} else if (state.domMap.size > domMap.size) {
for (const key of state.domMap.keys()) {
if (domMap.has(key)) {
state.domMap.set(key, domMap.get(key));
} else {
state.domMap.delete(key);
}
}
} else {
for (const key of domMap.keys()) {
state.domMap.set(key, domMap.get(key));
}
}
// console.log('state.domMap =', state.domMap);
onStartTimer();
});
}
}
......@@ -66,22 +152,57 @@ function onStartTimer() {
pointActive.value++;
lastIndex.value++;
}
nextTick(() => {
renderChart();
onStartTimer();
});
}, props.times);
}
function onClickPoint(val: any, index: number) {
if (index === lastIndex.value) return;
offTimer();
if (index > lastIndex.value) {
// 右
} else if (index < lastIndex.value) {
// 左
} else {
return;
}
pointActive.value = val[props.itemKey];
lastIndex.value = index;
nextTick(() => {
renderChart();
onStartTimer();
});
}
function renderChart() {
const key = `${DOM_PIE_KEY}${pointActive.value}`;
const currentDom = state.domMap.get(key);
// console.log('currentDom =', currentDom);
if (currentDom.myChart) {
if (currentDom.option) {
currentDom.myChart.clear();
currentDom.myChart.setOption(currentDom.option);
}
} else {
const myChart = echarts.init(currentDom.dom);
if (currentDom.option) {
myChart.clear();
myChart.setOption(currentDom.option);
}
const val = {
dom: currentDom.dom,
option: currentDom.option,
id: currentDom.id,
myChart,
};
state.domMap.set(key, val);
}
// console.log('domMap =', state.domMap);
// console.log('pointActive =', pointActive.value);
}
function offTimer() {
......@@ -109,9 +230,10 @@ function resetIndex() {
>
<!-- some item -->
<div class="my-item-box center">
<div class="fit" :id="`chart-pie-dom-${i[props.itemKey]}`">
{{ i.label }}
</div>
<div
class="fit"
:id="`${DOM_PIE_KEY}${i[props.itemKey]}`"
></div>
</div>
</div>
</template>
......@@ -170,7 +292,7 @@ function resetIndex() {
height: 100%;
overflow: auto;
position: absolute;
background-color: white;
background-color: #fff;
top: 0;
left: 0;
}
......
This diff is collapsed.
......@@ -4,17 +4,18 @@
<script setup lang="ts">
import { reactive, onMounted, onBeforeUnmount } from 'vue';
import Com from 'src/components';
import { WarpTestData, WarpTestData2 } from '../config';
import { WarpTestData, WarpTestData2, WarpTestData3 } from '../config';
import * as echarts from 'echarts';
const state = reactive({
list: [] as any,
times: 5000,
testChart: null as any,
});
onMounted(() => {
setTimeout(() => {
test111();
initData();
}, 3000);
});
onBeforeUnmount(() => {
......@@ -25,16 +26,72 @@ function initData() {
state.list = WarpTestData;
}
function onDataChange1() {
state.list = WarpTestData;
}
function onDataChange2() {
state.list = WarpTestData2;
}
function onDataChange3() {
state.list = WarpTestData3;
}
function onSetToEnpty() {
state.list = [];
}
function onChangeTimers() {
state.times = 1000;
state.times = 2000;
}
function test111() {
let chartDom: any = document.getElementById('test111');
state.testChart = echarts.init(chartDom);
const option = {
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',
},
],
};
state.testChart.setOption(option);
}
function onDestructionChart() {
state.testChart.dispose();
}
function onResetChart() {
test111();
}
function onResetData() {
const option = {
xAxis: {
type: 'category',
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
},
yAxis: {
type: 'value',
},
series: [
{
data: [300, 300, 300, 300, 300, 300, 300],
type: 'line',
},
],
};
state.testChart.setOption(option);
}
function onView() {
console.log('查看 =', state.testChart);
}
</script>
<template>
......@@ -49,18 +106,39 @@ function onChangeTimers() {
</Com.CarouselWarp>
</div>
<div class="btns">
<q-btn
label="图表轮播图测试数据1"
@click="onDataChange1"
color="primary"
/>
<q-btn
label="图表轮播图测试数据2"
@click="onDataChange2"
color="primary"
/>
<q-btn
label="图表轮播图测试数据3"
@click="onDataChange3"
color="primary"
/>
<q-btn label="将数据置为空" @click="onSetToEnpty" color="primary" />
<q-btn label="改变轮播时间" @click="onChangeTimers" color="orange" />
</div>
<q-btn label="销毁图表" @click="onDestructionChart" color="orange" />
<q-btn label="重绘图表" @click="onResetChart" color="orange" />
<q-btn label="重新设置数据" @click="onResetData" color="orange" />
<q-btn label="查看" @click="onView" color="orange" />
<div class="test111" id="test111"></div>
</div>
</template>
<style lang="scss" scoped>
.test111 {
width: 500px;
height: 500px;
border: 1px solid red;
}
.my-warp-box {
width: 500px;
height: 300px;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment