前言
之前在网上找了很多关于状态图的资料,但是很少是在winform上实现的。其实堆叠柱状图是来自于PPT的一种数据统计方式,展示给用户直观的图片印象。而C#很多时候要展现比较精美的界面都采用WPF来实现,像winform的技术一直没有更新,控件中只有老旧的chart控件,很难实现我们的需求,因此在winform平台上要实现堆叠柱状图需要引入第三方插件,调用的是百度开源的echart。
echart官网:
https://www.echartsjs.com/examples/zh/index.html
准备
1,首先在bin文件夹中下载添加echarts.js和echarts.min.js文件,echarts.min.js是需要自己在官网定制的。可以参考:https://blog.csdn.net/weixin_42528089/article/details/95487734
-
2,在winform窗口添加WebBrowser控件,属性Dock可以选在Fill填充整个窗口,我选择的是None可以自定义拉伸尺寸。下面是界面展示:
-
3,开始添加各功能模块的内容:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace MyEchart { //设置Com对外可访问 [System.Runtime.InteropServices.ComVisible(true)] public partial class Form1 : Form { /// <summary> /// 根目录 /// </summary> string str = System.Environment.CurrentDirectory; public Form1() { InitializeComponent(); //初始化浏览器 this.initWebBrowser(); //加载 文件 this.getAllHtmlFile(); } private void button1_Click(object sender, EventArgs e) { HTML.AddHtml("index1"); } private void Form1_FormClosing(object sender, FormClosingEventArgs e) { this.webBrowser1.Dispose(); } private void comboBox1_SelectedIndexChanged(object sender, EventArgs e) { this.webBrowser1.Url = new Uri(str + "\\" + comboBox1.Text.Trim()); } private void button2_Click(object sender, EventArgs e) { comboBox1.Items.Clear(); this.getAllHtmlFile(); } /// <summary> /// 刷新 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void button3_Click(object sender, EventArgs e) { this.webBrowser1.Refresh(); } /// <summary> /// 获取html文件 /// </summary> private void getAllHtmlFile() { //获取指定文件夹的所有文件 string[] paths = Directory.GetFiles(str); foreach (var item in paths) { //获取文件后缀名 string extension = Path.GetExtension(item).ToLower(); if (extension == ".html") { comboBox1.Items.Add(Path.GetFileName(item)); } } if (comboBox1.Items.Count > 0) { comboBox1.SelectedIndex = 0; this.webBrowser1.Url = new Uri(str + "\\" + comboBox1.Text.Trim()); } } private void Form1_Load(object sender, EventArgs e) { //浏览器url 取到index.html页面 //this.webBrowser1.Url = new Uri(str + "\\index.html"); //if (comboBox1.Items.Count > 0) //{ // comboBox1.SelectedIndex = 0; // this.webBrowser1.Url = new Uri(str +"\\"+ comboBox1.Text.Trim()); //} } /// <summary> /// 初始化浏览器 /// </summary> private void initWebBrowser() { //防止 WebBrowser 控件打开拖放到其上的文件。 webBrowser1.AllowWebBrowserDrop = false; //防止 WebBrowser 控件在用户右击它时显示其快捷菜单. webBrowser1.IsWebBrowserContextMenuEnabled = false; //以防止 WebBrowser 控件响应快捷键。 webBrowser1.WebBrowserShortcutsEnabled = false; //以防止 WebBrowser 控件显示脚本代码问题的错误信息。 webBrowser1.ScriptErrorsSuppressed = true; //(这个属性比较重要,可以通过这个属性,把WINFROM中的变量,传递到JS中,供内嵌的网页使用;但设置到的类型必须是COM可见的,所以要设置 [System.Runtime.InteropServices.ComVisibleAttribute(true)],因为我的值设置为this,所以这个特性要加载窗体类上) webBrowser1.ObjectForScripting = this; } } }
同时,为了可以添加HTML文件和修改HTML,增加HTML.cs文件,源代码如下:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
namespace MyEchart
{
public struct HTML
{
public static void EditHtml(string fileName)
{
Stream myStream = new FileStream(fileName, FileMode.Open);
//Encoding encode = System.Text.Encoding.GetEncoding("GB2312");
Encoding encode = System.Text.Encoding.GetEncoding("UTF-8");
StreamReader myStreamReader = new StreamReader(myStream, encode);
string strhtml = myStreamReader.ReadToEnd();
//string stroutput = strhtml.Replace("&*平均温度*&", "要替换的内容平均温度");
string stroutput = strhtml.Replace("123", "123456");
myStream.Seek(0, SeekOrigin.Begin);
myStream.SetLength(0);
StreamWriter sw = new StreamWriter(myStream, encode);
sw.Write(stroutput);
sw.Flush();
sw.Close();
myStream.Close();
}
public static void AddHtml(string path)
{
try
{
string fileName = path + ".html";
if (File.Exists(fileName))
{
File.Delete(fileName);
}
using (StreamWriter sw = new StreamWriter(fileName, false))
{
//sw.WriteLine("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">");
//sw.WriteLine("<html xmlns=\"http://www.w3.org/1999/xhtml\">");
//sw.WriteLine("<head>");
//sw.WriteLine("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" />");
//sw.WriteLine("<title> </title>");
//sw.WriteLine("</head>");
//sw.WriteLine("<body>");
//sw.WriteLine("<img src=" + path + ">");
//sw.WriteLine("</body>");
//sw.WriteLine("</html>");
sw.WriteLine("<!DOCTYPE html>");
sw.WriteLine("<html>");
sw.WriteLine("<head>");
sw.WriteLine(" <meta charset=\"utf-8\">");
sw.WriteLine(" <title>ECharts</title>");
sw.WriteLine(" <!-- 引入 echarts.js -->");
sw.WriteLine(" <script src=\"echarts.js\"></script>");
sw.WriteLine("</head>");
sw.WriteLine("<body>");
sw.WriteLine(" <!-- 为ECharts准备一个具备大小(宽高)的Dom -->");
sw.WriteLine(" <div id=\"main\" style=\"width: 1132px;height:516px;\"></div>");
sw.WriteLine(" <script type=\"text/javascript\">");
sw.WriteLine(" // 基于准备好的dom,初始化echarts实例");
sw.WriteLine(" var myChart = echarts.init(document.getElementById('main'));");
sw.WriteLine("");
sw.WriteLine("");
sw.WriteLine(" option = {");
sw.WriteLine(" tooltip: {");
sw.WriteLine(" trigger: 'axis',");
sw.WriteLine(" axisPointer: {");
sw.WriteLine(" type: 'cross',");
sw.WriteLine(" crossStyle: {");
sw.WriteLine(" color: '#999'");
sw.WriteLine(" }");
sw.WriteLine(" }");
sw.WriteLine(" },");
sw.WriteLine(" toolbox: {");
sw.WriteLine(" feature: {");
sw.WriteLine(" dataView: {show: true, readOnly: false},");
sw.WriteLine(" magicType: {show: true, type: ['line', 'bar']},");
sw.WriteLine(" restore: {show: true},");
sw.WriteLine(" saveAsImage: {show: true}");
sw.WriteLine(" }");
sw.WriteLine(" },");
sw.WriteLine(" legend: {");
sw.WriteLine(" data:['蒸发量','降水量', '1']");
sw.WriteLine(" },");
sw.WriteLine(" xAxis: [");
sw.WriteLine(" {");
sw.WriteLine(" type: 'category',");
sw.WriteLine(" data: ['1月','2月','3月','4月','5月','6月','7月','8月','9月','10月','11月','12月'],");
sw.WriteLine(" axisPointer: {");
sw.WriteLine(" type: 'shadow'");
sw.WriteLine(" }");
sw.WriteLine(" }");
sw.WriteLine(" ],");
sw.WriteLine(" yAxis: [");
sw.WriteLine(" {");
sw.WriteLine(" type: 'value',");
sw.WriteLine(" name: '水量',");
sw.WriteLine(" min: 0,");
sw.WriteLine(" max: 250,");
sw.WriteLine(" interval: 50,");
sw.WriteLine(" axisLabel: {");
sw.WriteLine(" formatter: '{value} ml'");
sw.WriteLine(" }");
sw.WriteLine(" },");
sw.WriteLine(" {");
sw.WriteLine(" type: 'value',");
sw.WriteLine(" name: '温度',");
sw.WriteLine(" min: 0,");
sw.WriteLine(" max: 25,");
sw.WriteLine(" interval: 5,");
sw.WriteLine(" axisLabel: {");
sw.WriteLine(" formatter: '{value} °C'");
sw.WriteLine(" }");
sw.WriteLine(" }");
sw.WriteLine(" ],");
sw.WriteLine(" series: [");
sw.WriteLine(" {");
sw.WriteLine(" name:'蒸发量',");
sw.WriteLine(" type:'bar',");
sw.WriteLine(" stack:'堆叠',//堆叠柱状图在此设置成统一名称即可");
sw.WriteLine(" data:[2.0, 4.9, 7.0, 23.2, 25.6, 76.7, 135.6, 162.2, 32.6, 20.0, 6.4, 3.3]");
sw.WriteLine(" },");
sw.WriteLine(" {");
sw.WriteLine(" name:'降水量',");
sw.WriteLine(" type:'bar',");
sw.WriteLine(" stack:'堆叠',//堆叠柱状图在此设置成统一名称即可");
sw.WriteLine(" data:[2.6, 5.9, 9.0, 26.4, 28.7, 70.7, 175.6, 182.2, 48.7, 18.8, 6.0, 2.3]");
sw.WriteLine(" },");
sw.WriteLine(" {");
sw.WriteLine(" name:'1',");
sw.WriteLine(" type:'line',");
sw.WriteLine(" yAxisIndex: 1,");
sw.WriteLine(" data:[2.0, 2.2, 3.3, 4.5, 6.3, 10.2, 20.3, 23.4, 23.0, 16.5, 12.0, 6.2]");
sw.WriteLine(" }");
sw.WriteLine(" ]");
sw.WriteLine("};");
sw.WriteLine("");
sw.WriteLine(" // 使用刚指定的配置项和数据显示图表。");
sw.WriteLine(" myChart.setOption(option);");
sw.WriteLine(" </script>");
sw.WriteLine("</body>");
sw.WriteLine("</html>");
sw.Close();
}
}
catch(ArithmeticException ex)
{
Console.WriteLine(ex);
}
}
}
}
以上是构建的所有源代码,欢迎交流。
///////////////////////我是分割线*///////////////////////////
(2019年12月30日补充)
当然啦,我们看到的官网HTML文件是开源的,我们要想拿过来直接用,就要自己制作HTML文件了。
将左侧的源代码放进debug文件夹的准备生成的文件.txt中,使用以下代码转换便可得到HTML文件了。
public static void MakOptionFile(string path)
{
//获取应用程序的当前工作目录
string filepath = System.IO.Directory.GetCurrentDirectory();
try
{
string fileName = path + ".txt";
if (File.Exists(fileName))
{
File.Delete(fileName);
}
using (StreamWriter sw = new StreamWriter(fileName, false))
{
string[] strs = File.ReadAllLines(filepath+ @"\准备生成的文件.txt", System.Text.Encoding.GetEncoding("gb2312"));
foreach(string strTemp in strs)
{
sw.WriteLine("sw.WriteLine(\""+ strTemp + "\");");
}
sw.Close();
}
}
catch (ArithmeticException ex)
{
Console.WriteLine(ex);
}
}
通过以上步骤,便可在winform平台创建堆叠柱状图了,按照惯例,在文章末尾贴上一张效果图吧。^ - ^