如何实时正确更新图表数值?

8

我最近遇到了一个叫做LiveChart的工具,决定测试一下。

不幸的是,我一直在尝试弄清楚如何实时更新图表数值。我相信有一种干净和正确的方法来做到这一点,但我找不到。

我希望能够通过private void或按钮来更新值。

在我的代码中,我正在使用ToolStripMenu进行测试。

[CODE]:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using LiveCharts;
using LiveCharts.WinForms;
using LiveCharts.Wpf;
using PokeShowdown_AccStats_T.Properties;
using LiveCharts.Defaults;

namespace PokeShowdown_AccStats_T
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            //int val1 = int.Parse(Settings.Default.Value1);

            var value1 = new ObservableValue(3);
            var value2 = new ObservableValue(7);
            var value3 = new ObservableValue(10);
            var value4 = new ObservableValue(2);

            //value1.Value = 5;

            cartesianChart1.Series.Add(new LineSeries 
            {
                Values = new ChartValues<ObservableValue> { value1, value2, value3, value4 },
                StrokeThickness = 4,
                StrokeDashArray = new System.Windows.Media.DoubleCollection(20),
                Stroke = new System.Windows.Media.SolidColorBrush(System.Windows.Media.Color.FromRgb(107, 185, 69)),
                Fill = System.Windows.Media.Brushes.Transparent,
                LineSmoothness = 0,
                PointGeometry = null
            });



            cartesianChart1.Background = new System.Windows.Media.SolidColorBrush(System.Windows.Media.Color.FromRgb(34, 46, 49));

            cartesianChart1.AxisX.Add(new Axis
            {
                IsMerged = true,
                Separator = new Separator
                {
                    StrokeThickness = 1,
                    StrokeDashArray = new System.Windows.Media.DoubleCollection(2),
                    Stroke = new System.Windows.Media.SolidColorBrush(System.Windows.Media.Color.FromRgb(64, 79, 86))
                }
            });
            cartesianChart1.AxisY.Add(new Axis
            {
                IsMerged = true,
                Separator = new Separator
                {
                    StrokeThickness = 1.5,
                    StrokeDashArray = new System.Windows.Media.DoubleCollection(4),
                    Stroke = new System.Windows.Media.SolidColorBrush(System.Windows.Media.Color.FromRgb(64, 79, 86))
                }
            });
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

        private void changeValue1ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Settings.Default.Value1 = "10";
            Settings.Default.Save();
            this.Text = Settings.Default.Value1;

        }

        private void changeValue1To3ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Settings.Default.Value1 = "3";
            Settings.Default.Save();
            this.Text = Settings.Default.Value1;

        }
    }
}

图表支持数据绑定。使用数据绑定并更新数据源。 - Reza Aghaei
3个回答

9
Live-Charts试图保持简单。其逻辑是使用具有您需要绘制的类型的通用集合,然后只需向该集合添加/删除或更新任何元素,您的图表就会更新。
回答您的问题,通常需要执行以下操作:
public partial class Form1 : Form
{
    private ObservableValue value1;

    public Form1()
    {
        InitializeComponent();

        //int val1 = int.Parse(Settings.Default.Value1);

        value1 = new ObservableValue(3);
        //...

        cartesianChart1.Series.Add(new LineSeries 
        {
            Values = new ChartValues<ObservableValue> { value1, ... },
        });
    }

    private void changeValue1ToolStripMenuItem_Click(object sender, EventArgs e)
    {
        value1.Value = 10;
        Settings.Default.Value1 = "10";
        Settings.Default.Save();
        this.Text = Settings.Default.Value1;

    }
}

然后该库将处理动画和更新。

enter image description here


我知道这已经过时了,但您能否分享添加、插入、删除和移动所有按钮的逻辑/代码的任何方法?我一直在尝试弄清楚如何实现这些,但是LiveCharts文档只显示如何通过用另一个ChartValues变量替换整个Values变量来更新系列的Values变量,这最终会重新绘制整个图表。 - Ahmed Khan

4

注意: 这个问题是关于LiveCharts的。但这个答案是基于MSChart发布的。要查看关于LiveCharts的答案,请查看其他答案。

图表支持数据绑定。使用数据绑定并更新数据源,然后刷新图表。例如:

DataTable table = new DataTable();
Random random = new Random();
private void Form1_Load(object sender, EventArgs e)
{
    table.Columns.Add("X", typeof(int));
    table.Columns.Add("Y", typeof(int));
    for (int i = 0; i < 10; i++)
        table.Rows.Add(i+1, random.Next(100));
    chart1.Series[0].ChartType = 
        System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Column;
    chart1.Series[0].XValueMember = "X";
    chart1.Series[0].YValueMembers = "Y";
    chart1.DataSource = table;
    chart1.ChartAreas[0].AxisX.Interval = 1;
    chart1.ChartAreas[0].AxisX.Minimum = 0;
    chart1.ChartAreas[0].AxisX.Maximum = 10;
    chart1.ChartAreas[0].AxisY.Interval = 10;
    chart1.ChartAreas[0].AxisY.Minimum = 0;
    chart1.ChartAreas[0].AxisY.Maximum = 100;
    chart1.DataBind();
    var timer = new Timer() { Interval= 300};
    timer.Tick += timer_Tick;
    timer.Start();
}
void timer_Tick(object sender, EventArgs e)
{
    for (int i = 0; i < 10; i++)
        table.Rows[i][1]= random.Next(100);
    chart1.DataBind();
}

enter image description here


这不是OP所问的,他在询问有关Live-Charts的问题。 - bto.rdz
@bto.rdz 看起来我错过了并错误地在编辑中删除了livecharts标签。是的,这个问题是关于livecharts的。 - Reza Aghaei
@bto,还有你/其他任何人不需要仅仅为了淡化它而对答案进行投票。这篇文章将对未来想要使用mschart进行技巧的读者有用。你可以发表一个好的答案,而不需要淡化其他答案。 - Reza Aghaei
抱歉,我想取消踩的操作,但为时已晚,我知道你的回答也很有帮助。 - bto.rdz
@bto.rdz 没问题。我已经编辑了答案,你现在可以操作了。 - Reza Aghaei

0

嗨,对于饼图,您可以通过以下简单的方式上传值:

后台代码:

/// <summary>
/// Interaction logic for StatusChart.xaml
/// </summary>
public partial class StatusChart : UserControl
{
    #region - Values -
    private List<Double> values;
    public List<Double> Values
    {
         
        get => values;
        set
        {
            if (value is null) throw new NullReferenceException();
            if (value.Count > PieChart.Series.Count) throw new IndexOutOfRangeException();

            for(int serie = 0; serie < PieChart.Series.Count; serie++)
            {
                PieChart.Series[serie].ActualValues[0] = values[serie];
            }

            PieChart.Series.ForEach((i, s) => s.ActualValues[0] = value[i]);
        }
    }
    #endregion
    public StatusChart()
    {
        InitializeComponent();
        
        values = Enumerable.Repeat(1D, PieChart.Series.Count).ToList();
        
        PointLabel = chartPoint => string.Format(new CultureInfo("en-US"), "{0:#0}s", chartPoint.Y);

        GridRoot.DataContext = this;
    }
    public Func<ChartPoint, string> PointLabel { get; set; }

    /// <summary>
    /// method to enalrge the slice (part of pie chart) 
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="chartpoint"></param>
    private void Chart_OnDataClick(object sender, ChartPoint chartpoint)
    {
        var chart = (LiveCharts.Wpf.PieChart)chartpoint.ChartView;

        //clear selected slice.
        foreach (PieSeries series in chart.Series)
            series.PushOut = 0;

        var selectedSeries = (PieSeries)chartpoint.SeriesView;
        selectedSeries.PushOut = 7;
    }             
}

和 XAML 代码:

<UserControl x:Class="StatusChart"
         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:lvc="clr-namespace:LiveCharts.Wpf;assembly=LiveCharts.Wpf"
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="500"
         d:DataContext="{d:DesignInstance local:StatusChart}">

<Grid x:Name="GridRoot">
    <lvc:PieChart x:Name="PieChart" LegendLocation="Bottom" DataClick="Chart_OnDataClick" Hoverable="False"><!-- DataTooltip="{x:Null}">-->
        <lvc:PieChart.Series>
            
            <lvc:PieSeries Title="serie1" 
                           Values="1" DataLabels="True" LabelPoint="{Binding PointLabel}">
            </lvc:PieSeries>

            <lvc:PieSeries Title="serie2" 
                           Values="1" DataLabels="True" LabelPoint="{Binding PointLabel}">
            </lvc:PieSeries>

            <lvc:PieSeries Title="serie3" Values="1" DataLabels="True" 
                           LabelPoint="{Binding PointLabel}"/>

            <lvc:PieSeries Title="serie4" Values="1" DataLabels="True" 
                           LabelPoint="{Binding PointLabel}">
            </lvc:PieSeries>

            <lvc:PieSeries Title="serie4" Values="1" DataLabels="True" 
                           LabelPoint="{Binding PointLabel}">
            </lvc:PieSeries>
        </lvc:PieChart.Series>            
    </lvc:PieChart>
</Grid>

为了在 WPF 窗口测试中尝试控件,请添加以下几行代码:

 var temporalSc = Enumerable.Repeat(1D, StatusChart.PieChart.Series.Count).ToList();
            for (var i = 0; i < StatusChart.PieChart.Series.Count; i++)
            {
                temporalSc[i] += rnd.Next(1, 87);
            }

            StatusChart.Values.Clear();
            StatusChart.Values = temporalSc;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接