You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
208 lines
7.8 KiB
C#
208 lines
7.8 KiB
C#
using ScottPlot.Plottable;
|
|
using ScottPlot;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using System.Windows;
|
|
using System.Windows.Controls;
|
|
using System.Windows.Data;
|
|
using System.Windows.Documents;
|
|
using System.Windows.Input;
|
|
using System.Windows.Navigation;
|
|
using System.Windows.Shapes;
|
|
using System.Drawing;
|
|
using System.Reflection;
|
|
using System.Windows.Threading;
|
|
using Microsoft.Win32;
|
|
using System.Windows.Media.Imaging;
|
|
using mseedChart.Main.Models;
|
|
using mseedChart.Main.ViewModels;
|
|
using System.Security;
|
|
|
|
namespace mseedChart.Main.Views
|
|
{
|
|
/// <summary>
|
|
/// ChartPlot.xaml 的交互逻辑
|
|
/// </summary>
|
|
public partial class ChartPlotView : UserControl
|
|
{
|
|
public DispatcherTimer _renderTimer = new DispatcherTimer();
|
|
//非定时更新需停止定时器
|
|
List<SignalPlot> scatterPlots = new List<SignalPlot>();
|
|
//每天生成的最大点数*1天
|
|
const int MaxPointCount = 30_000;
|
|
int nextDataIndex = 1;
|
|
WpfPlot pl;
|
|
public ChartPlotView()
|
|
{
|
|
InitializeComponent();
|
|
//去掉右键菜单
|
|
plt.RightClicked-=plt.DefaultRightClickEvent;
|
|
// plt.RightClicked+= RightClickEvent;
|
|
|
|
var model = this.DataContext as ChartPlotViewModel;
|
|
model.InializeChartPlotChange = InializeChartPlotDates;
|
|
model.PlotLineDataChanged = PlotLineLiveData;
|
|
plt.Plot.Palette = new ScottPlot.Palettes.ColorblindFriendly();
|
|
// plt.Configuration.LockVerticalAxis = true;
|
|
List<string> lineLabels;
|
|
|
|
lineLabels = new List<string>();
|
|
for (int i = 0; i < 72; i++)
|
|
{
|
|
lineLabels.Add(i.ToString());
|
|
}
|
|
foreach (var item in lineLabels)
|
|
{
|
|
double[] data = new double[MaxPointCount];
|
|
var line = plt.Plot.AddSignal(data);
|
|
line.Label = item;
|
|
// line.Smooth = true;
|
|
// line.SmoothTension = 0.6f;
|
|
scatterPlots.Add(line);
|
|
}
|
|
plt.Refresh();
|
|
|
|
plt.Plot.XAxis.Color(Color.Black);
|
|
plt.Plot.Legend(enable: false);
|
|
|
|
// plt.Plot.Legend( false,location: Alignment.MiddleLeft);
|
|
//X轴显示格式
|
|
// plt.Plot.XAxis.TickLabelFormat("yyyy-MM-dd HH:mm:ss", dateTimeFormat: true);
|
|
_renderTimer.Interval = TimeSpan.FromMilliseconds(1000);
|
|
_renderTimer.Tick += Render;
|
|
_renderTimer.Start();
|
|
}
|
|
void Render(object sender, EventArgs e)
|
|
{
|
|
if (AutoAxisCbox.IsChecked == true)
|
|
{
|
|
plt.Plot.AxisAuto();
|
|
}
|
|
plt.Refresh();
|
|
}
|
|
int index = 1;
|
|
void PlotLineLiveData(List<double[]> runData)
|
|
{
|
|
int number = runData[0].Length;
|
|
|
|
|
|
for (int i = 0; i < scatterPlots.Count; i++) //数组平移
|
|
{
|
|
// Array.Copy(scatterPlots[i].Xs, 1, scatterPlots[i].Xs, 0, scatterPlots[i].Xs.Length - 1);
|
|
Array.Copy(scatterPlots[i].Ys, number, scatterPlots[i].Ys, 0, scatterPlots[i].Ys.Length - number);
|
|
|
|
Array.Copy(runData[i], 0, scatterPlots[i].Ys, scatterPlots[i].Ys.Length - number, number);
|
|
}
|
|
}
|
|
void InializeChartPlotDates(List<LineDatas> lineDatas)
|
|
{
|
|
nextDataIndex = lineDatas[0].YData.Length;
|
|
for (int i = 0; i < scatterPlots.Count; i++)
|
|
{
|
|
if (nextDataIndex <= MaxPointCount)
|
|
{
|
|
//内存拷贝
|
|
Array.Copy(lineDatas[i].YData, scatterPlots[i].Ys, nextDataIndex);
|
|
scatterPlots[i].MaxRenderIndex = nextDataIndex-1;
|
|
}
|
|
else
|
|
{
|
|
// scatterPlots[i].OffsetX = lineDatas[0].XData[nextDataIndex - MaxPointCount]; // Set start date
|
|
// Array.Copy(lineDatas[i].XData, nextDataIndex - MaxPointCount, scatterPlots[i].Xs, 0, MaxPointCount);
|
|
Array.Copy(lineDatas[i].YData, nextDataIndex - MaxPointCount, scatterPlots[i].Ys, 0, MaxPointCount);
|
|
scatterPlots[i].MaxRenderIndex = MaxPointCount-1;
|
|
}
|
|
}
|
|
nextDataIndex = nextDataIndex < MaxPointCount ? nextDataIndex: MaxPointCount; //最大不能超过 MaxPointCount
|
|
// plt.Plot.AxisAuto();
|
|
// plt.Refresh();
|
|
}
|
|
|
|
private void OnMouseMove(object sender, MouseEventArgs e)
|
|
{
|
|
int pixelX = (int)e.MouseDevice.GetPosition(plt).X;
|
|
int pixelY = (int)e.MouseDevice.GetPosition(plt).Y;
|
|
|
|
(double coordinateX, double coordinateY) = plt.GetMouseCoordinates();
|
|
|
|
plt.Refresh();
|
|
}
|
|
|
|
private void wpfPlot1_MouseEnter(object sender, MouseEventArgs e)
|
|
{
|
|
// MouseTrackLabel.Content = "Mouse ENTERED the plot";
|
|
// Crosshair.IsVisible = true;
|
|
}
|
|
|
|
private void wpfPlot1_MouseLeave(object sender, MouseEventArgs e)
|
|
{
|
|
//MouseTrackLabel.Content = "Mouse LEFT the plot";
|
|
//XPixelLabel.Content = "--";
|
|
//YPixelLabel.Content = "--";
|
|
//XCoordinateLabel.Content = "--";
|
|
//YCoordinateLabel.Content = "--";
|
|
|
|
// Crosshair.IsVisible = false;
|
|
// plt.Refresh();
|
|
}
|
|
|
|
public void RightClickEvent(object sender, EventArgs e)
|
|
{
|
|
var cm = new ContextMenu();
|
|
|
|
MenuItem SaveImageMenuItem = new() { Header = "保存图片" };
|
|
SaveImageMenuItem.Click += RightClickMenu_SaveImage_Click;
|
|
cm.Items.Add(SaveImageMenuItem);
|
|
|
|
MenuItem CopyImageMenuItem = new() { Header = "复制图片" };
|
|
CopyImageMenuItem.Click += RightClickMenu_Copy_Click;
|
|
cm.Items.Add(CopyImageMenuItem);
|
|
|
|
MenuItem AutoAxisMenuItem = new() { Header = "自适应数据" };
|
|
AutoAxisMenuItem.Click += RightClickMenu_AutoAxis_Click;
|
|
cm.Items.Add(AutoAxisMenuItem);
|
|
cm.IsOpen = true;
|
|
}
|
|
|
|
#region 右键菜单
|
|
private void RightClickMenu_Copy_Click(object sender, EventArgs e) => System.Windows.Clipboard.SetImage(BmpImageFromBmp(plt.Plot.Render()));
|
|
// private void RightClickMenu_Help_Click(object sender, EventArgs e) => new WPF.HelpWindow().Show();
|
|
// private void RightClickMenu_OpenInNewWindow_Click(object sender, EventArgs e) => new WpfPlotViewer(plt.Plot).Show();
|
|
private void RightClickMenu_AutoAxis_Click(object sender, EventArgs e) { plt.Plot.AxisAuto(); plt.Refresh(); }
|
|
private void RightClickMenu_SaveImage_Click(object sender, EventArgs e)
|
|
{
|
|
var sfd = new SaveFileDialog
|
|
{
|
|
FileName = "ScottPlot.png",
|
|
Filter = "PNG Files (*.png)|*.png;*.png" +
|
|
"|JPG Files (*.jpg, *.jpeg)|*.jpg;*.jpeg" +
|
|
"|BMP Files (*.bmp)|*.bmp;*.bmp" +
|
|
"|All files (*.*)|*.*"
|
|
};
|
|
|
|
if (sfd.ShowDialog() is true)
|
|
plt.Plot.SaveFig(sfd.FileName);
|
|
}
|
|
private static BitmapImage BmpImageFromBmp(System.Drawing.Bitmap bmp)
|
|
{
|
|
using var memory = new System.IO.MemoryStream();
|
|
bmp.Save(memory, System.Drawing.Imaging.ImageFormat.Png);
|
|
memory.Position = 0;
|
|
|
|
var bitmapImage = new BitmapImage();
|
|
bitmapImage.BeginInit();
|
|
bitmapImage.StreamSource = memory;
|
|
bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
|
|
bitmapImage.EndInit();
|
|
bitmapImage.Freeze();
|
|
|
|
return bitmapImage;
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
}
|