GUI/PlotPanel.cs
author moel.mich
Sun, 09 Jun 2013 16:10:43 +0000
changeset 396 c7e2a6aa4f96
parent 344 3145aadca3d2
child 397 243b6d5afa7c
permissions -rw-r--r--
Added experimental support for Intel Haswell CPUs.
     1 /*
     2  
     3   This Source Code Form is subject to the terms of the Mozilla Public
     4   License, v. 2.0. If a copy of the MPL was not distributed with this
     5   file, You can obtain one at http://mozilla.org/MPL/2.0/.
     6  
     7   Copyright (C) 2009-2013 Michael Möller <mmoeller@openhardwaremonitor.org>
     8 	
     9 */
    10 
    11 using System;
    12 using System.Collections.Generic;
    13 using System.Drawing;
    14 using System.Linq;
    15 using System.Windows.Forms;
    16 using OpenHardwareMonitor.Hardware;
    17 using OxyPlot;
    18 using OxyPlot.Axes;
    19 using OxyPlot.WindowsForms;
    20 using OxyPlot.Series;
    21 using OpenHardwareMonitor.Collections;
    22 
    23 namespace OpenHardwareMonitor.GUI {
    24   public class PlotPanel : UserControl {
    25 
    26     private PersistentSettings settings;
    27 
    28     private readonly Plot plot;
    29     private readonly PlotModel model;
    30     private readonly TimeSpanAxis timeAxis = new TimeSpanAxis();
    31     private readonly SortedDictionary<SensorType, LinearAxis> axes =
    32       new SortedDictionary<SensorType, LinearAxis>();
    33 
    34     private DateTime now;
    35 
    36     public PlotPanel(PersistentSettings settings) {
    37       this.settings = settings;
    38       this.model = CreatePlotModel();
    39 
    40       this.plot = new Plot();
    41       this.plot.Dock = DockStyle.Fill;
    42       this.plot.Model = model;
    43       this.plot.BackColor = Color.White;
    44       this.plot.ContextMenu = new ContextMenu();
    45       this.plot.ContextMenu.MenuItems.Add(CreateMenu());
    46 
    47       this.SuspendLayout();
    48       this.Controls.Add(plot);
    49       this.ResumeLayout(true);
    50     }
    51 
    52     public void SetCurrentSettings() {
    53       settings.SetValue("plotPanel.MinTimeSpan", (float)timeAxis.ViewMinimum);
    54       settings.SetValue("plotPanel.MaxTimeSpan", (float)timeAxis.ViewMaximum);
    55 
    56       foreach (var axis in axes.Values) {
    57         settings.SetValue("plotPanel.Min" + axis.Key, (float)axis.ViewMinimum);
    58         settings.SetValue("plotPanel.Max" + axis.Key, (float)axis.ViewMaximum);
    59       }
    60     }
    61 
    62     private MenuItem CreateMenu() {
    63       MenuItem timeWindow = new MenuItem("Time Window");
    64 
    65       MenuItem[] timeWindowMenuItems =
    66         { new MenuItem("Auto", 
    67             (s, e) => { timeAxis.Zoom(0, double.NaN); InvalidatePlot(); }),
    68           new MenuItem("5 min", 
    69             (s, e) => { timeAxis.Zoom(0, 5 * 60); InvalidatePlot(); }),
    70           new MenuItem("10 min", 
    71             (s, e) => { timeAxis.Zoom(0, 10 * 60); InvalidatePlot(); }),
    72           new MenuItem("20 min", 
    73             (s, e) => { timeAxis.Zoom(0, 20 * 60); InvalidatePlot(); }),
    74           new MenuItem("30 min", 
    75             (s, e) => { timeAxis.Zoom(0, 30 * 60); InvalidatePlot(); }),
    76           new MenuItem("45 min", 
    77             (s, e) => { timeAxis.Zoom(0, 45 * 60); InvalidatePlot(); }),
    78           new MenuItem("1 h", 
    79             (s, e) => { timeAxis.Zoom(0, 60 * 60); InvalidatePlot(); }),
    80           new MenuItem("1.5 h", 
    81             (s, e) => { timeAxis.Zoom(0, 1.5 * 60 * 60); InvalidatePlot(); }),
    82           new MenuItem("2 h", 
    83             (s, e) => { timeAxis.Zoom(0, 2 * 60 * 60); InvalidatePlot(); }),
    84           new MenuItem("3 h", 
    85             (s, e) => { timeAxis.Zoom(0, 3 * 60 * 60); InvalidatePlot(); }),
    86           new MenuItem("6 h", 
    87             (s, e) => { timeAxis.Zoom(0, 6 * 60 * 60); InvalidatePlot(); }),
    88           new MenuItem("12 h", 
    89             (s, e) => { timeAxis.Zoom(0, 12 * 60 * 60); InvalidatePlot(); }),
    90           new MenuItem("24 h", 
    91             (s, e) => { timeAxis.Zoom(0, 24 * 60 * 60); InvalidatePlot(); }) };
    92 
    93       foreach (MenuItem mi in timeWindowMenuItems)
    94         timeWindow.MenuItems.Add(mi);
    95 
    96       return timeWindow;
    97     }
    98 
    99     private PlotModel CreatePlotModel() {
   100 
   101       timeAxis.Position = AxisPosition.Bottom;
   102       timeAxis.MajorGridlineStyle = LineStyle.Solid;
   103       timeAxis.MajorGridlineThickness = 1;
   104       timeAxis.MajorGridlineColor = OxyColor.FromRgb(192, 192, 192);
   105       timeAxis.MinorGridlineStyle = LineStyle.Solid;
   106       timeAxis.MinorGridlineThickness = 1;
   107       timeAxis.MinorGridlineColor = OxyColor.FromRgb(232, 232, 232);
   108       timeAxis.StartPosition = 1;
   109       timeAxis.EndPosition = 0;
   110       timeAxis.MinimumPadding = 0;
   111       timeAxis.MaximumPadding = 0;
   112       timeAxis.AbsoluteMinimum = 0;
   113       timeAxis.Minimum = 0;
   114       timeAxis.AbsoluteMaximum = 24 * 60 * 60;
   115       timeAxis.Zoom(
   116         settings.GetValue("plotPanel.MinTimeSpan", 0.0f),
   117         settings.GetValue("plotPanel.MaxTimeSpan", 10.0f * 60));
   118       timeAxis.StringFormat = "h:mm";
   119 
   120       var units = new Dictionary<SensorType, string>();
   121       units.Add(SensorType.Voltage, "V");
   122       units.Add(SensorType.Clock, "MHz");
   123       units.Add(SensorType.Temperature, "°C");
   124       units.Add(SensorType.Load, "%");
   125       units.Add(SensorType.Fan, "RPM");
   126       units.Add(SensorType.Flow, "L/h");
   127       units.Add(SensorType.Control, "%");
   128       units.Add(SensorType.Level, "%");
   129       units.Add(SensorType.Factor, "1");
   130       units.Add(SensorType.Power, "W");
   131       units.Add(SensorType.Data, "GB");
   132 
   133       foreach (SensorType type in Enum.GetValues(typeof(SensorType))) {
   134         var axis = new LinearAxis();
   135         axis.Position = AxisPosition.Left;
   136         axis.MajorGridlineStyle = LineStyle.Solid;
   137         axis.MajorGridlineThickness = 1;
   138         axis.MajorGridlineColor = timeAxis.MajorGridlineColor;
   139         axis.MinorGridlineStyle = LineStyle.Solid;
   140         axis.MinorGridlineThickness = 1;
   141         axis.MinorGridlineColor = timeAxis.MinorGridlineColor;
   142         axis.Title = type.ToString();
   143         axis.Key = type.ToString();
   144 
   145         axis.Zoom(
   146           settings.GetValue("plotPanel.Min" + axis.Key, float.NaN),
   147           settings.GetValue("plotPanel.Max" + axis.Key, float.NaN));
   148 
   149         if (units.ContainsKey(type))
   150           axis.Unit = units[type];
   151         axes.Add(type, axis);
   152       }
   153 
   154       var model = new PlotModel();
   155       model.Axes.Add(timeAxis);
   156       foreach (var axis in axes.Values)
   157         model.Axes.Add(axis);
   158       model.PlotMargins = new OxyThickness(0);
   159       model.IsLegendVisible = false;
   160 
   161       return model;
   162     }
   163 
   164     public void SetSensors(List<ISensor> sensors,
   165       IDictionary<ISensor, Color> colors) {
   166       this.model.Series.Clear();
   167 
   168       ListSet<SensorType> types = new ListSet<SensorType>();
   169 
   170       foreach (ISensor sensor in sensors) {
   171         var series = new LineSeries();
   172         series.ItemsSource = sensor.Values.Select(value => new DataPoint {
   173           X = (now - value.Time).TotalSeconds, Y = value.Value
   174         });
   175         series.Color = colors[sensor].ToOxyColor();
   176         series.StrokeThickness = 1;
   177         series.YAxisKey = axes[sensor.SensorType].Key;
   178         series.Title = sensor.Hardware.Name + " " + sensor.Name;
   179         this.model.Series.Add(series);
   180 
   181         types.Add(sensor.SensorType);
   182       }
   183 
   184       var start = 0.0;
   185       foreach (var pair in axes.Reverse()) {
   186         var axis = pair.Value;
   187         var type = pair.Key;
   188         axis.StartPosition = start;
   189         axis.IsAxisVisible = types.Contains(type);
   190         var delta = axis.IsAxisVisible ? 1.0 / types.Count : 0;
   191         start += delta;
   192         axis.EndPosition = start;
   193       }
   194 
   195       InvalidatePlot();
   196     }
   197 
   198     public void InvalidatePlot() {
   199       this.now = DateTime.UtcNow;
   200       this.plot.InvalidatePlot(true);
   201     }
   202 
   203   }
   204 }