Commit 841aaffb authored by hucy's avatar hucy

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

parent 96ed2a72
...@@ -2,10 +2,17 @@ ...@@ -2,10 +2,17 @@
* 轮播图 * 轮播图
--> -->
<script setup lang="ts"> <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 { isEmpty } from 'src/common/utils';
// import * as echarts from 'echarts'; import * as echarts from 'echarts';
// type EChartsOption = echarts.EChartsOption;
interface Props { interface Props {
itemKey: string; itemKey: string;
...@@ -21,10 +28,18 @@ const props = withDefaults(defineProps<Props>(), { ...@@ -21,10 +28,18 @@ const props = withDefaults(defineProps<Props>(), {
navigation: false, navigation: false,
}); });
const DOM_PIE_KEY = 'chart-pie-dom-';
const pointActive = ref<any>(1); const pointActive = ref<any>(1);
const lastIndex = ref(0); const lastIndex = ref(0);
const timer = ref<any>(null); const timer = ref<any>(null);
const state = reactive({
// vue3中使用proxy的方式监听响应式,chart会被在vue内部转换成响应式对象,从而在resize 的时候获取不到
// markRaw 标记一个对象,使其永远不会再成为响应式对象
domMap: markRaw(new Map()),
});
watch( watch(
() => props.list, () => props.list,
() => { () => {
...@@ -42,17 +57,88 @@ onBeforeUnmount(() => { ...@@ -42,17 +57,88 @@ onBeforeUnmount(() => {
// list改变 // list改变
function listChange() { function listChange() {
console.log('listChange', props.list); // console.log('listChange=', props.list);
offTimer(); // 清除定时器 offTimer(); // 清除定时器
if (isEmpty(props.list)) { if (isEmpty(props.list)) {
resetIndex(); resetIndex();
state.domMap.clear();
} else { } else {
// 如果当前下标 > list长度,则下标重新开始 // 如果当前下标 > list长度,则下标重新开始
if (pointActive.value > props.list.length) { if (pointActive.value > props.list.length) {
resetIndex(); 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(); onStartTimer();
});
} }
} }
...@@ -66,22 +152,57 @@ function onStartTimer() { ...@@ -66,22 +152,57 @@ function onStartTimer() {
pointActive.value++; pointActive.value++;
lastIndex.value++; lastIndex.value++;
} }
nextTick(() => {
renderChart();
onStartTimer(); onStartTimer();
});
}, props.times); }, props.times);
} }
function onClickPoint(val: any, index: number) { function onClickPoint(val: any, index: number) {
if (index === lastIndex.value) return;
offTimer(); offTimer();
if (index > lastIndex.value) { if (index > lastIndex.value) {
// 右 // 右
} else if (index < lastIndex.value) { } else if (index < lastIndex.value) {
// 左 // 左
} else {
return;
} }
pointActive.value = val[props.itemKey]; pointActive.value = val[props.itemKey];
lastIndex.value = index; lastIndex.value = index;
nextTick(() => {
renderChart();
onStartTimer(); 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() { function offTimer() {
...@@ -109,9 +230,10 @@ function resetIndex() { ...@@ -109,9 +230,10 @@ function resetIndex() {
> >
<!-- some item --> <!-- some item -->
<div class="my-item-box center"> <div class="my-item-box center">
<div class="fit" :id="`chart-pie-dom-${i[props.itemKey]}`"> <div
{{ i.label }} class="fit"
</div> :id="`${DOM_PIE_KEY}${i[props.itemKey]}`"
></div>
</div> </div>
</div> </div>
</template> </template>
...@@ -170,7 +292,7 @@ function resetIndex() { ...@@ -170,7 +292,7 @@ function resetIndex() {
height: 100%; height: 100%;
overflow: auto; overflow: auto;
position: absolute; position: absolute;
background-color: white; background-color: #fff;
top: 0; top: 0;
left: 0; left: 0;
} }
......
This diff is collapsed.
...@@ -4,17 +4,18 @@ ...@@ -4,17 +4,18 @@
<script setup lang="ts"> <script setup lang="ts">
import { reactive, onMounted, onBeforeUnmount } from 'vue'; import { reactive, onMounted, onBeforeUnmount } from 'vue';
import Com from 'src/components'; import Com from 'src/components';
import { WarpTestData, WarpTestData2 } from '../config'; import { WarpTestData, WarpTestData2, WarpTestData3 } from '../config';
import * as echarts from 'echarts';
const state = reactive({ const state = reactive({
list: [] as any, list: [] as any,
times: 5000, times: 5000,
testChart: null as any,
}); });
onMounted(() => { onMounted(() => {
setTimeout(() => { test111();
initData(); initData();
}, 3000);
}); });
onBeforeUnmount(() => { onBeforeUnmount(() => {
...@@ -25,16 +26,72 @@ function initData() { ...@@ -25,16 +26,72 @@ function initData() {
state.list = WarpTestData; state.list = WarpTestData;
} }
function onDataChange1() {
state.list = WarpTestData;
}
function onDataChange2() { function onDataChange2() {
state.list = WarpTestData2; state.list = WarpTestData2;
} }
function onDataChange3() {
state.list = WarpTestData3;
}
function onSetToEnpty() { function onSetToEnpty() {
state.list = []; state.list = [];
} }
function onChangeTimers() { 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> </script>
<template> <template>
...@@ -49,18 +106,39 @@ function onChangeTimers() { ...@@ -49,18 +106,39 @@ function onChangeTimers() {
</Com.CarouselWarp> </Com.CarouselWarp>
</div> </div>
<div class="btns"> <div class="btns">
<q-btn
label="图表轮播图测试数据1"
@click="onDataChange1"
color="primary"
/>
<q-btn <q-btn
label="图表轮播图测试数据2" label="图表轮播图测试数据2"
@click="onDataChange2" @click="onDataChange2"
color="primary" color="primary"
/> />
<q-btn
label="图表轮播图测试数据3"
@click="onDataChange3"
color="primary"
/>
<q-btn label="将数据置为空" @click="onSetToEnpty" color="primary" /> <q-btn label="将数据置为空" @click="onSetToEnpty" color="primary" />
<q-btn label="改变轮播时间" @click="onChangeTimers" color="orange" /> <q-btn label="改变轮播时间" @click="onChangeTimers" color="orange" />
</div> </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> </div>
</template> </template>
<style lang="scss" scoped> <style lang="scss" scoped>
.test111 {
width: 500px;
height: 500px;
border: 1px solid red;
}
.my-warp-box { .my-warp-box {
width: 500px; width: 500px;
height: 300px; 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