WPF—LiveCharts图表

news2024/9/22 4:23:11

LiveCharts图表

LiveCharts是一个简单灵活、交互式以及功能强大的跨平台图表库,支持wpf、winform...应用程序。

快速入门

安装

在应用程序中右键`引用`​,点击`管理NuGet程序包`​,选择`浏览`​,搜索`LiveChartsCore.SkiaSharpView.WPF`​,注意必须勾选`包括预发行版`​选项,否则搜索不到它。然后点击安装即可,此教程以WPF应用为例,其他应用程序参考官方文档,

第一个图表

首先先为图表创建一个容器,用于显示折线、柱...

    <Window 
      xmlns:lvc="clr-namespace:LiveChartsCore.SkiaSharpView.WPF;assembly=LiveChartsCore.SkiaSharpView.WPF"  // 注意添加命名空间
    >
        <Grid>
            <!-- 使用笛卡尔图表(坐标图表) 
            Series  绑定图表的数据
            -->
            <lvc:CartesianChart
                Series="{Binding Series}"   
            />
        </Grid>
    </Window>

定义数据并进行绑定

    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            this.DataContext = this;
        }
        // 定义属性存储图表数据,不管什么数据都实现了  ISeries   接口
        public ISeries[] Series { get; set; }   
        = new ISeries[]
        {   // 创建一个折线数据,存储double数据
            new LineSeries<double>()
            {
                Values = new List<double>(){ 10,20,44,12,41,31.2 },
            }
        };
    }

配置主题、字体或映射器(可选)

您可以配置 LiveCharts 以添加主题、注册全局字体、启用工具提示 或类型的自定义映射器,当您需要非拉丁字体时,您必须注册字体,以便 SkiaShap 可以呈现 文本正确,请在应用程序启动时添加以下代码

    // App.xaml.cs
    using LiveChartsCore; 
    using LiveChartsCore.SkiaSharpView; 
    using SkiaSharp; 
    
    public partial class App : Application
    {
        protected override void OnStartup(StartupEventArgs e)
        {
            base.OnStartup(e);
    
            LiveCharts.Configure(config => 
                config 
                    // 注册字体
                    //.HasGlobalSKTypeface(SKFontManager.Default.MatchCharacter('汉')) // <- 中文
                    //.HasGlobalSKTypeface(SKFontManager.Default.MatchCharacter('あ')) // <- 日语 
                    //.HasGlobalSKTypeface(SKFontManager.Default.MatchCharacter('헬')) // <- 韩语
                    //.HasGlobalSKTypeface(SKFontManager.Default.MatchCharacter('Ж'))  // <- 俄语
                    //.HasGlobalSKTypeface(SKFontManager.Default.MatchCharacter('أ'))  // <- 阿拉伯语
    
                    //.UseRightToLeftSettings() // 弃用从右到左布局
            ); 
        }
    }

CartesianChart 笛卡尔坐标图表

该控件是一个“随时可用”的控件,用于使用笛卡尔坐标系创建绘图, 首先,您需要做的就是使用 ICartesianSeries的集合为属性分配

    public ISeries[] Series { get; set; }   
    = new ISeries[]
    {  
        // LineSeries  定义一个折线数据
        new LineSeries<double>()
        {
            Values = new List<double>(){ 10,20,44,12,41,31.2 },
        },
        // ColumnSeries   定义一个柱状数据
        new ColumnSeries<double>()
        {
            Values = new List<double>() {22,3,52,4,23,12}
        }
    };
    <lvc:CartesianChart
        Series="{Binding Series}">
    </lvc:CartesianChart>

笛卡尔坐标图表主要包含Series系列、Axes轴、Tooltip工具提示、Legend图例

缩放和平移

默认情况下,它是禁用的,要启用它,您必须设置该属性。`ZoomMode`​

    <lvc:CartesianChart
        Series="{Binding Series}"
        ZoomMode="X"> 
    </lvc:CartesianChart>

AnimationsSpeed 属性

定义所有图表元素(轴、系列、截面)的动画速度。

    <lvc:CartesianChart
        Series="{Binding Series}"
        AnimationsSpeed="00:00:00.500"> <!-- 500 milliseconds --> 
    </lvc:CartesianChart>

禁用动画

    <lvc:CartesianChart
        EasingFunction="{x:Null}"> 
    </lvc:CartesianChart>

图表边距

定义从轴(如果没有轴,则为图表边缘)到绘制边距区域的距离。

    public LiveChartsCore.Measure.Margin ChartMargin { get; set; } = new LiveChartsCore.Measure.Margin(100); 
    <lvc:CartesianChart
        Series="{Binding Series}"
        DrawMargin="{Binding ChartMargin}"> 
    </lvc:CartesianChart>

控件容器样式

[DrawMarginFrame]控制图表容器的样式,可以设置背景和边框

    public DrawMarginFrame DrawMarginFrame => new DrawMarginFrame()
    {
        Fill = new SolidColorPaint(SKColors.Pink),  // 背景
        Stroke = new SolidColorPaint(SKColors.Red)  // 边框
        {
            StrokeThickness = 3,    // 宽度
            PathEffect = new DashEffect(new float[] { 3, 3 })   // 虚线
        },
    };
    <lvc:CartesianChart
        Series="{Binding Series}"   
        DrawMarginFrame="{Binding DrawMarginFrame}"
    />

系列 Series

库中有多个系列可用,您可以添加一个或将它们全部混合在同一个图表中,每个系列都有独特的属性, 下面的任何图像都是指向解释有关它们的更多信息的文章的链接。

坐标轴 Axes

笛卡尔坐标有两个轴,不仅用于控制标签格式、分隔符、颜色,还可以控制如缩放、平移、分页等功能,[详情查看](https://livecharts.dev/docs/wpf/2.0.0-rc2/CartesianChart.Axes%20properties),下面是对坐标轴的简单演示

* ​`name`​ 坐标轴名称
* ​`NamePaint`​坐标轴名称样式
* ​`LabelsPaint`​坐标轴文本样式
* ​`TextSize`​文本大小
* ​`Labels`​坐标轴文本
* ​`SeparatorsPaint`​分割线样式

    public Axis[] XAxes { get; set; } = new Axis[]
    {
        new Axis()
        {
            Name = "横坐标",   // 坐标名称
            NamePaint = new SolidColorPaint(SKColors.Red),  // 坐标名称颜色
            LabelsPaint = new SolidColorPaint(new SKColor(190, 75, 219)),   // 坐标文本颜色
            TextSize = 18,  // 坐标文字大小
            Labels = new string[]{"衣服", "裤子", "鞋子", "袜子", "帽子", "围巾" }  // 坐标文本列表
        }
    };
    public Axis[] YAxes { get; set; } = new Axis[]
    {
        new Axis()
        {
            Name = "纵坐标",
            // 分割线绘制
            SeparatorsPaint = new SolidColorPaint(SKColors.Yellow)  // 颜色
            {
                StrokeThickness = 4,        // 线条粗细
                PathEffect = new DashEffect(new float[]{ 3, 20 })   // 设置虚线间隔,3px线 20px白
            },
            // 最大值
            MaxLimit = 100,
            // 最小值
            MinLimit = 10,
            // 每个格子间隔的数值
            MinStep = 10,
        }
    };

工具提示 ToolTip

[工具提示]是帮助用户在指针移动时阅读图表的弹出窗口。

  • ​`TooltipPosition`​ 控制弹窗的位置,设置为`Hidden`​则不显示弹窗
    <lvc:CartesianChart
        Series="{Binding Series}"
        TooltipPosition="Top">
    </lvc:CartesianChart>

工具提示自定义文本

可以使用`XToolTipLabelFormatter`​或`YToolTipLabelFormatter`​自定义提示弹窗的文本,接收一个委托`Series.TooltipLabelFormatterFunc<ChartPoint, string>`

默认情况下,库已经为每个系列定义了一个默认值,所有系列都有不同的 格式化程序

    new LineSeries<double>
    {
        Name = "Sales",
        Values = new ObservableCollection<double> { 200, 558, 458 },
        TooltipLabelFormatter =
            (chartPoint) => $"{chartPoint.Context.Series.Name}: {chartPoint.PrimaryValue}"
    },
    
    new ColumnSeries<double>
    {
        Name = "Sales 2",
        Values = new ObservableCollection<double> { 250, 350, 240 },
        // 以货币的形式展示提示文本
        // result: Sales 2: $200.00
        TooltipLabelFormatter =
            (chartPoint) => $"{chartPoint.Context.Series.Name}: {chartPoint.PrimaryValue:C2}"
    },

图例 Legend

[图例]是一种视觉元素,它以图表的形式显示一个列表,其中包含该系列的名称、描边和填充:

* ​`LegendPosition`​ 控制图例的位置,`Hidden`​表示禁用图例

    <lvc:CartesianChart
        Series="{Binding Series}"   
        LegendPosition="Right"
    />

PieChart 饼图

饼状图,通常用于表示某个数据在数据中的占比,分为饼图、环形图、仪表图

    public ISeries[] Series => new ISeries[]
    {
        new PieSeries<double> { Values = new double[] { 2 }, Name="吃饭" },
        new PieSeries<double> { Values = new double[] { 4 }, Name="睡觉" },
        new PieSeries<double> { Values = new double[] { 1 }, Name="买菜" },
        new PieSeries<double> { Values = new double[] { 4 }, Name="洗澡" },
        new PieSeries<double> { Values = new double[] { 3 }, Name="抽烟" }
    };
    <lvc:PieChart
        Series="{Binding Series}" 
    />

会自动根据配置的数据从0°开始顺时针绘制图表

  • InitialRotation`​​ 绘制第一个切片的角度
  • MaxAngle`​​ 确定图表的完整角度(以度为单位),默认值为 360。
  • AnimationsSpeed`​​ 动画速度,和笛卡尔图相同
  • Stroke`​ 边框
  • Fill`​ 填充色
  • Pushout`​ 控件中心与饼图切片之间的距离
  • InnerRadius`​ 切片的内半径(以像素为单位),对于创建圆环图很有用

饼图文本

使用`DataLabels`​相关属性设置饼图上显示的文本相关信息

  • * ​`DataLabelsPosition`​ 文本显示位置
  • * ​`DataLabelsFormatter`​ 文本显示内容
  • * ​`DataLabelsPaint`​ 文本显示颜色
  • * ​`DataLabelsSize`​ 文本显示大小
    new PieSeries<int>{ 
      Values = new int[]{12}, 
      Name="吃饭",
      DataLabelsPosition = PolarLabelsPosition.Middle, 
      DataLabelsFormatter = point => point.Context.Series.Name + point.Context.DataSource,
      DataLabelsPaint = new SolidColorPaint(SKColors.Black),
      DataLabelsSize = 22, 
    }

极坐标图

极坐标图表用于显示类似雷达图的图表


快速使用

    public ISeries[] Series2 { get; set; } = new ISeries[]
    {
        new PolarLineSeries<int>
        {
            Values = new int[]{10,20,30,40,50,60},
            IsClosed = false,
        }
    };
    <lvc:PolarChart
        Series="{Binding Series2}"
    />

PolarLineSeries常用属性

  • * Values 指定数据值
  • * IsClosed 是否闭合数据线
  • * Fill 填充样式
  • * GeometryFill 标记点填充色
  • * GeometryStroke 标记点描边色
  • * GeometrySize 标记点大小
  • * LineSmoothness 确定序列线是直线还是曲线,其中 0 是直线,1 是最弯曲的线

PolarChart常用属性

  • * InitialRotation 初始角度
  • * InnerRadius 内环半径
  • * TotalAngle 展示数据的角度
  • * RadiusAxes 一圈一圈的线样式
    •   * ​`IPolarAxis[]`​ 类型
    •   * TextSize 文本大小
    •   * LabelsPaint 文本颜色
    •   * SeparatorsPaint 线条样式
    •   * IsVisible 是否显示
    •   * Labels 显示的文本
  • * AngleAxes 分割线的样式(米字形的),数据值类型和`RadiusAxes`​相同

  

动态图表

使用图表经常会有需要动态的添加或者修改数据的情况,使用liveCharts,我们只需要操作数据,图表将会自动进行更新,如下,点击按钮后图表的颜色和名字都将发生变化

    public MainWindow()
    {
      InitializeComponent();
      this.DataContext = this;
      Series.Add(columnSeries);
    }
    ColumnSeries<int> columnSeries = new ColumnSeries<int>
    {
      Values = new List<int> { 10, 2, 3, 4, 5, 6 },
      Name = "销量",
    };
    private void Button_Click(object sender, RoutedEventArgs e)
    {
      columnSeries.Name = "测试修改";
      columnSeries.Fill = new SolidColorPaint(SKColors.Gold);
    }

但是,同样的写法并不能在添加数据时生效,如下代码中向Values添加数据,图表不会发生更新

    (columnSeries.Values as List<int>).Add(20);

因为LiveCharts 更改检测基于`INotifyPropertyChanged`​和`INotifyCollectionChanged`​接口,两者均由 .Net 框架提供,每次属性或集合发生更改并且对象实现任何这些接口时,图表都会限制更新,而List没有实现这个接口,因此需要使用已经实现了该接口的类将需要更新的数据进行包裹,仅此而已。

代码如下,仅仅需要将Values属性的值由`List<int>`​修改为`ObservableCollection<int>`​即可,十分方便

   ColumnSeries<int> columnSeries = new ColumnSeries<int>
    {
        Values = new ObservableCollection<int> { 10, 2, 3, 4, 5, 6 },
        Name = "销量",
    };
    private void Button_Click(object sender, RoutedEventArgs e)
    {
        (columnSeries.Values as ObservableCollection<int>).Add(20);
    }

饼图数据的添加如下所示

    public ObservableCollection<ISeries> Series1 { get; set; } = new ObservableCollection<ISeries>()
    {
        new PieSeries<int>{ Values = new int[]{12}, Name="吃饭" },
        new PieSeries<int>{ Values = new int[]{22}, Name="睡觉" },
        new PieSeries<int>{ Values = new int[]{15}, Name="喝水" },
    };
    private void Button_Click(object sender, RoutedEventArgs e)
    {
        Series1.Add(new PieSeries<int> { Values = new int[] { 23 }, Name = "旅游" });
    }

简而言之,如果修改非枚举类型,直接修改即可,如果是可枚举类型,需要使用`ObservableCollection`​类而不是`List`​或者`Array`​


本篇文章来源网络,如有侵权请联系删除!!!!

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

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

相关文章

自动驾驶-机器人-slam-定位面经和面试知识系列10之高频面试题(04)

这个博客系列会分为C STL-面经、常考公式推导和SLAM面经面试题等三个系列进行更新&#xff0c;基本涵盖了自己秋招历程被问过的面试内容&#xff08;除了实习和学校项目相关的具体细节&#xff09;。在知乎和牛客也会同步更新&#xff0c;全网同号&#xff08;lonely-stone或者…

Cortex-A7的GIC(通用中断控制器):专有名词简介

0 资料 ARM Generic Interrupt Controller Architecture version 2.0 Architecture Specification1 专有名词简介 1.1 中断状态 说明&#xff1a; Inactive&#xff1a;未激活&#xff0c;中断无效。中断非挂起或非激活。 Pending&#xff1a;挂起&#xff0c;中断有效。等待…

【Web】NepCTF 2024题解

目录 PHP_MASTER!! NepDouble 蹦蹦炸弹&#xff08;boom_it&#xff09; NepRouter-白给 Always RCE First PHP_MASTER!! PHP反序列化键值逃逸mb_strpos与mb_substr连用导致的字符注入 https://www.cnblogs.com/EddieMurphy-blogs/p/18310518 flag在phpinfo里 payloa…

1/f噪声影响及解决措施

在将6位半数字万用表输入短接时&#xff0c;观察其输出。在逐渐增加均值次数后&#xff0c;噪声开始下降&#xff0c;达到一定程度后便停止下降&#xff0c;随着时间的推移&#xff0c;停止下降的噪声在逐渐增加&#xff0c;该部分主要是1/f噪声影响。 这种1/f噪声&#xff08;…

mPLUG-Owl3环境搭建推理测试

mPLUG-Owl3环境搭建&推理测试 引子 多模态的大模型也写了很多篇&#xff0c;阿里系的之前有一篇Qwen-VL的相关部署&#xff0c;感兴趣的童鞋请移步&#xff08;Qwen-VL环境搭建&推理测试-CSDN博客&#xff09;。今天这个mPLUG-Qwl3&#xff0c;更新换代也很快&#x…

Windows下线程的竞争与资源保护(win32-API)

一、前言 在线程编程中&#xff0c;资源共享与保护是一个核心议题&#xff0c;尤其当多个线程试图同时访问同一份资源时&#xff0c;如果不采取适当的措施&#xff0c;就会引发一系列的问题&#xff0c;如数据不一致、竞态条件、死锁等。为了确保数据的一致性和线程安全&#…

【游戏速递】 小猪冲刺:萌动指尖的极速挑战,小虎鲸Scratch资源站独家献映!

在线玩&#xff1a;Scratch小猪冲刺&#xff1a;全新挑战的几何冒险游戏-小虎鲸Scratch资源站 想象一下&#xff0c;一群憨态可掬的小猪&#xff0c;穿上炫酷的装备&#xff0c;踏上了追逐梦想的赛道。它们或跳跃、或滑行&#xff0c;灵活躲避各种障碍&#xff0c;只为那终点的…

微软亚研院哈佛:同行评议互一致的rStar

本来想将近期另一篇DeepSeek的“DeepSeek-Prover-V1.5: Harnessing Proof Assistant Feedback for Reinforcement Learning and Monte-Carlo Tree Search”与这篇同样基于强化学习思想的小型清爽型推理模型放在一个笔记中相互对比借鉴一下&#xff0c;考虑虽然两者有着一些共通…

论文3解析(复现):六自由度机械臂轨迹规划研究+机器人基础知识-部分1

论文&#xff1a;六自由度机械臂轨迹规划研究&#xff0c;马强 机器人一些关于数学基础的知识&#xff0c;简单的说一下&#xff1a; 向量 在机器人中&#xff0c;向量的含义并不是算算数那样子&#xff0c;而是在空间的本质含义。 向量叉乘&#xff1a;ab |a|*|b|*sin&am…

燃烧控制模型

加热炉燃烧控制 主要功能&#xff1a; 1&#xff0e; 把要轧制的钢坯加热的规定温度&#xff0c;即出炉目标温度&#xff0c;并尽量减少黑印。 2&#xff0e; 协调加热炉及轧机的生产能力&#xff0c;以提高轧机总的生产效率。 3&#xff0e; 节省燃料 在轧钢生产过程中&#x…

s3c2440移植Linux内核之引导

最近想尝试把新的Linux内核移植到tq2440的开发板上&#xff0c;看看还能不能顺利的跑起来。我的基础版本是买板子的时候提供的2.6.30版本&#xff0c;编译器版本是4.3.3.。 下载源码和编译器 下载linux源码&#xff0c;源码的官方网站是The Linux Kernel Archives&#xff0c…

沉积层的厚度为自振周期波长的1/4

要理解为什么是1/4&#xff0c;需要明白如下两点。 &#xff08;1&#xff09;自振周期&#xff08;fundamental model, or first harmonic&#xff09;取决于在某边界条件下可以出现驻波&#xff08;standing wave&#xff09;的最短距离。Standing wave, also known as a st…

AI助力水体保护区无人值守垂钓智能预警,基于YOLOv8全系列【n/s/m/l/x】参数模型开发构建水体保护区场景下无人值守垂钓智能检测预警系统

保护我们赖以生存的自然生态环境&#xff0c;无疑是一项意义深远且需要长期坚持的任务。自然界的生态系统&#xff0c;由水、气、森林、土壤等多要素组成&#xff0c;它们相互依存、相互影响&#xff0c;共同维系着地球的生态平衡。然而&#xff0c;在人类活动的影响下&#xf…

浅谈进程,线程,协程以及服务端高并发的处理

进程、线程、协程 进程&#xff1a;独立的程序实例&#xff0c;资源开销较大&#xff0c;适合隔离性要求高的任务。 独立性&#xff1a;进程具有独立的内存空间和资源&#xff0c;互不干扰。 资源开销大&#xff1a;由于每个进程都需要分配独立的内存和资源&#xff0c;创建和…

5个常用的物理仿真JavaScript插件

还是大剑师兰特&#xff1a;曾是美国某知名大学计算机专业研究生&#xff0c;现为航空航海领域高级前端工程师&#xff1b;CSDN知名博主&#xff0c;GIS领域优质创作者&#xff0c;深耕openlayers、leaflet、mapbox、cesium&#xff0c;canvas&#xff0c;webgl&#xff0c;ech…

【Python学习手册(第四版)】学习笔记21-模块概览

个人总结难免疏漏&#xff0c;请多包涵。更多内容请查看原文。本文以及学习笔记系列仅用于个人学习、研究交流。 import操作和模块是Python之中程序架构的核心。本文主要介绍了模块、属性以及导入的基础知识&#xff0c;并探索了import语句的操作&#xff08;搜索、可选编译、…

不同搜索引擎蜘蛛的功能、‌抓取策略与技术实现差异探究

搜索引擎作为互联网信息检索的重要工具&#xff0c;‌其核心功能依赖于背后的“蜘蛛”程序。‌这些蜘蛛程序负责访问互联网上的各种内容&#xff0c;‌并建立索引数据库&#xff0c;‌以便用户能够快速准确地找到所需信息。‌然而&#xff0c;‌不同搜索引擎的蜘蛛在功能、‌抓…

Python爬取静态网页技术解析

内容导读 实现HTTP请求解析网页存储数据静态网页爬取实例 一、实现HTTP请求 1、爬虫场景简介 &#xff08;1&#xff09;基本功能 爬虫的基本功能是读取URL和爬取网页内容&#xff0c;这就需要爬虫具备能够实现HTTP请求的功能。请求过程主要包括生成HTTP请求、请求头处理、…

《Programming from the Ground Up》阅读笔记:p95-p102

《Programming from the Ground Up》学习第6天&#xff0c;p95-p102总结&#xff0c;总计8页。 一、技术总结 1.directive(伪指令) 很多资料喜欢把directive和instruction都翻译成“指令”&#xff0c;这样在看到指令这个词时就不知道到底指的是什么&#xff1f;这里参考其它…

文件包含漏洞案例

一、PHP://INPUT Example 1&#xff1a;造成任意代码执行 源代码&#xff1a; <meta charset"utf8"> <?php error_reporting(0); $file $_GET["file"]; if(stristr($file,"php://filter") || stristr($file,"zip://") |…