<script setup lang="ts"> import { ref, reactive, onMounted, onUnmounted } from 'vue'; import * as echarts from 'echarts'; type EChartsOption = echarts.EChartsOption; type ECharts = echarts.ECharts; const chartClockRef = ref<any>(null); const state = reactive({ timer: null as any, option: null as unknown as EChartsOption, }); onMounted(() => { getChart(); }); onUnmounted(() => { clearTimer(); }); var clockChart: ECharts; function getChart() { if (clockChart != null && clockChart != undefined) { clockChart.dispose(); } clockChart = echarts.init(chartClockRef.value); state.option = { title: { text: '', textAlign: 'center', left: '50%', top: 25, textStyle: { color: '#A25B5B', }, }, series: [ { name: 'hour', type: 'gauge', startAngle: 90, endAngle: -270, min: 0, max: 12, splitNumber: 12, clockwise: true, axisLine: { lineStyle: { width: 11, color: [[1, '#809A6F']], shadowColor: 'rgba(0, 0, 0, 0.5)', shadowBlur: 15, }, }, splitLine: { lineStyle: { color: '#809A6F', shadowColor: 'rgba(0, 0, 0, 0.3)', shadowBlur: 3, shadowOffsetX: 1, shadowOffsetY: 2, }, }, axisTick: { lineStyle: { color: '#809A6F', }, }, axisLabel: { color: '#D5D8B5', fontSize: 35, distance: 25, formatter: function (value) { if (value === 0) { return ''; } return value + ''; }, }, pointer: { icon: 'path://M2.9,0.7L2.9,0.7c1.4,0,2.6,1.2,2.6,2.6v115c0,1.4-1.2,2.6-2.6,2.6l0,0c-1.4,0-2.6-1.2-2.6-2.6V3.3C0.3,1.9,1.4,0.7,2.9,0.7z', width: 11, length: '55%', offsetCenter: [0, '8%'], itemStyle: { color: '#CC9C75', shadowColor: 'rgba(0, 0, 0, 0.3)', shadowBlur: 8, shadowOffsetX: 2, shadowOffsetY: 4, }, }, detail: { show: false, }, title: { offsetCenter: [0, '30%'], }, data: [ { value: 0, }, ], }, { name: 'minute', type: 'gauge', startAngle: 90, endAngle: -270, min: 0, max: 60, clockwise: true, axisLine: { show: false, }, splitLine: { show: false, }, axisTick: { show: false, }, axisLabel: { show: false, }, pointer: { icon: 'path://M2.9,0.7L2.9,0.7c1.4,0,2.6,1.2,2.6,2.6v115c0,1.4-1.2,2.6-2.6,2.6l0,0c-1.4,0-2.6-1.2-2.6-2.6V3.3C0.3,1.9,1.4,0.7,2.9,0.7z', width: 8, length: '70%', offsetCenter: [0, '8%'], itemStyle: { color: '#CC9C75', shadowColor: 'rgba(0, 0, 0, 0.3)', shadowBlur: 8, shadowOffsetX: 2, shadowOffsetY: 4, }, }, anchor: { show: true, size: 20, showAbove: false, itemStyle: { borderWidth: 15, borderColor: '#CC9C75', shadowColor: 'rgba(0, 0, 0, 0.3)', shadowBlur: 8, shadowOffsetX: 2, shadowOffsetY: 4, }, }, detail: { show: false, }, title: { offsetCenter: ['0%', '-40%'], }, data: [ { value: 0, }, ], }, { name: 'second', type: 'gauge', startAngle: 90, endAngle: -270, min: 0, max: 60, animationEasingUpdate: 'bounceOut', clockwise: true, axisLine: { show: false, }, splitLine: { show: false, }, axisTick: { show: false, }, axisLabel: { show: false, }, pointer: { icon: 'path://M2.9,0.7L2.9,0.7c1.4,0,2.6,1.2,2.6,2.6v115c0,1.4-1.2,2.6-2.6,2.6l0,0c-1.4,0-2.6-1.2-2.6-2.6V3.3C0.3,1.9,1.4,0.7,2.9,0.7z', width: 4, length: '85%', offsetCenter: [0, '8%'], itemStyle: { color: '#CC9C75', shadowColor: 'rgba(0, 0, 0, 0.3)', shadowBlur: 8, shadowOffsetX: 2, shadowOffsetY: 4, }, }, anchor: { show: true, size: 15, showAbove: true, itemStyle: { color: '#CC9C75', shadowColor: 'rgba(0, 0, 0, 0.3)', shadowBlur: 8, shadowOffsetX: 2, shadowOffsetY: 4, }, }, detail: { show: false, }, title: { offsetCenter: ['0%', '-40%'], }, data: [ { value: 0, }, ], }, ], }; run(); state.option && clockChart.setOption(state.option); } function run() { if (state.timer) { clearTimer(); } state.timer = setInterval(function () { let date = new Date(); let dateStr = date.toLocaleDateString().replace(/\//g, '-'); let timeStr = date.toLocaleTimeString(); let titleStr = dateStr + ' ' + timeStr; let second = date.getSeconds(); let minute = date.getMinutes() + second / 60; let hour = (date.getHours() % 12) + minute / 60; state.option.animationDurationUpdate = 300; clockChart.setOption<EChartsOption>({ title: { text: titleStr, }, series: [ { name: 'hour', animation: hour !== 0, data: [{ value: hour }], }, { name: 'minute', animation: minute !== 0, data: [{ value: minute }], }, { animation: second !== 0, name: 'second', data: [{ value: second }], }, ], }); }, 1000); } function clearTimer() { clearInterval(state.timer); } </script> <template> <div ref="chartClockRef" class="fit"></div> </template> <style lang="scss" scoped></style>