Flask框架利用ajax數據驅動Echarts可視化

Python的可視化工具

python的數據可視化工具有很多,比如常見的matplotlib,但是講到視覺效果的華麗,動態的交互,目前最漂亮的應該就是Echarts了。用Echarts可以做出很多漂亮的圖形。Python裏也有pyecharts,但是這種單一的圖表頁面做簡單展示還可以,做一個完整的項目案例就比較麻煩了。
我對js幾乎不懂,不過看了一下語法結構,還是很接近python和C++的,而js的數據傳輸,一般通過POST+ajax推送json數據完成(也許是我見到太少),這種語句比較常見,把語句做好了解析就可以用到單個需要數據驅動的Echarts上面。這是常見的思路。

Flask驅動Echarts的路線圖

  1. 設計圖表頁面,引用echarts.js,設計圖表框架
  2. 圖表框架中嵌入接收數據的ajax
  3. Flask發送圖表頁面echarts.html
  4. Flask發送接送數據json
  5. 瀏覽器渲染圖表頁面echarts,運行含有ajax的js之後接收json數據
  6. json數據填充echarts,圖表頁面渲染完成

從這個路線圖看,起始都是flask向瀏覽器發送數據,對於瀏覽器來說,只不過是兩次"GET",並不是太難。
接下來,分佈進行實施。

1.設計圖表頁面

在head中引入echarts.js
在body中留出一個容器Dom,這都是常見操作

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>ECharts</title>
    <!-- 引入 echarts.js -->
    <script type="text/javascript"  src="{{ url_for('static',filename='js/echarts.min.js') }}"></script>
</head>
<body>
 	<!-- 爲ECharts準備一個具備大小(寬高)的Dom -->
    <div id="main" style="width: 600px;height:600px;"></div>
    <!-- 定義echarts結構的JavaScript -->
</body>
</html>

接下來在body中設計JavaScript 定義echarts對象結構。
用item_name代表echarts的X軸名稱,item_value代表名稱對應的值

  <script type="text/javascript">
        // 基於準備好的dom,初始化echarts實例
        var myChart = echarts.init(document.getElementById('main'));

        //建立ajax所需的json數據
        var json_data=
        {   item_name:[], item_value:[] };

        //發送ajax數據請求
        $(document).ready(function()
        {
            getData();
        });
    </script>

2.圖表框架中嵌入接收數據的ajax

接下來,設計接收數據的ajax放到getDta()函數中。
ajax之後,是加載數據到圖表中。
再補一個出錯處理。
可以看到,ajax接收的是封裝的json,也就是文本化的dictionary。這對後臺來說,簡直太方便了。

  function getData()
         {
                    $.ajax({
		                    url:'/echart_json',  //渲染的是/ehart_json下的json數據
		                    data:{},     //接收數據存放的位置
		                    type:'GET',  //此處是從服務器獲取數據,不涉及發送,因此是GET
		                    async:false,  //異步請求 同步請求將會鎖住瀏覽器,用戶其他操作必須等待請求完成纔可以執行,默認false
		                    dataType:'json',
		                    success:function(data)
		                   {    json_data=data;
		                        // 指定圖表的配置項和數據
			                    var option =({
		                       title: {text:'大燈材料類型'},
		                        tooltip: {},
		                        legend: { data:['材料'] },
		                        //X軸是由json發送的字典中item_name獲取的
		                        xAxis: { data: json_data['item_name']},
		                        yAxis: {},
		                        //Y軸數據系列1的data是由json發送的字典中item_value獲取的
		                        series: [{name: '數量',
		                                    type: 'bar',
		                                    data: json_data['item_value']}]
                        });
                        myChart.hideLoading(); //隱藏加載動畫
                        myChart.setOption(option);  // 初次加載圖表
                     },
                     
                    //如獲取數據失敗,則提示
                    error:function(msg)
                    { console.log(msg);
                      alert("數據加載失敗!請檢查數據鏈接是否正確");}
                    })

這部分函數設計完成之後,放到剛纔的JavaScript中。這段函數是從網上抄的,但是看起來並不是很費力。

3.Flask發送圖表頁面

在視圖代碼中加入圖表頁面的路由代碼:

from flask import Flask,Response,request
from flask import url_for
from flask import render_template
import json
app = Flask(__name__)
@app.route('/echarts')
def echarts():
    return render_template('echarts.html',title='echarts')

4.Flask發送圖表Json數據

在視圖代碼中加入發送json數據的路由代碼:

def Response_headers(content):
    resp = Response(content)
    resp.headers['Access-Control-Allow-Origin'] = '*'
    return resp
    
@app.route('/echart_json')
def get_data():
    item_name = ['LED', '鹵素', '氙氣']
    item_value = ['266', '126', '15']
    datas = {'item_name': item_name, 'item_value': item_value}
    # 如果有中文的話,就需要ensure_ascii=False
    content = json.dumps(datas, ensure_ascii=False)
    resp = Response_headers(content)
    return resp

5.瀏覽器渲染頁面接收數據

在這裏插入圖片描述

6.Echarts格式調整

(1) 以下是柱狀圖的參數設置,參考博客:https://blog.csdn.net/qq_42816550/article/details/91604978
寫的非常清楚,用心了。
版權聲明:本文爲CSDN博主「除了奮鬥別無選擇」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上

//定義圖表option  
            var option = {  
                //標題,每個圖表最多僅有一個標題控件,每個標題控件可設主副標題  
                title: {  
                    //主標題文本,'\n'指定換行  
                    text: '2013年廣州降水量與蒸發量統計報表',  
                    //主標題文本超鏈接  
                    link: 'http://www.tqyb.com.cn/weatherLive/climateForecast/2014-01-26/157.html',  
                    //副標題文本,'\n'指定換行  
                    subtext: 'www.stepday.com',  
                    //副標題文本超鏈接  
                    sublink: 'http://www.stepday.com/myblog/?Echarts',  
                    //水平安放位置,默認爲左側,可選爲:'center' | 'left' | 'right' | {number}(x座標,單位px)  
                    x: 'left',  
                    //垂直安放位置,默認爲全圖頂端,可選爲:'top' | 'bottom' | 'center' | {number}(y座標,單位px)  
                    y: 'top'  
                },  
                //提示框,鼠標懸浮交互時的信息提示  
                tooltip: {  
                    //觸發類型,默認('item')數據觸發,可選爲:'item' | 'axis'  
                    trigger: 'axis'  
                },  
                //圖例,每個圖表最多僅有一個圖例  
                legend: {  
                    //顯示策略,可選爲:true(顯示) | false(隱藏),默認值爲true  
                    show: true,  
                    //水平安放位置,默認爲全圖居中,可選爲:'center' | 'left' | 'right' | {number}(x座標,單位px)  
                    x: 'center',  
                    //垂直安放位置,默認爲全圖頂端,可選爲:'top' | 'bottom' | 'center' | {number}(y座標,單位px)  
                    y: 'top',  
                    //legend的data: 用於設置圖例,data內的字符串數組需要與sereis數組內每一個series的name值對應  
                    data: ['蒸發量','降水量']  
                },  
                //工具箱,每個圖表最多僅有一個工具箱  
                toolbox: {  
                    //顯示策略,可選爲:true(顯示) | false(隱藏),默認值爲false  
                    show: true,  
                    //啓用功能,目前支持feature,工具箱自定義功能回調處理  
                    feature: {  
                        //輔助線標誌  
                        mark: {show: true},  
                        //dataZoom,框選區域縮放,自動與存在的dataZoom控件同步,分別是啓用,縮放後退  
                        dataZoom: {  
                            show: true,  
                             title: {  
                                dataZoom: '區域縮放',  
                                dataZoomReset: '區域縮放後退'  
                            }  
                        },  
                        //數據視圖,打開數據視圖,可設置更多屬性,readOnly 默認數據視圖爲只讀(即值爲true),可指定readOnly爲false打開編輯功能  
                        dataView: {show: true, readOnly: true},  
                        //magicType,動態類型切換,支持直角系下的折線圖、柱狀圖、堆積、平鋪轉換  
                        magicType: {show: true, type: ['line', 'bar']},  
                        //restore,還原,復位原始圖表  
                        restore: {show: true},  
                        //saveAsImage,保存圖片(IE8-不支持),圖片類型默認爲'png'  
                        saveAsImage: {show: true}  
                    }  
                },  
                //是否啓用拖拽重計算特性,默認關閉(即值爲false)  
                calculable: true,  
                //直角座標系中橫軸數組,數組中每一項代表一條橫軸座標軸,僅有一條時可省略數值  
                //橫軸通常爲類目型,但條形圖時則橫軸爲數值型,散點圖時則橫縱均爲數值型  
                xAxis: [  
                    {  
                        //顯示策略,可選爲:true(顯示) | false(隱藏),默認值爲true  
                        show: true,  
                        //座標軸類型,橫軸默認爲類目型'category'  
                        type: 'category',  
                        //類目型座標軸文本標籤數組,指定label內容。 數組項通常爲文本,'\n'指定換行  
                        data: ['1月','2月','3月','4月','5月','6月','7月','8月','9月','10月','11月','12月']  
                    }  
                ],  
                //直角座標系中縱軸數組,數組中每一項代表一條縱軸座標軸,僅有一條時可省略數值  
                //縱軸通常爲數值型,但條形圖時則縱軸爲類目型  
                yAxis: [  
                    {  
                        //顯示策略,可選爲:true(顯示) | false(隱藏),默認值爲true  
                        show: true,  
                        //座標軸類型,縱軸默認爲數值型'value'  
                        type: 'value',  
                        //分隔區域,默認不顯示  
                        splitArea: {show: true}  
                    }  
                ],  
                  
                //sereis的數據: 用於設置圖表數據之用。series是一個對象嵌套的結構;對象內包含對象  
                series: [  
                    {  
                        //系列名稱,如果啓用legend,該值將被legend.data索引相關  
                        name: '蒸發量',  
                        //圖表類型,必要參數!如爲空或不支持類型,則該系列數據不被顯示。  
                        type: 'bar',  
                        //系列中的數據內容數組,折線圖以及柱狀圖時數組長度等於所使用類目軸文本標籤數組axis.data的長度,並且他們間是一一對應的。數組項通常爲數值  
                        data: [2.0, 4.9, 7.0, 23.2, 25.6, 76.7, 135.6, 162.2, 32.6, 20.0, 6.4, 3.3],  
                        //系列中的數據標註內容  
                        markPoint: {  
                            data: [  
                                {type: 'max', name: '最大值'},  
                                {type: 'min', name: '最小值'}  
                            ]  
                        },  
                        //系列中的數據標線內容  
                        markLine: {  
                            data: [  
                                {type: 'average', name: '平均值'}  
                            ]  
                        }  
                    },  
                    {  
                        //系列名稱,如果啓用legend,該值將被legend.data索引相關  
                        name: '降水量',  
                        //圖表類型,必要參數!如爲空或不支持類型,則該系列數據不被顯示。  
                        type: 'bar',  
                        //系列中的數據內容數組,折線圖以及柱狀圖時數組長度等於所使用類目軸文本標籤數組axis.data的長度,並且他們間是一一對應的。數組項通常爲數值  
                        data: [2.6, 5.9, 9.0, 26.4, 28.7, 70.7, 175.6, 182.2, 48.7, 18.8, 6.0, 2.3],  
                        //系列中的數據標註內容  
                        markPoint: {  
                            data: [  
                                {type: 'max', name: '最大值'},  
                                {type: 'min', name: '最小值'}  
                            ]  
                        },  
                        //系列中的數據標線內容  
                        markLine: {  
                            data: [  
                                {type: 'average', name: '平均值'}  
                            ]  
                        }  
                    }  
                ]  
            };  
                  
            //爲echarts對象加載數據              
            myChart.setOption(option);  
        }  
    );  

(2)還有一個比較重要的是formatter的設置
這是整個圖形的tooltip的formatter,可以設置鼠標經過的提示文字

tooltip: {
                            trigger: 'item',
                            折線(區域)圖、柱狀(條形)圖、K線圖 : {a}(系列名稱),{b}(類目值),{c}(數值), {d}(無)
							散點圖(氣泡)圖 : {a}(系列名稱),{b}(數據名稱),{c}(數值數組), {d}(無)
							地圖 : {a}(系列名稱),{b}(區域名稱),{c}(合併數值), {d}(無)
							餅圖、儀表盤、漏斗圖: {a}(系列名稱),{b}(數據項名稱),{c}(數值), {d}(百分比)
                            formatter:  "{a} <br/>{c} ({d}%)" //顯示 “系列名稱 系列名稱 20 (50%)”之類的效果
             }               

還有series裏label的famatter設置:

  itemStyle: { normal:
                                                  { label: 
                                                    {formatter: "{c}\n{d}%",
                                                        show: true,
                                                        position: "inside",
                                                        textStyle: {fontWeight: "bolder", fontSize: "12",color: "#000000" } }
                                                  }
                                               }

可以在餅圖裏顯示數量下一行百分比的效果。

7.Echarts最終效果

以下是調整後的最終效果,該有的都有了
關鍵的是json數據在後臺輸入,利用pymysql查詢數據庫轉json這個難度就非常小了。
所以,通過這種方式,打通數據庫與可視化Echarts界面的連接,可以說一件非常有意義的事情。
在這裏插入圖片描述
在這裏插入圖片描述

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