背景
前几天,我们介绍了 如何利用C# + Echarts 绘制 Bar Simple?,原以为把 Echarts 封装到这种程度就可以完成当前任务了。
可是,把软件原型提交给对方时,发现对方更希望“可视化设备发生缺陷的具体数据”。也即利用 堆叠条形图 来可视化设备缺陷的数据。
百度提供的详细Demo如下:
于是,咱们就需要在之前的基础上对 Echarts 进行近一步的封装。
技术分析
在进行封装代码之前,咱们先聊聊知识的层次问题。即我们所学的知识是分层次的。
第一层:应用层,即解决 How 的问题。我们学习的各种工具,解决问题的具体方法都属于这个层次,按照步骤去做就好。
第二层:认知层,即解决 What 的问题。我们所使用的工具,解决问题的方法,它们到底是什么。
第三层:原理层,即解决 Why 的问题,要想明白为什么可以怎样做。
咱们写的图文大部分属于 How 这个层次,而这个层次的知识往往是不稳定的,多变的。咱们还需往底层去学,这样才能举一反三,触类旁通,掌握真正的知识。
好了,我们开始封装 堆叠条形图 的代码。
<b>首先,我们对比一下百度提供的 “Bar Simple” 和 “堆叠条形图” 的示例代码</b>
<u>Bar Simple 示例代码:</u>
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'
}]
};
<u>堆叠条形图 示例代码:</u>
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
的封装。
<u>封装 坐标轴指示器 AxisPointer
</u>
public class AxisPointer
{
/// <summary>
/// 'line' 直线指示器;
/// 'shadow' 阴影指示器;
/// 'none' 无指示器
/// </summary>
public string type { get; set; } = "line";
}
<u>封装 提示框组件 Tooltip
</u>
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);
}
代码对应结果如下:
当然,咱们封装「堆叠条形图」是为了解决实际问题,咱们来看看这个控件在实际中的应用。
<u>基于保护类型的缺陷原因分布情况</u>
<u>基于生产厂家的缺陷原因分布情况</u>
好了,今天就到这里吧!希望咱们一起学习的知识对大家有用!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制作自动化交易系统 -- 订单系统