ブログ

割とコンピュータよりの情報をお届けします。

2024年

Plotly.Blazorのサンプル

.NET 8のリリースから半年近く経って、Plotly.Blazorのサンプルが増えていた。

Plotly.Blazorのサンプルが増えていたのでプロットしてみていた。とりあえず.NET6でプロットしたい場合にはサンプルのままで問題ない。
だが、縦横比を1:1にするときはどのようにするかが難しかった。とりあえずnugetパッケージをPlotly.Blazor(4.3.0)をインストール。
.NET 8になって、明示的にApp.razorのRoutesに@rendermodeを指定する必要が出ているようだ。以下Blazor serverで実装していく。
それからplotly.jsを追加していく。

<Routes @rendermode=RenderMode.InteractiveServer />
<script src="_content/Plotly.Blazor/plotly-latest.min.js" type="text/javascript"></script>
<script src="_content/Plotly.Blazor/plotly-interop.js" type="text/javascript"></script>
<script src="_framework/blazor.web.js"></script>

_Imports.razorに以下を追加する。

@using Plotly.Blazor
@using Plotly.Blazor.Traces

例えば、Home.razorに追加してみる。

@page "/"
@inject IJSRuntime JS
<PageTitle>Home</PageTitle>

<PlotlyChart
    @bind-Config="config"
    @bind-Layout="layout"
    @bind-Data="data" 
    @ref="chart"
    style="height: 500px;"/>

@code
{
    PlotlyChart? chart;
    Config config = new Config();
    Layout layout = new Layout();

    // Using of the interface IList is important for the event callback!
    IList<ITrace> data = new List<ITrace>
    {
        new Scatter
        {
            Name = "Sample circle small",
            Mode = Plotly.Blazor.Traces.ScatterLib.ModeFlag.Lines
                | Plotly.Blazor.Traces.ScatterLib.ModeFlag.Markers,
            X = new List<object>(),
            Y = new List<object>()
        },
        new Scatter
        {
            Name = "Sample circle large",
            Mode = Plotly.Blazor.Traces.ScatterLib.ModeFlag.Lines,
            X = new List<object>(),
            Y = new List<object>(),
            Line = new Plotly.Blazor.Traces.ScatterLib.Line() {
                Width = 1.85M,
                Dash = "3 12 5",
            },
        },
        new Scatter
        {
            Name = "Sample circle",
            Mode = Plotly.Blazor.Traces.ScatterLib.ModeFlag.Lines,
            X = new List<object>(),
            Y = new List<object>(),
            Line = new Plotly.Blazor.Traces.ScatterLib.Line() {
                Width = 0.5M,
                Dash = "dashdot",
            },
        },
    };

    private void AddData(int count = 360, double radius = 100D, Scatter? scatter = null)
    {
        Scatter refToScatter = (Scatter)data[0];
        if (scatter != null)
            refToScatter = scatter;

        double interval = 360D / (count - 1);
        for (int i = 0; i < count; i++)
        {
            double theta = ((double)i) * interval / 180D * Math.PI;
            double r = radius;
            refToScatter.X.Add(r * Math.Cos(theta));
            refToScatter.Y.Add(r * Math.Sin(theta));
        }
    }

    protected override void OnInitialized()
    {
        IList<Plotly.Blazor.LayoutLib.YAxis> ys = new List<Plotly.Blazor.LayoutLib.YAxis>();
        ys.Add(new Plotly.Blazor.LayoutLib.YAxis()
            {
                ScaleAnchor = "x",
            });
        layout.YAxis = ys;
        layout.AutoSize = true;

        AddData(count: 31, radius: 100D, scatter: (Scatter)data[0]);
        AddData(count: 98, radius: 60D, scatter: (Scatter)data[1]);
        AddData(count: 67, radius: 80D, scatter: (Scatter)data[2]);

        
    }
}


注意する点として、線幅がDoubleではなくDecimalで定義されている。とりあえず、PlotlyChartのstyleにheightを指定しているが、リサイズしても追従してこない。うまい方法がないかを探しているが、例えば、App.razorの
<script src="_framework/blazor.web.js"></script>
の後くらいに以下のようなコードを挿入して

    <script>
        window.viewportChangeCallback = (dotnetObject) => {
            window.addEventListener('load', () => {
                dotnetObject.invokeMethodAsync('OnResize', window.innerWidth, window.innerHeight);
            });
            window.addEventListener('resize', () => {
                dotnetObject.invokeMethodAsync('OnResize', window.innerWidth, window.innerHeight);
            });
        }
    </script>

Home.razorのコード部分に以下を追加してやる。引数はとりあえず使用していないが、何かあった時のために渡している。


    [JSInvokable]
    public void OnResize(int width, int height)
    {
        chart?.Update();
    }

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            await JS.InvokeVoidAsync("window.viewportChangeCallback", DotNetObjectReference.Create(this));
        }
    }

ここまで書いておいてなんだが、このOnResizeの対応は別に書かなくてもConfigのプロパティにResponsiveというのがあるので、これで多くの場合には事足りるようだ。

    Config config = new Config()
    {
        Responsive = true
    };

3次元プロットも以下のようになる。

@page "/Chart3D"

<PlotlyChart @bind-Config="config"
             @bind-Layout="layout"
             @bind-Data="data"
             @ref="chart"
             @bind-Style="Style" />

@code {
    PlotlyChart? chart;
    Config config = new Config()
    { 
        Responsive = true
    };
    Layout layout = new Layout();

    [Parameter]
    public string? Style { get; set; } = "height: 900px;";

    IList<ITrace> data = new List<ITrace>
    {
        new Scatter3D
        {
            Name = "Sample helix 3d",
            Mode = Plotly.Blazor.Traces.Scatter3DLib.ModeFlag.Lines
                | Plotly.Blazor.Traces.Scatter3DLib.ModeFlag.Markers,
            X = new List<object>(),
            Y = new List<object>(),
            Z = new List<object>(),
            Marker = new Plotly.Blazor.Traces.Scatter3DLib.Marker()
            {
                Size = 1M,
            }
        },
    };

    private void AddData(
        int count = 360,
        double radius = 100D,
        double lead = 10D,
        Scatter3D? scatter = null)
    {
        Scatter3D refToScatter = (Scatter3D)data[0];
        if (scatter != null)
            refToScatter = scatter;

        double interval = 360D / (count - 1);
        for (int i = 0; i < count; i++)
        {
            double theta = ((double)i) * interval / 180D * Math.PI;
            double r = radius;
            refToScatter.X.Add(r * Math.Cos(theta));
            refToScatter.Y.Add(r * Math.Sin(theta));
            refToScatter.Z.Add(interval / 360 * lead * i);
        }
    }

    protected override void OnInitialized()
    {
        IList<Plotly.Blazor.LayoutLib.Scene> scene = new List<Plotly.Blazor.LayoutLib.Scene>();
        scene.Add(new Plotly.Blazor.LayoutLib.Scene() {
                AspectMode = Plotly.Blazor.LayoutLib.SceneLib.AspectModeEnum.Data,
                AspectRatio = new Plotly.Blazor.LayoutLib.SceneLib.AspectRatio()
                    {
                        X = 1M,
                        Y = 1M,
                        Z = 1M
                    },
            }
        );
        layout.Scene = scene;


        AddData(count: 31, radius: 100D, lead: 400D, scatter: (Scatter3D)data[0]);
    }
    
}

≫ 続きを読む

2024/05/02 コンピュータ   TakeMe

Aterm WX3000HPと間違えてWX3000HP2を購入

Aterm WX3000HPと間違えてWX3000HP2を購入してしまった。
一応上位の機種なのか?

WX3000HP2とWX3000HPを比較すると中継機能部分が少し不足しているような感じだ。
ただし当然であるが親機としては使用できる。WX3000HP2から接続する機能はない。ほかのデバイスをWX3000HP2に接続してそのデバイス(WG1200HP2など)から有線機器つなぐことはできる。

以前から使用していたのもAtermだった。せっかくAterm同士の切り替えなのにこの機種では設定を引き継ぐ機能が使用できず最初からの設定になって時間がかかったが、動作はおおむね良好である。
本当は間違いだったけど割と良い。
今まで使用していたルータ(WG1200HS3)は子機にしようと思う。WG1200HS3に対して標準のIPv4のプライベートIPアドレスが違う。

そもそも、新規購入にいたったのは、子機に使用していたWG1200HP2が時々フリーズしてしまうことに気づいたことが原因。ファームウェアの更新を進めるページもあったが、ファームウェアの更新ができなくて…
今までWG1200HP2はCONVERTERモードで使用中はクイック設定Webにつながらないと思っていたが、Atermスマートリモコンというアプリがあればつながることが分かった。そもそも、有線接続してボタンを押しながら起動すればできるがかなり手間だった。
知らなかった... (取説読まなかったから)

古いWG1200HS3を子機に使用してしまうと若干速度が低下してしまう模様。そのうち中継機も購入しようか
ところで、AtermスマートリモコンというアプリはすべてAtermの場合には便利だ。同じネットワーク内の機器を一覧できる。
見えて安心ネット」も「MACアドレスフィルタ」より割と便利だ。
各端末が5 GHz帯でつながっているとか2.4 GHz帯でつながっているとかが表示できるようになる。

4月12日更新
使用を開始してしばらくして、Aterm製品におけるLAN側からの不正アクセスの脆弱性への対処方法について[2024年4月5日更新]という情報が入ってきた。
はこればっかりは仕方ないが偶然更新していた。

≫ 続きを読む

2024/03/20 コンピュータ   TakeMe

DKIM設定失敗

gmailでメールが受け取れなくなったので設定を見直していた。

メールアドレスは*@example.comだけどメールサーバはmail.example.comとなっていた場合はどうするのか...

gmailでメールが受け取れなくなったので設定を見直していた。

ここを参考として設定をしていたが、何かうまくいかなかった。

送信者メールアドレスは*@example.comなのだけどメールサーバはmail.example.comになっている場合、
MXレコードを追加して、example.comのメールはmail.example.comのサーバが担当することを記述する。

このとき DKIMのレコードは
xxxx._domainkey.example.com用のものを設定すればよいようだ。
xxxx._domainkey.mail.example.com用のものを設定しても意味がないようだ。
もちろん両方設定してもよい。

ADSPレコードは古いメールサーバ用の内容で、もう誰も読んでいないのでunknownでよい。消してもよい。

≫ 続きを読む

2024/01/21 コンピュータ   TakeMe