WPF实现统计图

43785eb5c765fc055ddd463c46cfec27.png

WPF开发者QQ群: 340500857  | 微信群 -> 进入公众号主页 加入组织

dd06d688031910754a44dfadc4ae7fc8.png 

8d5842d914d7c1a72f915c191138542d.png

有小伙伴提出需要实现统计图。                           

     由于在WPF中没有现成的统计图控件,所以我们自己实现一个。

PS:有更好的方式欢迎推荐。

01

代码如下

一、创建 BasicBarChart.cs 菜单继承 Control代码如下。

ed04799205e2cc914d59c66bbd266265.png

BasicBarChart.cs实现思路如下

1、SeriesArray :存放展示集合 。

2、重写OnRender 。

3、先绘制X轴线。

4、调用GetFormattedText()绘制底部类别。

5、调用GetFormattedText()绘制左侧标尺。

6、DrawingContext绘制Line的时候会发虚,以下方法可以避免

 var d = Pen.Thickness / 2;

 var guidelines = new GuidelineSet(new[] { d }, new[] { d });

drawingContext.PushGuidelineSet(guidelines);

或者调用

SnapDrawingExtensions.DrawSnappedLinesBetweenPoints

避免画线发虚。

2b7f035049897ad2941d121e96af4b70.png

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;namespace WPFDevelopers.Controls
{public class BasicBarChart : Control{public IEnumerable<KeyValuePair<string, double>> SeriesArray{get { return (IEnumerable<KeyValuePair<string, double>>)GetValue(SeriesArrayProperty); }set { SetValue(SeriesArrayProperty, value); }}public static readonly DependencyProperty SeriesArrayProperty =DependencyProperty.Register("SeriesArray", typeof(IEnumerable<KeyValuePair<string, double>>), typeof(BasicBarChart), new UIPropertyMetadata(SeriesArrayChanged));private static void SeriesArrayChanged(DependencyObject d, DependencyPropertyChangedEventArgs e){BasicBarChart radarChart = d as BasicBarChart;if (e.NewValue != null)radarChart.InvalidateVisual();}static BasicBarChart(){DefaultStyleKeyProperty.OverrideMetadata(typeof(BasicBarChart), new FrameworkPropertyMetadata(typeof(BasicBarChart)));}protected override void OnRender(DrawingContext drawingContext){//base.OnRender(drawingContext);if (SeriesArray == null || SeriesArray.Count() == 0)return;SnapsToDevicePixels = true;UseLayoutRounding = true;var brushConverter = new BrushConverter();var myPen = new Pen{Thickness = 1,Brush = (Brush)brushConverter.ConvertFromString("#6E7079")};myPen.Freeze();//var d = myPen.Thickness / 2;//var guidelines = new GuidelineSet(new[] { d }, new[] { d });//drawingContext.PushGuidelineSet(guidelines);var h = this.ActualHeight / 2 + 160;var w = this.ActualWidth / 2;var startX = w / 3;var width = SeriesArray.Count() * 120 + startX;//drawingContext.DrawLine(myPen, new Point(startX, h), new Point(width, h));var stratNum = 0;SnapDrawingExtensions.DrawSnappedLinesBetweenPoints(drawingContext,myPen,myPen.Thickness, new Point(startX, h), new Point(width, h));var formattedText = GetFormattedText(stratNum.ToString());drawingContext.DrawText(formattedText, new Point(startX - formattedText.Width * 2 - 10, h - formattedText.Height / 2));var x = startX;//var y = h + d;var y = h + myPen.Thickness;var points = new List<Point>();var rectBrush = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#5470C6"));for (int i = 0; i < SeriesArray.Count() + 1; i++){//drawingContext.DrawLine(myPen, new Point(x, y), new Point(x, y + 4));points.Add(new Point(x, y));points.Add(new Point(x, y + 4));x = x + 120;}SnapDrawingExtensions.DrawSnappedLinesBetweenPoints(drawingContext, myPen, myPen.Thickness, points.ToArray());var xAxisPen = new Pen{Thickness = 1,Brush = (Brush)brushConverter.ConvertFromString("#E0E6F1")};xAxisPen.Freeze();var xAxis = h - 80;int max = Convert.ToInt32(SeriesArray.Max(kvp => kvp.Value));max = (max / 50 + (max % 50 == 0 ? 0 : 1)) * 50 / 50;int min = Convert.ToInt32(SeriesArray.Min(kvp => kvp.Value));points.Clear();for (int i = 0; i < max; i++){//drawingContext.DrawLine(xAxisPen, new Point(startX, xAxis), new Point(width, xAxis));points.Add(new Point(startX, xAxis));points.Add(new Point(width, xAxis));stratNum += 50;formattedText = GetFormattedText(stratNum.ToString());drawingContext.DrawText(formattedText, new Point(startX - formattedText.Width - 10, xAxis - formattedText.Height / 2));xAxis = xAxis - 80;}SnapDrawingExtensions.DrawSnappedLinesBetweenPoints(drawingContext, xAxisPen, xAxisPen.Thickness, points.ToArray());x = startX;var rectWidth = 85;var rectHeight = 0D;for (int i = 0; i < SeriesArray.Count(); i++){formattedText = GetFormattedText(SeriesArray.ToList()[i].Key);drawingContext.DrawText(formattedText, new Point(x + 120 / 2 - formattedText.Width / 2, y + 4));var _value = SeriesArray.ToList()[i].Value;//rectHeight = _value * 200;rectHeight = (_value - 0) / (stratNum - 0) * (80 * max);//rectHeight = (stratNum - _value) / 100 * stratNum;drawingContext.DrawRectangle(rectBrush, null, new Rect(x + (120 - 85) / 2, h - rectHeight, rectWidth, rectHeight));x = x + 120;}}FormattedText GetFormattedText(string text){var brushConverter = new BrushConverter();return new FormattedText(text,CultureInfo.CurrentCulture,FlowDirection.LeftToRight,new Typeface(new FontFamily("Microsoft YaHei"), FontStyles.Normal, FontWeights.UltraLight, FontStretches.Normal),12, (Brush)brushConverter.ConvertFromString("#6E7079")){MaxLineCount = 1,TextAlignment = TextAlignment.Justify,Trimming = TextTrimming.CharacterEllipsis};}}public static class SnapDrawingExtensions{public static void DrawSnappedLinesBetweenPoints(this DrawingContext dc,Pen pen, double lineThickness, params Point[] points){var guidelineSet = new GuidelineSet();foreach (var point in points){guidelineSet.GuidelinesX.Add(point.X);guidelineSet.GuidelinesY.Add(point.Y);}var half = lineThickness / 2;points = points.Select(p => new Point(p.X + half, p.Y + half)).ToArray();dc.PushGuidelineSet(guidelineSet);for (var i = 0; i < points.Length - 1; i = i + 2){dc.DrawLine(pen, points[i], points[i + 1]);}dc.Pop();}}
}

二、创建BasicBarChartExample.xaml代码如下

2ebcc34d5622d75d27105e8c6c99d435.png

<UserControl x:Class="WPFDevelopers.Samples.ExampleViews.BasicBarChartExample"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:WPFDevelopers.Samples.ExampleViews"xmlns:wpfdev="https://github.com/yanjinhuagood/WPFDevelopers"mc:Ignorable="d" d:DesignHeight="450" d:DesignWidth="800"><Grid Background="Gainsboro"><BorderHeight="500"Background="White"Margin="30,0"><Grid Margin="20,10"><Grid.RowDefinitions><RowDefinition Height="40" /><RowDefinition /><RowDefinition Height="auto" /></Grid.RowDefinitions><WrapPanel HorizontalAlignment="Right"><RectangleWidth="6"Height="26"Fill="Black" /><TextBlockPadding="10,0"FontSize="24"FontWeight="Black"Text="{Binding KeyBarChart, RelativeSource={RelativeSource AncestorType=local:BasicBarChartExample}}" /></WrapPanel><wpfdev:BasicBarChartGrid.Row="1"SeriesArray="{Binding SeriesModels, RelativeSource={RelativeSource AncestorType=local:BasicBarChartExample}}"/><ButtonGrid.Row="2"Width="200"VerticalAlignment="Bottom"Click="Button_Click"Content="刷新"Style="{StaticResource PrimaryButton}" /></Grid></Border></Grid>
</UserControl>

三、创建BasicBarChartExample.xaml.cs代码如下

a2fbdf33e30d673fcccdf88373ce118d.png

/// <summary>/// BasicBarChartExample.xaml 的交互逻辑/// </summary>public partial class BasicBarChartExample : UserControl{public IEnumerable<KeyValuePair<string, double>> SeriesModels{get { return (IEnumerable<KeyValuePair<string, double>>)GetValue(SeriesModelsProperty); }set { SetValue(SeriesModelsProperty, value); }}public static readonly DependencyProperty SeriesModelsProperty =DependencyProperty.Register("SeriesModels", typeof(IEnumerable<KeyValuePair<string, double>>), typeof(BasicBarChartExample), new PropertyMetadata(null));Dictionary<string, IEnumerable<KeyValuePair<string, double>>> keyValues = new Dictionary<string, IEnumerable<KeyValuePair<string, double>>>();public string KeyBarChart{get { return (string)GetValue(KeyBarChartProperty); }set { SetValue(KeyBarChartProperty, value); }}public static readonly DependencyProperty KeyBarChartProperty =DependencyProperty.Register("KeyBarChart", typeof(string), typeof(BasicBarChartExample), new PropertyMetadata(null));private int _index = 0;public BasicBarChartExample(){InitializeComponent();var Models1 = new[]{new KeyValuePair<string, double>("Mon", 120),new KeyValuePair<string, double>("Tue", 130),new KeyValuePair<string, double>("Wed", 160),new KeyValuePair<string, double>("Thu", 140),new KeyValuePair<string, double>("Fri", 200) ,new KeyValuePair<string, double>("Sat", 80) ,new KeyValuePair<string, double>("Sun", 90) ,};keyValues.Add("到访数", Models1);var Models2 = new[]{new KeyValuePair<string, double>("蛐蛐", 120),new KeyValuePair<string, double>("常威", 170),new KeyValuePair<string, double>("来福", 30),new KeyValuePair<string, double>("包龙星", 200),new KeyValuePair<string, double>("包有为", 100) ,new KeyValuePair<string, double>("雷豹", 180) ,new KeyValuePair<string, double>("方唐镜", 90) ,};keyValues.Add("能力值", Models2);SeriesModels = keyValues.ToList()[0].Value;KeyBarChart = keyValues.ToList()[0].Key;}private void Button_Click(object sender, RoutedEventArgs e){_index++;if (_index >= keyValues.Count){_index = 0;}SeriesModels = keyValues.ToList()[_index].Value;KeyBarChart = keyValues.ToList()[_index].Key;}

02


效果预览

上一篇雷达图更新了

5e0a46131401d21499f4aa8c4640846a.gif

源码地址如下

github:https://github.com/yanjinhuagood/WPFDevelopers.git

gitee:https://gitee.com/yanjinhua/WPFDevelopers.git

WPF开发者QQ群: 340500857 

blogs: https://www.cnblogs.com/yanjinhua

Github:https://github.com/yanjinhuagood

出处:https://www.cnblogs.com/yanjinhua

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

转载请著名作者 出处 https://github.com/yanjinhuagood

8fb6774e53ba68d94b89ea34120ba8e7.png

扫一扫关注我们,

d0fdcdf3cc921b43c98d0465c15b8682.gif

更多知识早知道!

146be20e47e8346c787329482015a955.gif

点击阅读原文可跳转至源代码

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/296226.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java guava json文件_Json解析文件位置的问题

有这么一段Json{"name": "java3d:vecmath:1.3.1"},{"name": "net.sf.trove4j:trove4j:3.0.3"},{"name": "com.ibm.icu:icu4j-core-mojang:51.2"},{"name": "net.sf.jopt-simple:jopt-simple:4.5&q…

在此之前的软件系统做开发—需求的研究框架

最近的研究需要做一个软件&#xff0c;从一些方面中学习了下面的。当然&#xff0c;这些都是需求只是初步框架。也创下了基本的设计和开发&#xff0c;只是让软件公司可能对软件整体的了解需求和促进软件有一个粗略的估计。公司 实现的根本目的 现有的软件的情况下&#xff08;…

手绘图解:从零维到十维空间

全世界只有3.14 % 的人关注了爆炸吧知识事情是这样的&#xff0c;这周我给学生讲3dmax的课。为了让学生了解三视图我就顺便科普了一下什么是零维、一维、二维、三维空间。讲完不过瘾&#xff0c;感觉一支粉笔一块黑板讲维度是一件很爽的事情&#xff0c;那么.........接下来请同…

[for循环之等腰三角形]

public class IsoscelesTriangle { /*** 等腰三角形*/public void print1(){//形如 ▲向上的 for(int i1;i<5;i){for(int k1;k<5-i;k)System.out.print(" ");for(int j1;j<2*i-1;j)System.out.print("*");System.out.print("\n");}}pub…

ISA server的常见身份验证方式

ISA 2006的几种常用验证方式&#xff1a;1. 基本验证&#xff1a;此验证方式不会被加密&#xff0c;只是以明文的方式来传递信息&#xff0c;不安全。如果在“网络”的“内部”属性中将“域”选项卡里边的“选择域”来配置默认域&#xff0c;那么就会把用户送来的帐户与密码信息…

字节前端终于开源!吹爆!

Semi Design 发布&#xff0c;前端同学的福音大家好&#xff0c;我是鱼皮。最近&#xff0c;字节跳动的抖音前端技术团队开源了一款企业级应用设计系统 Semi Design 。这也是他们团队在 GitHub 上首次公开的项目&#xff0c;短短几天&#xff0c;就收获了 3.6 k 个 star。GitH…

CSS2-3常见的demo列子总结

CSS2-3常见的demo列子总结 阅读目录 1. css超过一行或者多行后显示省略号。2. css图片未知高度垂直居中完美解决方案。3. 学习使用 :before和 :after伪元素回到顶部1. css超过一行或者多行后显示省略号。 Css实现超过一行后显示省略号&#xff1b;代码如下&#xff1a;<p st…

18张难以置信的照片,封面这张你就没见过

全世界只有3.14 % 的人关注了爆炸吧知识感谢网络&#xff0c;只要点几下鼠标&#xff0c;就能看到我们以前从未见过的东西——有些甚至是难以置信的&#xff01;鲸鱼的心脏水中的鲨鱼卵幼年的箭鱼萌萌哒世界上最高的棕榈树&#xff0c;简直以为是PS的没见过的话&#xff0c;很容…

Java 关于中文乱码处理的经验总结

为什么说乱码是中国程序员无法避免的话题呢&#xff1f;这个首先要从编码机制上说起&#xff0c;大家都是中文和英文的编码格式不是一样&#xff0c;解码也是不一样的&#xff01;如果中国的程序员不会遇到乱码&#xff0c;那么只有使用汉语编程。汉语编程是怎么回事我也不大清…

[信息收集] HCOMP 2010概况及收录论文

这是第二届HCOMP. 全称&#xff1a;Human Computation Workshop(HCOMP2010) 时间&#xff1a;July 25, 2010 地点&#xff1a;Washington, D.C., USA 收录论文情况&#xff1a;共有4个session&#xff0c; 包括&#xff1a; Invited Talk(1篇&#xff09;, Market design(3篇),…

.NET 生态系统的蜕变之 .NET 6

.NET 6 是自.NET 4 框架以来生态系统看到的最大版本更新&#xff0c;虽然.NET Core 是2014年开始非常大的一项重大战略举措&#xff0c;但是.NET 6是真正的具有强大动力的非常重要的版本。2021年11月9日即将正式发布的.NET 6, 也许你认为.NET 5才刚刚发布&#xff0c;我才刚开始…

C语言程序读写文件(文件内存一个十进制数,每读一次数值加一)

1.问题&#xff1a;C语言程序实现读写一个txt文件&#xff0c;txt文件中存储一个十进制数、每读一次该数值加一。 2.实现&#xff1a;新建一个文件夹&#xff0c;在该文件夹中建一个outputFileName.txt文件、内容是&#xff1a;1&#xff0c;再在该文件夹中新建一个t.c文件、内…

php 电梯程序设计,教你写出京东电梯式轮播

效果知识点&#xff1a;企业布局技巧&#xff0c;如何高效的编写CSS样式&#xff0c;常用选择器&#xff0c;基本标签&#xff0c;盒子模型&#xff0c;jquery类库调用&#xff0c;JS特效编写&#xff0c;JS编程思维等。京东电梯式轮播源码&#xff1a;Document*{margin:0px;}/…

我看你还能坚持多久?!

1 我看你还能坚持多久&#xff01;▼2 依旧是熟悉的配方▼3 到哪儿都不愁工作......▼4 请问&#xff0c;当事喵作何感想&#xff1f;▼5 池塘危险&#xff0c;请勿靠近&#xff01;&#xff08;图源网络&#xff0c;侵删&#xff09;▼6 望周知&#xff01;▼7 实在是无…

查询一个表中所有id字段在另一个表中对应值的SQL语句怎么写?

编辑器加载中... 查询一个表中所有id字段在另一个表中对应值的SQL语句怎么写&#xff1f;多表联结查询:select rbd.RBDID, rbd.ProductCode,p.ProductCnName,p.[Standard],p.Impression,pb.BrandName,cgdw.UnitName,un.UnitName ,rbd.BuyingAmount,rbd.UnitPricefrom PCS_Requ…

CiberCut_5.6 标牌制作

CiberCut_5.6 标牌制作Elibrium.My.Professional.Business.Cards.v4.0 名片设计SummitSoft.Business.Cards.Plus.2004 名片设计SummitSoft.Label.Designer.Deluxe.2004 标签设计Teklynx.LabelView.Gold.v8.10.06 BrainVoyager QX 2.0.7 可视化核磁共振Dentrix.v10.5.4.4 牙医软…

Hello Blazor:(13)查找HTML元素对应.razor文件

前言Blazor是基于组件的开发&#xff0c;每个组件都是以一个.razor文件形式存在。当应用程序变得越来越大并且.razor文件的数量和层次结构越来越多时&#xff0c;想很快弄清页面上的HTML元素是由哪个组件生成的&#xff0c;就变得不那么容易了&#xff01;FindRazorSourceFile介…

C++STL之string (转)

在学习cSTL中的string&#xff0c;在这里做个笔记&#xff0c;以供自己以后翻阅和初学者参考。 1&#xff1a;string对象的定义和初始化以及读写 string s1; 默认构造函数&#xff0c;s1为空串 string s2(s1); 将s2初始化为s1的一个副本 string s3("valuee");…

当年的毒王熊猫烧香,现在怎么样了?

全世界只有3.14 % 的人关注了爆炸吧知识放假&#xff0c;小编来到了远在73公里之外的天后宫&#xff0c;终于是了了本命年的一桩心事。回想上一个本命年&#xff0c;当时小编还是沉迷扫雷和蜘蛛纸牌的孩子...但当时却发生了一件令我很不爽的事——“熊猫烧香”席卷全国&#xf…

$query php,phpQuery让php处理html代码像jQuery一样方便

简介如何在php中方便地解析html代码&#xff0c;估计是每个phper都会遇到的问题。用phpQuery就可以让php处理html代码像jQuery一样方便。DEMO我下的是onefile版&#xff1a;phpQuery-0.9.5.386-onefile.zip然后在项目中引用。html文件test.html&#xff1a;Spiderman City Driv…