ECharts實(shí)現(xiàn)移動(dòng)端自適應(yīng)

2018-08-26 12:00 更新

用戶(hù)使用 Echarts 工作的時(shí)候所需要用到的 組件系列 都在指定高寬的 DOM 節(jié)點(diǎn)(容器)中,其中每個(gè)節(jié)點(diǎn)都可以由用戶(hù)指定位置。

Echarts 圖表庫(kù)內(nèi)部采用的是類(lèi)似于絕對(duì)布局的易于理解的布局方式,因?yàn)閷?shí)現(xiàn) DOM 文檔流布局是不合適的。但是圖表庫(kù)所采用的布局方式會(huì)受到容器尺寸的影響,出現(xiàn)組件重疊的情況。這就帶來(lái)了一個(gè)問(wèn)題:如果圖表需要同時(shí)在 PC端和移動(dòng)端展示,該怎么解決內(nèi)部組件的布局?

上述問(wèn)題需要 Echarts 內(nèi)部組件能夠自動(dòng)地隨著容器尺寸的改變而進(jìn)行調(diào)整的能力。為了解決這個(gè)問(wèn)題,ECharts 完善了組件的定位設(shè)置,并且實(shí)現(xiàn)了類(lèi)似 CSS Media Query 的自適應(yīng)能力。

ECharts 組件的定位和布局


Echarts 中大部分組件系列會(huì)遵循兩種定位方式:

  • left/right/top/bottom/width/height 定位方式
  • center / radius 定位方式

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

該定位方式中的六個(gè)量,每個(gè)量都可以當(dāng)做 絕對(duì)值、百分比 或者 位置描述

  • 絕對(duì)值的單位是瀏覽器像素(px),用 number 形式書(shū)寫(xiě)(不寫(xiě)單位)。例如 {left: 23, height: 400}。
  • 百分比表示占 DOM 容器高寬的百分之多少,用 string 形式書(shū)寫(xiě)。例如 {right: '30%', bottom: '40%'}。
  • 位置描述可以設(shè)置 left: 'center',表示水平居中??梢栽O(shè)置 top: 'middle',表示垂直居中。

這六個(gè)量的概念,和 CSS 中六個(gè)量的概念類(lèi)似:

  • left:表示距離 DOM 容器左邊界的距離。
  • right:表示距離 DOM 容器右邊界的距離。
  • top:表示距離 DOM 容器上邊界的距離。
  • bottom:表示距離 DOM 容器下邊界的距離。
  • width:表示寬度。
  • height:表示高度。

小提示:

在表示橫向的量的時(shí)候,由于組件的位置和大小可以由任意的兩個(gè)量決定,所以在 left、right、width 三個(gè)量中,可以只提供兩個(gè)量的值。至于取哪兩個(gè)量的值就取決于用戶(hù),例如 left 和 right 或者 right 和 width 都可以決定組件的位置和大小。 

同理,在表示縱向的量 top、bottom、height 時(shí),取值與橫向量相同。

center / radius 定位方式

  • center 是一個(gè)數(shù)組,表示 [x, y],其中,x、y 可以是絕對(duì)值或者百分比,含義與前面描述的相同。
  • radius 是一個(gè)數(shù)組,表示 [內(nèi)半徑, 外半徑],其中,內(nèi)外半徑可以是絕對(duì)值或者百分比,含義與前面描述的相同。

注意:在自適應(yīng)容器大小時(shí),百分比設(shè)置是很有用的。

橫向(horizontal)和縱向(vertical)

ECharts 中像 legend、visualMap、dataZoom、timeline等狹長(zhǎng)型的組件,大部分都有橫向布局縱向布局這兩種選擇。例如,在寬少長(zhǎng)多的移動(dòng)端屏幕上,使用縱向布局更為合適;而在屏幕較寬的 PC 端上,則要選擇使用橫向布局。

橫縱向布局的設(shè)置:

  • 一般在組件或者系列的 orient 或者 layout 配置項(xiàng)上,設(shè)置為 'horizontal' 或者 'vertical'。

與 ECharts2 的兼容性:

ECharts2 中可以使用如 x/x2/y/y2 的命名方式,分別對(duì)應(yīng) left/right/top/bottom。但是寫(xiě)成 left/right/top/bottom 會(huì)更為規(guī)范。

為了兼容 ECharts2,在描述位置的時(shí)候可以支持一些看起來(lái)略奇怪的設(shè)置,例如:left: 'right'、left: 'left'、top: 'bottom'、top: 'top'。這些語(yǔ)句分別等效于:right: 0、left: 0、bottom: 0、top: 0,寫(xiě)成后者就不奇怪了。

Media Query


Media Query 提供了隨著容器尺寸改變而改變的能力。

下面的例子,可以拖動(dòng)右下角的圓點(diǎn)改變尺寸,隨著尺寸變化,legend 和 系列會(huì)自動(dòng)改變布局位置和方式:

南丁格爾玫瑰圖

點(diǎn)擊編輯實(shí)例 》》

在 option 中設(shè)置 Media Query 需要遵循下面的格式:

option = {
    baseOption: { // 這里是基本的『原子option』。
        title: {...},
        legend: {...},
        series: [{...}, {...}, ...],
        ...
    },
    media: [ // 這里定義了 media query 的逐條規(guī)則。
        {
            query: {...},   // 這里寫(xiě)規(guī)則。
            option: {       // 這里寫(xiě)此規(guī)則滿(mǎn)足下的option。
                legend: {...},
                ...
            }
        },
        {
            query: {...},   // 第二個(gè)規(guī)則。
            option: {       // 第二個(gè)規(guī)則對(duì)應(yīng)的option。
                legend: {...},
                ...
            }
        },
        {                   // 這條里沒(méi)有寫(xiě)規(guī)則,表示『默認(rèn)』,
            option: {       // 即所有規(guī)則都不滿(mǎn)足時(shí),采納這個(gè)option。
                legend: {...},
                ...
            }
        }
    ]
};

上述例子中的 baseOption、以及 media 每個(gè) option 都是原子 option,即普通的含有各組件、系列定義的 option。而由原子option組合成的整個(gè) option,我們稱(chēng)為復(fù)合 option。baseOption 是必然被使用的,此外,滿(mǎn)足了某個(gè) query 條件時(shí),對(duì)應(yīng)的 option 會(huì)被使用 chart.mergeOption() 來(lái) merge 進(jìn)去。

query:

每個(gè) query 可以寫(xiě)成下述形式:

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

目前 query 支持三個(gè)屬性:width、height、aspectRatio(長(zhǎng)寬比)。每個(gè)屬性都可以加上 min 或 max 前綴。比如,minWidth: 200 表示 大于等于200px寬度 。兩個(gè)屬性一起寫(xiě)表示   ,例如:{minWidth: 200, maxHeight: 300} 表示 大于等于200px寬度,且小于等于300px高度 。

option:

media 中的 option 既然是 原子 option ,理論上可以寫(xiě)任何 option 的配置項(xiàng)。但是一般我們只寫(xiě)跟布局定位相關(guān)的,例如截取上面例子中的一部分 query option:

media: [
    ...,
    {
        query: {
            maxAspectRatio: 1           // 當(dāng)長(zhǎng)寬比小于1時(shí)。
        },
        option: {
            legend: {                   // legend 放在底部中間。
                right: 'center',
                bottom: 0,
                orient: 'horizontal'    // legend 橫向布局。
            },
            series: [                   // 兩個(gè)餅圖左右布局。
                {
                    radius: [20, '50%'],
                    center: ['50%', '30%']
                },
                {
                    radius: [30, '50%'],
                    center: ['50%', '70%']
                }
            ]
        }
    },
    {
        query: {
            maxWidth: 500               // 當(dāng)容器寬度小于 500 時(shí)。
        },
        option: {
            legend: {
                right: 10,              // legend 放置在右側(cè)中間。
                top: '15%',
                orient: 'vertical'      // 縱向布局。
            },
            series: [                   // 兩個(gè)餅圖上下布局。
                {
                    radius: [20, '50%'],
                    center: ['50%', '30%']
                },
                {
                    radius: [30, '50%'],
                    center: ['50%', '75%']
                }
            ]
        }
    },
    ...
]

具有多個(gè) query 時(shí)的優(yōu)先級(jí):

注意,可以有多個(gè) query 同時(shí)被滿(mǎn)足,會(huì)都被 mergeOption,定義在后的后被 merge(即優(yōu)先級(jí)更高)。

默認(rèn) query:

如果 media 中有某項(xiàng)不寫(xiě) query,則表示『默認(rèn)值』,即所有規(guī)則都不滿(mǎn)足時(shí),采納這個(gè)option。

容器大小實(shí)時(shí)變化時(shí)的注意事項(xiàng):

如果容器DOM節(jié)點(diǎn)需要能任意隨著拖拽變化大小,那么目前使用時(shí)需要注意這件事:某個(gè)配置項(xiàng),如果在某一個(gè) query option 中出現(xiàn),那么在其他 query option 中也必須出現(xiàn),這樣才能夠回歸到原來(lái)的狀態(tài)。(left/right/top/bottom/width/height 不受這個(gè)限制。)

復(fù)合 option 中的 media 不支持 merge

也就是說(shuō),當(dāng)?shù)诙ɑ蛉?、四、?...)次 chart.setOption(rawOption) 時(shí),如果 rawOption 是 復(fù)合 option(即包含 media 列表),那么新的 rawOption.media 列表不會(huì)和老的 media 列表進(jìn)行 merge,而是簡(jiǎn)單替代。當(dāng)然,rawOption.baseOption 仍然會(huì)正常和老的 option 進(jìn)行merge。

其實(shí),很少有場(chǎng)景需要使用 復(fù)合 option 來(lái)多次 setOption,而我們推薦的做法是,使用 mediaQuery 時(shí),第一次 setOption 使用 復(fù)合 option ,后面 setOption 時(shí)僅使用 原子 option,也就是僅僅用 setOption 來(lái)改變 baseOption。

最后看一個(gè)和時(shí)間軸結(jié)合的例子:

ECharts 組件的定位和布局實(shí)例

點(diǎn)擊編輯實(shí)例 》》

以上內(nèi)容是否對(duì)您有幫助:
在線(xiàn)筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)