--------------------------------------------------------------------------------------------
・心電図、脳波計等のデータ表示アプリです。
・閾値を超えると注意喚起として円グラフが赤くなり、数値も点滅する仕様。
・非同期スレッドを多用してて結構複雑なコードになり、面倒なので一部コードのみ
記載してます。
・縦モニタに10個位並べて遊んでたら、妻子に「暇だなぁ」と言われました。。
--------------------------------------------------------------------------------------------
WQHD 2560x1440,自作機 i5-7600K 3.80GHz
・心電図、脳波計等のデータ表示アプリです。
・閾値を超えると注意喚起として円グラフが赤くなり、数値も点滅する仕様。
・非同期スレッドを多用してて結構複雑なコードになり、面倒なので一部コードのみ
記載してます。
・縦モニタに10個位並べて遊んでたら、妻子に「暇だなぁ」と言われました。。
--------------------------------------------------------------------------------------------
WQHD 2560x1440,自作機 i5-7600K 3.80GHz
以前、職場のLinuxメールサーバが不調で負荷監視にtopコマンドを使用してたが、数値でわかり辛いのでWinForms版を急遽作成。WPF+SkiaSharp版として作り直し。
- 開発にあたり、新たに考案した描画アルゴリズムを使用。
- 各種機器からソケットでデータを受信してグラフ化も可能。
- アイコン類は飾りです。
- 試験用にプリセットしたデータで疑似心電図の他、正弦波(y=sin x)もでます。
- 描画は一気に行う為、例えば下記の円グラフ描画ルーチン内でTask.Deley()は使えません。
※円グラフは円周上のXY点を算出し円中心から1本1本線を引いてグラフにしています。データが200(真円)の場合は360本ひいてる事になります。
・WPF(SkiaSharp) サンプルコード
// 円グラフ
void OnPaintCIRCLE(object sender, SKPaintSurfaceEventArgs e){
// グラフ部背景色
e.Surface.Canvas.Clear(SKColors.Black);
var skPaint = new SKPaint() {
FilterQuality = SKFilterQuality.High,
IsAntialias = true
};
skPaint.TextSize = 13f;
skPaint.Color = SKColors.White;
skPaint.Typeface = SKTypeface.FromFamilyName("LINE Seed JP_OTF");
e.Surface.Canvas.DrawText("0", 72, 12, skPaint);
e.Surface.Canvas.DrawText("50", 128, 70, skPaint);
e.Surface.Canvas.DrawText("100", 64, 129, skPaint);
e.Surface.Canvas.DrawText("150", 0, 70, skPaint);
// NOMAL
SKPaint A_LINE1= new SKPaint{
Style = SKPaintStyle.StrokeAndFill,
Color = new SKColor(0, 155, 0),
// StrokeCap = (SKStrokeCap)50,
IsAntialias=true,
StrokeWidth = 2
};
// OVER
SKPaint A_LINE2= new SKPaint{
Style = SKPaintStyle.StrokeAndFill,
//Color = SKColors.Red,
Color = new SKColor(155, 0, 0),
// StrokeCap = (SKStrokeCap)10,
IsAntialias=true,
StrokeWidth = 2
};
// BLACK
SKPaint A_LINE3= new SKPaint{
Style = SKPaintStyle.StrokeAndFill,
//Color = SKColors.Red,
Color = new SKColor(0, 0, 0),
// StrokeCap = (SKStrokeCap)10,
IsAntialias=true,
StrokeWidth = 2
};
double y, x;
// 扇描画 x1.8 は 0->200のデータを0->360に換算
if(GC.IsChecked == false) {
for(double h = 0; h < cnt2 * 1.8; h++) {
x = 75 + 50 * Math.Sin(h * Math.PI / 180);
y = 67 - 50 * Math.Cos(h * Math.PI / 180);
if(cnt2 < Y_LINEDAT.Value) {
e.Surface.Canvas.DrawLine(75, 67, (int)x, (int)y, A_LINE1);
}
else {
e.Surface.Canvas.DrawLine(75, 67, (int)x, (int)y, A_LINE2);
}
}
}
else {
// 扇描画 x1.8 は 0->200のデータを0->360に換算 (グラデーション有り)
int vc = 50;
for(double h = 0; h < cnt2 * 1.8; h++) {
x = 75 + 50 * Math.Sin(h * Math.PI / 180);
y = 67 - 50 * Math.Cos(h * Math.PI / 180);
if(cnt2 < Y_LINEDAT.Value) {
if(vc >= 256) vc = 255;
A_LINE1.Color = new SKColor(0, (byte)vc++, 0);
e.Surface.Canvas.DrawLine(75, 67, (int)x, (int)y, A_LINE1);
}
else {
if(vc >= 256) vc = 255;
A_LINE2.Color = new SKColor((byte)vc++, 0, 0);
e.Surface.Canvas.DrawLine(75, 67, (int)x, (int)y, A_LINE2);
}
}
}
// 円の中心に黒い円を描いてアナログ計を修飾する
if (GC2.IsChecked == true) e.Surface.Canvas.DrawCircle(75,67,30,A_LINE3);
}
}