「労働者が自分の仕事をうまくやりたいなら、まず自分の道具を研ぎ澄まさなければなりません。」 - 孔子、「論語。陸霊公」
表紙 > プログラミング > ActivityRenderer の構築

ActivityRenderer の構築

2024 年 8 月 5 日に公開
ブラウズ:641

ガント アクティビティ レンダラは、ScheduleJS ビューアのメイン レンダラです。この記事では、このアクティビティ レンダラーの構築方法とその特徴について説明します。

カスタムレンダラークラスを構築する方法

レンダラー クラスを構築する最初のステップは、上位フレームワーク クラスを拡張して属性とメソッドを継承することです。

タスクの開始時間と終了時間のディメンションのみでタスクを表現したいと考えています。これを行うための ScheduleJS の基本レンダラー クラスは、ActivityBarRenderer クラスです。

カスタム Row クラスと Activity クラスによって提供される属性とメソッドにアクセスできるように、カスタム タイプの引数を ActivityBarRenderer クラスに提供する必要があります。基本クラス API を使用します。

ScheduleJsViewerTaskActivityRenderer クラスを作成して、すべての ScheduleJsViewerTaskActivity をそれぞれの ScheduleJsViewerTaskRow に描画しましょう。

// Import the base ActivityBarRenderer class from ScheduleJS
import {ActivityBarRenderer} from "schedule";

// Import our custom Activity and Row types
import {ScheduleJsViewerTaskActivity} from "...";
import {ScheduleJsViewerTaskRow} from "...";

// Create our custom renderer by extending the ActivityBarRenderer class
export class ScheduleJsViewerTaskActivityRenderer extends ActivityBarRenderer { }

そのままでは、ActivityBarRenderer のデフォルトの動作を使用してアクティビティを描画するためにレンダラーをすでに登録できます。それでは、カスタマイズ方法を見ていきましょう。

基本アーキテクチャ

ScheduleJS の ActivityRenderer は、Graphics API を使用してプログラムで登録し、Row に特定の Activity を描画するクラスです。 ScheduleJsViewerTaskActivityRenderer を整理するために、コードを 3 つのセクションに分割します:

  • 属性には、特定の描画手順の動作を変更できる変数が保持されます。
  • コンストラクターを使用すると、レンダラーのデフォルト状態を定義できます。
  • 描画メソッドには、キャンバス上にアクティビティを描画するためのすべての命令が含まれます。

属性

属性はレンダラー全体で再利用される定数です。現状では、これらのプロパティはレンダラー コード内でのみ直接編集されます。ユーザーがこれらの設定を UI で直接変更できる特定の画面を想像できます。

// Attributes

// Pixels sizings
private readonly _parentActivityTrianglesWidthPx: number = 5;
private readonly _parentActivityTrianglesHeightPx: number = 8;
private readonly _defaultLineWidthPx: number = 0.5;

// Colors palette
private readonly _parentActivityColor: string = Color.GRAY.toCssString();
private readonly _strokeColor: string = Color.BLACK.toCssString();
private readonly _defaultActivityGreen: Color = Color.rgb(28, 187, 158);
private readonly _defaultActivityBlue: Color = Color.rgb(53, 152, 214);
private readonly _onHoverFillColor: string = Color.ORANGE.toCssString();

// Opacity ratio for baseline activities
private readonly _baselineOpacityRatio: number = 0.6;

コンストラクタ

コンストラクターはレンダラーのライフサイクル メソッドと密接に結合されています。 ScheduleJS ビューアでは、ユーザーが画面を切り替えるたびにレンダラーをインスタンス化して詳細を定義し、このレンダラーを実装するすべてのタブでコードを再利用することにしました。これは、ユーザーがこのレンダラーを備えた画面を選択するたびにコンストラクター関数が実行されることを意味します。

// Constructor

// The renderer requires the graphics and the current tab variable
constructor(graphics: GraphicsBase,
            private _currentRibbonMenuTab: ScheduleJsViewerRibbonMenuTabsEnum) {

  // The ActivityBarRenderer class requires the graphics and a name for the renderer
  super(graphics, ScheduleJsViewerRenderingConstants.taskActivityRendererName);

  // Default fill color when hovering an activity
  this.setFillHover(Color.web(this._onHoverFillColor));

  // Default stroke color when hovering an activity
  this.setStrokeHover(Color.BLACK);

  // Default stroke color
  this.setStroke(Color.BLACK);

  // Default thickness
  this.setLineWidth(this._defaultLineWidthPx);

  // Default bar height
  this.setBarHeight(8);

  // Default fill color based on current tab 
  switch (_currentRibbonMenuTab) {
    // Change color for the WBS tab
    case ScheduleJsViewerRibbonMenuTabsEnum.WBS:
      this._parentActivityColor = ScheduleJsViewerColors.brown;
      this.setFill(this._defaultActivityBlue);
      break;
    default:
      this._parentActivityColor = Color.GRAY.toCssString();
      this.setFill(this._defaultActivityGreen);
      break;
  }

}

setFill、setStroke、setFillHover、setStrokeHover、setLineWidth、および setBarHeight は継承され、ActivityBarRenderer クラスのデフォルトのレンダリング特性を変更するために使用されます。

このレンダラーのデフォルトの機能は次のとおりです:

  • アクティビティをホバーするときのカスタムカラー
  • 黒い線のストローク (アクティビティの境界線用)
  • ストローク線の太さ 0.5 ピクセル
  • アクティビティ バーの高さは 8 ピクセル
  • 条件付き塗りつぶし色: WBS タブの子供は青、親は茶色 他のタブの子供は緑色、親は灰色

描画

フレームワークは自動的にdrawActivityメソッドを呼び出して、キャンバス上にアクティビティをレンダリングします。すべてのパラメータは動的に入力されるため、アクティビティの現在の状態にリアルタイムで反応できます。

// Main drawing method

drawActivity(activityRef: ActivityRef,
             position: ViewPosition,
             ctx: CanvasRenderingContext2D,
             x: number,
             y: number,
             w: number,
             h: number,
             selected: boolean,    
             hover: boolean,
             highlighted: boolean,
             pressed: boolean     
            ): ActivityBounds {    // This method has to return ActivityBounds

    // True if current activity includes a comparison task
    const hasModifications = !!activityRef.getActivity().diffTask;

    // True if current row has children
    const isParent = activityRef.getRow().getChildren().length;

    // Set colors dynamically
    this._setActivityColor(activityRef, hasModifications);

    // Draw text
    this._drawActivityText(activityRef, ctx, x, y, w, h, hasModifications);

    // Run a custom method to draw parent activities or delegate to the default method
    return isParent
      ? this._drawParentActivity(activityRef, ctx, x, y, w, h, hover, hasModifications)
      : super.drawActivity(activityRef, position, ctx, x, y, w, h, selected, hover, highlighted, pressed);
  }

描画は次のように行われます:

  • ActivityRef API を使用して、現在の Activity および Row に関する情報を取得します
  • _setActivityColor メソッドを使用して動的に色を設定します
  • _drawActivityText メソッドを使用してアクティビティ テキストを描画します
  • 次の 2 つの方法を使用してアクティビティ自体を描画します。 親を描画する _drawParentActivity メソッド 子を描画するための super.drawActivity のデフォルトの ActivityBarRenderer メソッド

カスタムアクティビティの描画方法

_drawParentActivity メソッドを使用して独自のメソッドを設計し、アクティビティを自由に描画する方法を詳しく見てみましょう。

// Draw the parent activity

private _drawParentActivity(activityRef: ActivityRef,
                            ctx: CanvasRenderingContext2D,
                            x: number,
                            y: number,
                            w: number,
                            h: number,
                            hover: boolean,
                            hasModifications: boolean
                           ): ActivityBounds {

    // Set padding
    const topPadding = h / 3.5;
    const leftPadding = 1;

    // Set CanvasRenderingContext2D
    ctx.lineWidth = this._defaultLineWidthPx;
    if (hover) {
      ctx.fillStyle = this._onHoverFillColor;
      ctx.strokeStyle = ScheduleJsViewerColors.brown;
    } else if (hasModifications) {
      ctx.fillStyle = Color.web(this._parentActivityColor).withOpacity(this._baselineOpacityRatio).toCssString();
      ctx.strokeStyle = `rgba(0,0,0,${this._baselineOpacityRatio})`;
    } else {
      ctx.fillStyle = this._parentActivityColor;
      ctx.strokeStyle = this._strokeColor;
    }

    // Draw elements
    ScheduleJsViewerTaskActivityRenderer._drawParentActivityStartTriangle(ctx, x   leftPadding, y   topPadding, this._parentActivityTrianglesWidthPx, this._parentActivityTrianglesHeightPx);
    ScheduleJsViewerTaskActivityRenderer._drawParentActivityBody(ctx, x   leftPadding, y   topPadding, w, this._parentActivityTrianglesWidthPx, this._parentActivityTrianglesHeightPx);
    ScheduleJsViewerTaskActivityRenderer._drawParentActivityEndTriangle(ctx, x   leftPadding, y   topPadding, w, this._parentActivityTrianglesWidthPx, this._parentActivityTrianglesHeightPx);

    // Return positions to update where your activity should be responsive
    return new ActivityBounds(activityRef, x, y, w, h);
  }

ここでは、HTMLCanvas APIを直接使用して、CanvasRenderingContex2Dを設定することで描画戦略を定義します。このメソッドで行われる唯一のフレームワーク関連の操作は、現在の親 Activity に対して新しい ActivityBounds を作成することです。

フレームワークは、内部で ActivityBounds を使用してマップを作成し、画面上のすべてのアクティビティを登録します。このマップは、HTMLCanvas API のパフォーマンスを活用しながら、正確な情報に基づいて高度なユーザー エクスペリエンスを構築するための要素のようなロジックを提供することで開発者を支援します。

_drawParentActivityStartTriangle などの描画要素メソッドは、CanvasRenderingContext2D API に依存してピクセル レベルで描画します。

// Draw the start triangle element of the parent activity

private static _drawParentActivityStartTriangle(ctx: CanvasRenderingContext2D,
                                                x: number,
                                                y: number,
                                                triangleWidth: number,
                                                triangleHeight: number): void {
    ctx.beginPath();
    ctx.moveTo(x, y);
    ctx.lineTo(x , y   triangleHeight);
    ctx.lineTo(x   triangleWidth, y);
    ctx.lineTo(x, y);
    ctx.fill();
    ctx.stroke();
    ctx.closePath();
}

最終結果

新しいレンダラーを登録するには、graphics.setActivityRenderer メソッドを使用します。

// Register the renderer

graphics.setActivityRenderer(ScheduleJsViewerTaskActivity, GanttLayout, new ScheduleJsViewerTaskActivityRenderer(graphics, currentRibbonMenuTab));

brand-new renderer

最終結果のビデオを見るには、「ActivityRenderer の構築」を参照してください。

リリースステートメント この記事は次の場所に転載されています: https://dev.to/lenormor/building-an-activityrenderer-3o0?1 侵害がある場合は、[email protected] に連絡して削除してください。
最新のチュートリアル もっと>
  • CSSメディアクエリ
    CSSメディアクエリ
    Web サイトがさまざまなデバイス間でシームレスに機能することを保証することが、これまで以上に重要になっています。ユーザーがデスクトップ、ラップトップ、タブレット、スマートフォンから Web サイトにアクセスするようになったため、レスポンシブ デザインが必須となっています。レスポンシブ デザインの中...
    プログラミング 2024 年 11 月 5 日に公開
  • JavaScript でのホイスティングを理解する: 包括的なガイド
    JavaScript でのホイスティングを理解する: 包括的なガイド
    JavaScript でのホイスティング ホイストは、変数と関数の宣言が、含まれるスコープ (グローバル スコープまたは関数スコープ) の先頭に移動 (または「ホイスト」) される動作です。コードが実行されます。これは、コード内で実際に宣言される前に変数や関数を使用できることを意味...
    プログラミング 2024 年 11 月 5 日に公開
  • Stripe を単一製品の Django Python ショップに統合する
    Stripe を単一製品の Django Python ショップに統合する
    In the first part of this series, we created a Django online shop with htmx. In this second part, we'll handle orders using Stripe. What We'll...
    プログラミング 2024 年 11 月 5 日に公開
  • Laravel でキューに入れられたジョブをテストするためのヒント
    Laravel でキューに入れられたジョブをテストするためのヒント
    Laravel アプリケーションを使用する場合、コマンドが負荷の高いタスクを実行する必要があるシナリオに遭遇するのが一般的です。メインプロセスのブロックを避けるために、キューで処理できるジョブにタスクをオフロードすることを決定することもできます。 例を見てみましょう。コマンド app:import-...
    プログラミング 2024 年 11 月 5 日に公開
  • 人間レベルの自然言語理解 (NLU) システムを作成する方法
    人間レベルの自然言語理解 (NLU) システムを作成する方法
    Scope: Creating an NLU system that fully understands and processes human languages in a wide range of contexts, from conversations to literature. ...
    プログラミング 2024 年 11 月 5 日に公開
  • JSTL を使用して HashMap 内で ArrayList を反復するにはどうすればよいですか?
    JSTL を使用して HashMap 内で ArrayList を反復するにはどうすればよいですか?
    JSTL を使用した HashMap 内の ArrayList の反復Web 開発では、JSTL (JavaServer Pages Standard Tag Library) は、JSP での一般的なタスクを簡素化するためのタグのセットを提供します ( Javaサーバーページ)。そのようなタスクの...
    プログラミング 2024 年 11 月 5 日に公開
  • Encore.ts — ElysiaJS や Hono よりも高速
    Encore.ts — ElysiaJS や Hono よりも高速
    数か月前、私たちは TypeScript 用のオープンソース バックエンド フレームワークである Encore.ts をリリースしました。 すでに多くのフレームワークが存在するため、私たちが行った珍しい設計上の決定のいくつかと、それがどのようにして驚くべきパフォーマンス数値につながるのかを共有したい...
    プログラミング 2024 年 11 月 5 日に公開
  • + を使用した文字列連結が文字列リテラルで失敗するのはなぜですか?
    + を使用した文字列連結が文字列リテラルで失敗するのはなぜですか?
    文字列リテラルと文字列の連結C では、演算子を使用して文字列と文字列リテラルを連結できます。ただし、この機能には混乱を招く可能性のある制限があります。質問の中で、作成者は文字列リテラル「Hello」、「,world」、および「!」を連結しようとしています。 2つの異なる方法で。最初の例:const ...
    プログラミング 2024 年 11 月 5 日に公開
  • React の再レンダリング: 最適なパフォーマンスのためのベスト プラクティス
    React の再レンダリング: 最適なパフォーマンスのためのベスト プラクティス
    React の効率的なレンダリング メカニズムは、その人気の主な理由の 1 つです。ただし、アプリケーションが複雑になるにつれて、コンポーネントの再レンダリングの管理がパフォーマンスを最適化するために重要になります。 React のレンダリング動作を最適化し、不必要な再レンダリングを回避するためのベ...
    プログラミング 2024 年 11 月 5 日に公開
  • 条件付き列の作成を実現する方法: Pandas DataFrame で If-Elif-Else を探索する?
    条件付き列の作成を実現する方法: Pandas DataFrame で If-Elif-Else を探索する?
    条件付き列の作成: Pandas の If-Elif-Else指定された問題では、新しい列を DataFrame に追加することが求められます一連の条件付き基準に基づいて決定されます。課題は、コードの効率性と可読性を維持しながらこれらの条件を実装することにあります。関数アプリケーションを使用したソリ...
    プログラミング 2024 年 11 月 5 日に公開
  • 秋さんのご紹介です!
    秋さんのご紹介です!
    Qiu のリリースを発表できることを嬉しく思います。これは、生の SQL を再び楽しくするために設計された、実用的な SQL クエリ ランナーです。正直に言うと、ORM にはその役割がありますが、単純な SQL を書きたいだけの場合は、少し圧倒されてしまう可能性があります。私は生の SQL クエリ...
    プログラミング 2024 年 11 月 5 日に公開
  • CSS でコンテナの幅に基づいてマージントップのパーセンテージが計算されるのはなぜですか?
    CSS でコンテナの幅に基づいてマージントップのパーセンテージが計算されるのはなぜですか?
    CSS でのマージントップ パーセンテージの計算要素にマージントップ パーセンテージを適用する場合、その計算方法を理解することが重要です。実行されました。一般的な考えに反して、マージントップのパーセンテージは、ブロックを含むブロックの高さではなく、幅に基づいて決定されます。W3C 仕様の説明: W3...
    プログラミング 2024 年 11 月 5 日に公開
  • CSS 移行中の Webkit テキストのレンダリングの不一致を解決するにはどうすればよいですか?
    CSS 移行中の Webkit テキストのレンダリングの不一致を解決するにはどうすればよいですか?
    CSS 遷移中の Webkit テキスト レンダリングの不一致を解決するCSS 遷移中、特に要素をスケーリングするときに、Webkit 内でテキスト レンダリングの不一致が発生する可能性があります。ブラウザ。この問題は、ブラウザがレンダリング パフォーマンスを最適化しようとすることが原因で発生します...
    プログラミング 2024 年 11 月 5 日に公開
  • Reactables で簡素化された RxJS
    Reactables で簡素化された RxJS
    導入 RxJS は強力なライブラリですが、学習曲線が急であることが知られています。 ライブラリの大規模な API サーフェスは、リアクティブ プログラミングへのパラダイム シフトと相まって、初心者にとっては圧倒される可能性があります。 RxJS の使用法を簡素化し、開発者がリアクテ...
    プログラミング 2024 年 11 月 5 日に公開
  • Pandas の複数の列にわたる最大値を見つける方法?
    Pandas の複数の列にわたる最大値を見つける方法?
    Pandas の複数の列にわたる最大値の検索Pandas DataFrame の複数の列にわたる最大値を決定するには、さまざまなアプローチを使用できます。 。これを実現する方法は次のとおりです。指定された列で max() 関数を使用するこの方法では、目的の列を明示的に選択し、max() 関数を適用し...
    プログラミング 2024 年 11 月 5 日に公開

免責事項: 提供されるすべてのリソースの一部はインターネットからのものです。お客様の著作権またはその他の権利および利益の侵害がある場合は、詳細な理由を説明し、著作権または権利および利益の証拠を提出して、電子メール [email protected] に送信してください。 できるだけ早く対応させていただきます。

Copyright© 2022 湘ICP备2022001581号-3