如何利用 C# + Echarts 繪制 Bar Simple


背景

Echarts 是百度推出的一個使用 JavaScript 實現的開源可視化庫。 該庫提供了常規的折線圖、柱狀圖、散點圖、餅圖、K線圖,用於統計的盒形圖,用於地理數據可視化的地圖、熱力圖、線圖,用於關系數據可視化的關系圖、treemap、旭日圖,多維數據可視化的平行坐標,還有用於 BI 的漏斗圖,儀表盤,並且支持圖與圖之間的混搭。

 
柱狀圖
 
散點圖
 
關系圖
 
三維圖

既然 Echarts 提供了豐富的圖形,所以咱們有必要把它封裝起來,以便讓其支持 Windows 窗體應用程序。




技術分析

整體的技術方案就是做一個自定義控件,該控件中包含 WebBrowser 瀏覽器控件,通過該瀏覽器控件顯示指定位置的網頁。就像咱們直接通過 Web 瀏覽器網頁一樣。具體的步驟如下:

首先,創建一個在 Windows 窗體應用程序中使用的控件項目 LSGO.Core.ECharts

其次,在該控件項目的設計器中,拖入一個 WebBrowser 控件,並設置其 Dock 屬性為 Fill,即讓 WebBrowser 充滿整個容器。

接着,寫一個 InitialECharts 方法,加載指定目錄的網頁.\assets\echarts.html,讓該網頁在 WebBrowser 中打開。

當該網頁加載完成后,觸發 WebBrowserWebBrowserDocumentCompletedEventHandler 事件,在該事件注冊的方法中調用該網頁中用 JS 寫的 showChart 方法,則在該網頁中顯示圖形。

當窗體控件的尺寸發生變化后,觸發 WebBrowserSizeChanged 事件,在該事件注冊的方法中調用該網頁中用 JS 寫的 setPosition 方法,則重新調整顯示圖形的布局,以滿足新的尺寸。

WebBrowser 類的常用屬性、事件與方法

<u>屬性</u>

/// <summary> /// 獲取或設置一個對象,該對象可由顯示在 WebBrowser 控件中的網頁所包含的腳本代碼訪問。 /// </summary> /// <returns> /// 可用於腳本代碼的對象。 /// </returns> public object ObjectForScripting { get; set; } /// <returns> /// 表示當前頁的 HtmlDocument,如果未加載任何頁,則為 null。 /// </returns> public HtmlDocument Document { get; } 

<u>事件</u>

/// <summary> /// 在 WebBrowser 控件完成加載文檔時發生。 /// </summary> public event WebBrowserDocumentCompletedEventHandler DocumentCompleted; /// <summary> /// 在 Control.Size 屬性值更改時發生。 /// </summary> public event EventHandler SizeChanged; 

<u>方法</u>

/// <summary> /// 將指定的統一資源定位器 (URL) 處的文檔加載到 WebBrowser 控件中,替換上一個文檔。 /// </summary> /// <param name="urlString">要加載的文檔的 URL。</param> public void Navigate(string urlString); 

HtmlDocument 類的常用方法

/// <returns> /// 活動腳本調用所返回的對象。 /// </returns> /// <param name="scriptName">要調用的腳本方法的名稱。</param> /// <param name="args">要傳遞給腳本方法的參數。</param> public object InvokeScript(string scriptName, object[] args); 

代碼實現

Step1:創建一個用於顯示圖形的網頁

<u>初始顯示的網頁 echarts.html</u>

<!DOCTYPE html> <html lang="en-US"> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"> <link rel="stylesheet" href="./bootstrap/css/bootstrap.min.css" /> <script src="./jquery-1.11.2.min.js"></script> <script src="./bootstrap/js/bootstrap.min.js"></script> <script src="./json2.js"></script> <head> <title></title> </head> <body> <div class="container-fluid"> <div id="main" style="height:350px;"></div> </div> <script src="./echarts.js"></script> <script> var myChart = echarts.init(document.getElementById('main')); // 指定圖表的配置項和數據 var option = { title: { text: 'ECharts 入門示例' }, tooltip: {}, legend: { data:['銷量'] }, xAxis: { data: ["襯衫","羊毛衫","雪紡衫","褲子","高跟鞋","襪子"] }, yAxis: {}, series: [{ name: '銷量', type: 'bar', data: [5, 20, 36, 10, 10, 20] }] }; myChart.setOption(option); </script> </body> </html> 

<u>顯示圖形時調用的 JS 代碼 showChart</u>

function showChart(option) { myChart.clear(); var op = JSON.parse(option); myChart.setOption(op); } 

<u>當控件的尺寸發生變化時調用的 JS 代碼 setPosition</u>

function setPosition(height) { var divMain = document.getElementById("main"); divMain.style.height = height + "px"; window.onresize = myChart.resize(); } 

Step2:創建自定義控件 Echarts

<u>初始化 Echarts 控件的方法</u>

public object Option { get; set; } public void InitialECharts(Option option) { if (option == null) throw new ArgumentNullException(); Option = JsonConvert.SerializeObject(option); string strHtml = Application.StartupPath + @"\assets\echarts.html"; if (File.Exists(strHtml)) { webBrowserMain.Navigate(strHtml); webBrowserMain.ObjectForScripting = this; } } 

<u>當 echarts.htmlWebBrowser 內加載完成之后執行的方法</u>。

private void webBrowserMain_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e) { object[] objArray = new object[] {Option}; HtmlDocument htmlDocument = webBrowserMain.Document; if (htmlDocument != null) { htmlDocument.InvokeScript("showChart", objArray); objArray[0] = Height; htmlDocument.InvokeScript("setPosition", objArray); _isDocumentLoaded = true; } } 

<u>當控件 Echarts 尺寸發生變化之后執行的方法</u>。

private void webBrowserMain_SizeChanged(object sender, EventArgs e) { if (_isDocumentLoaded) { object[] objArray = new object[] {Height}; HtmlDocument htmlDocument = webBrowserMain.Document; if (htmlDocument != null) { htmlDocument.InvokeScript("setPosition", objArray); } } } 

Step3:對百度 Echarts 組件的封裝

<u>對 ECharts 中的 xAxis 結構的封裝</u>。

public class XAxis
{ /// <summary> /// 坐標軸類型 /// </summary> public string type { get; set; } = "category"; /// <summary> /// 類目數據 /// </summary> public List<string> data { get; set; } } 

<u>對 EChartsyAxis 結構的封裝</u>。

public class YAxis
{ /// <summary> /// 坐標軸類型 /// </summary> public string type { get; set; } = "value"; } 

<u>對 EChartsseries 集合元素的封裝</u>。

public class SeriesItem
{ /// <summary> /// 每個系列通過 type 決定自己的圖表類型 /// </summary> public string type { get; set; } /// <summary> /// 系列中的數據內容數組 /// </summary> public List<int> data { get; set; } } 

<u>對 EChartsoption 結構的封裝</u>。

public class Option
{ /// <summary> /// x軸 /// </summary> public XAxis xAxis { get; set; } /// <summary> /// y軸 /// </summary> public YAxis yAxis { get; set; } /// <summary> /// 數據 /// </summary> public List<SeriesItem> series { get; set; } } 

總結

百度示例的代碼:

option = {
    xAxis: {
        type: 'category',
        data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
    },
    yAxis: {
        type: 'value'
    },
    series: [{
        data: [120, 200, 150, 80, 70, 110, 130],
        type: 'bar'
    }]
};

封裝成控件之后的調用代碼:

private List<string> GetXAxisData() { List<string> reslt = new List<string> { "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" }; return reslt; } private List<SeriesItem> GetSeriesData() { List<SeriesItem> result = new List<SeriesItem>(); SeriesItem item = new SeriesItem { type = "bar", data = new List<double> { 120, 200, 150, 80, 70, 110, 130 } }; result.Add(item); return result; } private void FormMain_Load(object sender, EventArgs e) { Option option = new Option { title = new Title { text= "ECharts 入門示例", }, xAxis = new XAxis { type = "category", data = GetXAxisData() }, yAxis = new YAxis { type = "value" }, series = GetSeriesData() }; echartsMain.InitialECharts(option); } 

圖形顯示如下:

 
圖形顯示

當然,咱們封裝百度的 Echarts 並非心血來潮,學習任何技術的目的都要應用於實際,去體現技術的價值。

 
應用01
 
應用02

 




免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM