Removed the bitmap.GetHbitmap call for every redraw of the gadget. This should reduce dynamic memory allocation and freeing and removes some of the page faults increasing.
3 Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 The contents of this file are subject to the Mozilla Public License Version
6 1.1 (the "License"); you may not use this file except in compliance with
7 the License. You may obtain a copy of the License at
9 http://www.mozilla.org/MPL/
11 Software distributed under the License is distributed on an "AS IS" basis,
12 WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13 for the specific language governing rights and limitations under the License.
15 The Original Code is the Open Hardware Monitor code.
17 The Initial Developer of the Original Code is
18 Michael Möller <m.moeller@gmx.ch>.
19 Portions created by the Initial Developer are Copyright (C) 2009-2011
20 the Initial Developer. All Rights Reserved.
24 Alternatively, the contents of this file may be used under the terms of
25 either the GNU General Public License Version 2 or later (the "GPL"), or
26 the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 in which case the provisions of the GPL or the LGPL are applicable instead
28 of those above. If you wish to allow use of your version of this file only
29 under the terms of either the GPL or the LGPL, and not to allow others to
30 use your version of this file under the terms of the MPL, indicate your
31 decision by deleting the provisions above and replace them with the notice
32 and other provisions required by the GPL or the LGPL. If you do not delete
33 the provisions above, a recipient may use your version of this file under
34 the terms of any one of the MPL, the GPL or the LGPL.
39 using System.Collections.Generic;
40 using System.ComponentModel;
42 using System.Drawing.Drawing2D;
43 using System.Windows.Forms;
44 using OpenHardwareMonitor.Hardware;
46 namespace OpenHardwareMonitor.GUI {
47 public class PlotPanel : UserControl {
50 private List<ISensor> clocks = new List<ISensor>();
51 private List<ISensor> temperatures = new List<ISensor>();
52 private List<ISensor> fans = new List<ISensor>();
53 private IDictionary<ISensor, Color> colors;
55 private StringFormat centerlower;
56 private StringFormat centerleft;
57 private StringFormat lowerleft;
58 private Brush lightBrush;
62 this.SetStyle(ControlStyles.DoubleBuffer |
63 ControlStyles.UserPaint |
64 ControlStyles.AllPaintingInWmPaint |
65 ControlStyles.ResizeRedraw, true);
68 centerlower = new StringFormat();
69 centerlower.Alignment = StringAlignment.Center;
70 centerlower.LineAlignment = StringAlignment.Near;
72 centerleft = new StringFormat();
73 centerleft.Alignment = StringAlignment.Far;
74 centerleft.LineAlignment = StringAlignment.Center;
76 lowerleft = new StringFormat();
77 lowerleft.Alignment = StringAlignment.Far;
78 lowerleft.LineAlignment = StringAlignment.Near;
80 lightBrush = new SolidBrush(Color.FromArgb(245, 245, 245));
81 lightPen = new Pen(Color.FromArgb(200, 200, 200));
84 private List<float> GetTemperatureGrid() {
86 float? minTempNullable = null;
87 float? maxTempNullable = null;
88 foreach (ISensor sensor in temperatures) {
89 IEnumerable<SensorValue> values = sensor.Values;
90 foreach (SensorValue value in values) {
91 if (!float.IsNaN(value.Value)) {
92 if (!minTempNullable.HasValue || minTempNullable > value.Value)
93 minTempNullable = value.Value;
94 if (!maxTempNullable.HasValue || maxTempNullable < value.Value)
95 maxTempNullable = value.Value;
99 if (!minTempNullable.HasValue) {
100 minTempNullable = 20;
101 maxTempNullable = 30;
104 float maxTemp = (float)Math.Ceiling(maxTempNullable.Value / 10) * 10;
105 float minTemp = (float)Math.Floor(minTempNullable.Value / 10) * 10;
106 if (maxTemp == minTemp)
109 int countTempMax = 4;
110 float deltaTemp = maxTemp - minTemp;
111 int countTemp = (int)Math.Round(deltaTemp / 2);
112 if (countTemp > countTempMax)
113 countTemp = (int)Math.Round(deltaTemp / 5);
114 if (countTemp > countTempMax)
115 countTemp = (int)Math.Round(deltaTemp / 10);
116 if (countTemp > countTempMax)
117 countTemp = (int)Math.Round(deltaTemp / 20);
119 List<float> grid = new List<float>(countTemp + 1);
120 for (int i = 0; i <= countTemp; i++) {
121 grid.Add(minTemp + i * deltaTemp / countTemp);
126 private List<float> GetTimeGrid() {
129 if (temperatures.Count > 0) {
130 IEnumerator<SensorValue> enumerator =
131 temperatures[0].Values.GetEnumerator();
132 if (enumerator.MoveNext()) {
133 maxTime = (float)(now - enumerator.Current.Time).TotalMinutes;
139 while (deltaTime + 1 < maxTime && deltaTime < 10)
141 while (deltaTime + 2 < maxTime && deltaTime < 30)
143 while (deltaTime + 5 < maxTime && deltaTime < 100)
145 while (deltaTime + 50 < maxTime && deltaTime < 1000)
147 while (deltaTime + 100 < maxTime && deltaTime < 10000)
150 List<float> grid = new List<float>(countTime + 1);
151 for (int i = 0; i <= countTime; i++) {
152 grid.Add(i * deltaTime / countTime);
157 protected override void OnPaint(PaintEventArgs e) {
158 now = DateTime.Now - new TimeSpan(0, 0, 4);
160 List<float> timeGrid = GetTimeGrid();
161 List<float> tempGrid = GetTemperatureGrid();
163 Graphics g = e.Graphics;
166 new RectangleF(0, 0, Bounds.Width, Bounds.Height);
171 float w = r.Width - ml - mr;
176 float h = r.Height - mt - mb;
178 float leftScaleSpace = 5;
179 float bottomScaleSpace = 5;
181 g.Clear(Color.White);
183 if (w > 0 && h > 0) {
184 g.FillRectangle(lightBrush, x0, y0, w, h);
186 g.SmoothingMode = SmoothingMode.HighQuality;
187 for (int i = 0; i < timeGrid.Count; i++) {
188 float x = x0 + i * w / (timeGrid.Count - 1);
189 g.DrawLine(lightPen, x, y0, x, y0 + h);
192 for (int i = 0; i < tempGrid.Count; i++) {
193 float y = y0 + i * h / (tempGrid.Count - 1);
194 g.DrawLine(lightPen, x0, y, x0 + w, y);
197 float deltaTemp = tempGrid[tempGrid.Count - 1] - tempGrid[0];
198 float deltaTime = timeGrid[timeGrid.Count - 1];
199 foreach (ISensor sensor in temperatures) {
200 using (Pen pen = new Pen(colors[sensor])) {
201 IEnumerable<SensorValue> values = sensor.Values;
202 PointF last = new PointF();
204 foreach (SensorValue v in values) {
205 if (!float.IsNaN(v.Value)) {
206 PointF point = new PointF(
207 x0 + w - w * (float)(now - v.Time).TotalMinutes / deltaTime,
208 y0 + h - h * (v.Value - tempGrid[0]) / deltaTemp);
210 g.DrawLine(pen, last, point);
220 g.SmoothingMode = SmoothingMode.None;
221 g.FillRectangle(Brushes.White, 0, 0, x0, r.Height);
222 g.FillRectangle(Brushes.White, x0 + w + 1, 0, r.Width - x0 - w,
225 for (int i = 1; i < timeGrid.Count; i++) {
226 float x = x0 + (timeGrid.Count - 1 - i) * w / (timeGrid.Count - 1);
227 g.DrawString(timeGrid[i].ToString(), Font, Brushes.Black, x,
228 y0 + h + bottomScaleSpace, centerlower);
231 for (int i = 0; i < tempGrid.Count - 1; i++) {
232 float y = y0 + (tempGrid.Count - 1 - i) * h / (tempGrid.Count - 1);
233 g.DrawString(tempGrid[i].ToString(), Font, Brushes.Black,
234 x0 - leftScaleSpace, y, centerleft);
237 g.SmoothingMode = SmoothingMode.HighQuality;
238 g.DrawString("[°C]", Font, Brushes.Black, x0 - leftScaleSpace, y0,
240 g.DrawString("[min]", Font, Brushes.Black, x0 + w,
241 y0 + h + bottomScaleSpace, lowerleft);
245 public void SetSensors(List<ISensor> sensors,
246 IDictionary<ISensor, Color> colors) {
247 this.colors = colors;
248 List<ISensor> clocks = new List<ISensor>();
249 List<ISensor> temperatures = new List<ISensor>();
250 List<ISensor> fans = new List<ISensor>();
251 foreach (ISensor sensor in sensors)
252 switch (sensor.SensorType) {
253 case SensorType.Clock: clocks.Add(sensor); break;
254 case SensorType.Temperature: temperatures.Add(sensor); break;
255 case SensorType.Fan: fans.Add(sensor); break;
257 this.clocks = clocks;
258 this.temperatures = temperatures;