WPF 实现柱形统计图

 WPF 实现柱形统计图

WPF 实现柱形统计图

作者:WPFDevelopersOrg

原文链接:   https://github.com/WPFDevelopersOrg/WPFDevelopers

  • 框架使用大于等于.NET40

  • Visual Studio 2022;

  • 项目使用 MIT 开源许可协议;

  • 避免画线发虚DrawingContext绘制Line的时候会发虚,以下方法可以避免;

var d = Pen.Thickness / 2;var guidelines = new GuidelineSet(new[] { d }, new[] { d });drawingContext.PushGuidelineSet(guidelines);或者调用SnapDrawingExtensions.DrawSnappedLinesBetweenPoints

1) BasicBarChart.cs 代码如下;

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;namespace WPFDevelopers.Controls
{public class BasicBarChart : Control{public static readonly DependencyProperty SeriesArrayProperty =DependencyProperty.Register("SeriesArray", typeof(IEnumerable<KeyValuePair<string, double>>),typeof(BasicBarChart), new UIPropertyMetadata(SeriesArrayChanged));static BasicBarChart(){DefaultStyleKeyProperty.OverrideMetadata(typeof(BasicBarChart),new FrameworkPropertyMetadata(typeof(BasicBarChart)));}public IEnumerable<KeyValuePair<string, double>> SeriesArray{get => (IEnumerable<KeyValuePair<string, double>>)GetValue(SeriesArrayProperty);set => SetValue(SeriesArrayProperty, value);}private static void SeriesArrayChanged(DependencyObject d, DependencyPropertyChangedEventArgs e){var radarChart = d as BasicBarChart;if (e.NewValue != null)radarChart.InvalidateVisual();}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 = ActualHeight / 2 + 160;var w = 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;drawingContext.DrawSnappedLinesBetweenPoints(myPen, myPen.Thickness, new Point(startX, h),new Point(width, h));var formattedText = DrawingContextHelper.GetFormattedText(stratNum.ToString(),(Brush)brushConverter.ConvertFromString("#6E7079"), FlowDirection.LeftToRight);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 (var 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;}drawingContext.DrawSnappedLinesBetweenPoints(myPen, myPen.Thickness, points.ToArray());var xAxisPen = new Pen{Thickness = 1,Brush = (Brush)brushConverter.ConvertFromString("#E0E6F1")};xAxisPen.Freeze();var xAxis = h - 80;var max = Convert.ToInt32(SeriesArray.Max(kvp => kvp.Value));max = (max / 50 + (max % 50 == 0 ? 0 : 1)) * 50 / 50;var min = Convert.ToInt32(SeriesArray.Min(kvp => kvp.Value));points.Clear();for (var 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 = DrawingContextHelper.GetFormattedText(stratNum.ToString(),(Brush)brushConverter.ConvertFromString("#6E7079"), FlowDirection.LeftToRight);drawingContext.DrawText(formattedText,new Point(startX - formattedText.Width - 10, xAxis - formattedText.Height / 2));xAxis = xAxis - 80;}drawingContext.DrawSnappedLinesBetweenPoints(xAxisPen, xAxisPen.Thickness, points.ToArray());x = startX;var rectWidth = 85;var rectHeight = 0D;for (var i = 0; i < SeriesArray.Count(); i++){formattedText = DrawingContextHelper.GetFormattedText(SeriesArray.ToList()[i].Key,(Brush)brushConverter.ConvertFromString("#6E7079"), FlowDirection.LeftToRight);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;}}}
}

2) **BasicBarChartExample.xaml ** 代码如下;

<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/WPFDevelopersOrg/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>

2) BasicBarChartExample .xaml.cs 代码如下;

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;namespace WPFDevelopers.Samples.ExampleViews
{/// <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;}}
}
5e32ef9803210a13b60f15bb722fbaa6.png

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

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

相关文章

100亿人口会挨饿吗?人工智能迎击全球粮食问题

给作物看病的AI、走路“长眼”的拖拉机、上帝视角的卫星数据分析——未来吃饭就靠它们了。 图片来源&#xff1a;Blue River Technology 人类又面临了一项危机——随着人口不断膨胀&#xff0c;到2050年人类总人口也许要达到100亿&#xff0c;然而&#xff0c;地球却没有等比例…

switch注意事项

Day03_SHJavaTraining_4-5-2017 switch注意事项&#xff1a;①switch语句接受的数据类型  switch语句中的表达式的数据类型,是有要求的    JDK1.0 - 1.4 数据类型接受 byte short int char    JDK1.5 数据类型接受 byte short int char enum(枚举)  …

SkiaSharp 之 WPF 自绘 粒子花园(案例版)

此案例包含了简单的碰撞检测&#xff0c;圆形碰撞检测方法&#xff0c;也可以说是五环弹球的升级版&#xff0c;具体可以根据例子参考。粒子花园这名字是案例的名字&#xff0c;效果更加具有科技感&#xff0c;很是不错&#xff0c;搞搞做成背景特效也是不错的选择。Wpf 和 Ski…

xshell连接ubuntu

1.更新资料列表 sudo apt-get update2.安装openssh-server sudo apt-get install openssh-server3.查看ssh服务是否启动 sudo ps -e | grep ssh4.如果没有启动&#xff0c;启动ssh服务 sudo service ssh start5.查看IP地址 sudo ifconfig如果出现xshell无法输入密码的情况…

教你从零开始搭建一款前端脚手架工具

本文系原创&#xff0c;转载请附带作者信息&#xff1a;Jrain Lau项目地址&#xff1a;https://github.com/jrainlau/s...前言 在实际的开发过程中&#xff0c;从零开始建立项目的结构是一件让人头疼的事情&#xff0c;所以各种各样的脚手架工具应运而生。笔者使用较多的yoeman…

微信小程序 --- 页面跳转

第一种&#xff1a;wx.navigateTo({}); 跳转&#xff1a; 注意&#xff1a;这种跳转回触发当前页面的 onHide 方法&#xff0c;将当前页面隐藏&#xff0c;然后显示跳转页面。所以可以返回&#xff0c;返回的时候触发 onShow方法进行显示&#xff1a; &#xff08;项目的底部导…

Java基础 深拷贝浅拷贝

Java基础 深拷贝浅拷贝 非基本数据类型 需要new新空间class Student implements Cloneable{private int id;private String name;private Vector course;public Student(){try{Thread.sleep(1000);System.out.println("Student Constructor called.");}catch (Interr…

不安装运行时运行 .NET 程序

好久没写文章了&#xff0c;有些同学问我公众号是不是废了&#xff1f;其实并没有。其实想写的东西很多很多&#xff0c;主要是最近公司比较忙&#xff0c;以及一些其他个人原因没有时间来更新文章。这几天抽空写了一点点东西&#xff0c;证明公众号还活着。长久以来的认知&…

一文弄懂分布式和微服务

简单的说&#xff0c;微服务是架构设计方式&#xff0c;分布式是系统部署方式&#xff0c;两者概念不同。 微服务 简单来说微服务就是很小的服务&#xff0c;小到一个服务只对应一个单一的功能&#xff0c;只做一件事。这个服务可以单独部署运行&#xff0c;服务之间可以通过R…

JS 事件练习

QQ拖拽及状态栏选择 HTML 1 <!DOCTYPE html>2 <html xmlns"http://www.w3.org/1999/xhtml">3 <head>4 <title>QQ练习</title>5 <link href"css/main.css" rel"stylesheet" />6 <script src&…

Dubbo和Spring Cloud微服务架构对比

微服务架构是互联网很热门的话题&#xff0c;是互联网技术发展的必然结果。它提倡将单一应用程序划分成一组小的服务&#xff0c;服务之间互相协调、互相配合&#xff0c;为用户提供最终价值。目录 微服务主要的优势 降低复杂度 可独立部署 容错 扩展 核心部件 总体架构 Dubbo …

《ABP Framework 极速开发》 - 教程首发

‍写在发布之前强烈建议每一位小伙伴都应该好好看看 ABP Framework 官方文档&#xff0c;可能有很多的小伙伴跟我刚开始的感觉一样“一看文档深似海”&#xff0c;看完文档之后&#xff0c;想要上手却找不着头绪。本套教程写作的目的之一是为初学者提供一条相对简洁的快速上手路…

智能家居系统结构标准化

版权申明&#xff1a;本文为博主窗户(Colin Cai)原创&#xff0c;欢迎转帖。如要转贴&#xff0c;必须注明原文网址http://www.cnblogs.com/Colin-Cai/p/8490423.html作者&#xff1a;窗户QQ&#xff1a;6679072E-mail&#xff1a;6679072qq.com0 引 言 智能家居是指利用先进的…

洛谷 P3391 文艺平衡树

题目描述 您需要写一种数据结构&#xff08;可参考题目标题&#xff09;&#xff0c;来维护一个有序数列&#xff0c;其中需要提供以下操作&#xff1a;翻转一个区间&#xff0c;例如原有序序列是5 4 3 2 1&#xff0c;翻转区间是[2,4]的话&#xff0c;结果是5 2 3 4 1 --by洛谷…

JSONObject中optString和getString等的区别

2019独角兽企业重金招聘Python工程师标准>>> 同事在看到我写的解析数据代码后&#xff0c;告诉我optString比getString好用&#xff0c;optString不会抛异常&#xff0c;而getString会抛异常&#xff0c;自己是将信将疑&#xff0c;就说&#xff0c;回去后我查查资料…

Lombok插件安装(IDEA)、配置jar包、使用

点击进入Lombok官网下载Lombok jar包 使用Lombok可能需要注意的地方 &#xff08;1&#xff09;当你的IDE是Idea时&#xff0c;要注意你的Idea是支持Lombok的&#xff0c;如果不支持请更换高版本尝试&#xff08;这里采用2018 3.3&#xff09;。 &#xff08;2&#xff09;在使…

Blazor University (40)JavaScript 互操作 —— 传递 HTML 元素引用

原文链接&#xff1a;https://blazor-university.com/javascript-interop/calling-javascript-from-dotnet/passing-html-element-references/传递 HTML 元素引用源代码[1]在编写 Blazor 应用程序时&#xff0c;不鼓励对文档对象模型 (DOM) 进行操作&#xff0c;因为它可能会干…

RabbitMQ+PHP 教程六(RPC)

(using php-amqplib) 前提必读 本教程假设RabbitMQ是安装在标准端口上运行&#xff08;5672&#xff09;。如果您使用不同的主机、端口或凭据&#xff0c;则连接设置需要调整。 如果您在本教程中遇到困难&#xff0c;可以通过邮件列表与我们联系。 开始 在第二个教程中&#xf…

TKMybatis 介绍和使用

目录 一、什么是 TKMybatis 二、TKMybatis 使用 2.1 Springboot 项目中加入依赖 2.2 使用讲解 2.2.1 实体类中使用 2.2.2 dao中使用 2.2.3 Service 层中使用 2.3 实际案例 2.3.1 dao 层使用 2.3.2 service 层使用 一、什么是 TKMybatis TKMybatis 是基于 Mybatis 框…

WinForm(三)揭开可视化控件的面纱

WinForm所见即所得的UI设计框架&#xff0c;开发效率确实有所提升&#xff0c;同时降低了编程门槛&#xff0c;让WinForm更普及。拖拖拽拽就能设计出一个界面&#xff0c;那么我们拖拽的这些东西是什么&#xff1f;它们是什么原理&#xff1f;。WinForm我觉得很好的一点是&…