ECharts官方教程(七)【移動端自適應】

移動端自適應

ECharts 工作在用戶指定高寬的 DOM 節點(容器)中。ECharts 的『組件』和『系列』都在這個 DOM 節點中,每個節點都可以由用戶指定位置。圖表庫內部並不適宜實現 DOM 文檔流佈局,因此採用類似絕對佈局的簡單容易理解的佈局方式。但是有時候容器尺寸極端時,這種方式並不能自動避免組件重疊的情況,尤其在移動端小屏的情況下。

另外,有時會出現一個圖表需要同時在PC、移動端上展現的場景。這需要 ECharts 內部組件隨着容器尺寸變化而變化的能力。

爲了解決這個問題,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:高度。

在橫向,leftrightwidth 三個量中,只需兩個量有值即可,因爲任兩個量可以決定組件的位置和大小,例如 leftright 或者 rightwidth 都可以決定組件的位置和大小。 縱向,topbottomheight 三個量,和橫向類同不贅述。

center/radius 定位方式:

  • center

    是一個數組,表示 [x, y],其中,x、y可以是『絕對值』或者『百分比』,含義和前述相同。

  • radius

    是一個數組,表示 [內半徑, 外半徑],其中,內外半徑可以是『絕對值』或者『百分比』,含義和前述相同。

    在自適應容器大小時,百分比設置是很有用的。

橫向(horizontal)和縱向(vertical

ECharts的『外觀狹長』型的組件(如 legend、visualMap、dataZoom、timeline等),大多提供了『橫向佈局』『縱向佈局』的選擇。例如,在細長的移動端屏幕上,可能適合使用『縱向佈局』;在PC寬屏上,可能適合使用『橫向佈局』。

橫縱向佈局的設置,一般在『組件』或者『系列』的 orient 或者 layout 配置項上,設置爲 'horizontal' 或者 'vertical'

於 ECharts2 的兼容:

ECharts2 中的 x/x2/y/y2 的命名方式仍被兼容,對應於 left/right/top/bottom。但是建議寫 left/right/top/bottom

位置描述中,爲兼容 ECharts2,可以支持一些看起來略奇怪的設置:left: 'right'、left: 'left'、top: 'bottom'、top: 'top'。這些語句分別等效於:right: 0、left: 0、bottom: 0、top: 0,寫成後者就不奇怪了。

Media Query

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

如下例子,可嘗試拖動右下角的圓點,隨着尺寸變化,legend 和 系列會自動改變佈局位置和方式。
在這裏插入圖片描述要在 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
}

現在支持三個屬性:widthheightaspectRatio(長寬比)。每個屬性都可以加上 minmax 前綴。比如,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

最後看一個和時間軸結合的例子:
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章