echarts实践总结(常用三):圆环(特点:圆环、多层嵌套的间隙、标题问题解决)

本文详细介绍了Echarts库中圆环和多圆环嵌套的实践,包括配置项详解、解决空格问题、高亮功能、数据处理和间隔调整技巧,帮助读者理解和实现类似效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

第一章 基本使用

第二章  echarts实践——圆环

2.1 前言

2.1 正常圆环

2.2 多个圆环嵌套(间隔的另外一种处理方式)


  • 效果展示——圆环

  • 效果展示——多圆环嵌套

第一章 基本使用

Echarts常用配置项(详细入门)_echarts配置项手册-CSDN博客

第二章  echarts实践——圆环

  • html部分
<div class="bar" style="width: 1000px;height: 500px;">
   <!-- 圆环 -->
   <div id="handlerView" style="width: 100%;height: 100%;"></div>
</div>

2.1 前言

  • 百度时,我们查询这类效果图时,会遇到各种各样的解决方案,但是当我们放到自己项目时总会觉得达不到自己想要的效果,接下来小编通过两部分来解决有空格的圆环在什么情况下使用什么方法。

2.1 正常圆环

  • 解决问题1:如果时一个圆环的情况下,我们想要插入空格只需要使用这种描边效果即可,配置api如下
itemStyle: { 
    borderWidth: 5, // 描边线宽,为 0 时无描边。
    borderColor: '#FFFFFF' // 描边线颜色
},
  • 解决问题2:高亮问题,说明如下
// highlight 高亮指定的数据图形
dispatchAction({
    type: 'highlight',
    // 可选,系列 index,可以是一个数组指定多个系列
    seriesIndex?: number|Array,
    // 可选,系列名称,可以是一个数组指定多个系列
    seriesName?: string|Array,
    // 可选,数据的 index
    dataIndex?: number,
    // 可选,数据的 名称
    name?: string
})
// downplay 取消高亮指定的数据图形
dispatchAction({
    type: 'downplay',
    // 可选,系列 index,可以是一个数组指定多个系列
    seriesIndex?: number|Array,
    // 可选,系列名称,可以是一个数组指定多个系列
    seriesName?: string|Array,
    // 可选,数据的 index
    dataIndex?: number,
    // 可选,数据的 名称
    name?: string
})
  • 详细配置如下:(使用源码可以先拷贝下来针对点改,每一个配置项都有详细说明) 
    <script src="./base_js/echarts.min.js"></script>
    <script>
        const roseViewDom = document.getElementById('handlerView')

        const roseChart = echarts.init(roseViewDom)
        // 定义了内部圆渐变颜色信息
        const innerGradient = new echarts.graphic.RadialGradient(0.5, 0.5, 0.5, [
            { offset: 0, color: '#F6F9FF' },
            { offset: 0.91, color: '#F6F9FF' },
            { offset: 0.91, color: 'rgba(108, 137, 195, 0.01)' },
            { offset: 1, color: 'rgba(108, 137, 195, 0.30)' }
        ])
        const ROSE_DATA = [ // 数据格式
            {
                value: 5000,
                rate: 25,
                name: '王者荣耀',
                color: '#6ECDF9'
            },
            {
                value: 4300,
                rate: 22,
                name: '蛋仔派对',
                color: '#65B3FF'
            },
            {
                value: 3000,
                rate: 17,
                name: '刺激战场',
                color: '#5A93FC'
            },
            {
                value: 2867,
                rate: 15,
                name: '第五人格',
                color: '#9A86F3'
            },
            {
                value: 2167,
                rate: 13,
                name: '部落冲突',
                color: '#EB918E'
            },
            {
                value: 1876,
                rate: 9,
                name: '帝国时代',
                color: '#EFAD76'
            }
        ]
        // 当前索引值
        let currentIndex = 0
        const chartOptions = {
            tooltip: { // 提示框组件
                trigger: 'item' // 数据项图形触发
            },
            legend: { // 图例组件
                show: false // 不展示
            },
            series: [
                {
                    type: 'pie', // 类型
                    radius: ['75%', '90%'], // 饼图展示部分
                    avoidLabelOverlap: false, // 是否启用防止标签重叠策略
                    padAngle: 5, // 饼图扇区之间的间隔角度
                    itemStyle: { 
                        borderWidth: 5, // 描边线宽,为 0 时无描边。
                        borderColor: '#FFFFFF' // 描边线颜色
                    },
                    label: { // 饼图图形上的文本标签,可用于说明图形的一些数据信息
                        show: false, // 是否展示labe标签
                        position: 'center', // 标签的位置
                        formatter: (params) => { // 自定义标签内容:标签内容格式器,支持字符串模板和回调函数两种形式,字符串模板与回调函数返回的字符串均支持用 \n 换行。
                            const { rate, name } = params.data
                            return `
{rate|${rate}%}

{name|${name}}
        `
                        },
                        rich: { // 自定义富文本样式:与formatter同名设置
                            rate: {
                                fontWeight: 'bold',
                                fontSize: '24',
                                color: '#333333'
                            },
                            name: {
                                fontWeight: '500',
                                fontSize: '14',
                                color: '#666666'
                            }
                        }
                    },
                    labelLine: { // 标签的视觉引导线配置
                        show: false
                    },
                    emphasis: { // 高亮状态的扇区和标签样式
                        label: { // 标签样式
                            show: true
                        }
                    },
                    data: ROSE_DATA.map(item => { // 数据
                        return { ...item, itemStyle: { color: item.color } }
                    })
                },
                {
                    type: 'pie',
                    color: innerGradient,
                    radius: ['0%', '65%'],
                    emphasis: {
                        disabled: true // 是否关闭高亮状态
                    },
                    tooltip: { // 提示框组件
                        show: false
                    },
                    data: [
                        { value: 0, itemStyle: { color: innerGradient } }
                    ]
                }
            ]
        }
        // 使用刚指定的配置项和数据显示图表。
        chartOptions && roseChart.setOption(chartOptions)
        roseChart.resize()
        window.addEventListener('resize', () => {
            roseChart.resize()
        })
        // 设置高亮 --- 高亮指定的数据图形
        roseChart.dispatchAction({
            type: 'highlight', 
            seriesIndex: 0, // series 数据数组第几个
            dataIndex: currentIndex // 可选,数据的 index
        })
        roseChart.on('mouseover', e => {
            if (e.seriesIndex != 0) {
                return
            }
            //取消默认高亮
            roseChart.dispatchAction({
                type: 'downplay', // 取消高亮指定的数据图形
                seriesIndex: 0,
                dataIndex: currentIndex
            })
            currentIndex = e.dataIndex //将当前高亮的序号记录下来
            //鼠标悬停位置高亮
            roseChart.dispatchAction({
                type: 'highlight',
                seriesIndex: e.seriesIndex,
                dataIndex: e.dataIndex
            })
        })
    </script>

2.2 多个圆环嵌套(间隔的另外一种处理方式)

  • 问题解释:如果是多个圆环嵌套,那么当我们再使用上面那种方法时,效果如下:

这种方法的弊端就是外圆环与内圆环之间有间隔(如果大家的需求是这样的,那么知道上面那一方法即可,小编需求是后续的这种思路,与效果图一样,圆环与圆环之前嵌套,且他们之间没有间隔) 

  • 思路:(具体解决一定要看小编的源代码,都做了详细的说明)
  1. 了解圆环的我们都知道,圆环的每一个图形都是通过值渲染上的,那么我们是不是也可以对原来的的数据重新修改呢;其次,为了与后端配合,一般后端是不会给我们传一些没用的数据的,所以我们又如何处理数据呢?——小编的解决方法是先拿到后端传的值,然后在前端自己先处理数据,对每一个数据之间添加空格,表示我们之后需要渲染出空隙
  2. 先做初步修改,然后在配置项处理好之后再对数据结构处理,添加对象、值多大(空隙要展示多大)、颜色要透明(空隙没有颜色)
  • 遇到的问题解决:

1、解决文本标签居中展示——这里有两种方法,方法一:利用title配置项设置文本文字,然后通过left、top定位的方式将他们定位到大致居中的地方(缺点:当我们图表大小随着页面发生变化时,这个布局也可以会发生变化);方法二:利用label配置项的position定位实现,实现方法在后续代码中(小编对比两个,最终更倾向于方法二

文本居中方法一——

文本居中方法二—— 

 2、解决高亮展示问题,该方法与2.2圆环解决方法一样

3、解决前端自己配置的数据,鼠标移入数据展示的问题——方法:小编最终通过定义全局值实现,如果是鼠标滑过自己定义的圆环块,直接不计算,沿用上一次有效数据的值

  • 问题效果展示:

  •  最终代码,以及详细说明——
<script src="./base_js/echarts.min.js"></script>
<script>
const channelViewDom = document.getElementById('handlerView')
let channelChart = echarts.init(channelViewDom)
const CHANNEL_DATA = [{ // 数据格式
    name: '大厅办件',
    value: 8300
}, {
    name: '网上办件',
    value: 3000
}]
const channel_first_name = CHANNEL_DATA[0].name // 拿到第一个数据的name
let channel_total = 0 // 数据总数初始值
CHANNEL_DATA.forEach((item, index) => { // 计算数据总数
    channel_total += Number(item.value)
})
const channel_first_percent = Number((Number(CHANNEL_DATA[0].value) / channel_total).toFixed(2)) * 100 + '%' // 计算第一个数据的占比
let CHANNEL_COLOR_LIST1 = ['#FAAF45', '#5A93FC'] // 后续设置颜色的数组
let channelColorEle = ''
CHANNEL_COLOR_LIST1 = dealData(CHANNEL_COLOR_LIST1, channelColorEle) // 处理颜色数据,对每一个数据之间添加空格,后续图标有对应的颜色赋值空隙展示
let CHANNEL_COLOR_LIST2 = ['#F3ECE3', '#DBE8FF'] 
CHANNEL_COLOR_LIST2 = dealData(CHANNEL_COLOR_LIST2, channelColorEle)
let channelOption = {
    backgroundColor: '#F2F7FF', // 背景色
    legend: { // 图例组件
        left: '50%', // 图例组件离容器左侧的距离
        top: 'center', // 图例组件离容器顶部的距离
        selectedMode: false, // 图例选择的模式,控制是否可以通过点击图例改变系列的显示状态
        formatter: function (name) { // 自定义图例文本
            let total = 0
            let target
            for (let i = 0; i < CHANNEL_DATA.length; i++) {
                total += CHANNEL_DATA[i].value
                if (CHANNEL_DATA[i].name === name) {
                    target = CHANNEL_DATA[i].value
                }
            }
            let arr = [name, target]
            return `{a|${name}}{b| ${target} }{c| ${'个'}}`
        },
        textStyle: { // 图例的公用文本样式。
            rich: { // 自定义用来格式化图例文本样式
                a: {
                    color: '#666666',
                    fontSize: 14
                },
                b: {
                    color: '#666666',
                    fontSize: 16,
                    fontWeight: 'bold'
                },
                c: {
                    color: '#999999',
                    fontSize: 12
                }
            }
        }
    },
    series: [
        {
            name: '外圆',
            type: 'pie',
            radius: ['50%', '60%'],
            center: ['27%', '50%'],
            data: CHANNEL_DATA,
            position: 'outside',
            minAngle: 5, // 最小的扇区角度(0 ~ 360),用于防止某个值过小导致扇区太小影响交互
            color: [ // 文本颜色
                '#5A93FC',
                '#4FD1FF'
            ],
            labelLine: { // 标签的视觉引导线配置
                show: false
            },
            label: { // 饼图图形上的文本标签,可用于说明图形的一些数据信息
                show: true, // 是否展示
                position: 'center', // 标签的位置 
                formatter: (params) => { // 自定义标签内容
                    return `
{rate|${channel_first_percent}
{name|${channel_first_name}}
        `
                },
                rich: { // 自定义标签文本样式
                    rate: {
                        fontWeight: 'bold',
                        fontSize: '20',
                        color: '#5A93FC'
                    },
                    name: {
                        fontWeight: '500',
                        fontSize: '14',
                        color: '#666666'
                    }
                }
            },
            itemStyle: { // 图形样式
                color: function (params) {
                    return CHANNEL_COLOR_LIST1[params.dataIndex]
                },
            },
            z: 666
        },
        {
            name: '内圆',
            type: 'pie',
            silent: true,
            radius: ['40%', '55%'],
            center: ['27%', '50%'],
            data: CHANNEL_DATA,
            minAngle: 5,
            hoverAnimation: false,
            labelLine: {
                show: false
            },
            label: {
                show: false
            },
            emphasis: {
                scale: false,
            },
            itemStyle: {
                color: function (params) {
                    return CHANNEL_COLOR_LIST2[params.dataIndex]
                }
            },
            z: 1
        },
    ]
}
// 重新对option赋值解决圆环间隔问题
// 数据总数
const channelSum = channelOption.series[0].data.reduce((pre, cur) => {
    return pre + cur.value
}, 0)
// 计算插入间隔值的范围
const channelVal = channelSum / 100
for (let s of channelOption.series) {
    let channelEle = { // 要插入的颜色
        name: '', value: channelVal, itemStyle: { color: 'transparent' }
    }
    s.data = dealData(s.data, channelEle) // 重新赋值
}
channelOption && channelChart.setOption(channelOption)
// 处理高亮效果
let currentIndex = 0 //设置初始高亮索引为0的图形
channelChart.dispatchAction({ // 高亮初始记录
    type: 'highlight',
    seriesIndex: 0,
    dataIndex: currentIndex
})
let value = 0 // 记录值
let name = '' // 记录名
channelChart.on('mouseover', (params) => { // 鼠标移入事件
    if( params.data.name !== '' ){ // 只要不是我们为了添加空袭而添加的数据都进行统计,否则不统计,防止鼠标移入时出现的造的假数据的展示
        name = params.data.name
        value = Math.round((Number(params.data.value) / channelSum) * 100)
    }
    channelChart.setOption({ // 数据更新
        series: [
            {
                name: '外圆',
                label: {
                    show: false,
                    formatter: (params) => {
                        return `
{rate|${value}%
{name|${name}}
        `
                    },
                    rich: {
                        rate: {
                            fontWeight: 'bold',
                            fontSize: '20',
                            color: '#5A93FC'
                        },
                        name: {
                            fontWeight: '500',
                            fontSize: '14',
                            color: '#666666'
                        }
                    }
                },
            },
        ]
    })
    // 处理高亮效果
    // 取消默认高亮
    channelChart.dispatchAction({
        type: 'downplay',
        seriesIndex: 0,
        dataIndex: currentIndex,
    })
    channelChart.dispatchAction({
        type: 'highlight',
        seriesIndex: params.seriesIndex,
        dataIndex: params.dataIndex
    })
    currentIndex = params.dataIndex//将当前高亮的序号记录下来//鼠标县停位置高亮
})
// 处理圆环数据每个数组添加空格
function dealData(data, ele) {
    return data.map((item, index) => {
        return [item, ele]
    }).flat()
}
</script>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值