文档章节

Echarts图例legend过多,采用翻页处理

骚年_你渴望力量吗
 骚年_你渴望力量吗
发布于 2017/06/29 18:52
字数 1224
阅读 265
收藏 0

问题:
图例可以跟地图有联动效果,用来当列表使用,与地图有联动效果,简直太棒了,但是echarts图例太多,实在太占用空间,遮挡图表,又无法移动legend层。当屏幕小,满屏幕都是图例呀。。。如下图,头疼。

 

翻阅echarts相关文档,百度,Q群等途径寻找解决方法,都没有得到想要答案。于是鼓起勇气尝试修改源码。
开始的想法是:右边一列,不换行显示,出现滚动条,可以向下滚动。后来研究了echarts源码,觉得在canvas上加滚动条有点困难,所以选择了 向下翻页 的方式。

 

原理

echarts创建legend层是先创建每一条图例,再计算位置,全部渲染出来。发现echarts里一段主要代码,就是这里实现了"图例换行"

// Wrap when width exceeds maxHeight or meet a `newline` group
if (nextY > maxHeight || child.newline) {
    x += currentLineMaxSize + gap;
    y = 0;
    nextY = moveY;
    currentLineMaxSize = rect.width;
}
else {
    currentLineMaxSize = Math.max(currentLineMaxSize, rect.width);
}

那么,是不是可以把 ”换行“ 变成 “换页”! ^.^oh,good idea,get ! 于是这么干!

步骤如下:

为了避免 改动 会引起其他问题。通过自定义新的字段参数控制。
主要需要改动以下几个地方:

1.html页面中改动

我在初始化echarts的div标签下面添加<div class="js-eclegend-tool" style="position: absolute;right: 20px;top: 40%"></div>,用于存放上下翻页按钮,下面会用到。我写在echarts容器下面,css样式决定它的位置,代码如下:

<div class="ibox">
        <!--初始化echarts实例的容器-->
    <div id="eBaiduMap" class="ibox-size" style="width: 100%;"></div>
        <!--用于存放上下翻页按钮.js-eclegend-tool容器,页面中的修改只需增加下面这一句-->
    <div class="js-eclegend-tool" style="position: absolute;right: 20px;top: 40%"></div>
</div>

2.修改option配置

实例化echarts时,修改option配置,即添加pagemode: true,留意注释为//注意的地方

//modify by danhuan
legend: {
    orient: 'vertical', //注意
    right:0,
    top: 0, //注意
    //bottom:0,
    //left:0,
    //width:200,
    pagemode: true, //注意,自定义的字段,开启图例分页模式,只有orient: 'vertical'时才有效
    height:"100%",
    data: legendData,
    itemHeight:18,
    itemWidth: 18,
    textStyle: {
        fontWeight: 'bolder',
        fontSize: 12,
        color:'#fff'
    },
    inactiveColor:'#aaa',
    //padding: [20, 15],
    backgroundColor: 'rgba(0, 0, 0, 0.7)',
    shadowColor: 'rgba(0, 0, 0, 0.5)',
    shadowBlur: 5,
    zlevel: 100
},

3.修改echarts源码,总共两处修改

第一处修改,在源码中找到以下代码:

layout: function (group, componentModel, api) {
                var rect = layout.getLayoutRect(componentModel.getBoxLayoutParams(), {
                    width: api.getWidth(),
                    height: api.getHeight()
                }, componentModel.get('padding'));
                layout.box(
                    componentModel.get('orient'),
                    group,
                    componentModel.get('itemGap'),
                    rect.width,
                    rect.height
                );

                positionGroup(group, componentModel, api);
            },

找到这几行代码,修改为以下代码:

layout: function (group, componentModel, api) {
    var rect = layout.getLayoutRect(componentModel.getBoxLayoutParams(), {
        width: api.getWidth(),
        height: api.getHeight()
    }, componentModel.get('padding'));

    /*modify by danhuan 为了避免影响到其他模块,传参数判断修改 legend 是否要分页  s*/
    if(componentModel.get('pagemode')){//如果 legend 启用分页 modify by danhuan
        layout.box(
            componentModel.get('orient'),
            group,
            componentModel.get('itemGap'),
            rect.width,
            rect.height,
            componentModel.get('pagemode') //modify by danhuan
        );
    }
    if(!componentModel.get('pagemode')){
        layout.box(
            componentModel.get('orient'),
            group,
            componentModel.get('itemGap'),
            rect.width,
            rect.height
        );
    }
    /*modify by danhuan 传参数判断修改 legend 是否要分页  e*/

    positionGroup(group, componentModel, api);
},

这样做的目的是为了将步骤2的自定义参数 pagemode: true 传进echarts ,为了避免有其他方法调用layout方法导致其他图表错误,所以用了判断if(componentModel.get('pagemode')){...},有参数 pagemode: true 时,才会进入改动的代码。

第二处修改:

找到以下代码function boxLayout(orient, group, gap, maxWidth, maxHeight)...截图如下:

将该函数修改为:

function boxLayout(orient, group, gap, maxWidth, maxHeight,pagemode) {
    //console.log(group);
    var x = 0;
    var y = 0;
    if (maxWidth == null) {
        maxWidth = Infinity;
    }
    if (maxHeight == null) {
        maxHeight = Infinity;
    }
    var currentLineMaxSize = 0;
    group.eachChild(function (child, idx) {
        //console.log(child, idx);

        var position = child.position;
        var rect = child.getBoundingRect();
        var nextChild = group.childAt(idx + 1);
        var nextChildRect = nextChild && nextChild.getBoundingRect();
        var nextX;
        var nextY;
        if (orient === 'horizontal') {
            var moveX = rect.width + (nextChildRect ? (-nextChildRect.x + rect.x) : 0);
            nextX = x + moveX;
            // Wrap when width exceeds maxWidth or meet a `newline` group
            if (nextX > maxWidth || child.newline) {
                x = 0;
                nextX = moveX;
                y += currentLineMaxSize + gap;
                currentLineMaxSize = rect.height;
            }
            else {
                currentLineMaxSize = Math.max(currentLineMaxSize, rect.height);
            }
        }
        else {
            var moveY = rect.height + (nextChildRect ? (-nextChildRect.y + rect.y) : 0);

            nextY = y + moveY;

            /*by danhuan s*/
                    if(pagemode){

                        //console.log(pagemode);
                        if (nextY > maxHeight || child.newline) {
                            var html = '<div class="js-prePage"> ![](/mapout-web-visual/img/up-disable.png)</div>';
                            html +=    '<div class="js-nextPage"> ![](/mapout-web-visual/img/down-icon.png)</div>';
                            $('.js-eclegend-tool').html(html);
                        }
                        else {
                            currentLineMaxSize = Math.max(currentLineMaxSize, rect.width);
                        }
                    }else{
                        //console.log(pagemode);
                        // Wrap when width exceeds maxHeight or meet a `newline` group
                        if (nextY > maxHeight || child.newline) {
                            x += currentLineMaxSize + gap;
                            y = 0;
                            nextY = moveY;
                            currentLineMaxSize = rect.width;
                        }
                        else {
                            currentLineMaxSize = Math.max(currentLineMaxSize, rect.width);
                        }
                    }
                    /*by danhuan e*/
        }

        if (child.newline) {
            return;
        }

        position[0] = x;
        position[1] = y;

        orient === 'horizontal'
            ? (x = nextX + gap)
            : (y = nextY + gap);
    });
}

4.添加按钮事件

给”上一页“, ”下一页“按钮添加事件,通过echarts的setOption改变legend层的top,实现其翻页

/*=====legend 的分页控制 事件=s===*/
        var PageEvent = function (i) {
            var percent = -i * 98 + '%';
            myChart.setOption({
                legend: {
                    top: percent
                }
            });
        };

        if (option.legend.pagemode) {
            $('body').on('click', '.js-prePage', function () {

                if (clickCount > 0) {
                    clickCount = clickCount - 1;
                    PageEvent(clickCount);
                    //console.log(clickCount+'上一页');
                    $('.js-prePage img').attr({'src': '/mapout-web-visual/img/up-icon.png', 'title': '上一页'});
                    $('.js-prePage img').css('cursor','pointer');
                    //$('.js-nextPage img').attr('src','/mapout-web-visual/img/down-icon.png');
                    if(clickCount==0){
                        $('.js-prePage img').attr({'src': '/mapout-web-visual/img/up-disable.png', 'title': '已经是第一页'});
                        $('.js-prePage img').css('cursor','no-drop');
                    }
                } else {
                    //console.log(clickCount+'已经是第一页');
                    $('.js-prePage img').attr({'src': '/mapout-web-visual/img/up-disable.png', 'title': '已经是第一页'});
                    $('.js-prePage img').css('cursor','no-drop');
                }
            });
            $('body').on('click', '.js-nextPage', function () {
                clickCount = clickCount + 1;
                //console.log(clickCount);
                PageEvent(clickCount);
                $('.js-prePage img').attr({'src': '/mapout-web-visual/img/up-icon.png', 'title': '上一页'});
                $('.js-prePage img').css('cursor','pointer');
            });
        }
        /*=====legend 的分页控制 事件=e===*/

按钮图标:

本文转载自:http://blog.csdn.net/danhuan/article/details/72831245

骚年_你渴望力量吗
粉丝 0
博文 10
码字总数 16809
作品 0
杭州
程序员
私信 提问
Echarts弹出层

@小q蹲街 你好,想跟你请教个问题: <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <% String path = request.getContextPath(); String basePath = request.getS......

古月哥欠666
2017/08/10
62
2
基于echarts异步加载数据之多个series加载实例

前言 基于本人最近在参与研究公司echarts报表部分的功能,其中遇到了不少的坑,这里将echarts异步加载json数据中涉及到的多个series加载实例问题解决方案做一个共享。 问题描述 我们在加载e...

Airey
2018/09/14
0
0
ECharts v3.7 发布:增加富文本标签、可滚动图例

在 ECharts 新发布的 3.7 版本 中,广泛地增加了标签的表现力。可以支持定制文本块的样式,也支持对文本片段应用特定的样式,如设置颜色、大小、背景、图片、对齐方式等,从而可以做出丰富的...

ECharts
2017/08/22
4.3K
6
Echarts如何默认显示折线平铺图

@i6ma 你好,想跟你请教个问题:如图,我该如何设置,请指教,谢谢。 如图代码require.config({ paths: { echarts: 'http://echarts.baidu.com/build/dist' } }); require( [ 'echarts', 'e......

心路独舞
2015/02/03
3.8K
1
echarts 图例可以批量控制么?

echarts 图例可以批量控制么?比如下面的图例,我想控制只显示柱形图的,或者只显示折线图 legend:{}属性里面也没有看到这样的控制

沙漠飞鹰
2015/12/28
77
2

没有更多内容

加载失败,请刷新页面

加载更多

数组算法

/*数组的相关的算法操作:1、在数组中找最大值/最小值*/class Test11_FindMax{public static void main(String[] args){int[] array = {4,2,6,8,1};//在数组中找最大...

architect刘源源
31分钟前
1
0
okhttp3 以上版本在安卓9.0无法请求数据的解决方案

应用官方的说明:在 Android 6.0 中,我们取消了对 Apache HTTP 客户端的支持。 从 Android 9 开始,默认情况下该内容库已从 bootclasspath 中移除且不可用于应用。且Android P 限制了明文流量...

chenhongjiang
今天
11
0
简单示例:NodeJs连接mysql数据库

开篇引用网上的说法: 简单的说 Node.js 就是运行在服务端的 JavaScript。Node.js 是一个基于Chrome JavaScript 运行时建立的一个平台。Node.js是一个事件驱动I/O服务端JavaScript环境,基于...

李朝强
今天
8
0
大数据学习路线

年薪30W大数据学习路线图: 一、Hadoop入门,了解什么是Hadoop 1、Hadoop产生背景 2、Hadoop在大数据、云计算中的位置和关系 3、国内外Hadoop应用案例介绍 4、国内Hadoop的就业情况分析及课程...

陈小君
今天
3
0
解读 Kylin 3.0.0 | 更敏捷、更高效的 OLAP 引擎

在近期的 Apache Kylin Meetup 成都站上,我们邀请到 Kyligence 架构师 & Apache Kylin Committer 倪春恩对 Kylin 3.0.0 版本的一些重要功能及改进从使用到原理进行了介绍: Apache Kylin 在...

ApacheKylin
今天
6
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部