前几天为了画一张图,使用了开源类库LiveCharts做了一个WPF的小程序,效果还算不错,但是也发现LiveCharts的功能还并不是很丰富,比如没法直接将图表另存为图片,总是用截屏就比较Low了,所以想到了Echarts。
Echarts是一款功能比较丰富的js图表库,也有完善的文档资料。基于javascript和html开发的话对环境的要求也不高,难度也低于C#这样的语言。对于没有什么编程基础的人来讲也比较好接受,自己按照文档修改一些功能代码页比较简单。
从官网上的示例来看,制作包括散点图在内的图表的核心是一个标准的JSON数据结构,只要按照官方文档的说明搭建合适的JSON结构,几乎可以实现任何想要的效果,当然前提是Echarts能实现的效果。
基于以上原因要做一个Ehcarts的图表页面,不过有一个问题是需要从外部文件如Excel文件读取数据,个人感觉使用js解析Excel效率比较低,能否将之前WPF解析Excel数据的方案利用起来呢?而且Echarts的核心就是一个JSON结构,能否将从Excel解析出来的数据直接输出成符合Echarts的数据结构呢?答案是肯定的,确认方案如下:
这一步在上篇文章已经讲过,使用的是Aspose.Cells类库来解析Excel,过程不再细说。
WPF随笔(八)–使用LiveCharts创建散点图
由于Echarts里图表的数据源格式基本都为数组,散点图则是二维数组,所以优先将LiveCharts里的ScatterSeries类转换为二维数组。
private double[,] ConvertSeriesToArray(ScatterSeries series)
{
int count = series.Values.Count;
double[,] datas = new double[count, 2];
for (int i = 0; i < count; i++)
{
datas[i, 0] = ((ScatterPoint)series.Values[i]).X;
datas[i, 1] = ((ScatterPoint)series.Values[i]).Y;
}
return datas;
}
之后将二维数组序列化后输出到文件。
private void WriteToJsonFile(object datas, string filePath)
{
string json = Newtonsoft.Json.JsonConvert.SerializeObject(datas);
//string basePath = AppDomain.CurrentDomain.BaseDirectory;
//string fileName = "data.json";
//string filePath = basePath + "\\" + fileName;
FileStream fs;
StreamWriter sw;
if (File.Exists(filePath))
//验证文件是否存在,有则覆盖,无则创建
{
fs = new FileStream(filePath, FileMode.Truncate, FileAccess.Write);
}
else
{
fs = new FileStream(filePath, FileMode.Create, FileAccess.Write);
}
sw = new StreamWriter(fs);
sw.WriteLine(json);
sw.Close();
fs.Close();
}
其中文件路径可以选择指定的文件来输出。
#region 输出为JSON文件
private void btnJson_Click(object sender, RoutedEventArgs e)
{
System.Windows.Forms.OpenFileDialog dialog = new System.Windows.Forms.OpenFileDialog();
dialog.Filter = "JSON(*.json)|*.json";
System.Windows.Forms.DialogResult result = dialog.ShowDialog();
if (result == System.Windows.Forms.DialogResult.OK)
{
try
{
string fileName = dialog.FileName;//获取文件路径
Double[,] data = ConvertSeriesToArray(ScatterSeries);//转换为二维数组
WriteToJsonFile(data, fileName);//输出JSON文件
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
#endregion
JS读取JSON文件可以使用jQuery的Ajax或者getJson方法。
$.getJSON("data.json",function(result){
console.log(result);
})
页面完整代码如下:
<!DOCTYPE html>
<html style="height: 100%">
<head>
<meta charset="utf-8">
</head>
<body style="height: 100%; margin: 0">
<div id="container" style="height: 100%"></div>
<script type="text/javascript" src="Scripts/echarts.min.js"></script>
<!--引入shine主题-->
<script type="text/javascript" src="Scripts/shine.js"></script>
<script type="text/javascript" src="Scripts/jquery.min.js"></script>
<script type="text/javascript">
var dom = document.getElementById("container");
var myChart = echarts.init(dom,'shine');//第二个参数指定引入的主题
var app = {};
$(function(){
$.getJSON("data.json",function(result){
var option = {
title: {
text: '主标题',
subtext: '副标题'
},
toolbox: {
show: true,
feature: {
dataZoom: {
yAxisIndex: 'none'
},
saveAsImage: {}
}
},
color:['#2f4554', '#61a0a8', '#d48265'],
tooltip: {
trigger: 'item',
axisPointer: {
type: 'cross'
}
},
xAxis: {
scale: true,
name:'X轴名称',
nameLocation:'end'
},
yAxis: {
scale: true,
name:'Y轴名称',
nameLocation:'end'
},
series: [{
type: 'scatter',
data: result,
markLine:{
data:[
{
name:'1.3',
yAxis:1.3
}
]
}
}]
};
if (option && typeof option === "object") {
myChart.setOption(option, true);
}
})
})
</script>
</body>
</html>
没有什么高深的东西,但有趣的是过程。