技术图文:如何利用C# + Echarts 绘制「堆叠条形图」?
背景
前几天,我们介绍了 如何利用C# + Echarts 绘制 Bar Simple?,原以为把 Echarts 封装到这种程度就可以完成当前任务了。
可是,把软件原型提交给对方时,发现对方更希望“可视化设备发生缺陷的具体数据”。也即利用 堆叠条形图 来可视化设备缺陷的数据。
百度提供的详细Demo如下:
于是,咱们就需要在之前的基础上对 Echarts 进行近一步的封装。
技术分析
在进行封装代码之前,咱们先聊聊知识的层次问题。即我们所学的知识是分层次的。
第一层:应用层,即解决 How 的问题。我们学习的各种工具,解决问题的具体方法都属于这个层次,按照步骤去做就好。
第二层:认知层,即解决 What 的问题。我们所使用的工具,解决问题的方法,它们到底是什么。
第三层:原理层,即解决 Why 的问题,要想明白为什么可以怎样做。
咱们写的图文大部分属于 How 这个层次,而这个层次的知识往往是不稳定的,多变的。咱们还需往底层去学,这样才能举一反三,触类旁通,掌握真正的知识。
好了,我们开始封装 堆叠条形图 的代码。
首先,我们对比一下百度提供的 “Bar Simple” 和 “堆叠条形图” 的示例代码
Bar Simple 示例代码:
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' }] };
堆叠条形图 示例代码:
app.title = '堆叠条形图'; option = { tooltip : { trigger: 'axis', axisPointer : { // 坐标轴指示器,坐标轴触发有效 type : 'shadow' // 默认为直线,可选为:'line' | 'shadow' } }, legend: { data: ['直接访问', '邮件营销','联盟广告','视频广告','搜索引擎'] }, grid: { left: '3%', right: '4%', bottom: '3%', containLabel: true }, xAxis: { type: 'value' }, yAxis: { type: 'category', data: ['周一','周二','周三','周四','周五','周六','周日'] }, series: [ { name: '直接访问', type: 'bar', stack: '总量', label: { normal: { show: true, position: 'insideRight' } }, data: [320, 302, 301, 334, 390, 330, 320] }, { name: '邮件营销', type: 'bar', stack: '总量', label: { normal: { show: true, position: 'insideRight' } }, data: [120, 132, 101, 134, 90, 230, 210] }, { name: '联盟广告', type: 'bar', stack: '总量', label: { normal: { show: true, position: 'insideRight' } }, data: [220, 182, 191, 234, 290, 330, 310] }, { name: '视频广告', type: 'bar', stack: '总量', label: { normal: { show: true, position: 'insideRight' } }, data: [150, 212, 201, 154, 190, 330, 410] }, { name: '搜索引擎', type: 'bar', stack: '总量', label: { normal: { show: true, position: 'insideRight' } }, data: [820, 832, 901, 934, 1290, 1330, 1320] } ] };
通过两段代码的对比,我们还需要对 tooltip、legend、grid 进行封装,其余的 xAxis、yAxis、series 已经封装过了,只不过需要在每个对应的类中添加新增的属性即可。
再重复一下封装百度 Echarts 的思路:
首先,创建一个在 Windows 窗体应用程序中使用的控件项目 LSGO.Core.ECharts。
其次,在该控件项目的设计器中,拖入一个 WebBrowser 控件,并设置其 Dock 属性为 Fill,即让 WebBrowser 充满整个容器。
接着,写一个 InitialECharts 方法,加载指定目录的网页.\assets\echarts.html,让该网页在 WebBrowser 中打开。
当该网页加载完成后,触发 WebBrowser 的 WebBrowserDocumentCompletedEventHandler 事件,在该事件注册的方法中调用该网页中用 JS 写的 showChart 方法,则在该网页中显示图形。
当窗体控件的尺寸发生变化后,触发 WebBrowser 的 SizeChanged 事件,在该事件注册的方法中调用该网页中用 JS 写的 setPosition 方法,则重新调整显示图形的布局,以满足新的尺寸。
封装控件的代码、初始网页的代码以及调用对应 JS 的代码,参见:如何利用C# + Echarts 绘制 Bar Simple?。咱们这里只写进一步封装 Echarts 的代码。
代码实现
Step01 对tooltip的封装。
封装 坐标轴指示器 AxisPointer
public class AxisPointer { /// <summary> /// 'line' 直线指示器; /// 'shadow' 阴影指示器; /// 'none' 无指示器 /// </summary> public string type { get; set; } = "line"; }
封装 提示框组件 Tooltip
public class Tooltip { /// <summary> /// 触发类型 /// 'item':数据项图形触发,主要在散点图,饼图等无类目轴的图表中使用。 /// 'axis':坐标轴触发,主要在柱状图,折线图等会使用类目轴的图表中使用。 /// 'none':什么都不触发。 /// </summary> public string trigger { get; set; } = "item"; /// <summary> /// 坐标轴指示器 /// </summary> public AxisPointer axisPointer { get; set; } }
Step02 对legend的封装。
public class Legend { /// <summary> /// 图例的类型。 /// 可选值:'plain','scroll' /// </summary> public string type { get; set; } = "plain"; /// <summary> /// 图例列表的布局朝向。 /// 'horizontal''vertical' /// </summary> public string orient { get; set; } = "horizontal"; /// <summary> /// 图例组件离容器左侧的距离。 /// </summary> public string left { get; set; } = "auto"; /// <summary> /// 图例组件离容器上侧的距离。 /// </summary> public string top { get; set; } = "auto"; /// <summary> /// 图例组件离容器右侧的距离。 /// </summary> public string right { get; set; } = "auto"; /// <summary> /// 图例组件离容器下侧的距离。 /// </summary> public string bottom { get; set; } = "auto"; /// <summary> /// 图例的数据数组。 /// </summary> public List<string> data { get; set; } }
Step03 对 grid 的封装。
public class Grid { /// <summary> /// grid 组件离容器上侧的距离。 /// </summary> public string top { get; set; } = "60"; /// <summary> /// grid 组件离容器左侧的距离。 /// </summary> public string left { get; set; } = "10%"; /// <summary> /// grid 组件离容器右侧的距离。 /// </summary> public string right { get; set; } = "10%"; /// <summary> /// grid 组件离容器下侧的距离。 /// </summary> public string bottom { get; set; } = "60"; /// <summary> /// grid 区域是否包含坐标轴的刻度标签。 /// </summary> public bool containLabel { get; set; } = false; }
Step04 对整体的集成 Option。
public class Option { /// <summary> /// title /// </summary> public Title title { get; set; } /// <summary> /// tooltip /// </summary> public Tooltip tooltip { get; set; } /// <summary> /// legend /// </summary> public Legend legend { get; set; } /// <summary> /// grid /// </summary> public Grid grid { get; set; } /// <summary> /// x轴 /// </summary> public XAxis xAxis { get; set; } /// <summary> /// y轴 /// </summary> public YAxis yAxis { get; set; } /// <summary> /// 数据 /// </summary> public List<SeriesItem> series { get; set; } }
总结
集成 Echarts 之后客户端的代码,对应百度的 Demo:
private List<string> GetLegendData() { List<string> reslut = new List<string> { "直接访问", "邮件营销", "联盟广告", "视频广告", "搜索引擎" }; return reslut; } private List<string> GetYAxisData() { List<string> reslut = new List<string> { "周一", "周二", "周三", "周四", "周五", "周六", "周日" }; return reslut; } private List<SeriesItem> GetSeries() { List<SeriesItem> result = new List<SeriesItem>(); SeriesItem item1 = new SeriesItem { name = "直接访问", type = "bar", stack = "总量'", data = new List<double> { 320, 302, 301, 334, 390, 330, 320 }, label = new LSGO.Core.ECharts.Label { show = true, position = "insideRight" } }; SeriesItem item2 = new SeriesItem { name = "邮件营销", type = "bar", stack = "总量'", data = new List<double> { 120, 132, 101, 134, 90, 230, 210 }, label = new LSGO.Core.ECharts.Label { show = true, position = "insideRight" } }; SeriesItem item3 = new SeriesItem { name = "联盟广告", type = "bar", stack = "总量'", data = new List<double> { 220, 182, 191, 234, 290, 330, 310 }, label = new LSGO.Core.ECharts.Label { show = true, position = "insideRight" } }; SeriesItem item4 = new SeriesItem { name = "视频广告", type = "bar", stack = "总量'", data = new List<double> { 150, 212, 201, 154, 190, 330, 410 }, label = new LSGO.Core.ECharts.Label { show = true, position = "insideRight" } }; SeriesItem item5 = new SeriesItem { name = "搜索引擎", type = "bar", stack = "总量'", data = new List<double> { 820, 832, 901, 934, 1290, 1330, 1320 }, label = new LSGO.Core.ECharts.Label { show = true, position = "insideRight" } }; result.AddRange(new SeriesItem[] { item1, item2, item3, item4, item5 }); return result; } private void Form1_Load(object sender, EventArgs e) { Option option = new Option { tooltip = new Tooltip { trigger = "axis", axisPointer = new AxisPointer { type = "shadow" } }, legend = new Legend { data = GetLegendData() }, grid = new Grid { left = "3%", right = "4%", bottom = "3%", containLabel = true }, xAxis = new XAxis {type = "value"}, yAxis = new YAxis { type = "category", data = GetYAxisData() }, series = GetSeries(), }; echarts1.InitialECharts(option); }
代码对应结果如下:
当然,咱们封装「堆叠条形图」是为了解决实际问题,来看看这个控件在实际中的应用。
基于保护类型的缺陷原因分布情况
基于生产厂家的缺陷原因分布情况
好了,今天就到这里吧!希望咱们一起学习的知识对大家有用!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制作自动化交易系统 -- 订单系统
请先 后发表评论~