LoginSignup
0
0

[その他] A型リアルタイムオペレーショングラフ(SkiaSharpデモ)

Last updated at Posted at 2024-02-01
--------------------------------------------------------------------------------------------
・心電図、脳波計等のデータ表示アプリです。
・閾値を超えると注意喚起として円グラフが赤くなり、数値も点滅する仕様。
・非同期スレッドを多用してて結構複雑なコードになり、面倒なので一部コードのみ
 記載してます。
・縦モニタに10個位並べて遊んでたら、妻子に「暇だなぁ」と言われました。。
--------------------------------------------------------------------------------------------
WQHD 2560x1440,自作機 i5-7600K 3.80GHz

68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f323832313838322f39623165613037632d663662302d353937312d633066342d3565613133653939316439622e6a706567.jpg

以前、職場の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);
  }
}
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0