echarts使用多圖的表達

記錄瞬間javascript

在實際的工做中總會遇到一些報表的展現問題,echarts做爲百度的開源工具針對做圖來講是不二選擇。css

教程連接: https://echarts.apache.org/zh/tutorial.html#5%20%E5%88%86%E9%92%9F%E4%B8%8A%E6%89%8B%20EChartshtml

參數設置:https://echarts.apache.org/zh/option.html#title前端

本文主要介紹使用echarts時關於一批關聯數據,展現到一張圖上的方法java

主要應用:flask+bootstrap+echartsapache

因爲使用flask的三方插件(pyecharts)在靈活處理非圖表數據時較爲複雜,因此須要考慮,單獨使用echarts進行考慮json

先將flask的pyecharts實現簡單代碼做以展現flask

def render_result(data):
    from pyecharts.charts import Bar, Grid, Timeline
    from pyecharts import options as opts
    # 內置主題類型可查看 pyecharts.globals.ThemeType
    from pyecharts.globals import ThemeType
    from pyecharts.globals import CurrentConfig
    from jinja2 import Markup, Environment, FileSystemLoader
    from pyecharts.commons.utils import JsCode
    # 關於 CurrentConfig,可參考 [基本使用-全局變量]
    CurrentConfig.GLOBAL_ENV = Environment(loader=FileSystemLoader("./templates/echarts"))
    # js代碼
    js_code_str = '''
                        function(params){
                        return params.data.text;
                        }
                        '''

    all_bar_keys = []
    # 獲取全部的key數據  result是從執行結果的數據信息中獲取的數據,不是最完整的數據結果
    for get_data in data:
        all_bar_keys += data[get_data]['result'].keys()
    # 去重
    get_bar_keys = list(set(all_bar_keys))  # 全部模塊名稱去重後的結果
    get_bar_keys.sort()                     # 排序保證每次顯示的結果一致
    all_keys = list(data.keys())            # 獲取執行的全部時間區間的值
    all_keys.sort(reverse=True)                         # 按照大小進行排序
    bar = (
        Bar(init_opts=opts.InitOpts(theme=ThemeType.LIGHT))
        .add_xaxis([i for i in range(1, len(all_keys))])
        .set_global_opts(title_opts=opts.TitleOpts(title="結果展現", subtitle="統計當前展現結果"),
                         tooltip_opts=opts.TooltipOpts(formatter=JsCode(js_code_str)),
                         toolbox_opts=opts.ToolboxOpts(is_show=True,
                                                       feature={"saveAsImage": {},
                                                                "dataZoom": {"yAxisIndex": "none"},
                                                                "restore": {},
                                                                "magicType": {"show": True, "type": ["line", "bar",
                                                                                                     "stack"]}})
                         )
    )

    for bar_key in get_bar_keys:  # 遍歷全部的模塊數據
        get_list = []  # 保存執行結果中的,未出現模塊個數數據,但不是最準確的數據結果

        temp_dict = {"value": 0, "text": ""}
        for data_key in all_keys:  # 遍歷全部時間區間,篩選出符合相關模塊的query詞
            temp_dict["text"] = data_key + "<br>" + bar_key
            if bar_key in data[data_key]['result']:  # 結果是從執行query詞的結果中獲取的,不是最準確的結果,可參考
                temp_dict["value"] = len(data[data_key]['result'][bar_key])
                get_list.append(copy.deepcopy(temp_dict))
            else:
                temp_dict["value"] = 0
                get_list.append(copy.deepcopy(temp_dict))

        bar_ = (
            Bar()
            .add_xaxis([i for i in range(1, len(all_keys))])
            .add_yaxis(bar_key, get_list)
        )
        bar.overlap(bar_)

    get_all_order_dict = {}
    all_bar = []    # 保存全部模塊下的柱狀圖
    row_list = []   # 記錄行數據
    count = 1       # 遍歷全部模塊,每增長一個模塊進行 +1 處理
    revise = 0      # 數據校訂標記
    for bar_key in get_bar_keys:  # 遍歷全部的模塊數據
        get_all_order_dict[bar_key] = []
        for data_key in all_keys:
            if bar_key in data[data_key]['result']:
                for word in data[data_key]['result'][bar_key]:
                    if word not in get_all_order_dict[bar_key]:
                        get_all_order_dict[bar_key].append(word)
        get_len = len(str(get_all_order_dict[bar_key]))  # 獲取全部詞的長度
        rows = int(get_len / 85) + 1                     # 除以95後,獲取須要分幾行,每行在乘以30就能夠獲取到詞位置的高度了
        
        title_pos = 460 + 330 * (count - 1) + revise
        
        legend_pos = 510 + 330 * (count - 1) + revise
        row_list.append(rows)
        if row_list[count - 1] > 3:
            revise += (row_list[count - 1] - 3) * 30
        print(title_pos, legend_pos, revise)
        key_bar = (
            Bar(init_opts=opts.InitOpts(theme=ThemeType.DARK))
            .add_xaxis([i for i in range(1, len(all_keys))])
            .set_global_opts(title_opts=opts.TitleOpts(title="關鍵字統計展現-{}".format(bar_key),
                                                       subtitle="統計當前出現了關鍵字的相關詞展現結果",
                                                       pos_top="{}px".format(title_pos)),
                             tooltip_opts=opts.TooltipOpts(formatter=JsCode(js_code_str)),
                             legend_opts=opts.LegendOpts(pos_top="{}px".format(legend_pos),
                                                         is_show=True, selected_mode='single'))
            # selected_mode 可使用「single」、「multiple」使用單選或多選模式,默認爲multiple
        )
        count += 1
        for word in get_all_order_dict[bar_key]:
            get_keys = []               # 保存全部模塊的對應query詞的個數數據,準確的結果
            temp_dict = {"value": 0, "text": ""}
            for data_key in all_keys:   # 遍歷結果數據
                temp_dict["text"] = word + '<br>' + data_key + '<br>' + bar_key
                if bar_key in data[data_key]["keys_order"]:
                    if word in data[data_key]["keys_order"][bar_key]:
                        temp_dict['value'] = 1
                        get_keys.append(copy.deepcopy(temp_dict))
                    else:
                        temp_dict['value'] = 0
                        get_keys.append(copy.deepcopy(temp_dict))
                else:
                    temp_dict['value'] = 1
                    get_keys.append(copy.deepcopy(temp_dict))
            key_bar_ = (
                Bar()
                .add_xaxis([i for i in range(1, len(all_keys))])
                .add_yaxis(word, get_keys)
            )
            key_bar.overlap(key_bar_)
        all_bar.append(copy.deepcopy(key_bar))

    grid = Grid(init_opts=opts.InitOpts(theme=ThemeType.LIGHT, width='1100px', height='{}px'.format(700+len(row_list)*365)))
    grid.add(bar, grid_opts=opts.GridOpts(pos_left="5%", pos_right="1%", height="350px"))
    # grid.add(key_bar, grid_opts=opts.GridOpts(pos_top="520px", pos_left="5%", pos_right="1%", height="30%"))
    count = 1    # 循環展現模塊的柱形圖
    revise = 0   # 校訂數據
    for key_bar in all_bar:
        # grid_pos = 600 + (240 + (sum(row_list[:count])) * 30) * (count - 1)
        if row_list[count - 1] > 3:
            revise += (row_list[count - 1] - 3) * 30
        grid_pos = 600 + 330 * (count - 1) + revise
        grid.add(key_bar, grid_opts=opts.GridOpts(pos_top="{}px".format(grid_pos), pos_left="5%",
                                                  pos_right="1%", height="150px"))
        count += 1
    # return Markup(bar.render_embed())
    return grid.render_embed()

 

方法調用以下:bootstrap

 1 @ots.route('aisi_summary', methods=["GET"])
 2 def aisi_summary():
 3     get_time = get_time_section(96, flag=True)[1]
 4     get_objs = TempData.objects(CREATE_TIME__gte=get_time).all()
 5     if get_objs and len(get_objs) > 85:
 6         data = sfo.aisi_summary()
 7         from jinja2 import Markup
 8         get_render = render_result(data=data)
 9         return Markup(get_render)       # 直接渲染結果
10     else:
11         # 準備數據過程當中
12         try:
13             executor.submit(sfo.aisi_summary, flag=True)
14         except:
15             pass
16         return render_template("aisi_summary.html", error="數據修整中,請稍後重試!")

固然使用前提是須要安裝pyecharts,並將pyecharts下面的模板放到templates目錄下,才能夠正常展現結果。app

此結果是按照既定的pyecharts的模板進行渲染展現的,因此很大程度上沒法進行非圖表數據的展現

 


 

# 引入echarts

咱們但願在展現圖表數據的過程當中,還要展現其餘的數據,好比:判斷結果,表格,說明等等

過程分爲:一、數據準備;二、渲染頁面;三、展現結果

數據準備代碼

 1 def total_result_for_data(data):
 2     result = {"height": 0, "x": [], "y": [], "title": ['結果概覽'], "count": 0}
 3     all_bar_keys = []
 4     # 獲取全部的key數據  result是從執行結果的數據信息中獲取的數據,不是最完整的數據結果
 5     for get_data in data:
 6         all_bar_keys += data[get_data]['result'].keys()
 7     # 去重
 8     get_bar_keys = list(set(all_bar_keys))   # 全部模塊名稱去重後的結果
 9     get_bar_keys.sort()                      # 排序保證每次顯示的結果一致
10     result['title'] += get_bar_keys          # 主標題設置
11     result['count'] = len(result['title'])   # 記錄顯示的柱形圖的個數
12     all_keys = list(data.keys())             # 獲取執行的全部時間區間的值
13     all_keys.sort(reverse=True)              # 按照大小進行排序
14     result['all_keys'] = all_keys
15     result['x'] = [i for i in range(1, len(all_keys)+1)]   # 生成x軸刻度
16     # 整體數據展現結果
17     get_all_order_dict = {}
18     row_list = []  # 記錄行數據
19     count = 1      # 遍歷全部模塊,每增長一個模塊進行 +1 處理
20     result['結果概覽_source'] = []
21     result['結果概覽'] = get_bar_keys
22     result['grid_pos'] = [100]
23     for bar_key in get_bar_keys:
24         set_date_key = {"name": bar_key, "type": "bar", "data": [], "label": {"show": "true"}}
25         for data_key in all_keys:           # 遍歷全部時間區間,篩選出符合相關模塊的query詞
26             temp_dict = {"value": 0, "text": data_key + '===' + bar_key}
27             get_all_order_dict[bar_key] = []
28             if bar_key in data[data_key]['result']:  # 結果是從執行query詞的結果中獲取的
29                 data_value = len(data[data_key]['result'][bar_key])
30                 temp_dict["value"] = len(data[data_key]['result'][bar_key])
31             else:
32                 temp_dict["value"] = 0
33                 data_value = 0
34             set_date_key["data"].append(copy.deepcopy(temp_dict))
35             if bar_key in data[data_key]['result']:
36                 for word in data[data_key]['result'][bar_key]:
37                     if word not in get_all_order_dict[bar_key]:
38                         get_all_order_dict[bar_key].append(word)
39         result['結果概覽_source'].append(copy.deepcopy(set_date_key))
40     print(result['結果概覽_source'])
41     for bar_key in get_bar_keys:            # 遍歷全部的模塊數據
42         result[bar_key + "_source"] = []
43         get_all_order_dict[bar_key] = []
44         for data_key in all_keys:           # 遍歷全部時間區間,篩選出符合相關模塊的query詞
45             if bar_key in data[data_key]['result']:
46                 for word in data[data_key]['result'][bar_key]:
47                     if word not in get_all_order_dict[bar_key]:
48                         get_all_order_dict[bar_key].append(word)
49         result[bar_key] = copy.deepcopy(get_all_order_dict[bar_key])
50 
51         get_len = len(str(get_all_order_dict[bar_key]))  # 獲取全部詞的長度
52         rows = int(get_len / 85) + 1            # 除以85後,獲取須要分幾行,每行在乘以30就能夠獲取到詞位置的高度了
53 
54         result['grid_pos'].append(70 + 30 * rows)
55 
56         count += 1
57         for word in get_all_order_dict[bar_key]:
58             set_date_key = {"name": word, "type": "bar", "data": [], "label": {"show": "true"}}
59             for data_key in all_keys:  # 遍歷結果數據
60                 temp_dict = {"value": 0, "text": word + '===' + data_key + '===' + bar_key}
61                 if bar_key in data[data_key]["keys_order"]:
62                     if word in data[data_key]["keys_order"][bar_key]:
63                         temp_dict["value"] = 1
64                     else:
65                         temp_dict["value"] = 0
66                 else:
67                     temp_dict["value"] = 1
68                 set_date_key["data"].append(copy.deepcopy(temp_dict))
69             result[bar_key + "_source"].append(copy.deepcopy(set_date_key))
70         print(result[bar_key + "_source"])
71 
72     result['height'] = (len(row_list) + 1) * 365
73 
74     return result

 

前端代碼以下

  1 <!DOCTYPE html>
  2 <html lang="en">
  3 <head>
  4     <meta charset="UTF-8">
  5 
  6     <meta name="viewport" content="width=device-width, initial-scale=1">
  7     <meta name="description" content="">
  8     <meta name="generator" content="Hugo 0.84.0">
  9     <title>數據分析</title>
 10     <link href="{{ url_for('static', filename='bs/css/bootstrap.min.css') }}" rel="stylesheet">
 11     <link href="{{ url_for('static', filename='bs/css/carousel.css') }}" rel="stylesheet">
 12     <!-- 引入echarts -->
 13     <script src="/static/js/echarts.min.js"></script>
 14 </head>
 15 <body>
 16 {% include "common/header.html" %}
 17 
 18 <div class="container">
 19     <main>
 20         <div style="margin-top:25px">
 21             <nav aria-label="breadcrumb">
 22               <ol class="breadcrumb">
 23                 <li class="breadcrumb-item"><a href="#">監控</a></li>
 24                 <li class="breadcrumb-item active" aria-current="page">數據分析</li>
 25               </ol>
 26             </nav>
 27         </div>
 28     <div class="px-4 py-5 my-5 text-left">
 29         {% if error %}
 30         <span style="color: #e4393c">{{ error }}</span>
 31         {% endif %}
 32     <table class="table table-hover">
 33         <tr><th style="text-align: center;font-size: 0.8cm;background-color: #c8e0cf">結果一覽</th></tr>
 34         <tr>
 35             <td>
 36                 <div id="main_picture"></div>
 37             </td>
 38         </tr>
 39         {% for foo in range(data.count) %}
 40         <tr>
 41             <td>
 42                 <div id="main_picture_{{ foo }}"></div>
 43             </td>
 44         </tr>
 45         {% endfor %}
 46     </table>
 47 
 48     </div>
 49     </main>
 50 </div>
 51 
 52 {% include "common/footer.html" %}
 53 
 54 <script src="/static/bs/js/bootstrap.bundle.min.js"></script>
 55 
 56 <script type="text/javascript">
 57     let temp_str = "{{ data }}".replace(/&#39;/g, '"');
 58     // 將接受的數據轉換爲json對象
 59     let obj = eval("("+temp_str+")");
 60     {% if data %}
 61         init(obj);
 62     {% endif %}
 63 
 64     function init(obj){
 65         console.log(obj);
 66         let num = obj.count;
 67         let xdata = obj.x;
 68         let title_data = obj.title;
 69         let grid_pos = obj.grid_pos
 70         for (let mpnum=0; mpnum<num; mpnum++){
 71             let main_picture = document.getElementById('main_picture_' + mpnum);
 72             //計算所須要的高度
 73             if (mpnum === 0) {
 74                 main_picture.style.height = "440px";
 75             } else {
 76                 main_picture.style.height = 150 + grid_pos[mpnum] + "px";
 77             }
 78             // 基於準備好的dom,初始化echarts實例
 79             let myChart = echarts.init(main_picture);
 80             let toolbox = [];      // 設置
 81             let legend = [];       // 圖例顯示
 82 
 83             //經過配置xAxi和yAxis的gridIndex  series的xAxisIndex和yAxisIndex 來配套格子
 84             let option = {
 85                 title: {
 86                       textAlign: "left",
 87                       text: title_data[mpnum],
 88                       subtext: title_data[mpnum],
 89                       top: "0px"
 90                 },
 91                 xAxis: {
 92                     type: "category",
 93                     data: xdata
 94                 },
 95                 yAxis: {
 96                   type: "value",
 97                   inverse: false,
 98                   splitLine: {
 99                     show: true
100                   }
101                 },
102                 series: obj[title_data[mpnum]+"_source"],
103                 grid: {
104                     left: "3%",
105                     right: "1%",
106                     width: "95%",
107                     top: grid_pos[mpnum] + "px"
108                 }
109             };
110             // 工具欄設置
111             if (mpnum === 0) {
112                 toolbox.push({
113                     show: true,
114                     feature: {
115                         mark: {show: true},
116                         dataZoom: {show: true},
117                         dataView: {show: true,readOnly: false},
118                         magicType: {show: true,type: ['line', 'bar', 'stack']},
119                         restore: {show: true},
120                         saveAsImage: {show: true}
121                     }
122                 });
123             } else {
124                 toolbox.push({
125                     show: false
126                 });
127             }
128             option["toolbox"] = toolbox[0];
129             option["tooltip"] = {
130                 position: "top",
131                 formatter: function (params) {
132                     return params.data.text.replace(/===/g, "<br>");
133                 }
134             };
135 
136             // 圖例設置
137             if (mpnum === 0){
138                 legend.push({
139                     selectedMode: 'multiple',
140                     top: "60px",
141                     show: true
142                 });
143             } else {
144                 legend.push({
145                     selectedMode: 'single',
146                     top: "60px",
147                     show: true
148                });
149             }
150             option["legend"] = legend[0];
151             // 使用剛指定的配置項和數據顯示圖表。
152             myChart.setOption(option);
153         }
154     }
155 </script>
156 </body>
157 </html>

 

展現結果如圖

 

 

 固然圖表都是動態加載的,整圖下面還有其餘的圖表,因爲截屏關係只截取當前兩張

注意:當前使用的都是最新的版本(bootstrap-v5.0、echarts-5.1.2)

 


 

供參考---結束了

===

相關文章
相關標籤/搜索