支持功能
- 查看折线使能
- 查看点标记使能
- 数据保存到文件
支持数据类型
- 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);
}
}
}