pyecharts和echarts的混合使用

来源:https://www.cnblogs.com/pozhu15/archive/2019/11/05/11799982.html
-Advertisement-
Play Games

ECharts是一個由百度開發的純 Javascript 的圖表庫,pyecharts是某三位大佬將ECharts移植到Python項目中的產物,在Python網站中可以更輕鬆的接入圖表,但是個人感覺pyecharts比ECharts還是局限很大的,pyecharts1.x版本就更為縮水了,由於項目 ...


  ECharts是一個由百度開發的純 Javascript 的圖表庫,pyecharts是某三位大佬將ECharts移植到Python項目中的產物,在Python網站中可以更輕鬆的接入圖表,但是個人感覺pyecharts比ECharts還是局限很大的,pyecharts0.5.x版本就更為縮水了,由於項目之前用的是pyecharts0.5.11版本,圖表比較少,不足以解決問題,甚至自己用js實現了兩個圖表來使用,美觀度比ECharts還是遜色不少,如果將項目遷移到新版pyecharts v1.0.0則更為麻煩,就直接在原來的項目中引入echarts庫來混合使用,pyecharts v1.0.0雖然完善了不少問題,但是加入了新的配置規則,學習起來增加了不少負擔,靈活度也沒有echarts好,個人建議如果項目中使用的圖表不是很複雜,數據靜態的可以使用pyecharts,複雜點的還是儘量使用echarts比較方便,下麵開始進入主題:

1. 安裝pyecharts:

pip install pyecharts==0.5.11  #0.5.x的舊版,我目前使用的這個,要用pyecharts的話建議安裝下麵的最新版

pip install pyecharts     #安裝最新版

 pyecharts使用圖表可以直接在視圖代碼裡面構建圖表,Django會將其渲染到前端模板頁面中:

# 主體圖-1
def visualPage(request):
    template = loader.get_template('visualModule/visualPage.html')  #載入模板文件
    
    parseArgData()
    
    data3D1,weights3D1,bar = drawBar() #得到圖表數據
    context = dict(     #context添加在模板中要渲染的數據
        myechart = bar.render_embed(),  #圖表數據
        host = DEFAULT_HOST,
        script_list = bar.get_js_dependencies(),  #由pyecharts引入需要用到的js代碼文件
        guestSetArgs=startArgsSet,
        warningdata=argList,
        data3D=data3D1,
        weights3D=weights3D1,
    )
    return HttpResponse(template.render(context, request))#

構建圖表函數,這裡只粘貼了圖表的介面代碼,數據處理和邏輯代碼略去:

def drawBar(): #繪製
        x_axis = ['','','','','','','','','','','',''] #X軸
        y_axis = [0,1,2,3,4,5,6,7,8,9,10,11]

    
        data = [
        #閉源5個
        dict(
        name = "",
        value=[so[0], sor[0], projects[0][0][""]],
        itemStyle=dict(color=getColorstr2(0,weights[0]))
        ),

        dict(
        name="",
        value=[so[4], sor4[2], projects[4][2][""]],
        itemStyle=dict(color=getColorstr2(4,weights[18]))
        ),

        ...
        ]
        bar3d = Bar3D("", width=1000, height=500)
        bar3d.add("",x_axis,y_axis, data,
        is_visualmap=False,
        is_xaxis_show=True,
        is_yaxis_show=False,
        is_splitline_show=False,
        xaxis3d_name =' ',
        yaxis3d_name =' ',

        #is_label_show =True,
        mark_point_symbol='circle',
        is_more_utils=True,
        mark_point=['max','min'],
        mark_line=['average'],

        zaxis3d_name ='評分',
        xaxis3d_interval =0,
        grid3d_width=150, grid3d_depth=100,
        grid3d_shading='realistic',
        is_grid3d_ratate = True,
        grid3d_rotate_speed=180,
        tooltip_formatter=formatter)

        bar3d.on(MOUSE_CLICK, on_click)
        return data,weights,bar3d

這樣就可以在前端顯示柱狀圖圖表了

 

 

 

另外項目中還使用了一個折線圖也是同樣做法:

 

 

 

其他圖表也是類似添加,可以參考pyecharts官網教程:

https://pyecharts.org/#/

2. 接下來在項目中再引入echarts來使用,和pyecharts混合使用互不影響

安裝可參考echarts官網:

https://www.echartsjs.com/zh/

去https://github.com/apache/incubator-echarts下載echarts源碼包,解壓出來的文件夾里的 dist 目錄里可以找到最新版本的 echarts 庫,直接在前端頁面中引入即可使用echarts圖表,

1 {% for jsfile_name in script_list %}
2         <script src="{{ host }}/{{ jsfile_name }}.js"></script>
3     {% endfor %}
4     
5          <script src="{% static 'js/dist/echarts.min.js' %}"></script>
6      <script src="{% static 'js/dist/echarts-gl.js' %}"></script>
 <div id="container3" style="height: 800px"></div>
    
       <script type="text/javascript">
       //echarts柱狀圖
var dom3 = document.getElementById("container3");
var myChart3 = echarts.init(dom3);
var app = {};
option = null;

var hours = [];
var days = [];

$.get("{% static 'json/eachBar3dData.json' %}",function (json_data) {
    var jdata=[];
    $(json_data.items).each(function(i,ite){  
        jdata.push(ite)
    })
    rectSize=Math.sqrt(json_data.length);
    for(var i=0;i<rectSize;i++)
    {
        hours.push('');
        days.push('');
    }    
    option = {
        title: {
            text: '所有代碼子模塊代碼數量3D柱狀圖',
            subtext: '可顯示代碼數量,缺陷情況',
            left: 'leafDepth'
        },
        tooltip: {
            formatter:function(params)
                {
                   var errors=0;
                   for(var i =0;i< json_data.length;i++)
                   {
                        if (json_data[i][3]==params.name)
                        {
                            errors=json_data[i][4];
                            break;
                        }
                   }
                   return "<div >"+"文件路徑:"+params.name+'<br>'+
                  "代碼行數:"+params.value[2]+'<br>'+
                  "缺陷數量:"+errors+
                   "</div>";
                }, 
        },
        visualMap: {
            max: 4000,
            inRange: {
                color: ['#313695', '#4575b4', '#74add1', '#abd9e9', '#e0f3f8', '#ffffbf', '#fee090', '#fdae61', '#f46d43', '#d73027', '#a50026']
            }
        },
        xAxis3D: {
            type: 'category',
            data: hours,
            name: ''
        },
        yAxis3D: {
            type: 'category',
            data: days,
            name:''
        },
        zAxis3D: {
            type: 'value',
            name:'代碼數量'
        },
        grid3D: {
            boxWidth: 200,
            boxDepth: 180,
            viewControl: {
                // projection: 'orthographic'
            },
            light: {
                main: {
                    intensity: 1.2,
                    shadow: true
                },
                ambient: {
                    intensity: 0.3
                }
            }
        },
       /* dataset: {
            dimensions: [
                'Income',
                'Life Expectancy',
                'Population',
                'Country',
                {name: 'Year', type: 'ordinal'}
            ],
            source: json_data
        },
        */
        series: [{
            type: 'bar3D',
            data: json_data.map(function (item) {
                return {
                    name:item[3],
                    value: [item[1], item[0], item[2]],
                }
            }),
            shading: 'lambert',

            label: {
                textStyle: {
                    fontSize: 16,
                    borderWidth: 0
                }
            },

            emphasis: {
                label: {
                    textStyle: {
                        fontSize: 20,
                        color: '#900'
                    }
                },
                itemStyle: {
                    color: '#900'
                }
            }
        }]
    };
    myChart3.setOption(option, true);
}); 
if (option && typeof option === "object") {
    myChart3.setOption(option, true);
}
       </script>  
       
       
           
    </div>         

顯示效果:

 

 

 

 

另外項目中還用到樹形圖表用來表示文件目錄結構:

 

 

 可鑽入的矩形樹圖:

 

 

 

 

 由於pyecharts1.x中不存在這個圖表,pyecharts2.x和echarts中沒有添加還是我沒有認真看也沒有發現這個,就自己實現了和這個類似的鑽入樹形圖表:

 

同時為了練手也自己實現了一個條形圖表:

 

 

 圖形條數和形狀是根據數據變化來做適應的,但是美觀度比echarts還是遜色不少

3 . echarts事件交互的使用

項目中使用到一個雷達圖,需要滑鼠點擊便簽進入便簽的子圖,也是一個類似的鑽入圖形,邏輯代碼部分較多,省略了getOption( argName)函數中的部分邏輯代碼:

 <div id="container" style="height: 800px"></div>
    
       <script type="text/javascript">
var dom = document.getElementById("container");
var myChart = echarts.init(dom);
var app = {};
var weight=1000; //權重的倍數
var weight1=800;
function getOption( argName){
    var ardData=[];

    if(argName=="閉源特性"){ //判斷點擊文字
       var weightBuf= [{{weights3D.0}},{{weights3D.1}},{{weights3D.2}},{{weights3D.3}},{{weights3D.4}},
                        ];
                        
        var weightBuf1=[];
        weightBuf.forEach(myFunction);    
        function myFunction(value, index, array) {
          weightBuf1.push(value*weight1); 
        }
           ardData=[
                    {
                        value : [{{data3D.0.value.2}},{{data3D.1.value.2}},{{data3D.2.value.2}},{{data3D.3.value.2}},{{data3D.4.value.2}}, 
                       ],
                        name : '評分'
                    },
                     {
                        value : weightBuf1,
                        name : '權重'
                    }
                ];
        option = null;
        option = {
            title: {
                text: '雷達圖',
                subtext: '點擊文字要素返回頂層屬性雷達圖',
            },
            tooltip: {
                formatter:function(params)
                {
                    namelist=['正確性', '可靠性', '安全性', '可理解性','代碼熵']
                    var eachli=params.value;
                    if (params.name=='權重')
                    eachli=weightBuf;
                     return "<div >"+params.name+'<br>'+
                    namelist[0]+':'+eachli[0]+'<br>'+
                   namelist[1]+':'+eachli[1]+'<br>'+
                   namelist[2]+':'+eachli[2]+'<br>'+
                   namelist[3]+':'+eachli[3]+'<br>'+
                   namelist[4]+':'+eachli[4]+
                   "</div>";
                }, 
            },
            legend: {
                data: ['評分(scole)', '權重(weight)']
            },
            radar: {
                // shape: 'circle',
                name: {
                    textStyle: {
                        color: '#000',
                        backgroundColor: '#dee',
                        borderRadius: 3,
                        padding: [3, 5]
                   }
                }, 
                indicator: [
                   { name: '正確性', max: 100},
                   { name: '可靠性', max: 100},
                   { name: '安全性', max: 100},
                   { name: '可理解性', max: 100},
                   { name: '代碼熵', max: 100},
                ],
                triggerEvent:true
            },
            
            series: [{
                name: '評分 vs 權重',
                type: 'radar',
                // areaStyle: {normal: {}},
                data : ardData
            }]
        };;
    }
 return option;
}
option=getOption("root");
if (option && typeof option === "object") {
    myChart.setOption(option, true);
    
    
      myChart.on('click', function (params) {
        console.log(params);
       // alert(params.name);
        myChart.setOption(getOption(params.name), true);
     });

}
       </script>     
       

主要是用

 myChart.on('click', function (params) {
        console.log(params);
       // alert(params.name);
        myChart.setOption(getOption(params.name), true);
     });
來監聽滑鼠點擊標簽事件,然後通過getOption來動態構建option顯示,就達到了鑽入效果

點擊之後的鑽入效果

 

 

 4. 自定義tooltip標簽

在tooltip中定義formatter,params參數為當前活動的元素數據

tooltip: {
            formatter:function(params)
                {
                   var errors=0;
                   for(var i =0;i< json_data.length;i++)
                   {
                        if (json_data[i][3]==params.name)
                        {
                            errors=json_data[i][4];
                            break;
                        }
                   }
                   return "<div >"+"文件路徑:"+params.name+'<br>'+
                  "代碼行數:"+params.value[2]+'<br>'+
                  "缺陷數量:"+errors+
                   "</div>";
                }, 
        },

效果:

 

 

提示框浮層內容格式器,支持字元串模板和回調函數兩種形式。

1, 字元串模板

模板變數有 {a}{b}{c}{d}{e},分別表示系列名,數據名,數據值等。 在 trigger 為 'axis' 的時候,會有多個系列的數據,此時可以通過 {a0}{a1}{a2} 這種後面加索引的方式表示系列的索引。 不同圖表類型下的 {a}{b}{c}{d} 含義不一樣。 其中變數{a}{b}{c}{d}在不同圖表類型下代表數據含義為:

  • 折線(區域)圖、柱狀(條形)圖、K線圖 : {a}(系列名稱),{b}(類目值),{c}(數值), {d}(無)

  • 散點圖(氣泡)圖 : {a}(系列名稱),{b}(數據名稱),{c}(數值數組), {d}(無)

  • 地圖 : {a}(系列名稱),{b}(區功能變數名稱稱),{c}(合併數值), {d}(無)

  • 餅圖、儀錶盤、漏斗圖: {a}(系列名稱),{b}(數據項名稱),{c}(數值), {d}(百分比)

更多其它圖表模板變數的含義可以見相應的圖表的 label.formatter 配置項。

示例:

formatter: '{b0}: {c0}<br />{b1}: {c1}'

2, 回調函數

回調函數格式:

(params: Object|Array, ticket: string, callback: (ticket: string, html: string)) => string

第一個參數 params 是 formatter 需要的數據集。格式如下:

{
    componentType: 'series',
    // 系列類型
    seriesType: string,
    // 系列在傳入的 option.series 中的 index
    seriesIndex: number,
    // 系列名稱
    seriesName: string,
    // 數據名,類目名
    name: string,
    // 數據在傳入的 data 數組中的 index
    dataIndex: number,
    // 傳入的原始數據項
    data: Object,
    // 傳入的數據值。在多數系列下它和 data 相同。在一些系列下是 data 中的分量(如 map、radar 中)
    value: number|Array|Object,
    // 坐標軸 encode 映射信息,
    // key 為坐標軸(如 'x' 'y' 'radius' 'angle' 等)
    // value 必然為數組,不會為 null/undefied,表示 dimension index 。
    // 其內容如:
    // {
    //     x: [2] // dimension index 為 2 的數據映射到 x 軸
    //     y: [0] // dimension index 為 0 的數據映射到 y 軸
    // }
    encode: Object,
    // 維度名列表
    dimensionNames: Array<String>,
    // 數據的維度 index,如 0 或 1 或 2 ...
    // 僅在雷達圖中使用。
    dimensionIndex: number,
    // 數據圖形的顏色
    color: string,

    // 餅圖的百分比
    percent: number,

}

我這裡使用的回調函數,定義雷達圖更方便一點
其他可參考官方文檔教程:
https://www.echartsjs.com/zh/option.html#title

 

 

 

 

 

 

 

 

 

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); button = (B ...
  • 實現列表動畫 ...
  • 鉤子函數實現小球彈落 ...
  • 不使用動畫 使用過渡類名實現動畫 修改vue的首碼 第三方類實現動畫 需引入css文件:`` ...
  • 案例改進 vue resource全局配置: 全局啟用 emulateJSON 選項 ...
  • 負邊距與雙飛翼佈局 負邊距 當設置top和left方向的負邊距時,元素本身向指定方向移動。當設置bottom和right方向的負邊距時,元素本身不移動,處於元素後方的元素向前流動,覆蓋其上。 聖杯佈局 聖杯佈局是一個三欄佈局,左右定寬,中間自適應。 HTML佈局 得到如圖所示的三個div。 CSS設 ...
  • 先介紹下這個問題的由來: 上午其他項目組人員在rtx上問,求幫忙解決ie8相容性問題。 然後快到飯點,知道這個bug肯定不是那麼好解決,肯定不能耽誤吃飯時間。 果斷說,下午來弄。 下午3點開始去看這個bug。 具體問題就是:點擊修改按鈕報了缺少':',186行錯誤。 看了下他的代碼186行,是空白行 ...
  • transition過渡 和animation 動畫 要知道 transition過渡和animation動畫都是實現元素運動的一種方式。區別在於: transition過渡需要人為觸發,例如點擊觸發或者滑鼠懸停觸發,而animation是可以不需要人為觸發。transition功能支持從一個屬性值 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...