mirror of
https://github.com/openhardwaremonitor/openhardwaremonitor
synced 2025-08-22 09:57:20 +00:00
205 lines
7.2 KiB
C#
205 lines
7.2 KiB
C#
/*
|
|
|
|
This Source Code Form is subject to the terms of the Mozilla Public
|
|
License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
|
Copyright (C) 2009-2013 Michael Möller <mmoeller@openhardwaremonitor.org>
|
|
|
|
*/
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Drawing;
|
|
using System.Linq;
|
|
using System.Windows.Forms;
|
|
using OpenHardwareMonitor.Hardware;
|
|
using OxyPlot;
|
|
using OxyPlot.Axes;
|
|
using OxyPlot.WindowsForms;
|
|
using OxyPlot.Series;
|
|
using OpenHardwareMonitor.Collections;
|
|
|
|
namespace OpenHardwareMonitor.GUI {
|
|
public class PlotPanel : UserControl {
|
|
|
|
private PersistentSettings settings;
|
|
|
|
private readonly Plot plot;
|
|
private readonly PlotModel model;
|
|
private readonly TimeSpanAxis timeAxis = new TimeSpanAxis();
|
|
private readonly SortedDictionary<SensorType, LinearAxis> axes =
|
|
new SortedDictionary<SensorType, LinearAxis>();
|
|
|
|
private DateTime now;
|
|
|
|
public PlotPanel(PersistentSettings settings) {
|
|
this.settings = settings;
|
|
this.model = CreatePlotModel();
|
|
|
|
this.plot = new Plot();
|
|
this.plot.Dock = DockStyle.Fill;
|
|
this.plot.Model = model;
|
|
this.plot.BackColor = Color.White;
|
|
this.plot.ContextMenu = new ContextMenu();
|
|
this.plot.ContextMenu.MenuItems.Add(CreateMenu());
|
|
|
|
this.SuspendLayout();
|
|
this.Controls.Add(plot);
|
|
this.ResumeLayout(true);
|
|
}
|
|
|
|
public void SetCurrentSettings() {
|
|
settings.SetValue("plotPanel.MinTimeSpan", (float)timeAxis.ViewMinimum);
|
|
settings.SetValue("plotPanel.MaxTimeSpan", (float)timeAxis.ViewMaximum);
|
|
|
|
foreach (var axis in axes.Values) {
|
|
settings.SetValue("plotPanel.Min" + axis.Key, (float)axis.ViewMinimum);
|
|
settings.SetValue("plotPanel.Max" + axis.Key, (float)axis.ViewMaximum);
|
|
}
|
|
}
|
|
|
|
private MenuItem CreateMenu() {
|
|
MenuItem timeWindow = new MenuItem("Time Window");
|
|
|
|
MenuItem[] timeWindowMenuItems =
|
|
{ new MenuItem("Auto",
|
|
(s, e) => { timeAxis.Zoom(0, double.NaN); InvalidatePlot(); }),
|
|
new MenuItem("5 min",
|
|
(s, e) => { timeAxis.Zoom(0, 5 * 60); InvalidatePlot(); }),
|
|
new MenuItem("10 min",
|
|
(s, e) => { timeAxis.Zoom(0, 10 * 60); InvalidatePlot(); }),
|
|
new MenuItem("20 min",
|
|
(s, e) => { timeAxis.Zoom(0, 20 * 60); InvalidatePlot(); }),
|
|
new MenuItem("30 min",
|
|
(s, e) => { timeAxis.Zoom(0, 30 * 60); InvalidatePlot(); }),
|
|
new MenuItem("45 min",
|
|
(s, e) => { timeAxis.Zoom(0, 45 * 60); InvalidatePlot(); }),
|
|
new MenuItem("1 h",
|
|
(s, e) => { timeAxis.Zoom(0, 60 * 60); InvalidatePlot(); }),
|
|
new MenuItem("1.5 h",
|
|
(s, e) => { timeAxis.Zoom(0, 1.5 * 60 * 60); InvalidatePlot(); }),
|
|
new MenuItem("2 h",
|
|
(s, e) => { timeAxis.Zoom(0, 2 * 60 * 60); InvalidatePlot(); }),
|
|
new MenuItem("3 h",
|
|
(s, e) => { timeAxis.Zoom(0, 3 * 60 * 60); InvalidatePlot(); }),
|
|
new MenuItem("6 h",
|
|
(s, e) => { timeAxis.Zoom(0, 6 * 60 * 60); InvalidatePlot(); }),
|
|
new MenuItem("12 h",
|
|
(s, e) => { timeAxis.Zoom(0, 12 * 60 * 60); InvalidatePlot(); }),
|
|
new MenuItem("24 h",
|
|
(s, e) => { timeAxis.Zoom(0, 24 * 60 * 60); InvalidatePlot(); }) };
|
|
|
|
foreach (MenuItem mi in timeWindowMenuItems)
|
|
timeWindow.MenuItems.Add(mi);
|
|
|
|
return timeWindow;
|
|
}
|
|
|
|
private PlotModel CreatePlotModel() {
|
|
|
|
timeAxis.Position = AxisPosition.Bottom;
|
|
timeAxis.MajorGridlineStyle = LineStyle.Solid;
|
|
timeAxis.MajorGridlineThickness = 1;
|
|
timeAxis.MajorGridlineColor = OxyColor.FromRgb(192, 192, 192);
|
|
timeAxis.MinorGridlineStyle = LineStyle.Solid;
|
|
timeAxis.MinorGridlineThickness = 1;
|
|
timeAxis.MinorGridlineColor = OxyColor.FromRgb(232, 232, 232);
|
|
timeAxis.StartPosition = 1;
|
|
timeAxis.EndPosition = 0;
|
|
timeAxis.MinimumPadding = 0;
|
|
timeAxis.MaximumPadding = 0;
|
|
timeAxis.AbsoluteMinimum = 0;
|
|
timeAxis.Minimum = 0;
|
|
timeAxis.AbsoluteMaximum = 24 * 60 * 60;
|
|
timeAxis.Zoom(
|
|
settings.GetValue("plotPanel.MinTimeSpan", 0.0f),
|
|
settings.GetValue("plotPanel.MaxTimeSpan", 10.0f * 60));
|
|
timeAxis.StringFormat = "h:mm";
|
|
|
|
var units = new Dictionary<SensorType, string>();
|
|
units.Add(SensorType.Voltage, "V");
|
|
units.Add(SensorType.Clock, "MHz");
|
|
units.Add(SensorType.Temperature, "°C");
|
|
units.Add(SensorType.Load, "%");
|
|
units.Add(SensorType.Fan, "RPM");
|
|
units.Add(SensorType.Flow, "L/h");
|
|
units.Add(SensorType.Control, "%");
|
|
units.Add(SensorType.Level, "%");
|
|
units.Add(SensorType.Factor, "1");
|
|
units.Add(SensorType.Power, "W");
|
|
units.Add(SensorType.Data, "GB");
|
|
|
|
foreach (SensorType type in Enum.GetValues(typeof(SensorType))) {
|
|
var axis = new LinearAxis();
|
|
axis.Position = AxisPosition.Left;
|
|
axis.MajorGridlineStyle = LineStyle.Solid;
|
|
axis.MajorGridlineThickness = 1;
|
|
axis.MajorGridlineColor = timeAxis.MajorGridlineColor;
|
|
axis.MinorGridlineStyle = LineStyle.Solid;
|
|
axis.MinorGridlineThickness = 1;
|
|
axis.MinorGridlineColor = timeAxis.MinorGridlineColor;
|
|
axis.Title = type.ToString();
|
|
axis.Key = type.ToString();
|
|
|
|
axis.Zoom(
|
|
settings.GetValue("plotPanel.Min" + axis.Key, float.NaN),
|
|
settings.GetValue("plotPanel.Max" + axis.Key, float.NaN));
|
|
|
|
if (units.ContainsKey(type))
|
|
axis.Unit = units[type];
|
|
axes.Add(type, axis);
|
|
}
|
|
|
|
var model = new PlotModel();
|
|
model.Axes.Add(timeAxis);
|
|
foreach (var axis in axes.Values)
|
|
model.Axes.Add(axis);
|
|
model.PlotMargins = new OxyThickness(0);
|
|
model.IsLegendVisible = false;
|
|
|
|
return model;
|
|
}
|
|
|
|
public void SetSensors(List<ISensor> sensors,
|
|
IDictionary<ISensor, Color> colors) {
|
|
this.model.Series.Clear();
|
|
|
|
ListSet<SensorType> types = new ListSet<SensorType>();
|
|
|
|
foreach (ISensor sensor in sensors) {
|
|
var series = new LineSeries();
|
|
series.ItemsSource = sensor.Values.Select(value => new DataPoint {
|
|
X = (now - value.Time).TotalSeconds, Y = value.Value
|
|
});
|
|
series.Color = colors[sensor].ToOxyColor();
|
|
series.StrokeThickness = 1;
|
|
series.YAxisKey = axes[sensor.SensorType].Key;
|
|
series.Title = sensor.Hardware.Name + " " + sensor.Name;
|
|
this.model.Series.Add(series);
|
|
|
|
types.Add(sensor.SensorType);
|
|
}
|
|
|
|
var start = 0.0;
|
|
foreach (var pair in axes.Reverse()) {
|
|
var axis = pair.Value;
|
|
var type = pair.Key;
|
|
axis.StartPosition = start;
|
|
axis.IsAxisVisible = types.Contains(type);
|
|
var delta = axis.IsAxisVisible ? 1.0 / types.Count : 0;
|
|
start += delta;
|
|
axis.EndPosition = start;
|
|
}
|
|
|
|
InvalidatePlot();
|
|
}
|
|
|
|
public void InvalidatePlot() {
|
|
this.now = DateTime.UtcNow;
|
|
this.plot.InvalidatePlot(true);
|
|
}
|
|
|
|
}
|
|
}
|