| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451 |
- <template>
- <div ref="chartRef" :style="{ height, width }"></div>
- </template>
- <script lang="ts">
- import { defineComponent, PropType, ref, Ref, onMounted, reactive, nextTick, onUnmounted } from 'vue';
- import type { EChartsOption } from 'echarts';
- import { useECharts } from '/@/hooks/web/useECharts';
- export default defineComponent({
- props: {
- width: {
- type: String as PropType<string>,
- default: '100%',
- },
- height: {
- type: String as PropType<string>,
- default: 'calc(100vh - 178px)',
- },
- count: {
- type: Number,
- default: 10,
- },
- },
- setup(props) {
- const chartRef = ref<HTMLDivElement | null>(null);
- const { setOptions, echarts, getInstance } = useECharts(chartRef as Ref<HTMLDivElement>);
- const routeTimer = ref(null);
- // const echartInstance = ref();
- function _pie1() {
- let dataArr: any = [];
- for (var i = 0; i < 8; i++) {
- dataArr.push({
- name: (i + 1).toString(),
- value: 20,
- itemStyle: {
- color: 'rgba(88,142,197,0.4)',
- borderWidth: 0,
- borderColor: 'rgba(0,0,0,0)',
- },
- });
- }
- return dataArr;
- }
- function _pie2() {
- let dataArr: any = [];
- for (var i = 0; i < 8; i++) {
- if (i % 2 === 0) {
- dataArr.push({
- name: (i + 1).toString(),
- value: 25,
- itemStyle: {
- color: 'rgba(88,142,197,0.5)',
- borderWidth: 0,
- borderColor: 'rgba(0,0,0,0)',
- },
- });
- } else {
- dataArr.push({
- name: (i + 1).toString(),
- value: 20,
- itemStyle: {
- color: 'rgba(0,0,0,0)',
- borderWidth: 0,
- borderColor: 'rgba(0,0,0,0)',
- },
- });
- }
- }
- return dataArr;
- }
- function _pie3() {
- let dataArr: any = [];
- for (var i = 0; i < 100; i++) {
- if (i % 2 === 0) {
- dataArr.push({
- name: (i + 1).toString(),
- value: 25,
- itemStyle: {
- color: 'rgb(126,190,255)',
- borderWidth: 0,
- borderColor: 'rgba(0,0,0,0)',
- },
- });
- } else {
- dataArr.push({
- name: (i + 1).toString(),
- value: 20,
- itemStyle: {
- color: 'rgba(0,0,0,0)',
- borderWidth: 0,
- borderColor: 'rgba(0,0,0,0)',
- },
- });
- }
- }
- return dataArr;
- }
- function _pieData(data) {
- let _data = data;
- let dataArr: any = [];
- for (var i = 0; i < 5; i++) {
- if (i === 2) {
- let dt = data[0].unit ? 25 : Number(data[0].value);
- dataArr.push({
- name: (i + 1).toString(),
- value: dt,
- itemStyle: {
- color: new echarts.graphic.LinearGradient(0, 1, 1, 0, [
- {
- offset: 0,
- color: 'rgb(147,187,216)',
- },
- {
- offset: 1,
- color: '#588ec5',
- },
- ]),
- borderWidth: 0,
- borderColor: 'rgba(0,0,0,0.4)',
- },
- });
- } else {
- let dta = data[0].unit ? 25 : (1 - Number(data[0].value)) / 4;
- dataArr.push({
- name: (i + 1).toString(),
- value: dta,
- itemStyle: {
- color: 'rgba(0,0,0,0)',
- borderWidth: 0,
- borderColor: 'rgba(0,0,0,0)',
- },
- });
- }
- }
- //console.log(dataArr)
- return dataArr;
- }
- const option = <EChartsOption>reactive({
- backgroundColor: '#0f375f',
- title: [
- {
- text: '各渠道投诉占比',
- left: '2%',
- top: '1%',
- textStyle: {
- color: '#fff',
- fontSize: 14,
- },
- },
- ],
- // tooltip: {
- // // formatter: '{b} ({c})',
- // },
- series: [
- {
- type: 'pie',
- zlevel: 1,
- silent: true,
- /*
- radius
- 饼图的半径。可以为如下类型:
- number:直接指定外半径值。
- string:例如,'20%',表示外半径为可视区尺寸(容器高宽中较小一项)的 20% 长度。
- Array.<number|string>:数组的第一项是内半径,第二项是外半径。每一项遵从上述 number string 的描述。
- */
- radius: ['98%', '97%'],
- animation: false,
- color: 'rgba(88,142,197,0.5)',
- label: {
- show: false,
- },
- labelLine: {
- show: false,
- },
- // data: _pie1(),
- data: [1],
- },
- {
- type: 'pie',
- zlevel: 2,
- silent: true,
- radius: ['90%', '91%'],
- startAngle: 50,
- animation: false,
- label: {
- show: false,
- },
- labelLine: {
- show: false,
- },
- data: _pie2(),
- },
- {
- type: 'pie',
- zlevel: 3,
- silent: true,
- radius: ['88%', '87%'],
- label: {
- show: false,
- },
- labelLine: {
- show: false,
- },
- data: _pie2(),
- },
- {
- type: 'pie',
- zlevel: 4,
- silent: true,
- radius: ['84%', '83%'],
- label: {
- show: false,
- },
- labelLine: {
- show: false,
- },
- data: _pie3(),
- },
- {
- type: 'pie',
- zlevel: 5,
- silent: true,
- radius: ['80%', '78%'],
- color: ['#fc8d89', '#46d3f3', 'rgba(203,203,203,.2)'],
- startAngle: 50,
- animation: false,
- label: {
- show: false,
- },
- data: [50, 20, 40],
- },
- {
- name: '',
- type: 'gauge',
- splitNumber: 30, //刻度数量
- min: 0,
- max: 100,
- radius: '73%', //图表尺寸
- center: ['50%', '50%'],
- startAngle: 90,
- endAngle: -269.9999,
- axisLine: {
- show: false,
- lineStyle: {
- width: 0,
- shadowBlur: 0,
- color: [[1, '#0dc2fe']],
- },
- },
- axisTick: {
- show: false,
- lineStyle: {
- color: 'auto',
- width: 2,
- },
- length: 20,
- splitNumber: 5,
- },
- splitLine: {
- show: true,
- length: 32,
- lineStyle: {
- color: 'auto',
- },
- },
- axisLabel: {
- show: false,
- },
- pointer: {
- //仪表盘指针
- show: false,
- },
- detail: {
- show: false,
- },
- },
- {
- name: '统计',
- type: 'gauge',
- splitNumber: 30, //刻度数量
- min: 0,
- max: 100,
- radius: '68%', //图表尺寸
- center: ['50%', '50%'],
- startAngle: 90,
- endAngle: -269.9999,
- axisLine: {
- show: true,
- lineStyle: {
- width: 0,
- shadowBlur: 0,
- color: [
- [0, '#0dc2fe'],
- [1, '#0dc2fe'],
- ],
- },
- },
- axisTick: {
- show: true,
- lineStyle: {
- color: '#0dc2fe',
- width: 2,
- },
- length: 20,
- splitNumber: 5,
- },
- splitLine: {
- show: true,
- length: 20,
- lineStyle: {
- color: '#0dc2fe',
- },
- },
- axisLabel: {
- show: false,
- },
- pointer: {
- //仪表盘指针
- show: false,
- },
- detail: {
- borderColor: '#fff',
- shadowColor: '#fff', //默认透明
- shadowBlur: 2,
- offsetCenter: [0, '0%'], // x, y,单位px
- textBorderColor: '#fff',
- fontSize: 50,
- formatter: '{value}',
- },
- data: [
- {
- name: '',
- value: 1,
- detail: {
- color: '#ffffff99',
- },
- },
- ],
- },
- {
- type: 'pie',
- zlevel: 20,
- silent: true,
- radius: ['60%', '59%'],
- animation: false,
- color: '#2dc0c9',
- // color: '#fff',
- // animation:false,
- data: [1],
- labelLine: {
- show: false,
- },
- },
- {
- name: '中间环形图',
- type: 'pie',
- radius: ['35%', '55%'],
- avoidLabelOverlap: false,
- animation: false,
- itemStyle: {
- color: '#80ADD2',
- borderColor: '#3D4268',
- },
- label: {
- show: false,
- position: 'center',
- },
- emphasis: {
- label: {
- show: true,
- fontSize: '30',
- fontWeight: 'bold',
- },
- },
- labelLine: {
- show: false,
- },
- data: [25, 25, 25, 25, 25, 25],
- },
- ],
- });
- function doing() {
- // option.series[4].startAngle = option.series[4].startAngle - 1;
- // option.series[6].data[0].value = option.series[6].data[0].value + 1;
- const start = props.count - option.series[6].data[0].value;
- let step = 1;
- if (start / 1 < 10) {
- step = 1;
- } else if (start / 1 < 100) {
- step = 10;
- } else if (start / 1 < 1000) {
- step = 100;
- } else if (start / 1 < 10000) {
- step = 1000;
- }
- let timer = setInterval(() => {
- if (props.count > option.series[6].data[0].value) {
- option.series[6].data[0].value += step;
- setOptions(option);
- } else {
- clearInterval(timer);
- timer = null;
- routeTimer.value = setInterval(() => {
- rotate();
- }, 200);
- }
- }, 8);
- }
- function rotate() {
- // option.series[4].startAngle = option.series[4].startAngle - 5;
- // option.series[6].data[0].value = option.series[6].data[0].value + 5;
- // setOptions(option);
- }
- // const timer = <Ref<NodeJS.Timer>>ref();
- // const startTimer = () => {
- // timer.value = setInterval(doing, 1000);
- // };
- // const stopTimer = () => {
- // clearInterval(timer.value);
- // timer.value = null as unknown as NodeJS.Timer;
- // };
- onMounted(() => {
- setOptions(option);
- chartRef.value?.addEventListener('mouseover', () => {
- // startTimer();
- // doing();
- });
- chartRef.value?.addEventListener('mouseout', () => {
- // stopTimer();
- });
- doing();
- });
- onUnmounted(() => {
- clearInterval(routeTimer.value);
- routeTimer.value = null;
- });
- return { chartRef };
- },
- });
- </script>
|