当前位置: 首页 > 编程日记 > 正文

技术图文:如何利用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 中打开。

当该网页加载完成后,触发 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!


相关图文:

  • 如何利用 C# 实现 K 最邻近算法?
  • 如何利用 C# 实现 K-D Tree 结构?
  • 如何利用 C# + KDTree 实现 K 最邻近算法?
  • 如何利用 C# 对神经网络模型进行抽象?
  • 如何利用 C# 实现神经网络的感知器模型?
  • 如何利用 C# 实现 Delta 学习规则?
  • 如何利用 C# 爬取带 Token 验证的网站数据?
  • 如何利用 C# 向 Access 数据库插入大量数据?
  • 如何利用 C# 开发「桌面版百度翻译」软件!
  • 如何利用 C# 开发「股票数据分析软件」(上)
  • 如何利用 C# 开发「股票数据分析软件」(中)
  • 如何利用 C# 开发「股票数据分析软件」(下)
  • 如何利用 C# 爬取「财报说」中的股票数据?
  • 如何利用 C# 爬取 One 持有者返利数据!
  • 如何利用 C# 爬取Gate.io交易所的公告!
  • 如何利用 C# 爬取BigOne交易所的公告!
  • 如何利用 C# 爬取 ONE 的交易数据?
  • 如何利用 C# 爬取「猫眼电影:热映口碑榜」及对应影片信息!
  • 如何利用 C# 爬取「猫眼电影专业版:票房」数据!
  • 如何利用 C# 爬取「猫眼电影:最受期待榜」及对应影片信息!
  • 如何利用 C# 爬取「猫眼电影:国内票房榜」及对应影片信息!
  • 如何利用 C# + Python 破解猫眼电影的反爬虫机制?
  • 如何利用BigOne的API制作自动化交易系统 – 身份验证
  • 如何利用BigOne的API制作自动化交易系统 – 获取账户资产
  • 如何利用BigOne的API制作自动化交易系统 – 订单系统

相关文章:

Moss/Sharepoint 一些很重要的API备忘

1.根据用户名获取用户 SPUser user web.EnsureUser((new SPFieldLookupValue(item["Mitarbeiter"].ToString())).LookupValue); 2.根据guid获取Feature对象 SPFeature listDisplaySettingFeature site.Features[newGuid("88E9E47A-BA92-47ab-A253-8AA472CCC76B…

vue从创建到完整的饿了么(5)v-for,v-bind与计算属性

说明 1.上一章--Home.vue及vue-resource使用2.cangdu大神的项目源码地址--Github地址3.接口地址--Github地址4.UI框架用的是--Mint UI5.下一章--登录注册页面及密码的暗明文转换 开始 1.先看看Home.vue代码 <template><div><mt-header fixed><span slot&q…

python查询mysql中文乱码问题

相信很多在工作中的Python小伙伴&#xff0c;经常会遇到一些工作上的问题&#xff0c;例如查询mysql中文乱码问题&#xff0c;Python连接mysql数据库时&#xff0c;读取数据库中的中文出现乱码&#xff0c;所有中文都显示为问号了&#xff0c;那么该如何解决这个问题呢?解决问…

技术图文:如何利用C# + Echarts 绘制「堆叠条形图」?

背景 前几天&#xff0c;我们介绍了 如何利用C# Echarts 绘制 Bar Simple&#xff1f;&#xff0c;原以为把 Echarts 封装到这种程度就可以完成当前任务了。 可是&#xff0c;把软件原型提交给对方时&#xff0c;发现对方更希望“可视化设备发生缺陷的具体数据”。也即利用 堆…

Javascript原型链

这是关于原型链的一系列的现象与原理的解释以及例子 【转载请注明出处与地址】 分成4个部分阐述&#xff1a; 1.如何创建一个对象 2.使用原型链prototype实现对象的继承. 3.原型链上属性和方法的联系与规则 4.深入剖析原型链。 一、如何创建一个对象&#xff1a; 1.使用关键字n…

springbatch apache-activemq 整合(往mq中put数据,从mq中take数据)

简单测试如下&#xff1a;1&#xff1a;收下下载apache-activemq-5.14.4 解压apache-activemq-5.14.4\bin\win64&#xff0c;运行activemq.bat启动本地MQ服务器。通过浏览器可以查看本地MQ服务器的信息。http://127.0.0.1:8161/admin/index.jsp 2: 先往mq中put数据配置如下&…

什么是安全测试?哪些阶段需要安全测试?

安全测试是在IT软件产品的生命周期中&#xff0c;特别是产品开发基本完成到发布阶段&#xff0c;对产品进行检验以验证产品符合安全需求定义和产品质量标准的过程&#xff0c;可以说&#xff0c;安全测试贯穿于软件的整个生命周期。下面通过一张图描述软件生命周期各个阶段的安…

技术图文:如何利用C#爬取CSDN的博客文章?

背景 大家有没有这样的体验&#xff0c;在 CSDN 上发现某个博主有很多干货文章&#xff0c;我们就想拿到这个博主以往文章的列表&#xff0c;在需要的时候进行查询和浏览。 如果从 CSDN 网站上用复制粘贴的方式来建立这个列表&#xff0c;一个是工作量很大&#xff0c;另一个…

SAP BADI应用

SAP BADI应用 1.定义BADI 1) T-Code: SE18 Business Add-In Define. 2) 输入要创建的BADI的名字&#xff0c;点击"Create"。 3) 输入BADI的描述性文本&#xff0c;在"Interface"选项卡上输入接口的名字&#xff0c;也可以采用SAP建议的接口的…

为什么多 TCP 连接比单 TCP 连接传输快

转自&#xff1a; 我观察到&#xff0c;客户端机器从单一服务器使用 HTTP 下载一个文件&#xff1a;1. 单连接下载&#xff0c;速度没有达到客户端网络的最大带宽&#xff1b;2. 多连接同时下载&#xff0c;传输速度有极大的提高&#xff0c;带宽被占满。假设如下前提&#xff…

学Python的好处有哪些?

Python是一种比较简单的编程语言技术&#xff0c;想要快速进入到IT行业&#xff0c;Python是非常好的选择&#xff0c;为什么这么说呢?下面小编就为大家详细的介绍一下学Python的好处有哪些? ​  学Python的好处有哪些? 1.如果你是一名新媒体相关人员&#xff0c;学习Pyth…

技术图文:如何利用C# 实现 Kruskal 最小生成树算法?

背景 以前我写过一些图文来介绍有关数据结构与算法的知识&#xff1a; 8大排序算法之&#xff1a;直接插入排序&#xff08;Straight Insertion Sort&#xff09;8大排序算法之&#xff1a;希尔插入排序&#xff08;Shell Insertion Sort&#xff09;8大排序算法之&#xff1…

又偷懒了4个月,督促自己

又偷懒了4个月 每天浑浑噩噩&#xff0c;做着无聊简单的体力活&#xff0c;我不应该是这个追求撒&#xff01;~~ 爸爸说的对&#xff0c;无论怎么样自己都要独立&#xff0c;要学习&#xff0c;爸爸希望我还去继续学习会计&#xff0c;我看下半年吧&#xff0c;各种学习都要&am…

java.lang.NoSuchMethodError: org.springframework.web.context.support.XmlWebApplicationContext.getEnv

转自&#xff1a;https://blog.csdn.net/u012941811/article/details/16960493 ava.lang.NoSuchMethodError: org.springframework.web.context.support.XmlWebApplicationContext.getEnvironment()Lorg/springframework/core/env/ConfigurableEnvironment; at 缺 org.springf…

零基础可以学好UI设计吗

随着UI设计行业的不断扩大发展&#xff0c;很多人都想要学习UI设计技术&#xff0c;但有很多同学都是零基础&#xff0c;想知道零基础可以学好UI设计吗?我们来看看下面的详细介绍就知道了。 零基础可以学好UI设计吗? 如果零基础自己学习UI设计着实有点吃力&#xff0c;毕竟对…

技术图文:如何利用C# 实现 Prim 最小生成树算法?

背景 我们上一篇图文介绍了 如何利用 C# 实现 Kruskal 最小生成树算法&#xff1f;&#xff0c;Kruskal 算法通过寻找边最优的方式来构造最小生成树&#xff0c;本篇图文介绍如何利用 C# 实现 Prim 最小生成树算法&#xff0c;Prim 算法通过寻找顶点最优的方式来构造最小生成树…

去除iphone图标的半弧高亮效果

只需要在info.plist里面添加一条记录UIPrerenderedIcon 新版的XCODE 会自动识别为Icon already includes gloss effects 打上勾就OK了 如果没有识别的右边栏写上YES就可以。转载于:https://www.cnblogs.com/jiewong/archive/2011/01/14/1935718.html

【短视频SDK - 参数解析】对焦模式、裁剪模式、视频质量、分辨率、视频比例、帧率、关键帧间隔等参数解析...

1.参数简析 参数名称简介影响裁剪模式分为填充模式和裁剪模式影响图像画面的展示细节视频质量是指生成的视频的输出参数&#xff0c;是一组参数决定的数值视频清晰度和文件大小分辨率图像分辨率则是单位英寸中所包含的像素点数&#xff0c;分辨率影响图像大小&#xff0c;与图像…

21年最新Python面试题及答案汇总详解(上)

错过三月找工作的机会&#xff0c;还要错过四月的好时期吗?Python面试你做准备了吗?下面小编整理了一套2021年最新Python常见面试题目&#xff0c;及Python面试题目答案汇总。希望能够帮助到大家。 21年最新Python面试题及答案汇总详解(上) 1、列表(list)和元组(tuple)有什么…

sina微博api源码阅读之函数

1. array_map将类的静态成员函数作为回调函数用在指定的单元上&#xff0c;可以递归调用 public static function urlencode_rfc3986($input) { if (is_array($input)) { return array_map(array(OAuthUtil, urlencode_rfc3986), $input); } else …

LeetCode实战:将有序数组转换为二叉搜索树

题目英文 Given an array where elements are sorted in ascending order, convert it to a height balanced BST. For this problem, a height-balanced binary tree is defined as a binary tree in which the depth of the two subtrees of every node never differ by mo…

Spring、Spring Boot和TestNG测试指南 - @ActiveProfiles

Github地址 ActiveProfiles可以用来在测试的时候启用某些Profile的Bean。本章节的测试代码使用了下面的这个配置&#xff1a; Configuration public class Config {BeanProfile("dev")public Foo fooDev() {return new Foo("dev");}BeanProfile("prod…

python语言中如何使用注释

每一种计算机语言都有自己的注释方式&#xff0c;我们知道注释的作用是解释这些代码&#xff0c;方便程序员以后的检查和修改。而且注释的一部分在运行程序的过程中不起作用&#xff0c;也不会显示出来。下面我们将为大家介绍&#xff0c;在python语言中如何使用注释? 在pytho…

RHEL5(CentOS)下nginx+php+mysql+tomcat+memchached配置全过程(转)

RHEL5(CentOS)下nginxphpmysqltomcatmemchached配置全过程 一、准备工作&#xff1a; SSH,telnet终端中文显示乱码解决办法 vi /etc/sysconfig/i18n将内容改为 LANG"zh_CN.GB18030" LANGUAGE"zh_CN.GB18030:zh_CN.GB2312:zh_CN" SUPPORTED"zh_CN.GB18…

LeetCode实战:搜索二维矩阵

题目英文 Write an efficient algorithm that searches for a value in an m x n matrix. This matrix has the following properties: Integers in each row are sorted from left to right.The first integer of each row is greater than the last integer of the previou…

windows指令

为什么80%的码农都做不了架构师&#xff1f;>>> C:\Windows\System32\drivers\etc nbtstat -a 1.7.2.2s 检查该IP的主机名称 WExNmU5Z windows启动配置界面 在“运行”中输入“msconfig mstsc -admin 远程 虚拟机的判断&#xff1a;如果有vmtoolsd.exe进程就是虚拟…

Java培训好不好?零基础可以学吗?

5g时代的来临&#xff0c;越来越多的人开启智能时代&#xff0c;互联网行业的发展速度越来越快&#xff0c;高薪行业一直受到很多人的关注&#xff0c;尤其是java这一块&#xff0c;很多人都想学习&#xff0c;那么参加Java培训好不好?零基础可以学吗? Java培训好不好?零基础…

顺水行舟,逆水行舟

水&#xff0c;或温柔&#xff0c;或猛烈 万物皆可比喻为水 顺水行舟&#xff0c;逆水行舟&#xff0c;皆为操船者智慧之体现 翻船者。。。把船搞翻了几回还执意而为&#xff0c;SB也。。。转载于:https://www.cnblogs.com/Zetazzz/archive/2011/01/30/1948082.html

LeetCode实战:二叉树的最大深度

题目英文 Given a binary tree, find its maximum depth. The maximum depth is the number of nodes along the longest path from the root node down to the farthest leaf node. Note: A leaf is a node with no children. Example: Given binary tree [3,9,20,null,n…

jfinal整合shiro回顾

2019独角兽企业重金招聘Python工程师标准>>> 目前jfinal使用shiro进行身份验证和授权的后台实现已完成&#xff0c;现在我再来总结下学习过程及代码实现过程。最近半年多项目开发都用.net&#xff0c;但又不甘心用了一年多的java&#xff0c;jfinal就这样被废弃&…