ECharts饼图实现引导线结尾加空心圆环

967 阅读3分钟

首先上结果图:

image.png 设计给的样例图里每个折线结尾有一个空心环, echarts原生是没有这个设置的参数的,需要用series.label.rich 使用富文本加入一个空内容,空内容画一个边框,边框画圆,再用padding微调所有的位置,从而实现环与线连接. 需要注意ECharts V5和V4相同代码会导致结果不同, padding正负号两个版本处理不一致,

ECharts V5 代码

html代码如下:

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title>ECharts Pie Chart</title>
    <!-- Include ECharts library -->
    <script src="https://cdn.jsdelivr.net/npm/echarts/dist/echarts.min.js"></script>
    <!-- <script src="https://cdn.jsdelivr.net/npm/echarts@4.3.0/dist/echarts.min.js"></script> -->
</head>

<body>
    <!-- Prepare a DOM container with a defined width and height -->
    <div id="main" style="width: 800px; height: 600px;"></div>
    <script>
        // Initialize the echarts instance based on the prepared DOM
        var chartDom = document.getElementById('main');
        var myChart = echarts.init(chartDom);
        var option;

        option = {
            tooltip: {
                trigger: 'item'
            },
            legend: {
                orient: 'vertical',
                left: 'left'
            },
            series: [
                {
                    name: '样例',
                    type: 'pie',
                    radius: ['40%', '70%'],
                    avoidLabelOverlap: false,
                    label: {
                        show: true,
                        position: 'outside',
                        formatter: '{a|{b}:{c}}\n{before|}{circle|}{after|}',
                        rich: {
                            before:{
                                padding:[0,-5,0,0],
                            },
                            after:{
                                padding:[0,0,0,-5]
                            },
                             circle: {
                                backgroundColor: 'transparent',//背景透明
                                borderColor: 'auto',//环颜色等于对应的部分颜色
                                borderRadius: 20, //环的半径
                                borderWidth: 1, //环的宽度
                                width: 20, //强制撑开内容
                                height: 20,
                            },
                            a: {
                            	lineHeight: 0, //自动让环回中心
                                fontSize: 14,
                                color: '#000',
                                padding: [0, 20, -20, 20]
                            }
                        }
                    },
                    emphasis: {
                        itemStyle: {
                            shadowBlur: 10,
                            shadowOffsetX: 0,
                            shadowColor: 'rgba(0, 0, 0, 0.5)'
                        }
                    },
                    data: [
                        { value: 100, name: '直接访问' },
                        { value: 200, name: '邮件营销' },
                        { value: 300, name: '联盟广告' },
                        { value: 400, name: '视频广告' }
                    ]
                }
            ]
        };

        option && myChart.setOption(option);
    </script>
</body>
</html>

代码详解: formatter: '{a|{b}:{c}}\n{before|}{circle|}{after|}'设置两部分,前半边是展示的文本,后半边是环的实现, 用\n换行实现把让后面的环紧贴折线头, 必须有换行,不然在一行里label在左右就效果不同. 左右部分可以交换,需要调整a.padding的上下. ECcharts的padding很奇怪,差一些就偏了很多.

先设置circle的样式, 看代码注释, 边框强制撑开后设置颜色, 背景颜色透明就是环了,circle不应该特殊设置padding,因为是用框来画的,padding多了就导致成椭圆.

再设置padding来调整两部分的位置.首先是环的, 这里用了before和after来包围环, before处理左边,after处理右边, 负padding实现环向左右偏移, 因为里面是空文本,所以负数就意味着偏移.

之后处理a内容,lineHeight设置为0后不会让文本消失,因为换行了, 所以环会自动占据中央; 下padding设置负的实现文本向下移动, 和文本大小相关,微调实现文本正对折线(也可以用上padding). 左右padding根据环的大小设置.

ECharts V4 代码

V4效果和V5有些许差异, a.padding的下padding是正的才向下移动

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title>ECharts Pie Chart</title>
    <!-- Include ECharts library -->
    <!--<script src="https://cdn.jsdelivr.net/npm/echarts/dist/echarts.min.js"></script>-->
    <script src="https://cdn.jsdelivr.net/npm/echarts@4.3.0/dist/echarts.min.js"></script>
</head>

<body>
    <!-- Prepare a DOM container with a defined width and height -->
    <div id="main" style="width: 800px; height: 600px;"></div>
    <script>
        // Initialize the echarts instance based on the prepared DOM
        var chartDom = document.getElementById('main');
        var myChart = echarts.init(chartDom);
        var option;

       option = {
            tooltip: {
                trigger: 'item'
            },
            legend: {
                orient: 'vertical',
                left: 'left'
            },
            series: [
                {
                    name: '样例',
                    type: 'pie',
                    radius: ['40%', '70%'],
                    avoidLabelOverlap: false,
                    label: {
                        show: true,
                        position: 'outside',
                        formatter: '{a|{b}:{c}}\n{before|}{circle|}{after|}',
                        rich: {
                            before: {
                                padding: [0, -5, 0, 0],
                            },
                            after: {
                                padding: [0, 0, 0, -5]
                            },
                            circle: {
                                backgroundColor: 'transparent',//背景透明
                                borderColor: 'auto',//环颜色等于对应的部分颜色
                                borderRadius: 20, //环的半径
                                borderWidth: 1, //环的宽度
                                width: 20, //强制撑开
                                height: 20,

                            },
                            a: {
                                lineHeight: 0,
                                fontSize: 14,
                                color: '#000',
                                padding: [0, 20, 20, 20]
                            }
                        }
                    },
                    emphasis: {
                        itemStyle: {
                            shadowBlur: 10,
                            shadowOffsetX: 0,
                            shadowColor: 'rgba(0, 0, 0, 0.5)'
                        }
                    },
                    data: [
                        { value: 100, name: '直接访问' },
                        { value: 200, name: '邮件营销' },
                        { value: 300, name: '联盟广告' },
                        { value: 400, name: '视频广告' }
                    ]
                }
            ]
        };

        option && myChart.setOption(option);
    </script>
</body>

</html>