diff --git a/src/components/carousel-warp/CarouselWarp.vue b/src/components/carousel-warp/CarouselWarp.vue index bba83bc110d082089f248861e4b2d98de2ceef17..c6a2153566c1f6543cc0b2dd916a1e290811e2da 100644 --- a/src/components/carousel-warp/CarouselWarp.vue +++ b/src/components/carousel-warp/CarouselWarp.vue @@ -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(); } - onStartTimer(); + 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++; } - onStartTimer(); + + 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; - onStartTimer(); + + 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; } diff --git a/src/modules/page6/config.ts b/src/modules/page6/config.ts index f9eb7ad73858e4c1f39fa1a7ef5da95d1875e788..881d6ccd02db2b3f201dd34444ca9d413583c9c2 100644 --- a/src/modules/page6/config.ts +++ b/src/modules/page6/config.ts @@ -1,3 +1,16 @@ +const COLORLIST = [ + '#C0232C', + '#B6C335', + '#FBCE0F', + '#E87C24', + '#28727B', + '#FF8463', + '#9BCA62', + '#FAD75F', + '#F3A43B', + '#62BFE0', + '#D7504C', +]; // 图表轮æ’å›¾æµ‹è¯•æ•°æ® export const WarpTestData = [ { @@ -5,10 +18,9 @@ export const WarpTestData = [ label: '1å·', url: require('./element/imgs/carousel-1.jpg'), option: { + color: COLORLIST, title: { - text: 'Referer of a Website', - subtext: 'Fake Data', - left: 'center', + text: '1å·', }, tooltip: { trigger: 'item', @@ -16,26 +28,18 @@ export const WarpTestData = [ legend: { orient: 'vertical', left: 'left', + top: 'bottom', }, series: [ { - name: 'Access From', type: 'pie', - radius: '50%', data: [ - { value: 1048, name: 'Search Engine' }, - { value: 735, name: 'Direct' }, - { value: 580, name: 'Email' }, - { value: 484, name: 'Union Ads' }, - { value: 300, name: 'Video Ads' }, + { value: 1048, name: '苹果' }, + { value: 735, name: '香蕉' }, + { value: 580, name: 'è‘¡è„' }, + { value: 484, name: '梨' }, + { value: 300, name: 'è”æž' }, ], - emphasis: { - itemStyle: { - shadowBlur: 10, - shadowOffsetX: 0, - shadowColor: 'rgba(0, 0, 0, 0.5)', - }, - }, }, ], }, @@ -44,31 +48,136 @@ export const WarpTestData = [ id: 2, label: '2å·', url: require('./element/imgs/carousel-2.jpg'), - option: null, + option: { + color: COLORLIST, + title: { + text: '2å·', + }, + tooltip: { + trigger: 'axis', + }, + legend: { + data: ['苹果', '香蕉', 'è‘¡è„', '梨', 'è”æž'], + }, + xAxis: { + type: 'category', + boundaryGap: false, + data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'], + }, + yAxis: { + type: 'value', + }, + series: [ + { + name: '苹果', + type: 'line', + stack: 'Total', + data: [120, 132, 101, 134, 90, 230, 210], + }, + { + name: '香蕉', + type: 'line', + stack: 'Total', + data: [220, 182, 191, 234, 290, 330, 310], + }, + { + name: 'è‘¡è„', + type: 'line', + stack: 'Total', + data: [150, 232, 201, 154, 190, 330, 410], + }, + { + name: '梨', + type: 'line', + stack: 'Total', + data: [320, 332, 301, 334, 390, 330, 320], + }, + { + name: 'è”æž', + type: 'line', + stack: 'Total', + data: [820, 932, 901, 934, 1290, 1330, 1320], + }, + ], + }, }, { id: 3, label: '3å·', url: require('./element/imgs/carousel-3.jpg'), - option: null, + option: { + color: COLORLIST, + title: { + text: '3å·', + }, + tooltip: { + trigger: 'axis', + axisPointer: { + type: 'shadow', + }, + }, + legend: {}, + grid: { + left: '3%', + right: '4%', + bottom: '3%', + containLabel: true, + }, + xAxis: { + type: 'category', + data: ['Brazil', 'Indonesia', 'USA', 'India', 'China', 'World'], + }, + yAxis: { + type: 'value', + }, + series: [ + { + name: '2011', + type: 'bar', + data: [18203, 23489, 29034, 104970, 131744, 630230], + }, + { + name: '2012', + type: 'bar', + data: [19325, 23438, 31000, 121594, 134141, 681807], + }, + ], + }, }, { id: 4, label: '4å·', url: require('./element/imgs/carousel-4.jpg'), - option: null, - }, - { - id: 5, - label: '5å·', - url: require('./element/imgs/carousel-5.jpg'), - option: null, - }, - { - id: 6, - label: '6å·', - url: require('./element/imgs/carousel-2.jpg'), - option: null, + option: { + color: COLORLIST, + title: { + text: '4å·', + }, + tooltip: { + trigger: 'item', + }, + series: [ + { + type: 'pie', + radius: [20, 120], + center: ['50%', '50%'], + roseType: 'area', + itemStyle: { + borderRadius: 8, + }, + data: [ + { value: 40, name: 'rose 1' }, + { value: 38, name: 'rose 2' }, + { value: 32, name: 'rose 3' }, + { value: 30, name: 'rose 4' }, + { value: 28, name: 'rose 5' }, + { value: 26, name: 'rose 6' }, + { value: 22, name: 'rose 7' }, + { value: 18, name: 'rose 8' }, + ], + }, + ], + }, }, ]; @@ -76,13 +185,12 @@ export const WarpTestData = [ export const WarpTestData2 = [ { id: 1, - label: '1å·-å˜äº†1', + label: '1å·', url: require('./element/imgs/carousel-1.jpg'), option: { + color: COLORLIST, title: { - text: '图表轮æ’图测试数æ®2', - subtext: '666', - left: 'center', + text: '1å·-测试数æ®2', }, tooltip: { trigger: 'item', @@ -90,58 +198,232 @@ export const WarpTestData2 = [ legend: { orient: 'vertical', left: 'left', + top: 'bottom', }, series: [ { - name: 'Access From', type: 'pie', - radius: '50%', data: [ - { value: 1000, name: 'Search Engine' }, - { value: 1000, name: 'Direct' }, - { value: 1000, name: 'Email' }, - { value: 1000, name: 'Union Ads' }, - { value: 1000, name: 'Video Ads' }, + { value: 1048, name: '苹果' }, + { value: 735, name: '香蕉' }, + { value: 580, name: 'è‘¡è„' }, + { value: 484, name: '梨' }, + { value: 300, name: 'è”æž' }, ], - emphasis: { - itemStyle: { - shadowBlur: 10, - shadowOffsetX: 0, - shadowColor: 'rgba(0, 0, 0, 0.5)', - }, - }, }, ], }, }, { id: 2, - label: '2å·-å˜äº†1', + label: '2å·', url: require('./element/imgs/carousel-2.jpg'), - option: null, + option: { + color: COLORLIST, + title: { + text: '2å·-测试数æ®2', + }, + tooltip: { + trigger: 'axis', + }, + legend: { + data: ['苹果', '香蕉', 'è‘¡è„', '梨', 'è”æž'], + }, + xAxis: { + type: 'category', + boundaryGap: false, + data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'], + }, + yAxis: { + type: 'value', + }, + series: [ + { + name: '苹果', + type: 'line', + stack: 'Total', + data: [990, 1000, 1200, 800, 90, 230, 210], + }, + { + name: '香蕉', + type: 'line', + stack: 'Total', + data: [500, 200, 100, 700, 290, 330, 310], + }, + { + name: 'è‘¡è„', + type: 'line', + stack: 'Total', + data: [400, 300, 90, 750, 190, 330, 410], + }, + { + name: '梨', + type: 'line', + stack: 'Total', + data: [450, 220, 88, 680, 390, 330, 320], + }, + { + name: 'è”æž', + type: 'line', + stack: 'Total', + data: [550, 250, 120, 600, 1290, 1330, 1320], + }, + ], + }, }, { id: 3, - label: '3å·-å˜äº†1', + label: '3å·-测试数æ®2', url: require('./element/imgs/carousel-3.jpg'), - option: null, + option: { + color: COLORLIST, + title: { + text: '3å·-测试数æ®2', + }, + tooltip: { + trigger: 'axis', + axisPointer: { + type: 'shadow', + }, + }, + legend: {}, + grid: { + left: '3%', + right: '4%', + bottom: '3%', + containLabel: true, + }, + xAxis: { + type: 'category', + data: ['一月', '二月', '三月', '四月', '五月', 'å…æœˆ'], + }, + yAxis: { + type: 'value', + }, + series: [ + { + name: '陿°´', + type: 'bar', + data: [6000, 7000, 6500, 5800, 7000, 10000], + }, + { + name: '光照', + type: 'bar', + data: [10000, 9000, 8000, 7000, 10000, 12000], + }, + ], + }, }, { id: 4, - label: '4å·-å˜äº†1', + label: '4å·', url: require('./element/imgs/carousel-4.jpg'), - option: null, + option: { + color: COLORLIST, + title: { + text: '4å·-测试数æ®2', + }, + tooltip: { + trigger: 'item', + }, + series: [ + { + type: 'pie', + radius: [20, 120], + center: ['50%', '50%'], + roseType: 'area', + itemStyle: { + borderRadius: 8, + }, + data: [ + { value: 50, name: '周一' }, + { value: 60, name: '周二' }, + { value: 65, name: '周三' }, + { value: 75, name: '周四' }, + { value: 100, name: '周五' }, + { value: 120, name: '周å…' }, + { value: 80, name: '周日' }, + ], + }, + ], + }, + }, + { + id: 5, + label: '5å·', + url: require('./element/imgs/carousel-4.jpg'), + option: { + color: COLORLIST, + title: { + text: '5å·-测试数æ®2', + }, + xAxis: {}, + yAxis: {}, + series: [ + { + symbolSize: 20, + data: [ + [10.0, 8.04], + [8.07, 6.95], + [13.0, 7.58], + [9.05, 8.81], + [11.0, 8.33], + [14.0, 7.66], + [13.4, 6.81], + [10.0, 6.33], + [14.0, 8.96], + [12.5, 6.82], + [9.15, 7.2], + [11.5, 7.2], + [3.03, 4.23], + [12.2, 7.83], + [2.02, 4.47], + [1.05, 3.33], + [4.05, 4.96], + [6.03, 7.24], + [12.0, 6.26], + [12.0, 8.84], + [7.08, 5.82], + [5.02, 5.68], + ], + type: 'scatter', + }, + ], + }, + }, +]; + +// 图表轮æ’图测试数æ®3 +export const WarpTestData3 = [ + { + id: 1, + label: '1å·', + url: require('./element/imgs/carousel-1.jpg'), + option: { + color: COLORLIST, + title: { + text: '1å·-测试数æ®3', + }, + tooltip: { + trigger: 'item', + }, + legend: { + orient: 'vertical', + left: 'left', + top: 'bottom', + }, + series: [ + { + type: 'pie', + data: [ + { value: 100, name: 'A' }, + { value: 200, name: 'B' }, + { value: 300, name: 'C' }, + { value: 400, name: 'D' }, + { value: 500, name: 'E' }, + ], + }, + ], + }, }, - // { - // id: 5, - // label: '5å·-å˜äº†1', - // url: require('./element/imgs/carousel-5.jpg'), - // option: null, - // }, - // { - // id: 6, - // label: '6å·-å˜äº†1', - // url: require('./element/imgs/carousel-2.jpg'), - // option: null, - // }, ]; diff --git a/src/modules/page6/element/CarouselWarp.vue b/src/modules/page6/element/CarouselWarp.vue index fe3dc1ef396255f0b9829531e8bcb8b96ce9a09f..111ff23958ebe3e81a3506ab1bdfabef0c7c7fcc 100644 --- a/src/modules/page6/element/CarouselWarp.vue +++ b/src/modules/page6/element/CarouselWarp.vue @@ -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(() => { - initData(); - }, 3000); + test111(); + initData(); }); 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;