echarts柱图自定义为硬币堆叠的形式

时间:2022-08-23 20:21:48

看这标题,可能会有一些人不太明白,那么直接上图,就是柱图展示形式如下图(兼容IE8)

echarts柱图自定义为硬币堆叠的形式

要想实现这样展示效果。我们想用echarts直接实现不行的,即使是纹理填充也不可行的,但是我们可以借助echarts柱图展示来进行二次操作来现实。那么如何实现呢?

下面我们开始讲解:

1.思路:

从设计图中,我们要知道蓝色部分随着值的变化而变化,而灰色部分高度是不变的。

我们可以通过把柱图的透明度设为0,然后获取每根柱图的高度,每根柱图的位置,然后创建一个元素,把获取到每根柱图的高度和位置赋给这个元素,通过设置元素背景图片填充样式来实现

2.根据上面的思路,那就开始着手了,直接上代码

先把样式设置好:

    <style>
        *{margin: 0;padding: 0;}
        .bar-p,.bar-g{
            position: absolute;
            z-index: 9999;
            width:22px ;/*柱图的宽度*/
        }
        .bar-p>span,.bar-g>span{
            position: absolute;
            left: 50%;
            width: 80px;
            text-align: center;
            margin-left: -40px;
            margin-top: -18px;
        }
        .bar-g>span{
            color: #808182;
        }
        .bar-p>span{
            color: #0b7cd1;
        }
        .bar-p{background: url("../img/bar.png") repeat-y 50% 100%;}
        /*灰色的在这里高度是固定的,不管多大值*/
        .bar-g{background: url("../img/bar1.png") no-repeat 50% 100%;height: 5px!important;}
    </style>

html和js代码:

<div id="main" style="width: 60%; height: 500px;margin:10px auto;"></div>
    <script>
        /*
        * @echarts3版本:v3.2.2
        * */
        var option=null,xAxisData=[],numData=[],numData1=[];
        for(var i=1;i<9;i++){
            xAxisData.push('币种'+i);
            if(i>=6) numData[i-1]=-10;
            else numData[i-1]=i*20;
            numData1[i-1]=Math.abs(numData[i-1]);
        }
        option = {
            color: ['#3398DB'],
            tooltip : {
                trigger: 'item',
                formatter:'{b}:{c}',
                axisPointer : {            // 坐标轴指示器,坐标轴触发有效
                    type : 'shadow'        // 默认为直线,可选为:'line' | 'shadow'
                }
            },
            grid: {
                left: '3%',
                right: '4%',
                bottom: '3%',
                containLabel: true
            },
            xAxis : [
                {
                    type : 'category',
                    data : xAxisData,
                    axisLine:{
                        lineStyle:{
                            color:'#ccc'
                        }
                    },
                    axisTick:false // 坐标轴刻度不显示的话直接这样
                }
            ],
            yAxis : [
                {
                    type : 'value',
                    axisLabel:{
                        show:false
                    },
                    splitLine:{
                        lineStyle:{
                            color:'#ddd'
                        }
                    },
                    axisLine:{
                        show:false
                    },
                    axisTick:false // 坐标轴刻度不显示的话直接这样
                }
            ],
            series : [
                {
                    type:'bar',
                    barWidth: 22,
                    data:numData1,
                    itemStyle:{
                        normal:{
                            opacity:0
                        }
                    }
                }
            ]
        };
        var myChart = echarts.init(document.getElementById('main'));
        // 使用刚指定的配置项和数据显示图表。
        myChart.setOption(option);
        /*
        * getModel() echarts模型的获取
        * getSeriesByIndex(i) 这个i表示series的下标,现在的series只有一个 所以直接是0
        * */
        var model=myChart.getModel(),
            layer=model.getSeriesByIndex(0),
            layouts=layer._data._itemLayouts;// 获取每根柱图的位置和高度和宽度
        var div=document.getElementById('main').getElementsByTagName('div')[0]; // 获得div
        var elem,height=document.getElementById('main').offsetHeight,bottom=height-layouts[0]['y'];
        for(var i= 0,len=layouts.length;i<len;i++){
            elem=document.createElement('div');
            if(numData[i]<0) elem.className='bar-g';
            else elem.className='bar-p';
            elem.style.bottom=bottom+'px';
            elem.style.left=layouts[i]['x']+'px';
            elem.style.height=Math.abs(layouts[i]['height'])+'px';
            elem.innerHTML='<span>'+numData[i]+'</span>';
            div.appendChild(elem);
        }
    </script>

 

运行结果如下:

echarts柱图自定义为硬币堆叠的形式

其实上面的js代码是实现了这个效果,但是有一个问题,就是for循环输出div的,每次循环都是从document中创建一个div,其实这样是不可取的,而且每次都要设置样式!

所以我们应该通过从innerHTML来输出会更好,因为我们的代码就是要简洁、性能优化得最好、条理清晰,更少的代码做更多的事情等!

所以我们要改成下面这样的:

 

 

<script>
        /*
        * @echarts3版本:v3.2.2
        * */
        var option=null,xAxisData=[],numData=[],numData1=[];
        for(var i=1;i<9;i++){
            xAxisData.push('币种'+i);
            if(i>=6) numData[i-1]=-10;
            else numData[i-1]=i*20;
            numData1[i-1]=Math.abs(numData[i-1]);
        }
        option = {
            color: ['#3398DB'],
            tooltip : {
                trigger: 'item',
                formatter:'{b}:{c}',
                axisPointer : {            // 坐标轴指示器,坐标轴触发有效
                    type : 'shadow'        // 默认为直线,可选为:'line' | 'shadow'
                }
            },
            grid: {
                left: '3%',
                right: '4%',
                bottom: '3%',
                containLabel: true
            },
            xAxis : [
                {
                    type : 'category',
                    data : xAxisData,
                    axisLine:{
                        lineStyle:{
                            color:'#ccc'
                        }
                    },
                    axisTick:false // 坐标轴刻度不显示的话直接这样
                }
            ],
            yAxis : [
                {
                    type : 'value',
                    axisLabel:{
                        show:false
                    },
                    splitLine:{
                        lineStyle:{
                            color:'#ddd'
                        }
                    },
                    axisLine:{
                        show:false
                    },
                    axisTick:false // 坐标轴刻度不显示的话直接这样
                }
            ],
            series : [
                {
                    type:'bar',
                    barWidth: 22,
                    data:numData1,
                    itemStyle:{
                        normal:{
                            opacity:0
                        }
                    }
                }
            ]
        };
        var myChart = echarts.init(document.getElementById('main'));
        // 使用刚指定的配置项和数据显示图表。
        myChart.setOption(option);
        /*
        * getModel() echarts模型的获取
        * getSeriesByIndex(i) 这个i表示series的下标,现在的series只有一个 所以直接是0
        * */
        var model=myChart.getModel(),
            layer=model.getSeriesByIndex(0),
            layouts=layer._data._itemLayouts;// 获取每根柱图的位置和高度和宽度
        var div=document.getElementById('main').getElementsByTagName('div')[0]; // 获得div
        var elem="",height=document.getElementById('main').offsetHeight,bottom=height-layouts[0]['y'];
        for(var i= 0,len=layouts.length;i<len;i++){
            elem+='<div class="'+(numData[i]<0?'bar-g':'bar-p')+
            '"style="bottom:'+bottom+'px;left:'+layouts[i]['x']+'px;height:'+Math.abs(layouts[i]['height'])+'px;">'+
            '<span>'+numData[i]+'</span>'+
            '</div>';
        }
        div.appendChild(document.createElement('div'));
        div.getElementsByTagName('div')[0].innerHTML=elem;
    </script>

运行结果如下:

echarts柱图自定义为硬币堆叠的形式