WPF 实现扇形统计图

扇形统计图

原文作者:ArcherSong

博客地址:https://www.cnblogs.com/ganbei/

  • 绘制一个扇形原理也是基于Canvas进行绘制;

  • ArcSegment[1]绘制弧形;

  • 绘制指示线;

  • 绘制文本;

  • 鼠标移入动画;

  • 显示详情Popup

  • 源码Github[2]Gitee[3]

d98353b88539bcd0124950eb42a88472.png

1)SectorChart.cs代码如下;

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Effects;
using System.Windows.Shapes;
using WPFDevelopers.Charts.Models;namespace WPFDevelopers.Charts.Controls
{[TemplatePart(Name = CanvasTemplateName, Type = typeof(Canvas))][TemplatePart(Name = PopupTemplateName, Type = typeof(Popup))]public class SectorChart : Control{const string CanvasTemplateName = "PART_Canvas";const string PopupTemplateName = "PART_Popup";private Canvas _canvas;private Popup _popup;private double centenrX, centenrY, radius, offsetX, offsetY;private Point minPoint;private double fontsize = 12;private bool flg = false;public Brush Fill{get { return (Brush)GetValue(FillProperty); }set { SetValue(FillProperty, value); }}public static readonly DependencyProperty FillProperty =DependencyProperty.Register("Fill", typeof(Brush), typeof(SectorChart), new PropertyMetadata(null));public string Text{get { return (string)GetValue(TextProperty); }set { SetValue(TextProperty, value); }}public static readonly DependencyProperty TextProperty =DependencyProperty.Register("Text", typeof(string), typeof(SectorChart), new PropertyMetadata(null));public ObservableCollection<PieSerise> ItemsSource{get { return (ObservableCollection<PieSerise>)GetValue(ItemsSourceProperty); }set { SetValue(ItemsSourceProperty, value); }}public static readonly DependencyProperty ItemsSourceProperty =DependencyProperty.Register("ItemsSource", typeof(ObservableCollection<PieSerise>), typeof(SectorChart), new PropertyMetadata(null, new PropertyChangedCallback(ItemsSourceChanged)));private static void ItemsSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e){var view = d as SectorChart;if (e.NewValue != null)view.DrawArc();}static SectorChart(){DefaultStyleKeyProperty.OverrideMetadata(typeof(SectorChart), new FrameworkPropertyMetadata(typeof(SectorChart)));}public override void OnApplyTemplate(){base.OnApplyTemplate();_canvas = GetTemplateChild(CanvasTemplateName) as Canvas;_popup = GetTemplateChild(PopupTemplateName) as Popup;}void DrawArc(){if (ItemsSource is null || !ItemsSource.Any() || _canvas is null)return;_canvas.Children.Clear();var pieWidth = _canvas.ActualWidth > _canvas.ActualHeight ? _canvas.ActualHeight : _canvas.ActualWidth;var pieHeight = _canvas.ActualWidth > _canvas.ActualHeight ? _canvas.ActualHeight : _canvas.ActualWidth;centenrX = pieWidth / 2;centenrY = pieHeight / 2;radius = this.ActualWidth > this.ActualHeight ? this.ActualHeight / 2 : this.ActualWidth / 2;double angle = 0;double prevAngle = 0;var sum = ItemsSource.Select(ser => ser.Percentage).Sum();foreach (var item in ItemsSource){var line1X = radius * Math.Cos(angle * Math.PI / 180) + centenrX;var line1Y = radius * Math.Sin(angle * Math.PI / 180) + centenrY;angle = item.Percentage / sum * 360 + prevAngle;double arcX = 0;double arcY = 0;if (ItemsSource.Count() == 1 && angle == 360){arcX = centenrX + Math.Cos(359.99999 * Math.PI / 180) * radius;arcY = (radius * Math.Sin(359.99999 * Math.PI / 180)) + centenrY;}else{arcX = centenrX + Math.Cos(angle * Math.PI / 180) * radius;arcY = (radius * Math.Sin(angle * Math.PI / 180)) + centenrY;}var line1Segment = new LineSegment(new Point(line1X, line1Y), false);bool isLargeArc = item.Percentage / sum > 0.5;var arcWidth = radius;var arcHeight = radius;var arcSegment = new ArcSegment();arcSegment.Size = new Size(arcWidth, arcHeight);arcSegment.Point = new Point(arcX, arcY);arcSegment.SweepDirection = SweepDirection.Clockwise;arcSegment.IsLargeArc = isLargeArc;var line2Segment = new LineSegment(new Point(centenrX, centenrY), false);PieBase piebase = new PieBase();piebase.Title = item.Title;piebase.Percentage = item.Percentage;piebase.PieColor = item.PieColor;piebase.LineSegmentStar = line1Segment;piebase.ArcSegment = arcSegment;piebase.LineSegmentEnd = line2Segment;piebase.Angle = item.Percentage / sum * 360;piebase.StarPoint = new Point(line1X, line1Y);piebase.EndPoint = new Point(arcX, arcY);var pathFigure = new PathFigure(new Point(centenrX, centenrY), new List<PathSegment>(){line1Segment,arcSegment,line2Segment,}, true);var pathFigures = new List<PathFigure>(){pathFigure,};var pathGeometry = new PathGeometry(pathFigures);var path = new Path() { Fill = item.PieColor, Data = pathGeometry, DataContext = piebase };_canvas.Children.Add(path);prevAngle = angle;var line3 = DrawLine(path);if (line3 != null)piebase.Line = line3;var textPathGeo = DrawText(path);var textpath = new Path() { Fill = item.PieColor, Data = textPathGeo };piebase.TextPath = textpath;_canvas.Children.Add(textpath);path.MouseMove += Path_MouseMove1;path.MouseLeave += Path_MouseLeave;if (ItemsSource.Count() == 1 && angle == 360){_canvas.Children.Add(line3);}else{var outline1 = new Line(){X1 = centenrX,Y1 = centenrY,X2 = line1Segment.Point.X,Y2 = line1Segment.Point.Y,Stroke = Brushes.White,StrokeThickness = 0.8,};var outline2 = new Line(){X1 = centenrX,Y1 = centenrY,X2 = arcSegment.Point.X,Y2 = arcSegment.Point.Y,Stroke = Brushes.White,StrokeThickness = 0.8,};_canvas.Children.Add(outline1);_canvas.Children.Add(outline2);_canvas.Children.Add(line3);}}}private void Path_MouseLeave(object sender, MouseEventArgs e){_popup.IsOpen = false;var path = sender as Path;var dt = path.DataContext as PieBase;TranslateTransform ttf = new TranslateTransform();ttf.X = 0;ttf.Y = 0;path.RenderTransform = ttf;dt.Line.RenderTransform = new TranslateTransform(){X = 0,Y = 0,};dt.TextPath.RenderTransform = new TranslateTransform(){X = 0,Y = 0,};path.Effect = new DropShadowEffect(){Color = (Color)ColorConverter.ConvertFromString("#FF949494"),BlurRadius = 20,Opacity = 0,ShadowDepth = 0};flg = false;}private void Path_MouseMove1(object sender, MouseEventArgs e){Path path = sender as Path;//动画if (!flg){BegionOffsetAnimation(path);}ShowMousePopup(path, e);}void ShowMousePopup(Path path, MouseEventArgs e){var data = path.DataContext as PieBase;if (!_popup.IsOpen)_popup.IsOpen = true;var mousePosition = e.GetPosition((UIElement)_canvas.Parent);_popup.HorizontalOffset = mousePosition.X + 20;_popup.VerticalOffset = mousePosition.Y + 20;Text = (data.Title + " : " + data.Percentage);//显示鼠标当前坐标点Fill = data.PieColor;}void BegionOffsetAnimation(Path path){NameScope.SetNameScope(this, new NameScope());var pathDataContext = path.DataContext as PieBase;var angle = pathDataContext.Angle;minPoint = new Point(Math.Round(pathDataContext.StarPoint.X + pathDataContext.EndPoint.X) / 2, Math.Round(pathDataContext.StarPoint.Y + pathDataContext.EndPoint.Y) / 2);var v1 = minPoint - new Point(centenrX, centenrY);var v2 = new Point(2000, 0) - new Point(0, 0);double vAngle = 0;if (180 < angle && angle <= 360 && pathDataContext.Percentage / ItemsSource.Select(p => p.Percentage).Sum() >= 0.5){vAngle = Math.Round(Vector.AngleBetween(v2, -v1));}else{vAngle = Math.Round(Vector.AngleBetween(v2, v1));}offsetX = 10 * Math.Cos(vAngle * Math.PI / 180);offsetY = 10 * Math.Sin(vAngle * Math.PI / 180);var line3 = pathDataContext.Line;var textPath = pathDataContext.TextPath;TranslateTransform LineAnimatedTranslateTransform =new TranslateTransform();this.RegisterName("LineAnimatedTranslateTransform", LineAnimatedTranslateTransform);line3.RenderTransform = LineAnimatedTranslateTransform;TranslateTransform animatedTranslateTransform =new TranslateTransform();this.RegisterName("AnimatedTranslateTransform", animatedTranslateTransform);path.RenderTransform = animatedTranslateTransform;TranslateTransform TextAnimatedTranslateTransform =new TranslateTransform();this.RegisterName("TextAnimatedTranslateTransform", animatedTranslateTransform);textPath.RenderTransform = animatedTranslateTransform;DoubleAnimation daX = new DoubleAnimation();Storyboard.SetTargetProperty(daX, new PropertyPath(TranslateTransform.XProperty));daX.Duration = new Duration(TimeSpan.FromSeconds(0.2));daX.From = 0;daX.To = offsetX;DoubleAnimation daY = new DoubleAnimation();Storyboard.SetTargetName(daY, nameof(animatedTranslateTransform));Storyboard.SetTargetProperty(daY, new PropertyPath(TranslateTransform.YProperty));daY.Duration = new Duration(TimeSpan.FromSeconds(0.2));daY.From = 0;daY.To = offsetY;path.Effect = new DropShadowEffect(){Color = (Color)ColorConverter.ConvertFromString("#2E2E2E"),BlurRadius = 33,Opacity = 0.6,ShadowDepth = 0};animatedTranslateTransform.BeginAnimation(TranslateTransform.XProperty, daX);animatedTranslateTransform.BeginAnimation(TranslateTransform.YProperty, daY);LineAnimatedTranslateTransform.BeginAnimation(TranslateTransform.XProperty, daX);LineAnimatedTranslateTransform.BeginAnimation(TranslateTransform.YProperty, daY);TextAnimatedTranslateTransform.BeginAnimation(TranslateTransform.XProperty, daX);TextAnimatedTranslateTransform.BeginAnimation(TranslateTransform.YProperty, daY);flg = true;}/// <summary>/// 画指示线/// </summary>/// <param name="path"></param>/// <returns></returns>Polyline DrawLine(Path path){NameScope.SetNameScope(this, new NameScope());var pathDataContext = path.DataContext as PieBase;var angle = pathDataContext.Angle;pathDataContext.Line = null;minPoint = new Point(Math.Round(pathDataContext.StarPoint.X + pathDataContext.EndPoint.X) / 2, Math.Round(pathDataContext.StarPoint.Y + pathDataContext.EndPoint.Y) / 2);Vector v1;if (angle > 180 && angle < 360){v1 = new Point(centenrX, centenrY) - minPoint;}else if (angle == 180 || angle == 360){if (Math.Round(pathDataContext.StarPoint.X) == Math.Round(pathDataContext.EndPoint.X)){v1 = new Point(radius * 2, radius) - new Point(centenrX, centenrY);}else{if (Math.Round(pathDataContext.StarPoint.X) - Math.Round(pathDataContext.EndPoint.X) == 2 * radius){v1 = new Point(radius, 2 * radius) - new Point(centenrX, centenrY);}else{v1 = new Point(radius, 0) - new Point(centenrX, centenrY);}}}else{v1 = minPoint - new Point(centenrX, centenrY);}v1.Normalize();var Vmin = v1 * radius;var RadiusToNodal = Vmin + new Point(centenrX, centenrY);var v2 = new Point(2000, 0) - new Point(0, 0);double vAngle = 0;vAngle = Math.Round(Vector.AngleBetween(v2, v1));offsetX = 10 * Math.Cos(vAngle * Math.PI / 180);offsetY = 10 * Math.Sin(vAngle * Math.PI / 180);var prolongPoint = new Point(RadiusToNodal.X + offsetX * 1, RadiusToNodal.Y + offsetY * 1);if (RadiusToNodal.X == double.NaN || RadiusToNodal.Y == double.NaN || prolongPoint.X == double.NaN || prolongPoint.Y == double.NaN)return null;var point1 = RadiusToNodal;var point2 = prolongPoint;Point point3;if (prolongPoint.X >= radius)point3 = new Point(prolongPoint.X + 10, prolongPoint.Y);elsepoint3 = new Point(prolongPoint.X - 10, prolongPoint.Y);PointCollection polygonPoints = new PointCollection();polygonPoints.Add(point1);polygonPoints.Add(point2);polygonPoints.Add(point3);var line3 = new Polyline();line3.Points = polygonPoints;line3.Stroke = pathDataContext.PieColor;pathDataContext.PolylineEndPoint = point3;return line3;}PathGeometry DrawText(Path path){NameScope.SetNameScope(this, new NameScope());var pathDataContext = path.DataContext as PieBase;Typeface typeface = new Typeface(new FontFamily("Microsoft YaHei"),FontStyles.Normal,FontWeights.Normal, FontStretches.Normal);FormattedText text = new FormattedText(pathDataContext.Title,new System.Globalization.CultureInfo("zh-cn"),FlowDirection.LeftToRight, typeface, fontsize, Brushes.RosyBrown);var textWidth = text.Width;Geometry geo = null;if (pathDataContext.PolylineEndPoint.X > radius)geo = text.BuildGeometry(new Point(pathDataContext.PolylineEndPoint.X + 4, pathDataContext.PolylineEndPoint.Y - fontsize / 1.8));elsegeo = text.BuildGeometry(new Point(pathDataContext.PolylineEndPoint.X - textWidth - 4, pathDataContext.PolylineEndPoint.Y - fontsize / 1.8));PathGeometry pathGeometry = geo.GetFlattenedPathGeometry();return pathGeometry;}}
}

2)SectorChart.xaml 代码如下;

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:controls="clr-namespace:WPFDevelopers.Charts.Controls"><Style TargetType="{x:Type controls:SectorChart}"><Setter Property="Width" Value="300"/><Setter Property="Height" Value="300"/><Setter Property="Template"><Setter.Value><ControlTemplate TargetType="{x:Type controls:SectorChart}"><Grid><Popup x:Name="PART_Popup" IsOpen="False"Placement="Relative" AllowsTransparency="True"><Border Background="White" CornerRadius="5" Padding="14"BorderThickness="0"BorderBrush="Transparent"><StackPanel ><Ellipse Width="20" Height="20"Fill="{TemplateBinding Fill}"/><TextBlock Background="White" Padding="9,4,9,4" TextWrapping="Wrap" Text="{TemplateBinding Text}"/></StackPanel></Border></Popup><Canvas x:Name="PART_Canvas"  HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"Width="{TemplateBinding ActualWidth}"Height="{TemplateBinding ActualHeight}"></Canvas></Grid></ControlTemplate></Setter.Value></Setter></Style>
</ResourceDictionary>

3) MainWindow.xaml使用如下;

xmlns:wsCharts="https://github.com/WPFDevelopersOrg.WPFDevelopers.Charts"<wsCharts:SectorChart  ItemsSource="{Binding ItemsSource,RelativeSource={RelativeSource AncestorType=local:MainWindow}}"Margin="30" />

4) MainWindow.xaml.cs代码如下;

using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Media;
using WPFDevelopers.Charts.Models;namespace WPFDevelopers.Charts.Samples
{/// <summary>/// MainWindow.xaml 的交互逻辑/// </summary>public partial class MainWindow {public ObservableCollection<PieSerise> ItemsSource{get { return (ObservableCollection<PieSerise>)GetValue(ItemsSourceProperty); }set { SetValue(ItemsSourceProperty, value); }}public static readonly DependencyProperty ItemsSourceProperty =DependencyProperty.Register("ItemsSource", typeof(ObservableCollection<PieSerise>), typeof(MainWindow), new PropertyMetadata(null));public MainWindow(){InitializeComponent();Loaded += MainWindow_Loaded;}private void MainWindow_Loaded(object sender, RoutedEventArgs e){ItemsSource = new ObservableCollection<PieSerise>();var collection1 = new ObservableCollection<PieSerise>();collection1.Add(new PieSerise{Title = "2012",Percentage = 30,PieColor = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#5B9BD5")),});collection1.Add(new PieSerise{Title = "2013",Percentage = 140,PieColor = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#4472C4")),});collection1.Add(new PieSerise{Title = "2014",Percentage = 49,PieColor = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#007fff")),});collection1.Add(new PieSerise{Title = "2015",Percentage = 50,PieColor = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#ED7D31")),});collection1.Add(new PieSerise{Title = "2016",Percentage = 30,PieColor = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#FFC000")),});collection1.Add(new PieSerise{Title = "2017",Percentage = 30,PieColor = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#ff033e")),});ItemsSource = collection1;}}
}

参考资料

[1]

ArcSegment: https://docs.microsoft.com/zh-cn/dotnet/api/system.windows.media.arcsegment?view=windowsdesktop-6.0

[2]

Github: https://github.com/WPFDevelopersOrg/WPFDevelopers.Charts

[3]

Gitee: https://gitee.com/WPFDevelopersOrg/WPFDevelopers.Charts

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

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

相关文章

Flutter之测试Http和HttpClient

1 测试Http和HttpClient 导入包&#xff1a;在pubspec.yaml里面导入 http: ^0.12.2 main.dart里面导入 import package:http/http.dart as http; import dart:convert; import dart:io; 2 代码实现 import package:flutter/material.dart; import package:url_launcher/url_lau…

基于zookeeper的solrCloud集群搭建

1.安装及搭建相关环境 1.1环境准备 centos7,jdk1.8,tomcat8,zookeeper3.4.X,solr4.10.X 链接: https://pan.baidu.com/s/1i47IuKd 密码: emqt 2.zookeeper集群搭建 2.1复制zookeeper [rootMiWiFi-R3-srv ~]# mkdir /usr/local/solr-cloud [rootMiWiFi-R3-srv ~]# cp -r zookee…

【小白必懂】C语言求完全数

注意&#xff1a;学生党如果存在付费问题可以加我好友&#xff0c;我可以开单篇短时间的免费哟~ 私聊我就好~ 情景再现 &#x1f478;小媛&#xff1a;小C&#xff0c;你知道什么是完全数吗&#xff1f; &#x1f430;小C&#xff1a;知道呀&#xff0c;难道是今天老师又出题…

台式计算机硬件输入设备,台式电脑硬件配置有哪些

台式电脑硬件配置你知道有哪些?电脑的配置一般是指电脑的硬件配件的高档程度、性价比等&#xff0c;电脑的性能好坏主要决定于以下主要硬件配置。一起来看看台式电脑硬件配置有哪些&#xff0c;欢迎查阅!组装台式电脑配置1、实用性机型建议&#xff1a;首选1&#xff1a;intel…

Android WebView和JavaScript交互

JavaScript在现在的网页设计中用得很多&#xff0c;Android 的WebView可以载入网页&#xff0c;WebView也设计了与JavaScript通信的桥梁。这篇主要介绍一下WebViewk控件如何和JavaScript进行交互。 WebView: WebView和网页相关的主要有一下几个方法&#xff1a;  setWebViewCl…

Microsoft Dev Box 带来全新云上开发体验

在 5 月 24 日, 微软的产品经理 Anthony Cangialosi 在 Azure 社区发布了一篇博客(Introducing Microsoft Dev Box)&#xff0c; 宣布推出 Microsoft Dev Box !这是一种新的云服务&#xff0c;托管在 Microsoft Azure 中&#xff0c;提供了一个开箱即用的开发工作站&#xff0c…

游戏开发如此简单?我直接创建了一个游戏场景【python 游戏实战 02】

前言 本系列文章将会以通俗易懂的对话方式进行教学&#xff0c;对话中将涵盖了新手在学习中的一般问题。此系列将会持续更新&#xff0c;包括别的语言以及实战都将使用对话的方式进行教学&#xff0c;基础编程语言教学适用于零基础小白&#xff0c;之后实战课程也将会逐步更新…

【三维激光扫描】第五章:基于点云数据的三维建模

第一节 绘制立面图 1. 打开CAD 2014,新建一个文件,模板选择acadiso.dwt,如下图。 2. 点击插入→创建点云。

Flutter之基本数据类型测试

1、Flutter的数据基本类型 Dart语言里一切皆为对象&#xff0c;所以如果没有将变初始化,那么它的默认值为null Number(int、doubkle)StringBoolean(bool) List Map2、测试代码 void testData() {//Number包含了int和doubleint a 4;int b 8;print(a b);int a1;if (a null)…

清北·NOIP2017济南考前冲刺班 DAY1 morning

立方数(cubic) Time Limit:1000ms Memory Limit:128MB 题目描述 LYK定义了一个数叫“立方数”&#xff0c;若一个数可以被写作是一个正整数的3次方&#xff0c;则这个数就是立方数&#xff0c;例如1,8,27就是最小的3个立方数。 现在给定一个数P&#xff0c;LYK想要知道这个数…

2020美国纽约大学计算机科学排名,2020美国纽约大学排名第几

纽约大学在2020年《美国新闻与世界报道》美国全国性大学排名中排名第29名&#xff0c;在2020年QS世界大学排名中排名第39名。纽约大学专业排名QS世界大学生命科学与医学专业排名 2020年 第40名QS世界大学医学专业排名 2020年 第34名QS世界大学牙科专业排名 2020年 第14名QS世界…

游戏角色开始动起来了,真帅!【python 游戏实战 03】

前言 本系列文章将会以通俗易懂的对话方式进行教学&#xff0c;对话中将涵盖了新手在学习中的一般问题。此系列将会持续更新&#xff0c;包括别的语言以及实战都将使用对话的方式进行教学&#xff0c;基础编程语言教学适用于零基础小白&#xff0c;之后实战课程也将会逐步更新…

如何让 ASP.NET Core 支持绑定查询字符串中的数组

前言有网友在交流群中询问&#xff0c;如何让 ASP.NET Core 支持绑定查询字符串中的数组&#xff1a;据说&#xff0c;在 .NET 7 中已经支持了&#xff1a;但是&#xff0c;在这之前的 .NET 版本能实现相同功能吗&#xff1f;ByteArrayModelBinder这时&#xff0c;群里的网友提…

Docker Storm开发环境搭建

2019独角兽企业重金招聘Python工程师标准>>> 1. compose文件 storm-stack.yml version: 3.1services:zookeeper:image: zookeepercontainer_name: zookeeperrestart: alwaysports:- 2181:2181nimbus:image: stormcontainer_name: nimbuscommand: storm nimbusdepend…

南方方洲号无人测量船系统简介

南方智能测量船系统由小型无人船、自动导航模块、声纳探测模块、外围传感模块、岸基操控终端、无人船专用软件等部分组成。将先进的卫星定位、声纳、传感器与智能导航控制等众多技术相结合,提出了高精度、智能化、集成化、机动化、网络化的勘测解决方案。该系统能自主航行并完…

1小时1篇文学会python再做个飞机大战游戏

注&#xff1a; 想慢慢学习的同学可以看我的 《python 入门到游戏实战专栏》&#xff08;更新中&#xff09; 想学 C 的同学可以看《大话系列之C语言》&#xff08;基本更新完&#xff09; 想学 C 的同学可以看《大话C》&#xff08;更新中&#xff09; 想做习题的可以看《大学…

如何优雅的编写git的提交信息

前言在公司的日常工作当中或者个人的开源项目&#xff0c;将代码提交到代码库时。都会遇到下面这样的对话框&#xff0c;通常都会随便写点内容在里面。当遇到问题需要回溯的时候就成了给自己造成的麻烦&#xff0c;因为无法通过commit message来非常直观的看到这一次提交了什么…

android快捷开发之Retrofit网络加载框架的简单使用

大家都知道&#xff0c;安卓最大的特点就是开源化&#xff0c;这自然会产生很多十分好用的第三方API&#xff0c;而基本每一个APP都会与网络操作和缓存处理机制打交道&#xff0c;当然&#xff0c;你可以自己通过HttpUrlConnection再通过返回数据进行解析解决&#xff0c;而我们…

打开计算机无法显示工具栏,任务栏不显示打开的窗口怎么办教程

我们在使用电脑的时候&#xff0c;打开很多程序的时候&#xff0c;会最小化某些窗口&#xff0c;只留在用的窗口&#xff0c;而最小化都是缩小为一个图标放入屏幕下方的任务栏的&#xff0c;但有时候不知道为什么任务栏不显示打开的窗口了&#xff0c;这时候也就无法直接用鼠标…

ArcGIS 10.6提取道路中心线的两种方法经典教程

我们工作中碰到的道路数据通常为面状,需要提取道路中心线,本文讲解ArcGIS10.6中从面状道路数据中提取道路中心线的两种常用经典方法。 方法一:使用ArcGIS 10.6提供的提取道路中心线工具 本实验中使用到面状数据如下所示: 首先,将面状数据转为线状数据。 转完之后,道路尽头…