Echarts实现图表联动(多图联动、图表间联动)

一、背景

Echarts.js目前已经提供了connect功能,只要图标的legend一样,那么就能实现联动。
下面两个链接是介绍Echarts connect的用法的。
https://blog.csdn.net/u014452812/article/details/78202789
http://echarts.baidu.com/api.html#echarts.connect

真正的图表联动展示应该不止于此,D3.js理解思路上与Echarts.js有所不同,可能会更容易实现多图联动,这里先介绍Echarts如何让图标联动起来。

二、原始例子

通过重新绘制

http://echarts.baidu.com/examples/editor.html?c=dataset-link

在这个样例中,随着鼠标在坐标轴上的移动,饼图会不断的变化,其关键在于这一段代码。

myChart.on('updateAxisPointer', function (event) {
        var xAxisInfo = event.axesInfo[0];
        if (xAxisInfo) {
            var dimension = xAxisInfo.value + 1;
            myChart.setOption({
                series: {
                    id: 'pie',
                    label: {
                        formatter: '{b}: {@[' + dimension + ']} ({d}%)'
                    },
                    encode: {
                        value: dimension,
                        tooltip: dimension
                    }
                }
            });
        }
    });

本质上是通过鼠标事件,不断获取xAxisInfo,然后根据获取到的xAxisInfo.value(dimension)重新绘制饼图。这个可视化过程中数据是以数据集形式呈现的,所以用的encode,具体介绍可以在http://www.echartsjs.com/tutorial.html#%E4%BD%BF%E7%94%A8%20dataset%20%E7%AE%A1%E7%90%86%E6%95%B0%E6%8D%AE看到。

如果要看看event都有些什么,通过console.log(event)即可获取,比如移到第一个横轴坐标2012时,输出的内容如下,其value为0。

通过事件

Echarts事件介绍:
http://www.echartsjs.com/tutorial.html#ECharts%20%E4%B8%AD%E7%9A%84%E4%BA%8B%E4%BB%B6%E5%92%8C%E8%A1%8C%E4%B8%BA

轮流高亮例子:
http://www.echartsjs.com/gallery/editor.html?c=doc-example/pie-highlight

其关键在于

myChart.dispatchAction({
        type: 'highlight',
        seriesIndex: 0,
        dataIndex: app.currentIndex
});

Echarts的action还有很多,在echarts官网的API中可以输入action进行检索。

之所以可以使用这个实现多图联动,实质上是一个图上发生鼠标移动事件后,调用另一个图,使其产生动作。比如mychart1和mychart2,如果获取到了mychart1的params信息,通过这些信息可以对应到mychart2的dataIndex、SeriesIndex,那么,就可以用这样的形式实现联动。

三、实现方法

记住这两个东西就好。
myChart.setOption \\重新绘制
myChart.dispatchAction \\echarts action

四、具体例子

这是一个对http://echarts.baidu.com/examples/editor.html?c=dataset-link进行的改进。
效果示意:

样例.gif

全部源码如下,可以先粘走看看效果。

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>ECharts</title>
    <!-- 引入 echarts.js -->
    <script src="echarts.min.js"></script>
</head>
<body>
    <!-- 为ECharts准备一个具备大小(宽高)的Dom -->
<div id="main" style="width: 900px;height:600px;"></div>
<script type="text/javascript">
        // 基于准备好的dom,初始化echarts实例
var myChart = echarts.init(document.getElementById('main'));

// 指定图表的配置项和数据
var option = {
        legend: {},
        tooltip: {
            //trigger: 'axis',
            showContent: false,
        },
        dataset: {
            source: [
                ['product', '2012', '2013', '2014', '2015', '2016', '2017'],
                ['Matcha Latte', 41.1, 30.4, 65.1, 53.3, 83.8, 98.7],
                ['Milk Tea', 86.5, 92.1, 85.7, 83.1, 73.4, 55.1],
                ['Cheese Cocoa', 24.1, 67.2, 79.5, 86.4, 65.2, 82.5],
                ['Walnut Brownie', 55.2, 67.1, 69.2, 72.4, 53.9, 39.1]
            ]
        },
        xAxis: {type: 'category', 
                triggerEvent: true,
                //axisPointer: {show:true}
            },
        yAxis: {gridIndex: 0},
        grid: {top: '55%'},
        series: [
            {type: 'line', smooth: true, seriesLayoutBy: 'row', symbolSize: 10},
            {type: 'line', smooth: true, seriesLayoutBy: 'row', symbolSize: 10},
            {type: 'line', smooth: true, seriesLayoutBy: 'row', symbolSize: 10},
            {type: 'line', smooth: true, seriesLayoutBy: 'row', symbolSize: 10},
            {
                type: 'pie',
                id: 'pie',
                radius: '30%',
                center: ['50%', '25%'],
                label: {
                    formatter: '{b}: {@[2012]} ({d}%)'
                },
                encode: {
                    itemName: 'product',
                    value: '2012',
                    tooltip: '2012'
                }
            }
        ]
    };

setTimeout(function () {
    myChart.on('mouseover',function(params){

        if(params.componentType == "xAxis"){
            var xAxisInfo = params.value;
            myChart.setOption({
                series: {
                    id: 'pie',
                    label: {
                        formatter: '{b}: {@[' + xAxisInfo + ']} ({d}%)'
                    },
                    encode: {
                        value: xAxisInfo,
                        tooltip: xAxisInfo
                    }
                }
            });
        }
        if(params.componentType == "series" && params.seriesType == 'line'){
            var xAxisInfo = params.value[0];
            myChart.setOption({
                series: {
                    id: 'pie',
                    label: {
                        formatter: '{b}: {@[' + xAxisInfo + ']} ({d}%)'
                    },
                    encode: {
                        value: xAxisInfo,
                        tooltip: xAxisInfo
                    }
                }
            });
        }
        setTimeout(function(){
            myChart.dispatchAction({
                type: 'highlight',
                seriesIndex: 4,
                dataIndex: params.seriesIndex
            });
        },300);         
    });

    myChart.on('mouseout',function(params){
        myChart.dispatchAction({
            type: 'downplay',
            seriesIndex: 4,
            dataIndex: params.seriesIndex
        });         
    });
},0);

// 使用刚指定的配置项和数据显示图表。
myChart.setOption(option);
</script>
</body>
</html>

那两个if主要用于获取信息,如果不是两个图画在同一个mychart里其实就没有那么麻烦,实际上可以忽略不看。在鼠标移动到某一个折线图的点的时候,饼图中对应的块将会高亮。
实现的关键就在于通过鼠标事件,获取到了params的相关信息,通过

myChart.dispatchAction({
type: 'highlight',
seriesIndex: 4,
dataIndex: params.seriesIndex
});

实现饼图部分的高亮。这个例子中两个图是在同一个mychart中,如果我们画在两个不同的图像中如何实现高亮呢。
简化来写就是这样

myChart1.on('mouseover',function(params){
        myChart2.dispatchAction({
            type: 'highlight',
            seriesIndex: 4,
            dataIndex: params.seriesIndex
    });
});

具体需要根据params的对应情况来实现高亮。

有空再做更详细的联动展示例子。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,214评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,307评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,543评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,221评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,224评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,007评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,313评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,956评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,441评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,925评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,018评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,685评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,234评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,240评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,464评论 1 261
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,467评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,762评论 2 345

推荐阅读更多精彩内容