曲线方式观察double/float/int数组和列表(程序中断后)

支持功能

  • 查看折线使能
  • 查看点标记使能
  • 数据保存到文件

支持数据类型

  • double[] / float[] / int[] 最常见
  • List / List / List 比较常见
  • double[][] xy组依次排列
  • double[][] 多个y组

依赖
DynamicDataDisplay库

使用(Visual Studio 2019)
dll及相关文件放入文件夹
C:\Users\xxx\Documents\Visual Studio 2019\Visualizers

Visualizers.cs
using ClassLibrary2;
using Microsoft.VisualStudio.DebuggerVisualizers;
using System.Collections.Generic;


[assembly: System.Diagnostics.DebuggerVisualizer(
typeof(Lusong.Visualizer.ValueListVisualizer),
typeof(VisualizerObjectSource),
Target = typeof(List<double>),
Description = " 曲线查看 List<double> / List<float> / List<int>")]

[assembly: System.Diagnostics.DebuggerVisualizer(
typeof(Lusong.Visualizer.ValueArrayVisualizer),
typeof(VisualizerObjectSource),
Target = typeof(double[]),
Description = " 曲线查看 double[] / float[] / int[]")]

[assembly: System.Diagnostics.DebuggerVisualizer(
typeof(Lusong.Visualizer.DoublessVisualizer),
typeof(VisualizerObjectSource),
Target = typeof(double[][]),
Description = " 曲线查看 double[][],多个y组")]

[assembly: System.Diagnostics.DebuggerVisualizer(
typeof(Lusong.Visualizer.DoublessPointVisualizer),
typeof(VisualizerObjectSource),
Target = typeof(double[][]),
Description = " 曲线查看 double[][],xy组依次排列")]

namespace Lusong.Visualizer
{
    public class ValueListVisualizer : DialogDebuggerVisualizer
    {
        override protected void Show(IDialogVisualizerService windowService, IVisualizerObjectProvider objectProvider)
        {
            List<double> datad = objectProvider.GetObject() as List<double>;
            List<float> dataf = objectProvider.GetObject() as List<float>;
            List<int> datai = objectProvider.GetObject() as List<int>;
            CurveForm form = new CurveForm();
            if (datad != null)
                form.AddLine(datad.ToArray());
            else if (dataf != null)
                form.AddLine(dataf.ToArray());
            else if (datai != null)
                form.AddLine(datai.ToArray());
            windowService.ShowDialog(form);
        }
    }
    public class ValueArrayVisualizer : DialogDebuggerVisualizer
    {
        override protected void Show(IDialogVisualizerService windowService, IVisualizerObjectProvider objectProvider)
        {
            double[] datad = objectProvider.GetObject() as double[];
            float[] dataf = objectProvider.GetObject() as float[];
            int[] datai = objectProvider.GetObject() as int[];
            CurveForm form = new CurveForm();
            if(datad!=null)
                form.AddLine(datad);
            else if(dataf !=null)
                form.AddLine(dataf);
            else if (datai != null)
                form.AddLine(datai);
            windowService.ShowDialog(form);
        }
    }

    public class DoublessVisualizer : DialogDebuggerVisualizer
    {
        override protected void Show(IDialogVisualizerService windowService, IVisualizerObjectProvider objectProvider)

        {

            double[][] data = ((double[][])objectProvider.GetObject());

            if (data == null)
                return;

            CurveForm form = new CurveForm();

            for (int i = 0; i < data.Length; i++)
            {
                form.AddLine(data[i]);
            }

            windowService.ShowDialog(form);

        }
    }
    public class DoublessPointVisualizer : DialogDebuggerVisualizer
    {
        override protected void Show(IDialogVisualizerService windowService, IVisualizerObjectProvider objectProvider)
        {
            double[][] data = ((double[][])objectProvider.GetObject());

            if (data == null)
                return;
            CurveForm form = new CurveForm();
            for (int i = 0; i < data.Length/2; i++)
            {
                form.AddLine(data[i * 2], data[i * 2 + 1]);
            }
            windowService.ShowDialog(form);
        }
    }
}

CurveControl.xaml
<UserControl x:Class="ClassLibrary2.CurveControl"
             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:ClassLibrary2"
             xmlns:d3="http://research.microsoft.com/DynamicDataDisplay/1.0"
             mc:Ignorable="d" 
             Loaded="UserControl_Loaded"

             d:DesignHeight="450" d:DesignWidth="800">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <ToolBar>
            <Button x:Name="HideLineBtn" Click="HideLineBtn_Click">折线</Button>
            <Button x:Name="HideMarkerBtn" Click="HideMarkerBtn_Click">数据点标记</Button>
            <Button x:Name="SaveBtn" Click="SaveBtn_Click">保存</Button>
        </ToolBar>
        <d3:ChartPlotter Grid.Row="1" Name="plotter2" MinHeight="200" >

    <d3:VerticalRange Name="timerange2" Value1="0" Value2="0" Fill="LightGray" BorderBrush="Gray"/>

    <d3:CursorCoordinateGraph/>
            
</d3:ChartPlotter>

    </Grid>
</UserControl>

CurveControl.xaml.cs
using Microsoft.Research.DynamicDataDisplay;
using Microsoft.Research.DynamicDataDisplay.DataSources;
using Microsoft.Research.DynamicDataDisplay.PointMarkers;
using Microsoft.Win32;
using System.Collections.Generic;
using System.IO;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;

namespace ClassLibrary2
{
    /// <summary>
    /// CurveControl.xaml 的交互逻辑
    /// </summary>
    public partial class CurveControl : UserControl
    {
        public CurveControl()
        {
            InitializeComponent();
        }


        public string Title = "数据";

        private void UserControl_Loaded(object sender, RoutedEventArgs e)
        {
        }

        private Brush[] Brush = new Brush[] {Brushes.Red, Brushes.Green, Brushes.Blue, Brushes.DarkGoldenrod, Brushes.Purple, Brushes.Black, Brushes.DarkGray };
        List<LineAndMarker<ElementMarkerPointsGraph>> lines = new List<LineAndMarker<ElementMarkerPointsGraph>>();
        List<ObservableDataSource<OrderPoint>> datass = new List<ObservableDataSource<OrderPoint>>();
        public void AddLine(double[] datas)
        {
            ObservableDataSource<OrderPoint> ldata = new ObservableDataSource<OrderPoint>();
            datass.Add(ldata);

            ldata.SetXMapping(p => p.Index);

            ldata.SetYMapping(p =>
            {

                double v = p.Value;

                return v;

            });
            int c = datas.Length;
            OrderPoint[] ds = new OrderPoint[c];
            for (int i = 0; i < c; i++)
            {
                ds[i] = new OrderPoint(i, (float)datas[i]);
            }
            ldata.AppendMany(ds);

            var lg = plotter2.AddLineGraph(
                ldata,
                new Pen { Brush = this.Brush[lines.Count], Thickness = 2 },
                new CircleElementPointMarker { Size = 5, Fill = this.Brush[lines.Count], Brush = this.Brush[lines.Count] },
                new PenDescription(Title));
            lg.MarkerGraph.Visibility = Visibility.Visible;
            lines.Add(lg);
        }
        public void AddLine(int[] datas)
        {
            ObservableDataSource<OrderPoint> ldata = new ObservableDataSource<OrderPoint>();
            datass.Add(ldata);

            ldata.SetXMapping(p => p.Index);

            ldata.SetYMapping(p =>
            {

                double v = p.Value;

                return v;

            });
            int c = datas.Length;
            OrderPoint[] ds = new OrderPoint[c];
            for (int i = 0; i < c; i++)
            {
                ds[i] = new OrderPoint(i, datas[i]);
            }

            ldata.AppendMany(ds);

            var lg = plotter2.AddLineGraph(
                ldata,
                new Pen { Brush = this.Brush[lines.Count], Thickness = 2 },
                new CircleElementPointMarker { Size = 5, Fill = this.Brush[lines.Count], Brush = this.Brush[lines.Count] },
                new PenDescription(Title));
            lg.MarkerGraph.Visibility = Visibility.Visible;
            lines.Add(lg);
        }
        public void AddLine(float[] datas)
        {
            ObservableDataSource<OrderPoint> ldata = new ObservableDataSource<OrderPoint>();
            datass.Add(ldata);

            ldata.SetXMapping(p => p.Index);

            ldata.SetYMapping(p =>
            {

                double v = p.Value;

                return v;

            });
            int c = datas.Length;
            OrderPoint[] ds = new OrderPoint[c];
            for (int i = 0; i < c; i++)
            {
                ds[i] = new OrderPoint(i, datas[i]);
            }

            ldata.AppendMany(ds);

            var lg = plotter2.AddLineGraph(
                ldata,
                new Pen { Brush = this.Brush[lines.Count], Thickness = 2 },
                new CircleElementPointMarker { Size = 5, Fill = this.Brush[lines.Count], Brush = this.Brush[lines.Count] },
                new PenDescription(Title));
            lg.MarkerGraph.Visibility = Visibility.Visible;
            lines.Add(lg);
        }

        public void AddLine(double[] xs,double[] datas)
        {
            ObservableDataSource<OrderPoint> ldata = new ObservableDataSource<OrderPoint>();
            datass.Add(ldata);

            ldata.SetXMapping(p => p.Index);

            ldata.SetYMapping(p =>
            {

                double v = p.Value;

                return v;

            });
            int c = datas.Length;
            OrderPoint[] ds = new OrderPoint[c];
            for (int i = 0; i < c; i++)
            {
                ds[i] = new OrderPoint(xs[i], datas[i]);
            }
            ldata.AppendMany(ds);

            var lg = plotter2.AddLineGraph(
                ldata,
                new Pen { Brush = this.Brush[lines.Count], Thickness = 2 },
                new CircleElementPointMarker { Size = 5, Fill = this.Brush[lines.Count], Brush = this.Brush[lines.Count] },
                new PenDescription(Title));
            lg.MarkerGraph.Visibility = Visibility.Visible;
            lines.Add(lg);
        }

        private void HideLineBtn_Click(object sender, RoutedEventArgs e)
        {
            foreach (var line in lines)
            {
                if (line.LineGraph.Visibility != Visibility.Collapsed)
                    line.LineGraph.Visibility = Visibility.Collapsed;
                else
                    line.LineGraph.Visibility = Visibility.Visible;
            }
        }

        private void HideMarkerBtn_Click(object sender, RoutedEventArgs e)
        {
            foreach (var line in lines)
            {
                if (line.MarkerGraph.Visibility != Visibility.Collapsed)
                    line.MarkerGraph.Visibility = Visibility.Collapsed;
                else
                    line.MarkerGraph.Visibility = Visibility.Visible;
            }
        }

        public class OrderPoint
        {

            public OrderPoint(double index, double value)
            {
                this.Index = index;
                this.Value = value;
            }

            public double Index;
            public double Value;

        }

        private void SaveBtn_Click(object sender, RoutedEventArgs e)
        {
            SaveFileDialog dialog = new SaveFileDialog();
            dialog.Filter = "*.txt|*.txt";
            if (dialog.ShowDialog() != true)
            {
                return;
            }
            using (FileStream fs = new FileStream(dialog.FileName, FileMode.Create))
            {
                using (StreamWriter sw = new StreamWriter(fs))
                {
                    foreach (var data in datass)
                    {
                        sw.WriteLine("count=" + data.Collection.Count);
                        for (int i = 0; i < data.Collection.Count; i++)
                        {
                            sw.WriteLine(data.Collection[i].Value);
                        }
                    }
                }
            }
        }

    }
}
CurveForm.cs
using System;
using System.Windows.Forms;

namespace ClassLibrary2
{
    public partial class CurveForm : Form
    {
        public CurveForm()
        {
            InitializeComponent();
        }

        public void AddLine(double[] data)

        {
            try
            {
                this.curveControl1.AddLine(data);
            }catch(Exception ex)
            {

            }

        }
        public void AddLine(double[] xs,double[] ys)

        {
            try
            {
                this.curveControl1.AddLine(xs,ys);
            }
            catch (Exception ex)
            {

            }

        }
        public void AddLine(int[] data)

        {

            this.curveControl1.AddLine(data);

        }

        public void AddLine(float[] data)

        {

            this.curveControl1.AddLine(data);

        }
    }
}
posted @   lusonixs  阅读(13)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示