WPF数据可视化-瀑布图
实现方式一:
将数据(Point[])根据索引沿X轴使用虚拟画布进行绘制,每个数据绘制大小为1px * 1px;最终绘制出的宽度等于数据的总长度。标记并存储当前绘制的图为PreviousBitmap; 继续置顶绘制第二组数据,第二组数据绘制完后,将标记的PreviousBitmap作为Image在Y轴距离顶部距离为1px的地方用DrawingContext.DrawImage()方式绘制,以此类推。核心代码如下:
private void DoAddDataArray(Point[] arrPoints)
{
this.Dispatcher.Invoke(DispatcherPriority.Normal, new Action(() =>
{
double dPixelWidth = Pixel;
double dContainerWidth = this.VbxContainer.ActualWidth;
double dContainerHeight = this.VbxContainer.ActualHeight;
double dPixelHeight = Pixel/2d;
double dCellHeight = 1;
double dCellWidth = 1; DrawingVisual drawingVisual = new DrawingVisual();
DrawingContext drawingContext = drawingVisual.RenderOpen();
drawingContext.DrawRectangle(new SolidColorBrush(Colors.Blue),
new Pen(), new Rect(0, 0, dPixelWidth, dCellHeight)); // 绘制新数据 for (int i = 0; i < arrPoints.Length; i++)
{
double dCellX = Math.Round(((arrPoints[i].X - MinAxisX) / (MaxAxisX - MinAxisX)) * Pixel);
double dY = arrPoints[i].Y;
Color oColor = this.GetColor(dY);
//drawingContext.DrawRectangle(new SolidColorBrush(oColor),
// new Pen(), new Rect(dCellX, 0, dCellWidth, dCellHeight));
LinearGradientBrush lineBrush = new LinearGradientBrush();
lineBrush.GradientStops.Add(new GradientStop(Colors.Transparent, 0));
lineBrush.GradientStops.Add(new GradientStop(oColor, 0.25));
lineBrush.GradientStops.Add(new GradientStop(oColor, 0.5));
lineBrush.GradientStops.Add(new GradientStop(oColor, 0.75));
lineBrush.GradientStops.Add(new GradientStop(Colors.Transparent, 1));
drawingContext.DrawRectangle(lineBrush, new Pen(), new Rect(dCellX-1, 0, dCellWidth + 2, dCellHeight));
} // 绘制历史数据
if (this.PreviousBitmap != null)
drawingContext.DrawImage(this.PreviousBitmap, new Rect(0, dCellHeight, dPixelWidth, dPixelHeight));
drawingContext.Close(); // 生成图像处理
RenderTargetBitmap rtbCurrent = new RenderTargetBitmap((int)dPixelWidth,
(int)dPixelHeight, 96, 96, PixelFormats.Pbgra32);
rtbCurrent.Render(drawingVisual); this.PreviousBitmap = rtbCurrent; // 当前绘制的存为历史,下次绘制时直接调用
this.ImgMain.Source = rtbCurrent; // 显示绘制的图像
}));
}
运行效果
实现方式二:
将数据(Point[])根据索引沿X轴使用虚拟画布进行绘制,每个数据绘制大小为1px * 1px;最终绘制出的宽度等于数据的总长度。创建一个Rectangle,将绘制的图赋值给Rectangle.Fill属性,将绘制过程中不断创建的Rectangle插入控件Stackpanel的首位。核心代码如下:
private void DoAddDataArray(Point[] arrPoints)
{
this.Dispatcher.Invoke(DispatcherPriority.Normal, new Action(() =>
{
double dPixelWidth = Pixel;
double dContainerWidth = this.VbxContainer.ActualWidth;
double dContainerHeight = this.VbxContainer.ActualHeight;
double dPixelHeight = Pixel / 2d; DrawingVisual drawingVisual = new DrawingVisual();
DrawingContext drawingContext = drawingVisual.RenderOpen();
drawingContext.DrawRectangle(new SolidColorBrush(Colors.Blue),
new Pen(), new Rect(, , dPixelWidth, )); // 绘制新数据
double dCellHeight = ;
double dCellWidth = ;
for (int i = ; i < arrPoints.Length; i++)
{
double dCellX = Math.Round(((arrPoints[i].X - MinAxisX) / (MaxAxisX - MinAxisX)) * Pixel);
double dY = arrPoints[i].Y;
Color oColor = this.GetColor(dY);
//drawingContext.DrawRectangle(new SolidColorBrush(oColor),
// new Pen(), new Rect(dCellX, 0, dCellWidth, dCellHeight));
LinearGradientBrush lineBrush = new LinearGradientBrush();
lineBrush.GradientStops.Add(new GradientStop(Colors.Transparent, ));
lineBrush.GradientStops.Add(new GradientStop(oColor, 0.25));
lineBrush.GradientStops.Add(new GradientStop(oColor, 0.5));
lineBrush.GradientStops.Add(new GradientStop(oColor, 0.75));
lineBrush.GradientStops.Add(new GradientStop(Colors.Transparent, ));
drawingContext.DrawRectangle(lineBrush, new Pen(), new Rect(dCellX - 0.5, , dCellWidth + , dCellHeight));
}
drawingContext.Close(); // 生成图像处理
RenderTargetBitmap rtbCurrent = new RenderTargetBitmap((int)dPixelWidth, (int), , , PixelFormats.Pbgra32);
rtbCurrent.Render(drawingVisual); Rectangle rect = new Rectangle();
rect.Width = Pixel;
rect.Height = ;
rect.Fill = new ImageBrush(rtbCurrent);
// SpContainers ---- Stackpanel
this.SpContainers.Children.Insert(, rect);
if (this.SpContainers.Children.Count > )
this.SpContainers.Children.RemoveAt();
}));
}
运行效果:
相对而言,方式二由于不断插入新的Rectangle。下移效果为控件位置变化所呈现,不像方式一是一张完整图,故画质欠缺。
性能和测试:
采用Timer生成随机数据进行测试。10毫秒1组,每组1000个数据点。 相当于每秒绘制10万个点。
测试时在Release模式下,开启多个子模块,性能勉强能接受。
环境:
语言: C#
工程:WPF
工具:Visual Studio 2017
系统:Windows
第三方插件:无
微信扫码下载源代码:
WPF数据可视化-瀑布图的更多相关文章
- WPF数据可视化-趋势图
环境: 系统: Window 7以上: 工具:VS2013及以上. 研发语言及工程: C# WPF 应用程序 效果: 简介: 不需要调用第三方Dll, 仅仅在WPF中使用贝塞尔曲线,不到500 ...
- 手把手教你做一个python+matplotlib的炫酷的数据可视化动图
1.效果图 2.注意: 上述资料是虚拟的,为了学习制作动图,构建的. 仅供学习, 不是真实数据,请别误传. 当自己需要对真实数据进行可视化时,可进行适当修改. 3.代码: #第1步:导出模块,固定 i ...
- 基于matplotlib的数据可视化 - 热图imshow
热图: Display an image on the axes. 可以用来比较两个矩阵的相似程度 mp.imshow(z, cmap=颜色映射,origin=垂直轴向) imshow( X, cma ...
- g2蚂蚁数据可视化折线图,点位坐标label 图形文本设置
应用g2可视化插件画了个粉丝分析图 要求显示如图所见的节点参数,查看文档蚂蚁图形文本设置,得知需要引入如下代码: chart.point().position('update*praises').la ...
- flask+sqlite3+echarts2+ajax数据可视化--静态图
结构: /www | |-- /static | | | |-- echarts.js(当然还有echarts原dist目录下的文件(夹)) | |-- /templates | | | |-- in ...
- 气象netCDF数据可视化分析
气象netCDF数据可视化分析 2019-09-19 15:34:22 自走棋 阅读数 162更多 分类专栏: web前端 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载 ...
- 用Python的Plotly画出炫酷的数据可视化(含各类图介绍,附代码)
前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 作者: 我被狗咬了 在谈及数据可视化的时候,我们通常都会使用到matplo ...
- Webstorm+Webpack+echarts构建个性化定制的数据可视化图表&&两个echarts详细教程(柱状图,南丁格尔图)
Webstorm+Webpack+echarts ECharts 特性介绍 ECharts,一个纯 Javascript 的图表库,可以流畅的运行在 PC 和移动设备上,兼容当前绝大部分浏览器(I ...
- [原创.数据可视化系列之五]韩国"萨德"系统防御图
自从7月8日美国和韩国共同宣布将在韩国部署萨德反导系统后,韩国国内对此事的巨大争议以及本地区一些国家的强烈不满情绪在持续发酵.“萨德”(THAAD)全称“末段高空区域防御系统”,是美国导弹防御局和美国 ...
随机推荐
- DRF Django REST framework 之 解析器(二)
引入 Django Rest framework帮助我们实现了处理application/json协议请求的数据,如果不使用DRF,直接从 request.body 里面拿到原始的客户端请求的字节数据 ...
- 转:SpringBoot系列: 使用 flyway 管理数据库版本
Flyway 和 Liquibase 都是 Java 项目中常用的 DB migration 工具, 从使用简便性看,Flyway 比 Liquibase 更简单, 从 github 的 star 数 ...
- TypeError: 'list' object cannot be interpreted as an integer
TypeError: 'list' object cannot be interpreted as an integer 类型错误,不能将list对象转换为一个整数. 错误代码,例如如下例子: arg ...
- FF.PyAdmin 接口服务/后台管理微框架 (Flask+LayUI)
源码(有兴趣的朋友请Star一下) github: https://github.com/fufuok/FF.PyAdmin gitee: https://gitee.com/fufuok/FF.Py ...
- Spring MVC上传文件原理和resolveLazily说明
问题:使用Spring MVC上传大文件,发现从页面提交,到进入后台controller,时间很长.怀疑是文件上传完成后,才进入.由于在HTTP首部自定义了“Token”字段用于权限校验,Token的 ...
- 快速搭建 Serverless 在线图片处理应用
作者:倚贤 首先介绍下在本文出现的几个比较重要的概念: 函数计算(Function Compute):函数计算是一个事件驱动的服务,通过函数计算,用户无需管理服务器等运行情况,只需编写代码并上传.函数 ...
- IOS UIAlertView(警告框)方法总结
转自:my.oschina.net/u/2340880/blog/408873?p=1 IOS中UIAlertView(警告框)常用方法总结 一.初始化方法 - (instancetype)initW ...
- componentWillMount VS componentDidMount
前言 这与React组件的生命周期有关,组件挂载时有关的生命周期有以下几个: constructor(){} componentWillMount(){} render(){} componentDi ...
- Java修炼——四种方式解析XML_SAX
四种方式解析XML:DOM JDOM DOM4J SAX 先写一个XML栗子: <?xml version="1.0" encoding="U ...
- HDU5919 Sequence II(主席树)
Mr. Frog has an integer sequence of length n, which can be denoted as a1,a2,⋯,ana1,a2,⋯,anThere are ...