Easy Tutorial
❮ Home Echarts Tutorial ❯

ECharts Responsive

ECharts displays charts within a DOM node (container) specified by the user with a given width and height.

Sometimes, we want the charts to be displayed well on both PC and mobile devices, achieving a responsive design. To address this, ECharts has enhanced the positioning settings of components and implemented adaptive capabilities similar to CSS Media Query.


ECharts Component Positioning and Layout

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

left/right/top/bottom/width/height Positioning Method

Each of these six values can be an 'absolute value', 'percentage', or 'position description'.

-

Absolute Value

The unit is browser pixels (px), written in number form (without units). For example, {left: 23, height: 400}.

-

Percentage

Represents a percentage of the DOM container's width and height, written in string form. For example, {right: '30%', bottom: '40%'}.

-

Position Description

These six values are similar to the six values in CSS:

In the horizontal direction, among left, right, and width, only two values need to be specified, as any two values can determine the position and size of the component, such as left and right or right and width. In the vertical direction, top, bottom, and height are similar and need not be repeated.

center / radius Positioning Method

-

center

Is an array representing [x, y], where x and y can be 'absolute values' or 'percentages', with the same meanings as previously described.

-

radius

Is an array representing [inner radius, outer radius], where the inner and outer radii can be 'absolute values' or 'percentages', with the same meanings as previously described.

Percentage settings are very useful when adapting to container size changes.

Horizontal and Vertical

ECharts' 'narrow and long' components (such as legend, visualMap, dataZoom, timeline, etc.) generally provide options for 'horizontal layout' and 'vertical layout'. For example, on narrow mobile screens, 'vertical layout' may be suitable; on PC wide screens, 'horizontal layout' may be suitable.

The settings for horizontal and vertical layouts are usually on the 'component' or 'series' configuration item, set to 'horizontal' or 'vertical'.


Example

In the following example, you can try dragging the circle at the bottom right, and the chart will change with the screen size, with the legend and series automatically adjusting their layout positions and methods.

In this example, we use jQuery to load external data, and we need to include the jQuery library when using it.

Example

$.when(
    $.getScript('https://www.tutorialpro.org/static/js/timelineGDP.js'),
    $.getScript('https://www.tutorialpro.org/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 Diagram',
                subtext: 'Purely Fictional',
                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%']
            }
        ]
    }
}
]
};
Currently supports three properties: width, height, and aspectRatio (aspect ratio). Each property can be prefixed with min or max. 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 configuration item can be written. However, generally, we only write those related to layout positioning, such as taking a part of the query option from the example above:

media: [ ..., { query: { maxAspectRatio: 1 // When the aspect ratio is less than 1. }, option: { legend: { // Legend placed at the bottom center. right: 'center', bottom: 0, orient: 'horizontal' // Legend laid out horizontally. }, series: [ // Two pie charts laid out side by side. { radius: [20, '50%'], center: ['50%', '30%'] }, { radius: [30, '50%'], center: ['50%', '70%'] } ] } }, { query: { maxWidth: 500 // When the container width is less than 500. }, option: { legend: { right: 10, // Legend placed on the right center. top: '15%', orient: 'vertical' // Vertical layout. }, series: [ // Two pie charts laid out vertically. { 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 simultaneously, and all will be merged with the option, with those defined later having higher priority.

### Default Query

If a query is not written in a media item, it represents the 'default value', meaning this option is adopted when none of the rules are satisfied.

### Considerations for Real-Time Changes in Container Size

In many cases, the container DOM node does not need to change size arbitrarily with dragging, but rather is set to a few typical sizes based on different terminals.

However, if the container DOM node needs to change size arbitrarily with dragging, it is currently necessary to pay attention to this: A configuration item, if it appears in one query option, must also appear in other query options, otherwise it cannot revert to the original state. (left/right/top/bottom/width/height are not subject to this restriction.)

### Media in 'Composite Option' Does Not Support Merge

Below we use jQuery to load external data, and we need to include the jQuery library when using it. This example is combined with a timeline:

## Example

$.when( $.getScript('https://www.tutorialpro.org/static/js/timelineGDP.js'), $.getScript('https://www.tutorialpro.org/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 (billion 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 Proportion', 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 Proportion', 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 Proportion', 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 Proportion', center: ['45%', '20%'], radius: '28%'} ] } } ], options: [ { title: {text: '2002 National Macro Economic 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 Macro Economic 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 Macro Economic 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 Macro Economic 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 Macro Economic 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 Macro Economic 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 Macro Economic 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 Macro Economic 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);

});
❮ Home Echarts Tutorial ❯