ECharts responsive

ECharts charts are displayed in a DOM node (container) whose width and height are specified by the user.

Sometimes we want to display chart content well on both PC and mobile devices, achieving responsive design. To solve this problem, ECharts has improved component positioning settings and implemented something similar toCSS Media Queryadaptive capability.


Positioning and layout of ECharts components

Most "components" and "series" follow two positioning methods.

left/right/top/bottom/width/height positioning method

Among these six quantities, each can be an "absolute value", "percentage", or "position description".

  • absolute value

    The unit is the browser pixel (px), written in thenumberform (without units). For example{left: 23, height: 400}。

  • percentage

    Indicates what percentage of the DOM container's height and width it occupies, usingstringWritten in the form. For example{right: '30%', bottom: '40%'}。

  • Position Description

    • Can be setleft: 'center', indicates horizontal centering.
    • Can be settop: 'middle', indicates vertical centering.

The concepts of these six quantities are similar to those in CSS:

  • left: distance from the left border of the DOM container.
  • right: distance from the right border of the DOM container.
  • top: distance from the top border of the DOM container.
  • bottom: distance from the bottom border of the DOM container.
  • width: width.
  • height: height.

Horizontally, among the three quantities left, right, and width, only two need to have values, because any two quantities can determine the component's position and size. For example, left and right, or right and width, can determine the position and size of the component. Vertically, the three quantities top, bottom, and height are similar to the horizontal case and will not be repeated.

center / radius positioning method

  • center

    is an array, indicating[x, y], where,x、yIt can be an "absolute value" or "percentage", with the same meaning as described above.

  • radius

    is an array, indicating[inner radius, outer radius]The inner and outer radii can be "absolute values" or "percentages", with the same meanings as described above.

    Percentage settings are very useful when adapting to container size.

Horizontal and vertical

ECharts components with an "elongated appearance" (such as legend, visualMap, dataZoom, timeline, etc.) mostly provide a choice between "horizontal layout" and "vertical layout". For example, on a tall narrow mobile screen, a "vertical layout" may be suitable; on a PC widescreen, a "horizontal layout" may be suitable.

The setting for horizontal/vertical layout is generally on the orient or layout configuration item of the "component" or "series", set to 'horizontal' or 'vertical'.


Example

In the following example, we can try to drag the dot in the lower right corner; the chart will change with the screen size, and the legend and series will automatically adjust their layout positions and methods.

In the example, we used jQuery to load external data. When using it, we need to include the jQuery library.

Example

$.when(
    $.getScript('https://www.example.com/static/js/timelineGDP.js'),
    $.getScript('https://www.example.com/static/js/draggable.js')
).done(function () {

    draggable.init(
        $('div[_echarts_instance_]')[0],
        myChart,
        {
            width: 700,
            height: 400,
            throttle: 70
        }
    );

    myChart.hideLoading();



    option = {
        baseOption: {
            title : {
                text: 'Nightingale rose chart',
                subtext: Pure Fiction,
                x:'center'
            },
            tooltip : {
                trigger: 'item',
                formatter: "{a} <br/>{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:Radius Mode,
                    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:Area Mode,
                    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);

});

Try it Yourself »

To set Media Query in option, you must follow the following format:

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

In the above example, baseOption and each option in media are "atomic options", i.e., ordinary options containing definitions of components and series. The entire option composed of "atomic options" is called a "compound option". baseOption is always used; in addition, when a query condition is satisfied, the corresponding option is merged in using chart.mergeOption().

query

Each query looks like this:

{
    minWidth: 200,
    maxHeight: 300,
    minAspectRatio: 1.3
}

Currently supports three properties: width, height, aspectRatio. Each property can have a min or max prefix. For example, minWidth: 200 means "width greater than or equal to 200px". Writing two properties together means "and", for example: {minWidth: 200, maxHeight: 300} means "width greater than or equal to 200px, and height less than or equal to 300px".

option

Since the option in media is an "atomic option", theoretically any option configuration item can be written. But generally we only write the ones related to layout and positioning, for example, take a part of the query option from the above example:

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%']
                }
            ]
        }
    },
    ...
]

Priority when multiple queries are satisfied

Note that multiple queries can be satisfied at the same time, and all will be merged via mergeOption; those defined later are merged later (i.e., have higher priority).

Default query

If an item in media does not have a query, it represents the "default value", i.e., this option is adopted when none of the rules are satisfied.

Notes when the container size changes in real time

In many cases, the container DOM node does not need to arbitrarily change size with dragging, but rather only a few typical sizes are set according to different devices.

However, if the container DOM node needs to be able to arbitrarily change size with dragging, then currently you need to be careful about this: if a configuration item appears in one query option, it must also appear in other query options, otherwise it cannot return to its original state. (left/right/top/bottom/width/height are not subject to this restriction.)

The media in the "compound option" does not support merge.

alsoJustYes说, whenNo.二(orthree、four、五 ...)times chart.setOption(rawOption) when,if rawOption Yes 复combineoption(i.e.contains media List), thenNew rawOption.media ListWill notand老of media Listenterline merge, whereasYesSimplereplacement.Whenbut,rawOption.baseOption 仍butwillnormaland老of option enterlinemerge。 itsreal,很fewYesScenariosneed to use『复combine option』comemanytimes setOption, whereasI们RecommendedofMethodis,Usage mediaQuery when,No.onetimessetOptionUsage『复combine option』,behind setOption whenonlyUsage 『Original子 option』, that is,onlyonlyuse setOption comechange baseOption。

In the following, we used jQuery to load external data. When using it, we need to include the jQuery library. This example is one combined with a timeline:

Example

$.when(
    $.getScript('https://www.example.com/static/js/timelineGDP.js'),
    $.getScript('https://www.example.com/static/js/draggable.js')
).done(function () {

    draggable.init(
        $('div[_echarts_instance_]')[0],
        myChart,
        {
            width: 700,
            height: 630,
            lockY: true,
            throttle: 70
        }
    );

    myChart.hideLoading();

    var categoryData = [
        'Beijing','Tianjin','Hebei','Shanxi','Inner Mongolia','Liaoning','Jilin','Heilongjiang',
        'Shanghai','Jiangsu','Zhejiang','Anhui','Fujian','Jiangxi','Shandong','Henan',
        'Hubei','Hunan','Guangdong','Guangxi','Hainan','Chongqing','Sichuan','Guizhou',
        'Yunnan','Tibet','Shaanxi','Gansu','Qinghai','Ningxia','Xinjiang'
    ];


    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 Example'
            },
            tooltip: {
                trigger:'axis',
                axisPointer: {
                    type: 'shadow'
                }
            },
            xAxis: {
                type: 'value',
                name: 'GDP (100 million yuan)',
                max: 30000,
                data: null
            },
            yAxis: {
                type: 'category',
                data: categoryData,
                axisLabel: {interval: 0},
                splitLine: {show: false}
            },
            legend: {
                data: [Primary Industry, Secondary Industry, Tertiary Industry, 'GDP', 'Finance', 'Real estate'],
                selected: {
                    'GDP': false, 'Finance': false, 'Real estate': false
                }
            },
            calculable : true,
            series: [
                {name: 'GDP', type: 'bar'},
                {name: 'Finance', type: 'bar'},
                {name: 'Real estate', type: 'bar'},
                {name: Primary Industry, type: 'bar'},
                {name: Secondary Industry, type: 'bar'},
                {name: Tertiary Industry, type: 'bar'},
                {name: 'GDP share', 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 share', 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 share', 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 share', center: ['45%', '20%'], radius: '28%'}
                    ]
                }
            }
        ],
        options: [
            {
                title: {text: '2002 National Macroeconomic Indicators'},
                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: Primary Industry, value: dataMap.dataPI['2002sum']},
                        {name: Secondary Industry, value: dataMap.dataSI['2002sum']},
                        {name: Tertiary Industry, value: dataMap.dataTI['2002sum']}
                    ]}
                ]
            },
            {
                title : {text: '2003 National Macroeconomic Indicators'},
                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: Primary Industry, value: dataMap.dataPI['2003sum']},
                        {name: Secondary Industry, value: dataMap.dataSI['2003sum']},
                        {name: Tertiary Industry, value: dataMap.dataTI['2003sum']}
                    ]}
                ]
            },
            {
                title : {text: '2004 National Macroeconomic Indicators'},
                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: Primary Industry, value: dataMap.dataPI['2004sum']},
                        {name: Secondary Industry, value: dataMap.dataSI['2004sum']},
                        {name: Tertiary Industry, value: dataMap.dataTI['2004sum']}
                    ]}
                ]
            },
            {
                title : {text: '2005 National Macroeconomic Indicators'},
                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: Primary Industry, value: dataMap.dataPI['2005sum']},
                        {name: Secondary Industry, value: dataMap.dataSI['2005sum']},
                        {name: Tertiary Industry, value: dataMap.dataTI['2005sum']}
                    ]}
                ]
            },
            {
                title : {text: '2006 National Macroeconomic Indicators'},
                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: Primary Industry, value: dataMap.dataPI['2006sum']},
                        {name: Secondary Industry, value: dataMap.dataSI['2006sum']},
                        {name: Tertiary Industry, value: dataMap.dataTI['2006sum']}
                    ]}
                ]
            },
            {
                title : {text: '2007 National Macroeconomic Indicators'},
                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: Primary Industry, value: dataMap.dataPI['2007sum']},
                        {name: Secondary Industry, value: dataMap.dataSI['2007sum']},
                        {name: Tertiary Industry, value: dataMap.dataTI['2007sum']}
                    ]}
                ]
            },
            {
                title : {text: '2008 National Macroeconomic Indicators'},
                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: Primary Industry, value: dataMap.dataPI['2008sum']},
                        {name: Secondary Industry, value: dataMap.dataSI['2008sum']},
                        {name: Tertiary Industry, value: dataMap.dataTI['2008sum']}
                    ]}
                ]
            },
            {
                title : {text: '2009 National Macroeconomic Indicators'},
                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: Primary Industry, value: dataMap.dataPI['2009sum']},
                        {name: Secondary Industry, value: dataMap.dataSI['2009sum']},
                        {name: Tertiary Industry, value: dataMap.dataTI['2009sum']}
                    ]}
                ]
            },
            {
                title : {text: '2010 National Macroeconomic Indicators'},
                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: Primary Industry, value: dataMap.dataPI['2010sum']},
                        {name: Secondary Industry, value: dataMap.dataSI['2010sum']},
                        {name: Tertiary Industry, value: dataMap.dataTI['2010sum']}
                    ]}
                ]
            },
            {
                title : {text: '2011 National Macroeconomic Indicators'},
                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: Primary Industry, value: dataMap.dataPI['2011sum']},
                        {name: Secondary Industry, value: dataMap.dataSI['2011sum']},
                        {name: Tertiary Industry, value: dataMap.dataTI['2011sum']}
                    ]}
                ]
            }
        ]
    };

    myChart.setOption(option);

});

Try it Yourself »
other extensions