教程 > echarts 教程 > 阅读:71

echarts 响应式——迹忆客-ag捕鱼王app官网

echarts 图表显示在用户指定高宽的 dom 节点(容器)中。

有时候我们希望在 pc 和 移动设备上都能够很好的展示图表的内容,实现响应式的设计,为了解决这个问题,echarts 完善了组件的定位设置,并且实现了类似 css media query 的自适应能力。

echarts 组件的定位和布局

大部分『组件』和『系列』会遵循两种定位方式。

left/right/top/bottom/width/height 定位方式

这六个量中,每个量都可以是『绝对值』或者『百分比』或者『位置描述』。

绝对值

单位是浏览器像素(px),用 number 形式书写(不写单位)。例如 {left: 23, height: 400}。

百分比

表示占 dom 容器高宽的百分之多少,用 string 形式书写。例如 {right: '30%', bottom: '40%'}。

位置描述

  • 可以设置 left: 'center',表示水平居中。
  • 可以设置 top: 'middle',表示垂直居中。

这六个量的概念,和 css 中六个量的概念类似:

  • left:距离 dom 容器左边界的距离。
  • right:距离 dom 容器右边界的距离。
  • top:距离 dom 容器上边界的距离。
  • bottom:距离 dom 容器下边界的距离。
  • width:宽度。
  • height:高度。

在横向,left、right、width 三个量中,只需两个量有值即可,因为任两个量可以决定组件的位置和大小,例如 left 和 right 或者 right 和 width 都可以决定组件的位置和大小。 纵向,top、bottom、height 三个量,和横向类同不赘述。

center / radius 定位方式

center

是一个数组,表示 [x, y],其中,x、y可以是『绝对值』或者『百分比』,含义和前述相同。

radius

是一个数组,表示 [内半径, 外半径],其中,内外半径可以是『绝对值』或者『百分比』,含义和前述相同。

在自适应容器大小时,百分比设置是很有用的。

横向(horizontal)和纵向(vertical)

echarts的『外观狭长』型的组件(如 legend、visualmap、datazoom、timeline等),大多提供了『横向布局』『纵向布局』的选择。例如,在细长的移动端屏幕上,可能适合使用『纵向布局』;在pc宽屏上,可能适合使用『横向布局』。

横纵向布局的设置,一般在『组件』或者『系列』的 orient 或者 layout 配置项上,设置为 'horizontal' 或者 'vertical'。


实例

以下实例中我们可以可尝试拖动右下角的圆点,图表会随着屏幕尺寸变化,legend 和 系列会自动改变布局位置和方式。

实例中我们使用了 jquery 来加载外部数据,使用时我们需要引入 jquery 库。

$.when(
    $.getscript('/demo_source/timelinegdp.js'),
    $.getscript('/demo_source/draggable.js')
).done(function () {
    draggable.init(
        $('div[_echarts_instance_]')[0],
        mychart,
        {
            width: 700,
            height: 400,
            throttle: 70
        }
    );
    mychart.hideloading();
    option = {
        baseoption: {
            title : {
                text: '南丁格尔玫瑰图',
                subtext: '纯属虚构',
                x:'center'
            },
            tooltip : {
                trigger: 'item',
                formatter: "{a} 
{b} : {c} ({d}%)" }, legend: { data:['rose1','rose2','rose3','rose4','rose5','rose6','rose7','rose8'] }, toolbox: { show : true, feature : { mark : {show: true}, dataview : {show: true, readonly: false}, magictype : { show: true, type: ['pie', 'funnel'] }, restore : {show: true}, saveasimage : {show: true} } }, calculable : true, series : [ { name:'半径模式', type:'pie', rosetype : 'radius', label: { normal: { show: false }, emphasis: { show: true } }, lableline: { normal: { show: false }, emphasis: { show: true } }, data:[ {value:10, name:'rose1'}, {value:5, name:'rose2'}, {value:15, name:'rose3'}, {value:25, name:'rose4'}, {value:20, name:'rose5'}, {value:35, name:'rose6'}, {value:30, name:'rose7'}, {value:40, name:'rose8'} ] }, { name:'面积模式', type:'pie', rosetype : 'area', data:[ {value:10, name:'rose1'}, {value:5, name:'rose2'}, {value:15, name:'rose3'}, {value:25, name:'rose4'}, {value:20, name:'rose5'}, {value:35, name:'rose6'}, {value:30, name:'rose7'}, {value:40, name:'rose8'} ] } ] }, media: [ { option: { legend: { right: 'center', bottom: 0, orient: 'horizontal' }, series: [ { radius: [20, '50%'], center: ['25%', '50%'] }, { radius: [30, '50%'], center: ['75%', '50%'] } ] } }, { query: { minaspectratio: 1 }, option: { legend: { right: 'center', bottom: 0, orient: 'horizontal' }, series: [ { radius: [20, '50%'], center: ['25%', '50%'] }, { radius: [30, '50%'], center: ['75%', '50%'] } ] } }, { query: { maxaspectratio: 1 }, option: { legend: { right: 'center', bottom: 0, orient: 'horizontal' }, series: [ { radius: [20, '50%'], center: ['50%', '30%'] }, { radius: [30, '50%'], center: ['50%', '70%'] } ] } }, { query: { maxwidth: 500 }, option: { legend: { right: 10, top: '15%', orient: 'vertical' }, series: [ { radius: [20, '50%'], center: ['50%', '30%'] }, { radius: [30, '50%'], center: ['50%', '75%'] } ] } } ] }; mychart.setoption(option); });

echarts 自适应 -南丁格尔玫瑰图

要在 option 中设置 media query 须遵循如下格式:

option = {
    baseoption: { // 这里是基本的『原子option』。
        title: {...},
        legend: {...},
        series: [{...}, {...}, ...],
        ...
    },
    media: [ // 这里定义了 media query 的逐条规则。
        {
            query: {...},   // 这里写规则。
            option: {       // 这里写此规则满足下的option。
                legend: {...},
                ...
            }
        },
        {
            query: {...},   // 第二个规则。
            option: {       // 第二个规则对应的option。
                legend: {...},
                ...
            }
        },
        {                   // 这条里没有写规则,表示『默认』,
            option: {       // 即所有规则都不满足时,采纳这个option。
                legend: {...},
                ...
            }
        }
    ]
};

上面的例子中,baseoption、以及 media 每个 option 都是『原子 option』,即普通的含有各组件、系列定义的 option。而由『原子option』组合成的整个 option,我们称为『复合 option』。baseoption 是必然被使用的,此外,满足了某个 query 条件时,对应的 option 会被使用 chart.mergeoption() 来 merge 进去。

query

每个 query 类似于这样:

{
    minwidth: 200,
    maxheight: 300,
    minaspectratio: 1.3
}

现在支持三个属性:width、height、aspectratio(长宽比)。每个属性都可以加上 min 或 max 前缀。比如,minwidth: 200 表示『大于等于200px宽度』。两个属性一起写表示『并且』,比如:{minwidth: 200, maxheight: 300} 表示『大于等于200px宽度,并且小于等于300px高度』。

option

media中的 option 既然是『原子 option』,理论上可以写任何 option 的配置项。但是一般我们只写跟布局定位相关的,例如截取上面例子中的一部分 query option:

media: [
    ...,
    {
        query: {
            maxaspectratio: 1           // 当长宽比小于1时。
        },
        option: {
            legend: {                   // legend 放在底部中间。
                right: 'center',
                bottom: 0,
                orient: 'horizontal'    // legend 横向布局。
            },
            series: [                   // 两个饼图左右布局。
                {
                    radius: [20, '50%'],
                    center: ['50%', '30%']
                },
                {
                    radius: [30, '50%'],
                    center: ['50%', '70%']
                }
            ]
        }
    },
    {
        query: {
            maxwidth: 500               // 当容器宽度小于 500 时。
        },
        option: {
            legend: {
                right: 10,              // legend 放置在右侧中间。
                top: '15%',
                orient: 'vertical'      // 纵向布局。
            },
            series: [                   // 两个饼图上下布局。
                {
                    radius: [20, '50%'],
                    center: ['50%', '30%']
                },
                {
                    radius: [30, '50%'],
                    center: ['50%', '75%']
                }
            ]
        }
    },
    ...
]

多个 query 被满足时的优先级

注意,可以有多个 query 同时被满足,会都被 mergeoption,定义在后的后被 merge(即优先级更高)。

默认 query

如果 media 中有某项不写 query,则表示『默认值』,即所有规则都不满足时,采纳这个option。

容器大小实时变化时的注意事项

在不少情况下,并不需要容器dom节点任意随着拖拽变化大小,而是只是根据不同终端设置几个典型尺寸。

但是如果容器dom节点需要能任意随着拖拽变化大小,那么目前使用时需要注意这件事:某个配置项,如果在某一个 query option 中出现,那么在其他 query option 中也必须出现,否则不能够回归到原来的状态。(left/right/top/bottom/width/height 不受这个限制。)

『复合 option』 中的 media 不支持 merge

也就是说,当第二(或三、四、五 ...)次 chart.setoption(rawoption) 时,如果 rawoption 是 复合option(即包含 media 列表),那么新的 rawoption.media 列表不会和老的 media 列表进行 merge,而是简单替代。当然,rawoption.baseoption 仍然会正常和老的 option 进行merge。 其实,很少有场景需要使用『复合 option』来多次 setoption,而我们推荐的做法是,使用 mediaquery 时,第一次setoption使用『复合 option』,后面 setoption 时仅使用 『原子 option』,也就是仅仅用 setoption 来改变 baseoption。 以下中我们使用了 jquery 来加载外部数据,使用时我们需要引入 jquery 库。该实例是一个和时间轴结合的例子:

$.when(
    $.getscript('/demo_source/timelinegdp.js'),
    $.getscript('/demo_source/draggable.js')
).done(function () {
    draggable.init(
        $('div[_echarts_instance_]')[0],
        mychart,
        {
            width: 700,
            height: 630,
            locky: true,
            throttle: 70
        }
    );
    mychart.hideloading();
    var categorydata = [
        '北京','天津','河北','山西','内蒙古','辽宁','吉林','黑龙江',
        '上海','江苏','浙江','安徽','福建','江西','山东','河南',
        '湖北','湖南','广东','广西','海南','重庆','四川','贵州',
        '云南','西藏','陕西','甘肃','青海','宁夏','新疆'
    ];
    option = {
        baseoption: {
            timeline: {
                axistype: 'category',
                autoplay: true,
                playinterval: 1000,
                data: [
                    '2002-01-01', '2003-01-01', '2004-01-01',
                    '2005-01-01', '2006-01-01', '2007-01-01',
                    '2008-01-01', '2009-01-01', '2010-01-01',
                    '2011-01-01'
                ],
                label: {
                    formatter : function(s) {
                        return (new date(s)).getfullyear();
                    }
                }
            },
            title: {
                subtext: 'media query 示例'
            },
            tooltip: {
                trigger:'axis',
                axispointer: {
                    type: 'shadow'
                }
            },
            xaxis: {
                type: 'value',
                name: 'gdp(亿元)',
                max: 30000,
                data: null
            },
            yaxis: {
                type: 'category',
                data: categorydata,
                axislabel: {interval: 0},
                splitline: {show: false}
            },
            legend: {
                data: ['第一产业', '第二产业', '第三产业', 'gdp', '金融', '房地产'],
                selected: {
                    'gdp': false, '金融': false, '房地产': false
                }
            },
            calculable : true,
            series: [
                {name: 'gdp', type: 'bar'},
                {name: '金融', type: 'bar'},
                {name: '房地产', type: 'bar'},
                {name: '第一产业', type: 'bar'},
                {name: '第二产业', type: 'bar'},
                {name: '第三产业', type: 'bar'},
                {name: 'gdp占比', type: 'pie'}
            ]
        },
        media: [
            {
                option: {
                    legend: {
                        orient: 'horizontal',
                        left: 'right',
                        itemgap: 10
                    },
                    grid: {
                        left: '10%',
                        top: 80,
                        right: 90,
                        bottom: 100
                    },
                    xaxis: {
                        namelocation: 'end',
                        namegap: 10,
                        splitnumber: 5,
                        splitline: {
                            show: true
                        }
                    },
                    timeline: {
                        orient: 'horizontal',
                        inverse: false,
                        left: '20%',
                        right: '20%',
                        bottom: 10,
                        height: 40
                    },
                    series: [
                        {name: 'gdp占比', center: ['75%', '30%'], radius: '28%'}
                    ]
                }
            },
            {
                query: {maxwidth: 670, minwidth: 550},
                option: {
                    legend: {
                        orient: 'horizontal',
                        left: 200,
                        itemgap: 5
                    },
                    grid: {
                        left: '10%',
                        top: 80,
                        right: 90,
                        bottom: 100
                    },
                    xaxis: {
                        namelocation: 'end',
                        namegap: 10,
                        splitnumber: 5,
                        splitline: {
                            show: true
                        }
                    },
                    timeline: {
                        orient: 'horizontal',
                        inverse: false,
                        left: '20%',
                        right: '20%',
                        bottom: 10,
                        height: 40
                    },
                    series: [
                        {name: 'gdp占比', center: ['75%', '30%'], radius: '28%'}
                    ]
                }
            },
            {
                query: {maxwidth: 550},
                option: {
                    legend: {
                        orient: 'vertical',
                        left: 'right',
                        itemgap: 5
                    },
                    grid: {
                        left: 55,
                        top: '32%',
                        right: 100,
                        bottom: 50
                    },
                    xaxis: {
                        namelocation: 'middle',
                        namegap: 25,
                        splitnumber: 3
                    },
                    timeline: {
                        orient: 'vertical',
                        inverse: true,
                        right: 10,
                        top: 150,
                        bottom: 10,
                        width: 55
                    },
                    series: [
                        {name: 'gdp占比', center: ['45%', '20%'], radius: '28%'}
                    ]
                }
            }
        ],
        options: [
            {
                title: {text: '2002全国宏观经济指标'},
                series: [
                    {data: datamap.datagdp['2002']},
                    {data: datamap.datafinancial['2002']},
                    {data: datamap.dataestate['2002']},
                    {data: datamap.datapi['2002']},
                    {data: datamap.datasi['2002']},
                    {data: datamap.datati['2002']},
                    {data: [
                        {name: '第一产业', value: datamap.datapi['2002sum']},
                        {name: '第二产业', value: datamap.datasi['2002sum']},
                        {name: '第三产业', value: datamap.datati['2002sum']}
                    ]}
                ]
            },
            {
                title : {text: '2003全国宏观经济指标'},
                series : [
                    {data: datamap.datagdp['2003']},
                    {data: datamap.datafinancial['2003']},
                    {data: datamap.dataestate['2003']},
                    {data: datamap.datapi['2003']},
                    {data: datamap.datasi['2003']},
                    {data: datamap.datati['2003']},
                    {data: [
                        {name: '第一产业', value: datamap.datapi['2003sum']},
                        {name: '第二产业', value: datamap.datasi['2003sum']},
                        {name: '第三产业', value: datamap.datati['2003sum']}
                    ]}
                ]
            },
            {
                title : {text: '2004全国宏观经济指标'},
                series : [
                    {data: datamap.datagdp['2004']},
                    {data: datamap.datafinancial['2004']},
                    {data: datamap.dataestate['2004']},
                    {data: datamap.datapi['2004']},
                    {data: datamap.datasi['2004']},
                    {data: datamap.datati['2004']},
                    {data: [
                        {name: '第一产业', value: datamap.datapi['2004sum']},
                        {name: '第二产业', value: datamap.datasi['2004sum']},
                        {name: '第三产业', value: datamap.datati['2004sum']}
                    ]}
                ]
            },
            {
                title : {text: '2005全国宏观经济指标'},
                series : [
                    {data: datamap.datagdp['2005']},
                    {data: datamap.datafinancial['2005']},
                    {data: datamap.dataestate['2005']},
                    {data: datamap.datapi['2005']},
                    {data: datamap.datasi['2005']},
                    {data: datamap.datati['2005']},
                    {data: [
                        {name: '第一产业', value: datamap.datapi['2005sum']},
                        {name: '第二产业', value: datamap.datasi['2005sum']},
                        {name: '第三产业', value: datamap.datati['2005sum']}
                    ]}
                ]
            },
            {
                title : {text: '2006全国宏观经济指标'},
                series : [
                    {data: datamap.datagdp['2006']},
                    {data: datamap.datafinancial['2006']},
                    {data: datamap.dataestate['2006']},
                    {data: datamap.datapi['2006']},
                    {data: datamap.datasi['2006']},
                    {data: datamap.datati['2006']},
                    {data: [
                        {name: '第一产业', value: datamap.datapi['2006sum']},
                        {name: '第二产业', value: datamap.datasi['2006sum']},
                        {name: '第三产业', value: datamap.datati['2006sum']}
                    ]}
                ]
            },
            {
                title : {text: '2007全国宏观经济指标'},
                series : [
                    {data: datamap.datagdp['2007']},
                    {data: datamap.datafinancial['2007']},
                    {data: datamap.dataestate['2007']},
                    {data: datamap.datapi['2007']},
                    {data: datamap.datasi['2007']},
                    {data: datamap.datati['2007']},
                    {data: [
                        {name: '第一产业', value: datamap.datapi['2007sum']},
                        {name: '第二产业', value: datamap.datasi['2007sum']},
                        {name: '第三产业', value: datamap.datati['2007sum']}
                    ]}
                ]
            },
            {
                title : {text: '2008全国宏观经济指标'},
                series : [
                    {data: datamap.datagdp['2008']},
                    {data: datamap.datafinancial['2008']},
                    {data: datamap.dataestate['2008']},
                    {data: datamap.datapi['2008']},
                    {data: datamap.datasi['2008']},
                    {data: datamap.datati['2008']},
                    {data: [
                        {name: '第一产业', value: datamap.datapi['2008sum']},
                        {name: '第二产业', value: datamap.datasi['2008sum']},
                        {name: '第三产业', value: datamap.datati['2008sum']}
                    ]}
                ]
            },
            {
                title : {text: '2009全国宏观经济指标'},
                series : [
                    {data: datamap.datagdp['2009']},
                    {data: datamap.datafinancial['2009']},
                    {data: datamap.dataestate['2009']},
                    {data: datamap.datapi['2009']},
                    {data: datamap.datasi['2009']},
                    {data: datamap.datati['2009']},
                    {data: [
                        {name: '第一产业', value: datamap.datapi['2009sum']},
                        {name: '第二产业', value: datamap.datasi['2009sum']},
                        {name: '第三产业', value: datamap.datati['2009sum']}
                    ]}
                ]
            },
            {
                title : {text: '2010全国宏观经济指标'},
                series : [
                    {data: datamap.datagdp['2010']},
                    {data: datamap.datafinancial['2010']},
                    {data: datamap.dataestate['2010']},
                    {data: datamap.datapi['2010']},
                    {data: datamap.datasi['2010']},
                    {data: datamap.datati['2010']},
                    {data: [
                        {name: '第一产业', value: datamap.datapi['2010sum']},
                        {name: '第二产业', value: datamap.datasi['2010sum']},
                        {name: '第三产业', value: datamap.datati['2010sum']}
                    ]}
                ]
            },
            {
                title : {text: '2011全国宏观经济指标'},
                series : [
                    {data: datamap.datagdp['2011']},
                    {data: datamap.datafinancial['2011']},
                    {data: datamap.dataestate['2011']},
                    {data: datamap.datapi['2011']},
                    {data: datamap.datasi['2011']},
                    {data: datamap.datati['2011']},
                    {data: [
                        {name: '第一产业', value: datamap.datapi['2011sum']},
                        {name: '第二产业', value: datamap.datasi['2011sum']},
                        {name: '第三产业', value: datamap.datati['2011sum']}
                    ]}
                ]
            }
        ]
    };
    mychart.setoption(option);
});

查看笔记

扫码一下
查看教程更方便
网站地图