背景 Echarts 是百度推出的一个使用 JavaScript 实现的开源可视化库。 该库提供了常规的折线图、柱状图、散点图、饼图、K线图,用于统计的盒形图,用于地理数据可视化的地图、热力图、线图,用于关系数据可视化的关系图、treemap、旭日图,多维数据可视化的平行坐标,还有用于 BI 的漏斗图,仪表盘,并且支持图与图之间的混搭。
柱状图
散点图
关系图
三维图 既然 Echarts
提供了丰富的图形,所以咱们有必要把它封装起来,以便让其支持 Windows 窗体应用程序。
技术分析 整体的技术方案就是做一个自定义控件,该控件中包含 WebBrowser 浏览器控件,通过该浏览器控件显示指定位置的网页。就像咱们直接通过 Web 浏览器网页一样。具体的步骤如下:
首先 ,创建一个在 Windows 窗体应用程序中使用的控件项目 LSGO.Core.ECharts
。
其次 ,在该控件项目的设计器中,拖入一个 WebBrowser 控件,并设置其 Dock
属性为 Fill
,即让 WebBrowser 充满整个容器。
接着 ,写一个 InitialECharts
方法,加载指定目录的网页.\assets\echarts.html
,让该网页在 WebBrowser 中打开。
当该网页加载完成后,触发 WebBrowser 的 WebBrowserDocumentCompletedEventHandler
事件,在该事件注册的方法中调用该网页中用 JS 写的 showChart
方法,则在该网页中显示图形。
当窗体控件的尺寸发生变化后,触发 WebBrowser 的 SizeChanged
事件,在该事件注册的方法中调用该网页中用 JS 写的 setPosition
方法,则重新调整显示图形的布局,以满足新的尺寸。
WebBrowser
类的常用属性、事件与方法 。
属性
/// <summary> /// 获取或设置一个对象,该对象可由显示在 WebBrowser 控件中的网页所包含的脚本代码访问。 /// </summary> /// <returns> /// 可用于脚本代码的对象。 /// </returns> public object ObjectForScripting { get; set ; }/// <returns> /// 表示当前页的 HtmlDocument,如果未加载任何页,则为 null。 /// </returns> public HtmlDocument Document { get; }
事件
/// <summary> /// 在 WebBrowser 控件完成加载文档时发生。 /// </summary> public event WebBrowserDocumentCompletedEventHandler DocumentCompleted;/// <summary> /// 在 Control.Size 属性值更改时发生。 /// </summary> public event EventHandler SizeChanged;
方法
/// <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:创建一个用于显示图形的网页 。
初始显示的网页 echarts.html
<!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 >
显示图形时调用的 JS 代码 showChart
function showChart (option ) { myChart.clear(); var op = JSON .parse(option); myChart.setOption(op); }
当控件的尺寸发生变化时调用的 JS 代码 setPosition
function setPosition (height ) { var divMain = document .getElementById("main" ); divMain.style.height = height + "px" ; window .onresize = myChart.resize(); }
Step2:创建自定义控件 Echarts 。
初始化 Echarts 控件的方法
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 ; } }
当 echarts.html
在 WebBrowser 内加载完成之后执行的方法 。
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 ; } }
当控件 Echarts 尺寸发生变化之后执行的方法 。
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 组件的封装 。
对 ECharts 中的 xAxis
结构的封装 。
public class XAxis { /// <summary> /// 坐标轴类型 /// </summary> public string type { get; set ; } = "category" ; /// <summary> /// 类目数据 /// </summary> public List<string > data { get; set ; } }
对 ECharts 中 yAxis
结构的封装 。
public class YAxis { /// <summary> /// 坐标轴类型 /// </summary> public string type { get; set ; } = "value" ; }
对 ECharts 中 series
集合元素的封装 。
public class SeriesItem { /// <summary> /// 每个系列通过 type 决定自己的图表类型 /// </summary> public string type { get; set ; } /// <summary> /// 系列中的数据内容数组 /// </summary> public List<int > data { get; set ; } }
对 ECharts 中 option
结构的封装 。
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 好了,今天就到这里吧!See You!
相关图文 :
经过8年多的发展,LSGO软件技术团队在「地理信息系统」、「数据统计分析」、「计算机视觉」等领域积累了丰富的研发经验,也建立了人才培养的完备体系,目前深耕的领域为「机器学习与量化金融」, 欢迎对计算机技术感兴趣的同学加入,与我们共同成长进步。