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

背景

Echarts 是百度推出的一个使用 JavaScript 实现的开源可视化库。 该库提供了常规的折线图、柱状图、散点图、饼图、K线图,用于统计的盒形图,用于地理数据可视化的地图、热力图、线图,用于关系数据可视化的关系图、treemap、旭日图,多维数据可视化的平行坐标,还有用于 BI 的漏斗图,仪表盘,并且支持图与图之间的混搭。

3648525-e4bdc11dbab923c0.png
柱状图
3648525-99b0fa8a5cb8985a.png
散点图
3648525-1496600e960f190f.png
关系图
3648525-d087604bd685143b.png
三维图

既然 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);
}

图形显示如下:

3648525-0e591172ba9a4483.png
图形显示

当然,咱们封装百度的 Echarts 并非心血来潮,学习任何技术的目的都要应用于实际,去体现技术的价值。

3648525-a1c81f6eabd5e6cb.png
应用01
3648525-3a50f72955243b25.png
应用02

好了,今天就到这里吧!See You!


相关图文

转载于:https://www.jianshu.com/p/db6ce949e599

猜你喜欢

转载自blog.csdn.net/weixin_34358365/article/details/91151432
bar