最適化サーフェス
SurfaceWidget は、パラメーター探索の結果を三次元の地形として表示します。2 つの離散的な軸の上に 1 つの指標が乗り、指標の値が高さと色の両方を決めます。このコントロールは最適化ヒートマップと同じデータを受け取るため、1 つの結果セットを平面のマップとして、サーフェスとして、あるいはその両方で同時に表示できます。

作成と更新
import {
HeatDirections,
SurfaceWidget,
type SurfaceData,
type TradingHost,
} from '@stocksharp/trading-controls';
declare const host: TradingHost;
const surface = SurfaceWidget.create(
document.querySelector<HTMLElement>('#surface')!,
{},
{ host },
);
const sweep: SurfaceData = {
xLabel: 'Fast',
yLabel: 'Slow',
metricLabel: 'Net profit',
betterWhen: HeatDirections.Higher,
cells: [
{ x: '10', y: '50', value: 1_250 },
{ x: '10', y: '80', value: -320 },
{ x: '20', y: '50', value: 2_480 },
{ x: '20', y: '80', value: 640 },
],
};
surface.update(sweep);
依存関係は host だけで、SurfaceDeps インターフェイスに他のフィールドはありません。create の第 2 引数はインスタンスの保存状態ですが、サーフェスはこれを読み取らず、書き込みもしません。
update はセット全体を置き換えます。サーフェスは 1 回の探索そのものであるため、部分的な更新はありません。ある探索の半分の上に別の探索の半分を重ねれば、2 つの異なる集計から成る地形ができてしまいます。
静的プロパティ SurfaceWidget.TYPE は ControlTypes.OptimizationSurface、つまり識別子 optimizationSurface と等しくなります。
データ
HeatCell のセルは、軸の値の組と計測された指標、すなわち { x, y, value } です。軸は離散的であるため、軸の値は文字列です。10、00:05:00、True はいずれも軸上の対等な位置です。数値は数値として、それ以外はテキストとして並べられるので、5、8、12、40 という探索は順序を保ったままになります。
betterWhen フィールドは必須で、HeatDirections.Higher または HeatDirections.Lower を取ります。これがないと、ドローダウンの地形では最悪の隅が頂上になってしまいます。
同じ組み合わせに対する複数の実行結果は平均にまとめられ、1 つのセルになります。探索が通らなかった組み合わせは穴のまま残ります。面は 4 つの角がすべて分かっている場合にのみ描かれ、抜けは補間されません。結果がないことは結果がゼロであることとは違うからです。セルが 1 つもない場合、またはいずれかの軸で異なる値が 2 つ未満の場合は、地形の代わりに NoOptimizationResults キーのテキストを表示するプレースホルダーが出ます。
xLabel、yLabel、metricLabel のラベルは軸の見出しになります。metricLabel はパネルの見出しにも表示されます。
表示
面の高さは、スケールの基準点に対する値の位置を、床から天井までの範囲に収めたものです。基準点は高さの中央に来るため、床は「最悪の結果」ではなくスケールの下端を意味します。色は host.presentation.canvasPalette() から取得します。基準点より良い値には up、悪い値には down が使われ、基準点から離れるほど濃くなります。面は奥から手前へ塗られるため、手前の尾根がその奥にあるものを隠します。また、面は grid 色で縁取られ、隣り合う 2 つの面がほぼ同じ色合いのところでもグリッドが読み取れるようになっています。
投影は正射投影です。サーフェスは領域全体で高さを比べながら読むものであり、透視投影では尾根の奥側が手前側より短く見えてしまいます。
地形の下には、床の 2 本の稜線とスケールの垂直軸が描かれます。パラメーター軸には最大 8 個の目盛りが表示されます。値が入りきる間はすべて、それ以降は 1 つおき、2 つおきと間引かれますが、最初と最後には必ずラベルが付きます。垂直軸には 5 個の目盛りがあり、指標の値でラベル付けされます。ラベルは、観察者に近いほうの床の稜線へ移されます。回転のたびにこれは再計算され、数値がグリッドの上に重ならないようにします。
表示操作とジェスチャー
すべてのジェスチャーは pointer イベントで届くため、マウス、ペン、指は同じ経路を通ります。
- ポインター 1 つでのドラッグはサーフェスを回転させます。水平方向で
yaw、垂直方向でpitchが変わります。 - ポインター 2 つは、その間の距離で拡大率を変えます。このとき回転はポインター 1 つのままです。
- ホイールでも拡大率が変わります。デルタは、ブラウザーがピクセル、行、ページのどれで報告したかに関わらず「クリック数」に換算され、1 イベントあたり 2 クリックまでに制限されます。これにより、マウスとトラックパッドで同程度の刻みになります。
キャンバス上のジェスチャーはコントロールが自分で受け取ります。そうしないと、スマートフォンでのドラッグやデスクトップブラウザーでのホイールが、地形ではなくページをスクロールさせてしまいます。
傾きと拡大率には制限があります。pitch は MIN_PITCH(0.12)から MAX_PITCH(1.45)まで、拡大率は 0.4 から 4 までです。傾きがゼロだとどの面も線に潰れ、直角では平面のマップ、つまり別のコントロールになってしまいます。yaw の回転に制限はなく、一周してつながります。尾根の裏側を見るために地形をぐるりと回すのは、意味のあるジェスチャーだからです。初期の表示状態は DEFAULT_VIEW で、パネル見出しのボタン(ResetView)がそこへ戻します。
ポインターがサーフェスを回転させていないとき、コントロールは半径 22 CSS ピクセル以内で最も近い計測点を探します。見つかった点は up 色のリングで囲まれ、キャンバスの上のバーに 1 行が表示されます。xLabel 軸の値、yLabel 軸の値、そして指標です。このバーはパネルの見出しではなくキャンバスの上に重ねられます。その表示はポインターの下にある点についてのものであり、その近くになければならないからです。探索が通らなかった組み合わせはポインターに提示されません。距離が等しい場合は、観察者に近いほうの点が選ばれます。
コントロールの役割とホストに残る役割
コントロールはジェスチャーを自分で処理し、ResizeObserver でキャンバスのサイズを監視して、現在のサイズと画面のピクセル密度に合わせて地形を描き直し、表示リセットのボタンと host.close() を呼び出すパネルの閉じるボタンを受け持ち、さらに host.register で登録され、dispose で登録解除されます。キャンバスの色とフォントは host.presentation.canvasPalette() から届きます。表示されるテキストはすべて host.t から取得されます。OptimizationSurface、ResetView、ClosePanel、OptimizationSurfaceChart、NoOptimizationResults です。
データを供給するのはホストです。コントロールは最適化を起動せず、その進行を購読せず、結果がどのように得られたかも知りません。update に渡されたものがそのまま描画されます。面のクリックはありません。面は個々の実行ではなくセルに対応するため、そこから開くものは何もなく、押す操作は地形の回転になります。
コントロールは host.preferences に独自の設定を保存せず、キーも持たず、host.persistState も呼び出しません。現在の表示状態は view() メソッドで取得できます。セッションをまたいで復元したい場合は、ホストがこれらの値を自分で保存して戻します。
公開メソッド
update(data)— 結果セットを丸ごと表示します。view()— 現在の表示状態(yaw、pitch、zoom)のコピーを返します。resetView()— 表示状態をDEFAULT_VIEWに戻します。dispose()— サイズのオブザーバーを解除し、host.unregisterを呼び出してルート要素を取り除きます。
補助関数
ジオメトリはコントロールから別モジュールに切り出され、パッケージからエクスポートされています。これを土台に独自の描画を組むこともできます。
surfaceLayout(input)— 指定したサイズと表示状態に対して、セルを面、軸、頂点へ展開します。描くものがない場合はnullです。project(nx, ny, nz, view, box)— 単位立方体の点をキャンバスに投影します。dragView(view, dx, dy)— 指定したピクセル数だけドラッグした後の表示状態。zoomView(view, factor)— 拡大率を変更した後の表示状態。clampView(view)— 許容範囲に収めた表示状態。DEFAULT_VIEW、MIN_PITCH、MAX_PITCH— 初期の表示状態と傾きの限界。