使用ECharts繪製網址徑向樹狀圖

an.rustfisher.com有很多內容,很多頁面。如果用一個樹狀圖把所有頁面展示出來會是什麼效果?
第一時間想到了ECharts

最後效果: https://an.rustfisher.com/an-tree.html

數據處理

數據來源於配置文件。我們只需要把內容讀出來,整理成ECharts需要的格式並保存爲文件。

yml

Android站用的框架是Mkdocs,網址都設置在mkdocs.yml裏。關鍵配置如下

nav:
  - Android basic:
    - 開始:
      - 新建工程: android/startProject/start_new_project.md
      - 使用Kotlin: android/startProject/as-use-kotlin.md
    - Activity:
      - Activity綜述: android/activity/overview.md

我們需要把這些數據讀出來,弄成ECharts可以用的格式。

打開PyCharm,用python來處理數據。

python處理數據

我們使用3.7版本python。要讀取yml的內容,不想用讀文本的方式一行行來讀,還得自己解析。
python中有個庫PyYAML專門用於讀取yml格式的數據。

在PyCharms裏裝上這個包。用它來讀取yml裏的數據。

import yaml

    with open(md_file, encoding='utf8') as a_yaml_file:
        # 解析yaml
        yaml_data = yaml.load(a_yaml_file, Loader=yaml.FullLoader)
        nav = yaml_data['nav']

ECharts需要的格式是namechildren。同時可以添加別的字段。

{
  "name": "Android教程",
  "children": [
    {
      "name": "Android basic",
      "children": []
    }]
}

讀取到的數據層級比較多,用遞歸方法來處理它們。把所有的數據都遍歷一遍,整理成需要的格式。

遞歸的時候,遇到數組,則繼續遞歸;遇到字符串,則表示可以拼接網址了。

完整腳本如下

import json
import os
import yaml


def gen_url_map(main_site, md_file):
    with open(md_file, encoding='utf8') as a_yaml_file:
        # 解析yaml
        yaml_data = yaml.load(a_yaml_file, Loader=yaml.FullLoader)

        nav = yaml_data['nav']

        sorted_data = {"name": "Android教程", "children": [], "collapsed": False}

        for big_dict in nav:
            load_url(main_site, big_dict, sorted_data)

        url_file = 'android-url-map.json'
        if os.path.exists(url_file):
            os.remove(url_file)
        with open(url_file, 'w') as s:
            s.write(str(json.dumps(sorted_data, ensure_ascii=False)))


def load_url(main_site, input_dict, res_data):
    """
    遞歸處理數據
    """
    for k1 in input_dict:
        v1 = input_dict[k1]
        if isinstance(v1, list):
            item1 = {"name": k1, "children": []}
            res_data['children'].append(item1)
            for v1_child in v1:
                load_url(main_site, v1_child, item1)
        elif isinstance(v1, str):
            # 此時已經是url了
            final_item = {"name": k1, "url": main_site + v1[0:-3]}
            res_data['children'].append(final_item)
            return final_item


if __name__ == '__main__':
    print("生成android站的sitemap")
    gen_url_map('https://www.an.rustfisher.com/',
                '/Users/rustfisher/mkdocs.yml')

最後寫一個android-url-map.json文件。

製作網頁

經過觀察,我們選用徑向樹狀圖(tree-radial)。
查看ECharts的徑向樹狀圖使用示例,下載一個示例html,在它的基礎上修改。

添加上jquery的引用。

<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script>

修改要讀取的json文件名

$.getJSON('./android-url-map.json', function (data) { /* ... */ }

把前面得到的json文件和這個html文件放在同一層級,上傳服務器。

打開: https://an.rustfisher.com/an-tree.html 可以看到效果。

擴大顯示範圍

這個時候的網頁體驗不是很好,頁面不夠大,圖表超出上下範圍了。可以給它添個豎直的滾動條overflow-y: scroll

<html style="height: 100%; width: 100%; overflow-y: scroll;">

修改一下網頁的body。外層的container佔100%寬高,裏面的chartContainer給一個min-height: 1600px

<body style="height: 100%; margin: 0; width: 100%;">
    <div id="container" style="height: 100%; width: 100%;">
        <div id="chartContainer" style="width: 100%; min-height: 1600px"></div>
    </div>

script里加上對resize的監聽

$(window).on('resize', function () {
    if (myChart != null && myChart != undefined) {
        myChart.resize();
    }
});

這時再看瀏覽器的效果,圖表有了更多的空間顯示。

參考

點擊打開頁面

默認點擊效果是摺疊和展開。對於最末尾的葉子節點,加一個點擊事件讓它打開相應的界面。

myChart.on('click', function (params) {
    if (params.data && params.data.url) {
        window.open(params.data.url);
    }
});

最後效果: https://an.rustfisher.com/an-tree.html

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