enhanced ping graph

This commit is contained in:
kshman 2021-03-27 19:39:21 +09:00
parent ccd5faf8a9
commit e09c84a027
5 changed files with 167 additions and 115 deletions

View file

@ -72,6 +72,7 @@
<Compile Include="DcControl.Designer.cs"> <Compile Include="DcControl.Designer.cs">
<DependentUpon>DcControl.cs</DependentUpon> <DependentUpon>DcControl.cs</DependentUpon>
</Compile> </Compile>
<Compile Include="Libre\PingGrapher.cs" />
<Compile Include="Tab\ConfigForm.cs"> <Compile Include="Tab\ConfigForm.cs">
<SubType>Form</SubType> <SubType>Form</SubType>
</Compile> </Compile>
@ -95,7 +96,6 @@
<DependentUpon>DutyOvForm.cs</DependentUpon> <DependentUpon>DutyOvForm.cs</DependentUpon>
</Compile> </Compile>
<Compile Include="ThirdParty\Converter.cs" /> <Compile Include="ThirdParty\Converter.cs" />
<Compile Include="ThirdParty\FastGraphLine.cs" />
<Compile Include="ThirdParty\LineDb.cs" /> <Compile Include="ThirdParty\LineDb.cs" />
<Compile Include="ThirdParty\NativeMethods.cs" /> <Compile Include="ThirdParty\NativeMethods.cs" />
<Compile Include="ThirdParty\ThreadWorker.cs" /> <Compile Include="ThirdParty\ThreadWorker.cs" />

148
Libre/PingGrapher.cs Normal file
View file

@ -0,0 +1,148 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Drawing;
namespace DutyContent.Libre
{
class PingGrapher
{
private PictureBox _pbx;
private Bitmap _bmp;
private Font _fnt;
private int _count_per_line;
public int Width { get; private set; } = -1;
public int Height { get; private set; } = -1;
public int Step { get; set; } = 20;
//
public PingGrapher(PictureBox container_pbx)
{
_pbx = container_pbx;
_fnt = new Font(FontFamily.GenericSansSerif, 7.0f, FontStyle.Regular, GraphicsUnit.Pixel);
}
//
public void Enter()
{
if (_pbx == null)
return;
if (Width != _pbx.ClientSize.Width || Height != _pbx.ClientSize.Height)
{
Width = _pbx.ClientSize.Width;
Height = _pbx.ClientSize.Height;
_count_per_line = (Width - Step + Step) / Step + 1;
_bmp = new Bitmap(Width, Height);
}
if (_bmp != null)
{
using (var g = Graphics.FromImage(_bmp))
g.Clear(Color.Black);
}
}
//
class CalcData
{
public int[] Values { get; set; }
public int Count { get; set; }
public int Min { get; set; } = int.MaxValue;
public int Max { get; set; } = int.MinValue;
public int RangeMax { get; set; }
public int RangeStep { get; set; }
public CalcData(List<int> lst, int count_per_line, int range_delta)
{
var at = Math.Max(lst.Count - count_per_line, 0);
Count = lst.Count - at;
Values = new int[Count];
for (int j = 0, i = lst.Count - 1; i >= at; i--)
{
if (Min > lst[i]) Min = lst[i];
if (Max < lst[i]) Max = lst[i];
Values[j++] = lst[i];
}
var rf = (float)(Max + range_delta) / 10.0f;
RangeMax = ((int)Math.Round(rf) + 1) * 10;
RangeStep =
RangeMax < 100 ? 20 :
RangeMax < 300 ? 40 :
RangeMax < 1000 ? 100 : 200;
}
}
public void DrawValues(List<int> values)
{
if (_bmp == null || values.Count < 2)
return;
var cd = new CalcData(values, _count_per_line, 5);
var height = (float)Height;
var scale = height / cd.RangeMax;
using (var g = Graphics.FromImage(_bmp))
{
float f;
int u;
for (var i = cd.RangeStep; i < cd.RangeMax; i += cd.RangeStep)
{
f = height - i * scale;
u = (int)f;
g.DrawLine(Pens.DarkBlue, 0, u, Width - 1, u);
g.DrawString(i.ToString(), _fnt, Brushes.DarkGray, 0.0f, f);
}
var pen = new Pen(Color.White, 2.0f);
#if false
u = 0;
// linear
for (var i = 0; i < cd.Count - 1; i++)
{
var y1 = height - cd.Values[i] * scale;
var y2 = height - cd.Values[i + 1] * scale;
g.DrawLine(pen, u, y1, u + Step, y2);
u += Step;
}
#else
// curved
u = 10;
var pts = new PointF[cd.Count - 1];
for (var i = 0; i < cd.Count - 1; i++, u += Step)
pts[i] = new PointF(u, height - cd.Values[i] * scale);
g.DrawCurve(pen, pts, 0.6f);
#endif
}
}
//
public void Leave()
{
_pbx.Image = _bmp;
_pbx.Refresh();
}
}
}

View file

@ -123,5 +123,12 @@ namespace DutyContent
string msg = ExceptionPattern.Replace(ex.Message, "{{$1}}"); string msg = ExceptionPattern.Replace(ex.Message, "{{$1}}");
Write(Color.Red, $"{text}: {msg}"); Write(Color.Red, $"{text}: {msg}");
} }
// exception
public static void Ex(Exception ex)
{
string msg = ExceptionPattern.Replace(ex.Message, "{{$1}}");
Write(Color.Red, $"EX: {msg}");
}
} }
} }

View file

@ -31,7 +31,7 @@ namespace DutyContent.Tab
private System.Timers.Timer _ping_timer; private System.Timers.Timer _ping_timer;
private long _ping_last; private long _ping_last;
private Color _ping_color = Color.Transparent; private Color _ping_color = Color.Transparent;
private ThirdParty.FastGraphLine _ping_graph; private Libre.PingGrapher _ping_grpr;
private List<int> _ping_keeps = new List<int>(); private List<int> _ping_keeps = new List<int>();
public DutyForm() public DutyForm()
@ -41,7 +41,8 @@ namespace DutyContent.Tab
InitializeComponent(); InitializeComponent();
_overlay = new Overlay.DutyOvForm(); _overlay = new Overlay.DutyOvForm();
_ping_graph = new ThirdParty.FastGraphLine(pbxPingGraph); _ping_grpr = new Libre.PingGrapher(pbxPingGraph);
_ping_keeps.Add(0);
} }
private void DutyTabForm_FormClosing(object sender, FormClosingEventArgs e) private void DutyTabForm_FormClosing(object sender, FormClosingEventArgs e)
@ -135,7 +136,10 @@ namespace DutyContent.Tab
_ping_timer.Elapsed += (sender, e) => PingOnce(); _ping_timer.Elapsed += (sender, e) => PingOnce();
if (DcConfig.Duty.UsePing) if (DcConfig.Duty.UsePing)
{
PingOnce();
_ping_timer.Start(); _ping_timer.Start();
}
} }
public void PluginDeinitialize() public void PluginDeinitialize()
@ -1442,12 +1446,12 @@ namespace DutyContent.Tab
if (DcConfig.Duty.PingGraph) if (DcConfig.Duty.PingGraph)
{ {
_ping_keeps.Add((int)rtt); _ping_keeps.Add((int)rtt);
if (_ping_keeps.Count > 100) if (_ping_keeps.Count > 120)
_ping_keeps.Remove(0); _ping_keeps.RemoveAt(0);
_ping_graph.Enter(); _ping_grpr.Enter();
_ping_graph.SetValues(_ping_keeps); _ping_grpr.DrawValues(_ping_keeps);
WorkerAct.Invoker(() => _ping_graph.Leave()); WorkerAct.Invoker(() => _ping_grpr.Leave());
} }
} }

View file

@ -1,107 +0,0 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace DutyContent.ThirdParty
{
class FastGraphLine
{
private PictureBox _pbx;
private Bitmap _bmp;
private int _midv;
private int _dcnt;
public int Width { get; private set; } = -1;
public int Height { get; private set; } = -1;
//
public FastGraphLine(PictureBox pbx)
{
_pbx = pbx;
}
//
public void Enter()
{
if (_pbx == null)
return;
if (Width != _pbx.ClientSize.Width || Height != _pbx.ClientSize.Height)
{
Width = _pbx.ClientSize.Width;
Height = _pbx.ClientSize.Height;
_midv = Height / 2;
_dcnt = (Width - 40) / 20;
_bmp = new Bitmap(Width, Height);
}
if (_bmp != null)
{
using (var g = Graphics.FromImage(_bmp))
{
g.Clear(Color.Black);
g.DrawLine(Pens.DarkBlue, 0, _midv, Width - 1, _midv);
}
}
}
//
public void SetValues(List<int> vs, int mindelta = 5, int maxdelta = 5)
{
if (_bmp == null && vs.Count >= 2)
return;
int min = int.MaxValue, max = int.MinValue;
int cnt = vs.Count - _dcnt;
if (cnt < 0)
cnt = 0;
for (var i = vs.Count - 1; i >= cnt; i--)
{
if (min > vs[i])
min = vs[i];
if (max < vs[i])
max = vs[i];
}
min -= mindelta;
max += maxdelta;
//
MesgLog.L("Count: {0}, MM: {1}/{2}", vs.Count, min, max);
float scale = (float)Height / (float)(max - min);
int xx = 10;
using (var g = Graphics.FromImage(_bmp))
{
Pen pen = new Pen(Color.White, 2.0f);
for (var i = vs.Count - 2; i >= cnt; i--)
{
var y1 = (int)((vs[i + 1] - min) * scale);
var y2 = (int)((vs[i] - min) * scale);
g.DrawLine(pen, xx, y1, xx + 10, y2);
xx += 10;
}
}
}
//
public void Leave()
{
_pbx.Image = _bmp;
_pbx.Refresh();
}
}
}